Skip to content

Refactor(workspace): Updated workspace models and resource#106

Merged
isivaselvan merged 4 commits intonext-0.1.3from
refactor/workspace-models
Mar 13, 2026
Merged

Refactor(workspace): Updated workspace models and resource#106
isivaselvan merged 4 commits intonext-0.1.3from
refactor/workspace-models

Conversation

@isivaselvan
Copy link
Copy Markdown
Collaborator

@isivaselvan isivaselvan commented Mar 4, 2026

Description

This PR refactors the workspace models layer to leverage Pydantic's native capabilities for validation, serialization, and alias-based field mapping — replacing the previous pattern of manual attribute construction and standalone validation functions.

Changes

models/workspace.py

  • Added model_config = ConfigDict(populate_by_name=True, validate_by_name=True) to all workspace models.
  • Added kebab-case alias to every Field() to match the TFC JSON:API wire format directly.
  • Changed boolean/string default values (e.g., False, "", 0) to None across Workspace — fields are now optional and only populated when present in the API response.
  • Split VCSRepo (read model, full response fields) from VCSRepoOptions (write model, create/update payload subset). Added rich response fields to VCSRepo: display_identifier, repository_http_url, service_provider, webhook_url, tag_prefix, source_directory, etc.
  • Moved WorkspaceSource, WorkspaceActions, WorkspacePermissions, WorkspaceSettingOverwrites, WorkspaceOutputs, LockedByChoice, and VCSRepo definitions above Workspace (forward-reference fix).
  • Added @model_validator(mode="after") to WorkspaceCreateOptions and WorkspaceUpdateOptions, moving all validation logic (name format, agent mode, execution mode conflicts, trigger pattern/prefix conflicts, tags regex conflicts) directly into the model — removing the need for external validate_workspace_create_options / validate_workspace_update_options helpers.
  • Removed the WorkspaceList model (pagination handled at the service layer).
  • Added _rebuild_workspace_model() helper to resolve the circular forward reference to Run.
  • Workspace.organization changed from str to Organization | None; agent_pool typed as AgentPool | None, current_run typed as Run | None.
  • WorkspaceListOptions, WorkspaceReadOptions, WorkspaceListRemoteStateConsumersOptions, WorkspaceTagListOptions — query param fields now use API-format aliases (e.g., page[size], search[name], filter[project][id]);.
  • WorkspaceAssignSSHKeyOptions / workspaceUnassignSSHKeyOptions — ssh_key_id field alias changed to id to match the relationships payload.
  • WorkspaceLockOptions.reason made optional (defaults to None).

resources/workspace.py

  • _ws_from() signature simplified — org parameter removed; organization now parsed from the relationships block using Organization.model_validate(...).
  • All manual field-by-field construction replaced with Model.model_validate(...) calls (WorkspaceActions, WorkspacePermissions, WorkspaceSettingOverwrites, VCSRepo, outputs, locked-by, data retention policy).
  • _build_workspace_payload(): replaced ~80 lines of if attr is not None: attrs["attr"] = attr logic with options.model_dump(by_alias=True, exclude_none=True, exclude={...}).
  • list(): query params now built directly from options.model_dump(...) instead of individual if branches. Tag binding filter key corrected from search[tag-bindings] → filter[tagged].
  • list_remote_state_consumers(): options parameter changed to optional.
  • list_tags(), list_remote_state_consumers(): params built via model_dump instead of manual mapping.
  • Removed imports of validate_workspace_create_options, validate_workspace_update_options, _safe_str, WorkspaceSource, WorkspaceRemoveVCSConnectionOptions.
  • remove_vcs_connection / remove_vcs_connection_by_id: simplified to pass {"vcs-repo": None} directly instead of creating an intermediary options object.
  • Added explicit return None to all void methods for clarity.

utils.py

  • Removed validate_workspace_create_options() and validate_workspace_update_options() (logic moved into model validators).
  • Removed imports of WorkspaceCreateOptions, WorkspaceUpdateOptions, VCSRepo, and the associated error types from this file.
  • has_tags_regex_defined() type hint updated from VCSRepo → VCSRepoOptions.
  • Added TYPE_CHECKING import guard for VCSRepoOptions to avoid circular imports.

models/init.py

  • Removed WorkspaceList from imports and all.

run_trigger.py

  • Workspace(...) constructor calls replaced with Workspace.model_validate({...}) for consistency with the new alias-based model config.

variable_set.py

  • Removed "organization" placeholder from inline workspace construction (field no longer required as a plain string).

examples/workspace.py

  • Removed --page CLI argument and page_number from WorkspaceListOptions (parameter no longer exists).

Unit tests at test_workspace.py, test_run.py, test_run_trigger.py

  • organization field in Workspace(...) test fixtures changed from a string value to None (field is now Organization | None).
  • VCSRepo import replaced with VCSRepoOptions in workspace tests.
  • _ws_from(data, "test-org") calls updated to _ws_from(data).
  • Assertions updated: None fields no longer fall back to "" or 0 — e.g., workspace.description is None, workspace.terraform_version is None.
  • page_number removed from WorkspaceListRemoteStateConsumersOptions and WorkspaceTagListOptions test calls; corresponding params assertions removed.

Testing plan

External links

Output from tests

Including output from tests may require access to a TFE instance. Ignore this section if you have no environment to test against.

python examples/workspace.py --org=siva

================================================================================
Listing workspaces
================================================================================
Fetching workspaces from organization 'prab-sandbox01', size 10)...
Found 20 workspaces

 1. test-duplicate-20251125-185311
    ID: ws-1B8Jn
    Execution Mode: ExecutionMode.REMOTE
    Auto Apply: False

 2. test-tagbindings-20251217-215641
    ID: ws-veAeUx8i
    Execution Mode: ExecutionMode.REMOTE
    Auto Apply: False

 3. test-ssh-20251217-192455
    ID: ws-hepopaxG
    Execution Mode: ExecutionMode.REMOTE
    Auto Apply: False

 4. test-lock-20251217-192042
    ID: ws-b6fCKzrKQ
    Execution Mode: ExecutionMode.REMOTE
    Auto Apply: False

 5. test-vcs-byid-20251217-191041
    ID: ws-5pc3d
    Execution Mode: ExecutionMode.REMOTE
    Auto Apply: False

 6. test-vcs-removal-byid-20251217-191015
    ID: ws-cgUzGn
    Execution Mode: ExecutionMode.REMOTE
    Auto Apply: False

Rollback Plan

Changes to Security Controls

PCI review checklist

  • I have documented a clear reason for, and description of, the change I am making.

  • If applicable, I've documented a plan to revert these changes if they require more than reverting the pull request.

  • If applicable, I've documented the impact of any changes to security controls.

    Examples of changes to security controls include using new access control methods, adding or removing logging pipelines, etc.

If you have any questions, please contact your direct supervisor, GRC (#team-grc), or the PCI working group (#proj-pci-reboot). You can also find more information at PCI Compliance.

@isivaselvan isivaselvan requested a review from a team as a code owner March 4, 2026 05:20
@isivaselvan isivaselvan force-pushed the refactor/workspace-models branch from dbbdfdd to c1d0ec5 Compare March 12, 2026 11:17
@isivaselvan isivaselvan merged commit a001f7d into next-0.1.3 Mar 13, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant