Skip to content

Commit 25bf170

Browse files
org functions update
1 parent 0bce1e1 commit 25bf170

6 files changed

Lines changed: 866 additions & 22 deletions

File tree

examples/org.py

Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
from tfe import TFEClient, TFEConfig
2+
from tfe.types import (
3+
DataRetentionPolicyDeleteOlderSetOptions,
4+
DataRetentionPolicyDontDeleteSetOptions,
5+
OrganizationCreateOptions,
6+
ReadRunQueueOptions,
7+
)
8+
9+
10+
def test_basic_org_operations(client):
11+
"""Test basic organization CRUD operations."""
12+
print("=== Testing Basic Organization Operations ===")
13+
14+
# List organizations
15+
print("\n1. Listing Organizations:")
16+
try:
17+
org_list = client.organizations.list()
18+
orgs = list(org_list)
19+
print(f" ✓ Found {len(orgs)} organizations")
20+
21+
# Show first few organizations
22+
for i, org in enumerate(orgs[:5], 1):
23+
print(f" {i:2d}. {org.name} (ID: {org.id})")
24+
if org.email:
25+
print(f" Email: {org.email}")
26+
27+
if len(orgs) > 5:
28+
print(f" ... and {len(orgs) - 5} more")
29+
30+
return orgs[0].name if orgs else None # Return first org name for testing
31+
32+
except Exception as e:
33+
print(f" ✗ Error listing organizations: {e}")
34+
return None
35+
36+
37+
def test_org_read_operations(client, org_name):
38+
"""Test organization read operations."""
39+
print(f"\n=== Testing Organization Read Operations for '{org_name}' ===")
40+
41+
# Read organization details
42+
print("\n1. Reading Organization Details:")
43+
try:
44+
org = client.organizations.read(org_name)
45+
print(f" ✓ Organization: {org.name}")
46+
print(f" ID: {org.id}")
47+
print(f" Email: {org.email or 'Not set'}")
48+
print(f" Created: {org.created_at or 'Unknown'}")
49+
print(f" Execution Mode: {org.default_execution_mode or 'Not set'}")
50+
print(f" Two-Factor: {org.two_factor_conformant}")
51+
except Exception as e:
52+
print(f" ✗ Error reading organization: {e}")
53+
54+
# Test capacity
55+
print("\n2. Reading Organization Capacity:")
56+
try:
57+
capacity = client.organizations.read_capacity(org_name)
58+
print(" ✓ Capacity:")
59+
print(f" Pending runs: {capacity.pending}")
60+
print(f" Running runs: {capacity.running}")
61+
print(f" Total active: {capacity.pending + capacity.running}")
62+
except Exception as e:
63+
print(f" ✗ Error reading capacity: {e}")
64+
65+
# Test entitlements
66+
print("\n3. Reading Organization Entitlements:")
67+
try:
68+
entitlements = client.organizations.read_entitlements(org_name)
69+
print(" ✓ Entitlements:")
70+
print(f" Operations: {entitlements.operations}")
71+
print(f" Teams: {entitlements.teams}")
72+
print(f" State Storage: {entitlements.state_storage}")
73+
print(f" VCS Integrations: {entitlements.vcs_integrations}")
74+
print(f" Cost Estimation: {entitlements.cost_estimation}")
75+
print(f" Sentinel: {entitlements.sentinel}")
76+
print(f" Private Module Registry: {entitlements.private_module_registry}")
77+
print(f" SSO: {entitlements.sso}")
78+
except Exception as e:
79+
print(f" ✗ Error reading entitlements: {e}")
80+
81+
# Test run queue
82+
print("\n4. Reading Organization Run Queue:")
83+
try:
84+
queue_options = ReadRunQueueOptions(page_number=1, page_size=10)
85+
run_queue = client.organizations.read_run_queue(org_name, queue_options)
86+
print(" ✓ Run Queue:")
87+
print(f" Items in queue: {len(run_queue.items)}")
88+
89+
if run_queue.pagination:
90+
print(f" Current page: {run_queue.pagination.current_page}")
91+
print(f" Total count: {run_queue.pagination.total_count}")
92+
93+
# Show details of first few runs
94+
for i, run in enumerate(run_queue.items[:3], 1):
95+
print(f" Run {i}: ID={run.id}, Status={run.status}")
96+
97+
if len(run_queue.items) > 3:
98+
print(f" ... and {len(run_queue.items) - 3} more runs")
99+
100+
except Exception as e:
101+
print(f" ✗ Error reading run queue: {e}")
102+
103+
104+
def test_data_retention_policies(client, org_name):
105+
"""Test data retention policy operations."""
106+
print(f"\n=== Testing Data Retention Policy Operations for '{org_name}' ===")
107+
print("Note: These functions are only available in Terraform Enterprise")
108+
109+
# Test reading current policy
110+
print("\n1. Reading Current Data Retention Policy:")
111+
try:
112+
policy_choice = client.organizations.read_data_retention_policy_choice(org_name)
113+
if policy_choice is None:
114+
print(" ✓ No data retention policy currently configured")
115+
elif policy_choice.data_retention_policy_delete_older:
116+
policy = policy_choice.data_retention_policy_delete_older
117+
print(
118+
f" ✓ Delete Older Policy: {policy.delete_older_than_n_days} days (ID: {policy.id})"
119+
)
120+
elif policy_choice.data_retention_policy_dont_delete:
121+
policy = policy_choice.data_retention_policy_dont_delete
122+
print(f" ✓ Don't Delete Policy (ID: {policy.id})")
123+
elif policy_choice.data_retention_policy:
124+
policy = policy_choice.data_retention_policy
125+
print(
126+
f" ✓ Legacy Policy: {policy.delete_older_than_n_days} days (ID: {policy.id})"
127+
)
128+
except Exception as e:
129+
if "not found" in str(e).lower() or "404" in str(e):
130+
print(
131+
" ⚠ Data retention policies not available (Terraform Enterprise feature)"
132+
)
133+
else:
134+
print(f" ✗ Error reading data retention policy: {e}")
135+
136+
# Test setting delete older policy
137+
print("\n2. Setting Delete Older Data Retention Policy (30 days):")
138+
try:
139+
options = DataRetentionPolicyDeleteOlderSetOptions(delete_older_than_n_days=30)
140+
policy = client.organizations.set_data_retention_policy_delete_older(
141+
org_name, options
142+
)
143+
print(" ✓ Created Delete Older Policy:")
144+
print(f" ID: {policy.id}")
145+
print(f" Delete after: {policy.delete_older_than_n_days} days")
146+
except Exception as e:
147+
if "not found" in str(e).lower() or "404" in str(e):
148+
print(" ⚠ Feature not available (Terraform Enterprise only)")
149+
else:
150+
print(f" ✗ Error setting delete older policy: {e}")
151+
152+
# Test updating delete older policy
153+
print("\n3. Updating Delete Older Policy (15 days):")
154+
try:
155+
options = DataRetentionPolicyDeleteOlderSetOptions(delete_older_than_n_days=15)
156+
policy = client.organizations.set_data_retention_policy_delete_older(
157+
org_name, options
158+
)
159+
print(" ✓ Updated Delete Older Policy:")
160+
print(f" ID: {policy.id}")
161+
print(f" Delete after: {policy.delete_older_than_n_days} days")
162+
except Exception as e:
163+
if "not found" in str(e).lower() or "404" in str(e):
164+
print(" ⚠ Feature not available (Terraform Enterprise only)")
165+
else:
166+
print(f" ✗ Error updating delete older policy: {e}")
167+
168+
# Test setting don't delete policy
169+
print("\n4. Setting Don't Delete Data Retention Policy:")
170+
try:
171+
options = DataRetentionPolicyDontDeleteSetOptions()
172+
policy = client.organizations.set_data_retention_policy_dont_delete(
173+
org_name, options
174+
)
175+
print(" ✓ Created Don't Delete Policy:")
176+
print(f" ID: {policy.id}")
177+
print(" Data will never be automatically deleted")
178+
except Exception as e:
179+
if "not found" in str(e).lower() or "404" in str(e):
180+
print(" ⚠ Feature not available (Terraform Enterprise only)")
181+
else:
182+
print(f" ✗ Error setting don't delete policy: {e}")
183+
184+
# Test reading policy after changes
185+
print("\n5. Reading Data Retention Policy After Changes:")
186+
try:
187+
policy_choice = client.organizations.read_data_retention_policy_choice(org_name)
188+
if policy_choice is None:
189+
print(" ✓ No data retention policy configured")
190+
elif policy_choice.data_retention_policy_delete_older:
191+
policy = policy_choice.data_retention_policy_delete_older
192+
print(
193+
f" ✓ Current Policy: Delete Older ({policy.delete_older_than_n_days} days)"
194+
)
195+
elif policy_choice.data_retention_policy_dont_delete:
196+
print(" ✓ Current Policy: Don't Delete")
197+
198+
# Test legacy conversion
199+
if policy_choice and policy_choice.is_populated():
200+
legacy = policy_choice.convert_to_legacy_struct()
201+
if legacy:
202+
print(
203+
f" ✓ Legacy representation: {legacy.delete_older_than_n_days} days"
204+
)
205+
except Exception as e:
206+
if "not found" in str(e).lower() or "404" in str(e):
207+
print(" ⚠ Feature not available (Terraform Enterprise only)")
208+
else:
209+
print(f" ✗ Error reading updated policy: {e}")
210+
211+
# Test deleting policy
212+
print("\n6. Deleting Data Retention Policy:")
213+
try:
214+
client.organizations.delete_data_retention_policy(org_name)
215+
print(" ✓ Successfully deleted data retention policy")
216+
217+
# Verify deletion
218+
policy_choice = client.organizations.read_data_retention_policy_choice(org_name)
219+
if policy_choice is None or not policy_choice.is_populated():
220+
print(" ✓ Verified: No policy configured after deletion")
221+
else:
222+
print(" ⚠ Policy still exists after deletion attempt")
223+
except Exception as e:
224+
if "not found" in str(e).lower() or "404" in str(e):
225+
print(" ⚠ Feature not available (Terraform Enterprise only)")
226+
else:
227+
print(f" ✗ Error deleting policy: {e}")
228+
229+
230+
def test_organization_creation_and_cleanup(client):
231+
"""Test organization creation and cleanup (if permissions allow)."""
232+
print("\n=== Testing Organization Creation (Optional) ===")
233+
234+
test_org_name = f"python-tfe-test-{int(__import__('time').time())}"
235+
236+
try:
237+
print(f"\n1. Creating Test Organization '{test_org_name}':")
238+
create_opts = OrganizationCreateOptions(
239+
name=test_org_name, email="aayush.singh@hashicorp.com"
240+
)
241+
new_org = client.organizations.create(create_opts)
242+
print(f" ✓ Created organization: {new_org.name}")
243+
print(f" ID: {new_org.id}")
244+
print(f" Email: {new_org.email}")
245+
246+
# Test reading the newly created org
247+
print("\n2. Reading Newly Created Organization:")
248+
read_org = client.organizations.read(test_org_name)
249+
print(f" ✓ Successfully read organization: {read_org.name}")
250+
251+
# Cleanup
252+
print("\n3. Cleaning Up Test Organization:")
253+
client.organizations.delete(test_org_name)
254+
print(" ✓ Successfully deleted test organization")
255+
256+
return True
257+
258+
except Exception as e:
259+
print(f" ⚠ Organization creation/deletion test skipped: {e}")
260+
print(
261+
" This is normal if you don't have organization management permissions"
262+
)
263+
return False
264+
265+
266+
def main():
267+
"""Main function to test all organization functionalities."""
268+
print("🚀 Python TFE Organization Functions Test Suite")
269+
print("=" * 60)
270+
271+
# Initialize client
272+
try:
273+
client = TFEClient(TFEConfig.from_env())
274+
print("✓ TFE Client initialized successfully")
275+
except Exception as e:
276+
print(f"✗ Failed to initialize TFE client: {e}")
277+
print(
278+
"Please ensure TF_CLOUD_ORGANIZATION and TF_CLOUD_TOKEN environment variables are set"
279+
)
280+
return 1
281+
282+
# Test basic operations
283+
test_org_name = test_basic_org_operations(client)
284+
if not test_org_name:
285+
print("\n✗ Cannot continue without a valid organization")
286+
return 1
287+
288+
# Test read operations
289+
test_org_read_operations(client, test_org_name)
290+
291+
# # Test data retention policies
292+
# test_data_retention_policies(client, test_org_name)
293+
294+
# Test organization creation (if permissions allow)
295+
creation_success = test_organization_creation_and_cleanup(client)
296+
297+
# Summary
298+
print("\n" + "=" * 60)
299+
print("📊 Test Summary:")
300+
print("✓ Basic organization operations tested")
301+
print("✓ Organization read operations tested")
302+
print("✓ Data retention policy operations tested")
303+
if creation_success:
304+
print("✓ Organization creation/deletion tested")
305+
else:
306+
print("⚠ Organization creation/deletion skipped (permissions)")
307+
308+
print(
309+
f"\n🎯 All available organization functions have been tested against '{test_org_name}'"
310+
)
311+
print("Note: Data retention policy features require Terraform Enterprise")
312+
print("\n✅ Test suite completed successfully!")
313+
314+
return 0
315+
316+
317+
if __name__ == "__main__":
318+
exit(main())

examples/ws_list.py

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/tfe/errors.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,16 @@ class UnsupportedInCloud(TFEError): ...
4444

4545

4646
class UnsupportedInEnterprise(TFEError): ...
47+
48+
49+
class InvalidValues(TFEError): ...
50+
51+
52+
class RequiredFieldMissing(TFEError): ...
53+
54+
55+
# Error message constants
56+
ERR_INVALID_NAME = "invalid value for name"
57+
ERR_REQUIRED_NAME = "name is required"
58+
ERR_INVALID_ORG = "invalid organization name"
59+
ERR_REQUIRED_EMAIL = "email is required"

0 commit comments

Comments
 (0)