Skip to content

Commit 0e0f770

Browse files
committed
Updates to scenario flow.
1 parent 72daf33 commit 0e0f770

File tree

6 files changed

+81
-39
lines changed

6 files changed

+81
-39
lines changed

python/example_code/controltower/README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,16 @@ Code examples that show you how to perform the essential operations within a ser
5252

5353
Code excerpts that show you how to call individual service functions.
5454

55-
- [DisableBaseline](controltower_wrapper.py#L365)
56-
- [DisableControl](controltower_wrapper.py#L240)
57-
- [EnableBaseline](controltower_wrapper.py#L64)
58-
- [EnableControl](controltower_wrapper.py#L143)
59-
- [GetControlOperation](controltower_wrapper.py#L186)
60-
- [ListBaselines](controltower_wrapper.py#L36)
61-
- [ListEnabledBaselines](controltower_wrapper.py#L305)
62-
- [ListEnabledControls](controltower_wrapper.py#L401)
63-
- [ListLandingZones](controltower_wrapper.py#L278)
64-
- [ResetEnabledBaseline](controltower_wrapper.py#L332)
55+
- [DisableBaseline](controltower_wrapper.py#L392)
56+
- [DisableControl](controltower_wrapper.py#L263)
57+
- [EnableBaseline](controltower_wrapper.py#L69)
58+
- [EnableControl](controltower_wrapper.py#L159)
59+
- [GetControlOperation](controltower_wrapper.py#L209)
60+
- [ListBaselines](controltower_wrapper.py#L39)
61+
- [ListEnabledBaselines](controltower_wrapper.py#L330)
62+
- [ListEnabledControls](controltower_wrapper.py#L431)
63+
- [ListLandingZones](controltower_wrapper.py#L300)
64+
- [ResetEnabledBaseline](controltower_wrapper.py#L358)
6565

6666

6767
<!--custom.examples.start-->

python/example_code/controltower/controltower_wrapper.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import logging
55
import boto3
66
import time
7+
from typing import Dict, List, Optional, Any
78

89
from botocore.exceptions import ClientError
910

@@ -17,7 +18,9 @@
1718
class ControlTowerWrapper:
1819
"""Encapsulates AWS Control Tower and Control Catalog functionality."""
1920

20-
def __init__(self, controltower_client, controlcatalog_client):
21+
def __init__(
22+
self, controltower_client: boto3.client, controlcatalog_client: boto3.client
23+
):
2124
"""
2225
:param controltower_client: A Boto3 Amazon ControlTower client.
2326
:param controlcatalog_client: A Boto3 Amazon ControlCatalog client.
@@ -66,10 +69,10 @@ def list_baselines(self):
6669
# snippet-start:[python.example_code.controltower.EnableBaseline]
6770
def enable_baseline(
6871
self,
69-
target_identifier,
70-
identity_center_baseline,
71-
baseline_identifier,
72-
baseline_version,
72+
target_identifier: str,
73+
identity_center_baseline: str,
74+
baseline_identifier: str,
75+
baseline_version: str,
7376
):
7477
"""
7578
Enables a baseline for the specified target if it's not already enabled.
@@ -154,7 +157,7 @@ def list_controls(self):
154157
# snippet-end:[python.example_code.controltower.ListControls]
155158

156159
# snippet-start:[python.example_code.controltower.EnableControl]
157-
def enable_control(self, control_arn, target_identifier):
160+
def enable_control(self, control_arn: str, target_identifier: str):
158161
"""
159162
Enables a control for a specified target.
160163
@@ -187,8 +190,11 @@ def enable_control(self, control_arn, target_identifier):
187190
):
188191
logger.info("Control is already enabled for this target")
189192
return None
190-
elif (err.response["Error"]["Code"] == "ResourceNotFoundException"
191-
and "not registered with AWS Control Tower" in err.response["Error"]["Message"]):
193+
elif (
194+
err.response["Error"]["Code"] == "ResourceNotFoundException"
195+
and "not registered with AWS Control Tower"
196+
in err.response["Error"]["Message"]
197+
):
192198
logger.error("Control Tower must be enabled to work with controls.")
193199
return None
194200
logger.error(
@@ -201,7 +207,7 @@ def enable_control(self, control_arn, target_identifier):
201207
# snippet-end:[python.example_code.controltower.EnableControl]
202208

203209
# snippet-start:[python.example_code.controltower.GetControlOperation]
204-
def get_control_operation(self, operation_id):
210+
def get_control_operation(self, operation_id: str):
205211
"""
206212
Gets the status of a control operation.
207213
@@ -228,7 +234,7 @@ def get_control_operation(self, operation_id):
228234
# snippet-end:[python.example_code.controltower.GetControlOperation]
229235

230236
# snippet-start:[python.example_code.controltower.GetBaselineOperation]
231-
def get_baseline_operation(self, operation_id):
237+
def get_baseline_operation(self, operation_id: str):
232238
"""
233239
Gets the status of a baseline operation.
234240
@@ -255,7 +261,7 @@ def get_baseline_operation(self, operation_id):
255261
# snippet-end:[python.example_code.controltower.GetBaselineOperation]
256262

257263
# snippet-start:[python.example_code.controltower.DisableControl]
258-
def disable_control(self, control_arn, target_identifier):
264+
def disable_control(self, control_arn: str, target_identifier: str):
259265
"""
260266
Disables a control for a specified target.
261267
@@ -350,7 +356,7 @@ def list_enabled_baselines(self):
350356
# snippet-end:[python.example_code.controltower.ListEnabledBaselines]
351357

352358
# snippet-start:[python.example_code.controltower.ResetEnabledBaseline]
353-
def reset_enabled_baseline(self, enabled_baseline_identifier):
359+
def reset_enabled_baseline(self, enabled_baseline_identifier: str):
354360
"""
355361
Resets an enabled baseline for a specific target.
356362
@@ -384,7 +390,7 @@ def reset_enabled_baseline(self, enabled_baseline_identifier):
384390
# snippet-end:[python.example_code.controltower.ResetEnabledBaseline]
385391

386392
# snippet-start:[python.example_code.controltower.DisableBaseline]
387-
def disable_baseline(self, enabled_baseline_identifier):
393+
def disable_baseline(self, enabled_baseline_identifier: str):
388394
"""
389395
Disables a baseline for a specific target and waits for the operation to complete.
390396
@@ -423,7 +429,7 @@ def disable_baseline(self, enabled_baseline_identifier):
423429
# snippet-end:[python.example_code.controltower.DisableBaseline]
424430

425431
# snippet-start:[python.example_code.controltower.ListEnabledControls]
426-
def list_enabled_controls(self, target_identifier):
432+
def list_enabled_controls(self, target_identifier: str):
427433
"""
428434
Lists all enabled controls for a specific target.
429435
@@ -445,8 +451,11 @@ def list_enabled_controls(self, target_identifier):
445451
"Access denied. Please ensure you have the necessary permissions."
446452
)
447453
return enabled_controls
448-
elif (err.response["Error"]["Code"] == "ResourceNotFoundException"
449-
and "not registered with AWS Control Tower" in err.response["Error"]["Message"]):
454+
elif (
455+
err.response["Error"]["Code"] == "ResourceNotFoundException"
456+
and "not registered with AWS Control Tower"
457+
in err.response["Error"]["Message"]
458+
):
450459
logger.error("Control Tower must be enabled to work with controls.")
451460
return enabled_controls
452461
else:

python/example_code/controltower/hello/hello_controltower.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33

44
# snippet-start:[python.example_code.controltower.Hello]
55
import boto3
6+
from typing import Any, List
67

78

8-
def hello_controltower(controltower_client):
9+
def hello_controltower(controltower_client: Any) -> None:
910
"""
1011
Use the AWS SDK for Python (Boto3) to create an AWS Control Tower client
1112
and list all available baselines.
@@ -19,7 +20,7 @@ def hello_controltower(controltower_client):
1920
paginator = controltower_client.get_paginator("list_baselines")
2021
page_iterator = paginator.paginate()
2122

22-
baseline_names: [str] = []
23+
baseline_names: List[str] = []
2324
try:
2425
for page in page_iterator:
2526
for baseline in page["baselines"]:

python/example_code/controltower/scenario_controltower.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import logging
66
import sys
77
import time
8+
from typing import Any, Optional
89

910
import boto3
1011
from botocore.exceptions import ClientError
@@ -20,9 +21,12 @@
2021

2122
# snippet-start:[python.example_code.controltower.ControlTowerScenario]
2223
class ControlTowerScenario:
24+
IDENTITY_CENTER_BASELINE = "baseline/LN25R72TTG6IGPTQ"
2325
stack_name = ""
2426

25-
def __init__(self, controltower_wrapper, org_client):
27+
def __init__(
28+
self, controltower_wrapper: ControlTowerWrapper, org_client: boto3.client
29+
):
2630
"""
2731
:param controltower_wrapper: An instance of the ControlTowerWrapper class.
2832
:param org_client: A Boto3 Organization client.
@@ -36,17 +40,17 @@ def __init__(self, controltower_wrapper, org_client):
3640
self.landing_zone_id = None
3741
self.use_landing_zone = False
3842

39-
def run_scenario(self):
43+
def run_scenario(self) -> None:
4044
print("-" * 88)
4145
print(
4246
"\tWelcome to the AWS Control Tower with ControlCatalog example scenario."
4347
)
4448
print("-" * 88)
4549

4650
print(
47-
"This demo will walk you through working with AWS Control Tower for landing zones,"
51+
"This demo will walk you through working with AWS Control Tower for landing zones,\n"
52+
"managing baselines, and working with controls."
4853
)
49-
print("managing baselines, and working with controls.")
5054

5155
self.account_id = boto3.client("sts").get_caller_identity()["Account"]
5256

@@ -102,7 +106,7 @@ def run_scenario(self):
102106
enabled_baselines = self.controltower_wrapper.list_enabled_baselines()
103107
for baseline in enabled_baselines:
104108
# If the Identity Center baseline is enabled, the identifier must be used for other baselines.
105-
if "baseline/LN25R72TTG6IGPTQ" in baseline["baselineIdentifier"]:
109+
if self.IDENTITY_CENTER_BASELINE in baseline["baselineIdentifier"]:
106110
identity_center_baseline = baseline
107111
print(f"{baseline['baselineIdentifier']}")
108112

@@ -151,6 +155,15 @@ def run_scenario(self):
151155
)
152156
print(f"\nDisabled baseline operation id {operation_id}.")
153157

158+
# Re-enable the baseline for the next step.
159+
print("\nEnabling Control Tower Baseline.")
160+
self.controltower_wrapper.enable_baseline(
161+
self.ou_arn,
162+
ic_baseline_arn,
163+
control_tower_baseline["arn"],
164+
"4.0",
165+
)
166+
154167
# List and Enable Controls.
155168
print("\nManaging Controls:")
156169
controls = self.controltower_wrapper.list_controls()
@@ -186,10 +199,8 @@ def run_scenario(self):
186199

187200
if operation_id:
188201
print(f"Enabled control with operation id {operation_id}")
189-
else:
190-
print("Control is already enabled for this target")
191202

192-
if q.ask(
203+
if control_arn and q.ask(
193204
f"Do you want to disable the control? (y/n) ",
194205
q.is_yesno,
195206
):

python/example_code/controltower/test/test_scenario_run.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,19 @@ def mock_get_caller_identity():
171171
self.baseline_operation_id,
172172
"SUCCEEDED",
173173
)
174+
runner.add(
175+
self.scenario_data.controltower_stubber.stub_enable_baseline,
176+
self.baseline_arn,
177+
"4.0",
178+
self.sandbox_ou_arn,
179+
self.enabled_baseline_arn,
180+
self.baseline_operation_id,
181+
)
182+
runner.add(
183+
self.scenario_data.controltower_stubber.stub_get_baseline_operation,
184+
self.baseline_operation_id,
185+
"SUCCEEDED",
186+
)
174187

175188
# List and enable controls
176189
runner.add(

scenarios/basics/controltower/SPECIFICATION.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,19 @@ Baseline operation status: SUCCEEDED
130130
Reset baseline operation id 64f9c26e-c2d4-46c1-8863-f2b6382c2b4d.
131131
132132
Do you want to disable the Control Tower Baseline? (y/n) y
133-
Disabling baseline ARN: arn:aws:controltower:us-east-1:478643181688:enabledbaseline/XOVK3ATZUCD5A04QV
134-
Conflict disabling baseline: AWS Control Tower cannot perform a DisableBaseline operation on a target OU with enabled optional controls.. Skipping disable step.
133+
Disabling baseline ARN: arn:aws:controltower:us-east-1:478643181688:enabledbaseline/XOVK3ATZUCD5BUH7N
134+
Baseline operation status: IN_PROGRESS
135+
Baseline operation status: SUCCEEDED
135136
136-
Disabled baseline operation id None.
137+
Disabled baseline operation id ff86f9d7-8f08-4bfa-b071-5469c0dfbe60.
137138
139+
Enabling Control Tower Baseline.
140+
Baseline operation status: IN_PROGRESS
141+
Baseline operation status: IN_PROGRESS
142+
Baseline operation status: IN_PROGRESS
143+
Baseline operation status: IN_PROGRESS
144+
Baseline operation status: IN_PROGRESS
145+
Baseline operation status: SUCCEEDED
138146
139147
```
140148

0 commit comments

Comments
 (0)