Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0b500d4
[COMPLIANCE] Add Copyright and License Headers
hashicorp-copywrite[bot] Mar 10, 2026
30fcdaf
Merge pull request #112 from hashicorp/compliance/add-headers
ritikrajdev Apr 2, 2026
9d6c3ae
Release 0.1.3 (#122)
isivaselvan Apr 6, 2026
3682795
makefile updated to run example files
KshitijaChoudhari Apr 7, 2026
d46ea8e
makefile updated tun run example file - so ci/cd can run
KshitijaChoudhari Apr 7, 2026
0cc4acf
updated make file to run alll integration tests and have ddedd integr…
KshitijaChoudhari Apr 7, 2026
f4a33d9
updates varibles and oauth client example file sto pickup runtime env…
KshitijaChoudhari Apr 7, 2026
6248b9e
updates variables and ouath client exampel files to use run time work…
KshitijaChoudhari Apr 7, 2026
40975a8
updates variables and uath client exampel files to use run time works…
KshitijaChoudhari Apr 7, 2026
74739bf
makecheck file restored to orginial one and updated integration file …
KshitijaChoudhari Apr 7, 2026
9699016
intgeration-test.yml, configuration_version and query/-run
KshitijaChoudhari Apr 9, 2026
65a08aa
Updated integration-test to remove true
KshitijaChoudhari Apr 9, 2026
6093e21
Updated integration-test, configuration-version and query_run
KshitijaChoudhari Apr 9, 2026
2293756
have kepttrue on for oauth client and token
KshitijaChoudhari Apr 9, 2026
58c2563
Updated integration-test.yml
KshitijaChoudhari Apr 9, 2026
bab9c41
Updated integration-test.yml for oauth-token.py
KshitijaChoudhari Apr 9, 2026
bf8f476
Updated integration-test.yml for oauth-token.py
KshitijaChoudhari Apr 9, 2026
aeb7025
made changes to example files notification_configuration and registr…
KshitijaChoudhari Apr 9, 2026
f2d121c
made changes to example files notification_configuration and integra…
KshitijaChoudhari Apr 10, 2026
eccc98e
made changes to example files notification_configuration and integra…
KshitijaChoudhari Apr 10, 2026
5c5e75c
Updated organization_mebership and respectiev integration tests
KshitijaChoudhari Apr 10, 2026
7095e73
formatted organization_mebership
KshitijaChoudhari Apr 10, 2026
229ea98
Merge pull request #125 from KshitijaChoudhari/main
KshitijaChoudhari Apr 13, 2026
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
3 changes: 3 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright IBM Corp. 2025, 2026
# SPDX-License-Identifier: MPL-2.0

blank_issues_enabled: false
contact_links:
- name: HCP Terraform and Terraform Enterprise Troubleshooting and Feature Requests
Expand Down
195 changes: 195 additions & 0 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
name: SDK Integration Tests

on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:

jobs:
unit-tests:
name: Unit Tests
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install dependencies
run: make dev-install

- name: Run format check
run: make fmt-check

- name: Run lint
run: make lint

- name: Run unit tests
run: make type-check && .venv/bin/python -m pytest -v tests/

integration-tests:
name: Integration Tests (Example Files)
runs-on: ubuntu-latest
needs: unit-tests # only runs if unit tests pass

env:
TFE_TOKEN: ${{ secrets.TFE_TOKEN }}
TFE_ORG: ${{ secrets.TFE_ORG }}
TFE_ADDRESS: ${{ secrets.TFE_ADDRESS }}
TFE_WORKSPACE_ID: ${{ secrets.TFE_WORKSPACE_ID }}
TFE_WORKSPACE_NAME: ${{ secrets.TFE_WORKSPACE_NAME }}
TFE_TEAM_ID: ${{ secrets.TFE_TEAM_ID }}
TFE_RUN_ID: ${{ secrets.TFE_RUN_ID }}
TFE_APPLY_ID: ${{ secrets.TFE_APPLY_ID }}
TFE_PLAN_ID: ${{ secrets.TFE_PLAN_ID }}
TFE_TASK_STAGE_ID: ${{ secrets.TFE_TASK_STAGE_ID }}
TFE_POLICY_SET_ID: ${{ secrets.TFE_POLICY_SET_ID }}
TFE_POLICY_NAME: ${{ secrets.TFE_POLICY_NAME }}
TFE_REG_PROV_NS: ${{ secrets.TFE_REG_PROV_NS }}
TFE_REG_PROV_NAME: ${{ secrets.TFE_REG_PROV_NAME }}
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
OAUTH_CLIENT_GITHUB_TOKEN: ${{ secrets.OAUTH_CLIENT_GITHUB_TOKEN }}
WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }}
TEAMS_WEBHOOK_URL: ${{ secrets.TEAMS_WEBHOOK_URL }}
TEST_MEMBER_EMAIL: ${{ secrets.TEST_MEMBER_EMAIL }}
TEAM_MEMBERSHIP_ID: ${{secretS.TEAM_MEBERSHIP_ID}}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install dependencies
run: make dev-install

- name: agent.py
run: .venv/bin/python examples/agent.py

- name: agent_pool.py
run: .venv/bin/python examples/agent_pool.py

- name: apply.py
if: ${{ env.TFE_APPLY_ID != '' }}
run: .venv/bin/python examples/apply.py --apply-id "$TFE_APPLY_ID"

- name: configuration_version.py
if: ${{ env.TFE_WORKSPACE_ID != '' }}
run: .venv/bin/python examples/configuration_version.py

- name: notification_configuration.py
if: ${{ env.TFE_WORKSPACE_ID != '' || env.TFE_WORKSPACE_NAME != '' }}
run: .venv/bin/python examples/notification_configuration.py

- name: oauth_client.py
run: .venv/bin/python examples/oauth_client.py

- name: oauth_token.py
run: .venv/bin/python examples/oauth_token.py

- name: org.py
run: .venv/bin/python examples/org.py

- name: organization_membership.py
run: .venv/bin/python examples/organization_membership.py

- name: plan.py
if: ${{ env.TFE_PLAN_ID != '' }}
run: .venv/bin/python examples/plan.py --plan-id "$TFE_PLAN_ID"

- name: policy_check.py
if: ${{ env.TFE_RUN_ID != '' }}
run: .venv/bin/python examples/policy_check.py --run-id "$TFE_RUN_ID"

- name: policy_evaluation.py
if: ${{ env.TFE_TASK_STAGE_ID != '' }}
run: .venv/bin/python examples/policy_evaluation.py --task-stage-id "$TFE_TASK_STAGE_ID"

- name: policy_set_parameter.py
if: ${{ env.TFE_POLICY_SET_ID != '' }}
run: .venv/bin/python examples/policy_set_parameter.py --policy-set-id "$TFE_POLICY_SET_ID"

- name: policy_set.py
run: .venv/bin/python examples/policy_set.py --org "$TFE_ORG"

- name: policy.py
if: ${{ env.TFE_POLICY_NAME != '' }}
run: .venv/bin/python examples/policy.py --org "$TFE_ORG" --policy-name "$TFE_POLICY_NAME"

- name: project.py
run: .venv/bin/python examples/project.py --list --organization "$TFE_ORG"

- name: query_run.py
if: ${{ env.TFE_WORKSPACE_NAME != '' }}
run: .venv/bin/python examples/query_run.py

- name: registry_module.py
run: .venv/bin/python examples/registry_module.py

- name: registry_provider_version.py
if: ${{ env.TFE_REG_PROV_NS != '' && env.TFE_REG_PROV_NAME != '' }}
run: |
.venv/bin/python examples/registry_provider_version.py \
--organization "$TFE_ORG" \
--namespace "$TFE_REG_PROV_NS" \
--name "$TFE_REG_PROV_NAME"

- name: registry_provider.py
run: .venv/bin/python examples/registry_provider.py

- name: reserved_tag_key.py
run: .venv/bin/python examples/reserved_tag_key.py

- name: run_events.py
if: ${{ env.TFE_RUN_ID != '' }}
run: .venv/bin/python examples/run_events.py --run-id "$TFE_RUN_ID"

- name: run_task.py
run: .venv/bin/python examples/run_task.py --org "$TFE_ORG"

- name: run_trigger.py
run: .venv/bin/python examples/run_trigger.py --org "$TFE_ORG"

- name: run.py
run: .venv/bin/python examples/run.py --organization "$TFE_ORG"

- name: ssh_keys.py
if: ${{ env.SSH_PRIVATE_KEY != '' }}
run: .venv/bin/python examples/ssh_keys.py

- name: state_versions.py
if: ${{ env.TFE_WORKSPACE_ID != '' && env.TFE_WORKSPACE_NAME != '' }}
run: |
.venv/bin/python examples/state_versions.py \
--org "$TFE_ORG" \
--workspace "$TFE_WORKSPACE_NAME" \
--workspace-id "$TFE_WORKSPACE_ID"

- name: variable_sets.py
run: .venv/bin/python examples/variable_sets.py

- name: variables.py
if: ${{ env.TFE_WORKSPACE_ID != '' }}
run: .venv/bin/python examples/variables.py

- name: workspace_resources.py
if: ${{ env.TFE_WORKSPACE_ID != '' }}
run: |
.venv/bin/python examples/workspace_resources.py \
--list \
--workspace-id "$TFE_WORKSPACE_ID" \
--page-size 10

- name: workspace.py
run: .venv/bin/python examples/workspace.py --org "$TFE_ORG" --list
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,4 @@ protos.bin

# Local RSA keys
.local/*

39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,44 @@
# Unreleased

# v0.1.3

## Enhancements

### Iterator Pattern Migration
* Migrated Run resource list operations to iterator pattern by @NimishaShrivastava-dev [#91](https://github.com/hashicorp/python-tfe/pull/91)
* Migrated Policy resource list operations to iterator pattern by @TanyaSingh369-svg [#92](https://github.com/hashicorp/python-tfe/pull/92)
* Migrated Policy Set resource list operations to iterator pattern by @TanyaSingh369-svg [#95](https://github.com/hashicorp/python-tfe/pull/95)
* Migrated Run Event resource list operations to iterator pattern by @NimishaShrivastava-dev [#97](https://github.com/hashicorp/python-tfe/pull/97)
* Migrated SSH Keys resource list operations to iterator pattern by @NimishaShrivastava-dev [#101](https://github.com/hashicorp/python-tfe/pull/101)
* Migrated Notification Configuration resource list operations to iterator pattern by @TanyaSingh369-svg [#109](https://github.com/hashicorp/python-tfe/pull/109)
* Migrated Variable Set list operations to iterator pattern by @isivaselvan [#113](https://github.com/hashicorp/python-tfe/pull/113)
* Migrated Variable Set Variables list operations to iterator pattern by @isivaselvan [#113](https://github.com/hashicorp/python-tfe/pull/113)
* Migrated State Version list operations to iterator pattern by @isivaselvan [#113](https://github.com/hashicorp/python-tfe/pull/113)
* Migrated State Version Output list operations to iterator pattern by @isivaselvan [#113](https://github.com/hashicorp/python-tfe/pull/113)
* Migrated Policy Check list operations to iterator pattern by @isivaselvan [#113](https://github.com/hashicorp/python-tfe/pull/113)
* Refreshed examples and unit tests to align with iterator pattern updates by @NimishaShrivastava-dev, @TanyaSingh369-svg, @isivaselvan [#91](https://github.com/hashicorp/python-tfe/pull/91) [#92](https://github.com/hashicorp/python-tfe/pull/92) [#95](https://github.com/hashicorp/python-tfe/pull/95) [#97](https://github.com/hashicorp/python-tfe/pull/97) [#101](https://github.com/hashicorp/python-tfe/pull/101) [#109](https://github.com/hashicorp/python-tfe/pull/109) [#113](https://github.com/hashicorp/python-tfe/pull/113)

### Project and Workspace Management
* Updated Project create and update models, including Project model refinements by @isivaselvan [#120](https://github.com/hashicorp/python-tfe/pull/120)
* Updated Project endpoints for list-effective-tag-bindings and delete-tag-bindings by @isivaselvan [#120](https://github.com/hashicorp/python-tfe/pull/120)
* Refactored Workspace models to improve validation with Pydantic by @isivaselvan [#106](https://github.com/hashicorp/python-tfe/pull/106)

## Breaking Change

### List Method Behavior
* Standardized list methods across multiple resources to iterator-based behavior, replacing legacy list response patterns by @NimishaShrivastava-dev, @TanyaSingh369-svg, @isivaselvan [#91](https://github.com/hashicorp/python-tfe/pull/91) [#92](https://github.com/hashicorp/python-tfe/pull/92) [#95](https://github.com/hashicorp/python-tfe/pull/95) [#97](https://github.com/hashicorp/python-tfe/pull/97) [#101](https://github.com/hashicorp/python-tfe/pull/101) [#109](https://github.com/hashicorp/python-tfe/pull/109) [#113](https://github.com/hashicorp/python-tfe/pull/113)

## Bug Fixes
* Fixed pagination parameter handling across iterator-based page traversal by @isivaselvan [#111](https://github.com/hashicorp/python-tfe/pull/111)
* Fixed state version and state version output model import/export registration by @isivaselvan [#105](https://github.com/hashicorp/python-tfe/pull/105)
* Fixed the tag based filtering of workspace in list operation by @isivaselvan [#106](https://github.com/hashicorp/python-tfe/pull/106)
* Fixed the project response of workspace relationship by @isivaselvan [#106](https://github.com/hashicorp/python-tfe/pull/106)
* Fixed configuration version examples and added terraform+cloud support for ConfigurationSource usage by @isivaselvan [#107](https://github.com/hashicorp/python-tfe/pull/107)
* Fixed configuration upload packaging flow (tarfile-based handling) by @isivaselvan [#107](https://github.com/hashicorp/python-tfe/pull/107)
* Updated agent pool workspace assign/remove operations to consistently return AgentPool objects by @KshitijaChoudhari [#110](https://github.com/hashicorp/python-tfe/pull/110)
* Updated Run relationships handling for improved model consistency by @ibm-richard [#119](https://github.com/hashicorp/python-tfe/pull/119)
* Updated additional Run Source attributes by @isivaselvan [#123](https://github.com/hashicorp/python-tfe/pull/123)

# v0.1.2

## Features
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,4 @@ clean:
find . -type d -name ".ruff_cache" -exec rm -rf {} +
rm -rf build/ dist/ $(VENV)

all: clean dev-install fmt lint test
all: clean dev-install fmt lint test
3 changes: 3 additions & 0 deletions bin/publish-pypi.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#!/usr/bin/env bash
# Copyright IBM Corp. 2025, 2026
# SPDX-License-Identifier: MPL-2.0

set -euo pipefail


Expand Down
3 changes: 3 additions & 0 deletions examples/agent.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright IBM Corp. 2025, 2026
# SPDX-License-Identifier: MPL-2.0

"""Simple Individual Agent operations example with the TFE Python SDK.

This example demonstrates:
Expand Down
37 changes: 33 additions & 4 deletions examples/agent_pool.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
# Copyright IBM Corp. 2025, 2026
# SPDX-License-Identifier: MPL-2.0

"""Simple Agent Pool operations example with the TFE Python SDK.

This example demonstrates:
1. Agent Pool CRUD operations (Create, Read, Update, Delete)
2. Agent token creation and management
3. Using the organization SDK client
3. Workspace assignment using assign_to_workspaces and remove_from_workspaces
4. Proper error handling

Make sure to set the following environment variables:
- TFE_TOKEN: Your Terraform Cloud/Enterprise API token
- TFE_ADDRESS: Your Terraform Cloud/Enterprise URL (optional, defaults to https://app.terraform.io)
- TFE_ORG: Your organization name
- TFE_WORKSPACE_ID: A workspace ID for testing workspace assignment (optional)

Usage:
export TFE_TOKEN="your-token-here"
Expand All @@ -24,8 +28,10 @@
from pytfe.errors import NotFound
from pytfe.models import (
AgentPoolAllowedWorkspacePolicy,
AgentPoolAssignToWorkspacesOptions,
AgentPoolCreateOptions,
AgentPoolListOptions,
AgentPoolRemoveFromWorkspacesOptions,
AgentPoolUpdateOptions,
AgentTokenCreateOptions,
)
Expand All @@ -37,6 +43,9 @@ def main():
token = os.environ.get("TFE_TOKEN")
org = os.environ.get("TFE_ORG")
address = os.environ.get("TFE_ADDRESS", "https://app.terraform.io")
workspace_id = os.environ.get(
"TFE_WORKSPACE_ID"
) # optional, for workspace assignment

if not token:
print("TFE_TOKEN environment variable is required")
Expand Down Expand Up @@ -96,7 +105,27 @@ def main():
updated_pool = client.agent_pools.update(new_pool.id, update_options)
print(f"Updated agent pool name to: {updated_pool.name}")

# Example 5: Create an agent token
# Example 5: Workspace assignment
# assign_to_workspaces sends PATCH /agent-pools/:id with relationships.allowed-workspaces
# remove_from_workspaces sends PATCH /agent-pools/:id with relationships.excluded-workspaces
if workspace_id:
print("\n Assigning workspace to agent pool...")
updated_pool = client.agent_pools.assign_to_workspaces(
new_pool.id,
AgentPoolAssignToWorkspacesOptions(workspace_ids=[workspace_id]),
)
print(f" Assigned workspace {workspace_id} to pool {updated_pool.name}")

print("\n Removing workspace from agent pool...")
updated_pool = client.agent_pools.remove_from_workspaces(
new_pool.id,
AgentPoolRemoveFromWorkspacesOptions(workspace_ids=[workspace_id]),
)
print(f" Removed workspace {workspace_id} from pool {updated_pool.name}")
else:
print("\n Skipping workspace assignment (set TFE_WORKSPACE_ID to test)")

# Example 6: Create an agent token
print("\n Creating agent token...")
token_options = AgentTokenCreateOptions(
description="SDK example token" # Optional description
Expand All @@ -107,7 +136,7 @@ def main():
if agent_token.token:
print(f" Token (first 10 chars): {agent_token.token[:10]}...")

# Example 6: List agent tokens
# Example 7: List agent tokens
print("\n Listing agent tokens...")
tokens = client.agent_tokens.list(new_pool.id)

Expand All @@ -117,7 +146,7 @@ def main():
for token in token_list:
print(f" - {token.description or 'No description'} (ID: {token.id})")

# Example 7: Clean up - delete the token and pool
# Example 8: Clean up - delete the token and pool
print("\n Cleaning up...")
client.agent_tokens.delete(agent_token.id)
print("Deleted agent token")
Expand Down
3 changes: 3 additions & 0 deletions examples/apply.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright IBM Corp. 2025, 2026
# SPDX-License-Identifier: MPL-2.0

from __future__ import annotations

import argparse
Expand Down
Loading
Loading