Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
529 changes: 529 additions & 0 deletions examples/agent.py

Large diffs are not rendered by default.

664 changes: 664 additions & 0 deletions examples/agent_pool.py

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/tfe/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from ._http import HTTPTransport
from .config import TFEConfig
from .resources.agent_pools import AgentPools
from .resources.agents import Agents, AgentTokens
from .resources.organizations import Organizations
from .resources.projects import Projects
from .resources.registry_module import RegistryModules
Expand Down Expand Up @@ -32,6 +34,12 @@ def __init__(self, config: TFEConfig | None = None):
proxies=cfg.proxies,
ca_bundle=cfg.ca_bundle,
)
# Agent resources
self.agent_pools = AgentPools(self._transport)
self.agents = Agents(self._transport)
self.agent_tokens = AgentTokens(self._transport)

# Core resources
self.organizations = Organizations(self._transport)
self.projects = Projects(self._transport)
self.variables = Variables(self._transport)
Expand All @@ -41,6 +49,7 @@ def __init__(self, config: TFEConfig | None = None):
self.registry_modules = RegistryModules(self._transport)
self.registry_providers = RegistryProviders(self._transport)

# State and execution resources
self.state_versions = StateVersions(self._transport)
self.state_version_outputs = StateVersionOutputs(self._transport)
self.run_tasks = RunTasks(self._transport)
Expand Down
35 changes: 35 additions & 0 deletions src/tfe/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@
import importlib.util
import os

# Re-export all agent and agent pool types
from .agent import (
Agent,
AgentListOptions,
AgentPool,
AgentPoolAllowedWorkspacePolicy,
AgentPoolAssignToWorkspacesOptions,
AgentPoolCreateOptions,
AgentPoolListOptions,
AgentPoolReadOptions,
AgentPoolRemoveFromWorkspacesOptions,
AgentPoolUpdateOptions,
AgentReadOptions,
AgentStatus,
AgentToken,
AgentTokenCreateOptions,
AgentTokenListOptions,
)

# Re-export all registry module types
from .registry_module_types import (
AgentExecutionMode,
Expand Down Expand Up @@ -51,6 +70,22 @@

# Define what should be available when importing with *
__all__ = [
# Agent and agent pool types
"Agent",
"AgentPool",
"AgentPoolAllowedWorkspacePolicy",
"AgentPoolAssignToWorkspacesOptions",
"AgentPoolCreateOptions",
"AgentPoolListOptions",
"AgentPoolReadOptions",
"AgentPoolRemoveFromWorkspacesOptions",
"AgentPoolUpdateOptions",
"AgentStatus",
"AgentListOptions",
"AgentReadOptions",
"AgentToken",
"AgentTokenCreateOptions",
"AgentTokenListOptions",
# Registry module types
"AgentExecutionMode",
"Commit",
Expand Down
172 changes: 172 additions & 0 deletions src/tfe/models/agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
"""Agent and Agent Pool models for the Python TFE SDK.

This module contains Pydantic models for Terraform Enterprise/Cloud agents and agent pools,
including all necessary option classes for CRUD operations.

Based on the Go TFE implementation:
https://github.com/hashicorp/go-tfe/blob/main/agent.go

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these lines of go-tfe ref

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

https://github.com/hashicorp/go-tfe/blob/main/agent_pool.go
"""

from __future__ import annotations

from datetime import datetime
from enum import Enum
from typing import Any

from pydantic import BaseModel, Field


class AgentStatus(str, Enum):
"""Agent status enumeration."""

IDLE = "idle"
BUSY = "busy"
UNKNOWN = "unknown"


class AgentPoolAllowedWorkspacePolicy(str, Enum):
"""Agent pool allowed workspace policy enumeration."""

ALL_WORKSPACES = "all-workspaces"
SPECIFIC_WORKSPACES = "specific-workspaces"


class Agent(BaseModel):
"""Agent represents a Terraform Enterprise agent."""

id: str
name: str | None = None
status: AgentStatus | None = None
version: str | None = None
last_ping_at: datetime | None = None
ip_address: str | None = None

# Relations
agent_pool: AgentPool | None = None


class AgentPool(BaseModel):
"""Agent Pool represents a Terraform Enterprise agent pool."""

id: str
name: str | None = None
created_at: datetime | None = None
organization_scoped: bool | None = None
allowed_workspace_policy: AgentPoolAllowedWorkspacePolicy | None = None
agent_count: int = 0

# Relations
organization: Any | None = None # Organization type from main types
workspaces: list[Any] = Field(default_factory=list) # Workspace types
agents: list[Agent] = Field(default_factory=list)


# Agent Pool Options


class AgentPoolListOptions(BaseModel):
"""Options for listing agent pools."""

# Pagination options
page_number: int | None = None
page_size: int | None = None
# Optional: Include related resources
include: list[str] | None = None
# Optional: Filter by allowed workspace policy
allowed_workspace_policy: AgentPoolAllowedWorkspacePolicy | None = None


class AgentPoolCreateOptions(BaseModel):
"""Options for creating an agent pool."""

# Required: A name to identify the agent pool
name: str
# Optional: Whether the agent pool is organization scoped
organization_scoped: bool | None = None
# Optional: Allowed workspace policy
allowed_workspace_policy: AgentPoolAllowedWorkspacePolicy | None = None


class AgentPoolUpdateOptions(BaseModel):
"""Options for updating an agent pool."""

# Optional: A name to identify the agent pool
name: str | None = None
# Optional: Whether the agent pool is organization scoped
organization_scoped: bool | None = None
# Optional: Allowed workspace policy
allowed_workspace_policy: AgentPoolAllowedWorkspacePolicy | None = None


class AgentPoolReadOptions(BaseModel):
"""Options for reading an agent pool."""

# Optional: Include related resources
include: list[str] | None = None


# Agent Pool Workspace Assignment Options


class AgentPoolAssignToWorkspacesOptions(BaseModel):
"""Options for assigning an agent pool to workspaces."""

workspace_ids: list[str] = Field(default_factory=list)


class AgentPoolRemoveFromWorkspacesOptions(BaseModel):
"""Options for removing an agent pool from workspaces."""

workspace_ids: list[str] = Field(default_factory=list)


# Agent Options


class AgentListOptions(BaseModel):
"""Options for listing agents."""

# Pagination options
page_number: int | None = None
page_size: int | None = None
# Optional: Filter by status
status: AgentStatus | None = None


class AgentReadOptions(BaseModel):
"""Options for reading an agent."""

# Optional: Include related resources
include: list[str] | None = None


# Agent Token Options


class AgentTokenCreateOptions(BaseModel):
"""Options for creating an agent token."""

# Required: A description for the token
description: str


class AgentToken(BaseModel):
"""Agent Token represents an authentication token for agents."""

id: str
description: str | None = None
created_at: datetime | None = None
last_used_at: datetime | None = None
token: str | None = None # Only returned on creation

# Relations
agent_pool: AgentPool | None = None


class AgentTokenListOptions(BaseModel):
"""Options for listing agent tokens."""

# Pagination options
page_number: int | None = None
page_size: int | None = None
29 changes: 29 additions & 0 deletions src/tfe/models/agent_pool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Legacy Agent Pool model - DEPRECATED.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need backward compatibility right now. This package is still under internal development. As we have moved to agent.py, please update run_task to inherit from new model file.


This file is kept for backward compatibility.
Please use src/tfe/models/agent.py for new agent and agent pool models.
"""

from __future__ import annotations

from typing import Any

from pydantic import BaseModel

# Re-export from the new agent module


class AgentPool(BaseModel):
"""Legacy Agent Pool model - use agent.AgentPool instead."""

id: str

def __init_subclass__(cls, **kwargs: Any) -> None:
import warnings

warnings.warn(
"AgentPool from agentpool.py is deprecated. Use agent.AgentPool instead.",
DeprecationWarning,
stacklevel=2,
)
super().__init_subclass__(**kwargs)
7 changes: 0 additions & 7 deletions src/tfe/models/agentpool.py

This file was deleted.

2 changes: 1 addition & 1 deletion src/tfe/models/run_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from pydantic import BaseModel, Field

from ..types import Pagination
from .agentpool import AgentPool
from .agent_pool import AgentPool

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just use model/agent.py here ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

from .organization import Organization
from .workspace_run_task import WorkspaceRunTask

Expand Down
Loading
Loading