Skip to content

Commit e72bb1b

Browse files
committed
fix linting issues
1 parent 2325ce4 commit e72bb1b

File tree

4 files changed

+37
-117
lines changed

4 files changed

+37
-117
lines changed

aws_sra_examples/solutions/genai/bedrock_org/lambda/src/app.py

Lines changed: 34 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,8 @@
2727
# TODO(liamschn): deploy example bedrock guardrail
2828
# TODO(liamschn): deploy example iam role(s) and policy(ies) - lower priority/not necessary?
2929
# TODO(liamschn): deploy example bucket policy(ies) - lower priority/not necessary?
30-
# TODO(liamschn): deal with linting failures in pipeline
31-
# TODO(liamschn): deal with typechecking/mypy
32-
# TODO(liamschn): check for unused parameters
30+
# TODO(liamschn): deal with linting failures in pipeline (and deal with typechecking/mypy)
31+
# TODO(liamschn): check for unused parameters (in progress)
3332
# TODO(liamschn): make sure things don't fail (create or delete) if the dynamodb table is deleted/doesn't exist (use case, maybe someone deletes it)
3433

3534
from typing import TYPE_CHECKING, Sequence # , Union, Literal, Optional
@@ -74,7 +73,6 @@ def load_sra_cloudwatch_dashboard() -> dict:
7473

7574
# Global vars
7675
RESOURCE_TYPE: str = ""
77-
STATE_TABLE: str = "sra_state"
7876
SOLUTION_NAME: str = "sra-bedrock-org"
7977
GOVERNED_REGIONS = []
8078
ORGANIZATION_ID = ""
@@ -86,8 +84,10 @@ def load_sra_cloudwatch_dashboard() -> dict:
8684
LAMBDA_START: str = ""
8785
LAMBDA_FINISH: str = ""
8886

89-
ACCOUNT: str = boto3.client("sts").get_caller_identity().get("Account")
90-
REGION: str = os.environ.get("AWS_REGION")
87+
ACCOUNT: str | None = boto3.client("sts").get_caller_identity().get("Account")
88+
LOGGER.info(f"Account: {ACCOUNT}")
89+
REGION: str | None = os.environ.get("AWS_REGION")
90+
LOGGER.info(f"Region: {REGION}")
9191
CFN_RESOURCE_ID: str = "sra-bedrock-org-function"
9292
ALARM_SNS_KEY_ALIAS = "sra-alarm-sns-key"
9393

@@ -158,7 +158,7 @@ def load_sra_cloudwatch_dashboard() -> dict:
158158
# propagate solution name to class objects
159159
cloudwatch.SOLUTION_NAME = SOLUTION_NAME
160160

161-
def get_resource_parameters(event):
161+
def get_resource_parameters(event: dict) -> None:
162162
global DRY_RUN
163163
global GOVERNED_REGIONS
164164
global CFN_RESPONSE_DATA
@@ -251,7 +251,7 @@ def validate_parameters(parameters: Dict[str, str], rules: Dict[str, str]) -> Di
251251
}
252252

253253

254-
def get_accounts_and_regions(resource_properties):
254+
def get_accounts_and_regions(resource_properties: dict) -> tuple[list, list]:
255255
"""Get accounts and regions from event and return them in a tuple
256256
257257
Args:
@@ -280,7 +280,7 @@ def get_accounts_and_regions(resource_properties):
280280
regions = []
281281
return accounts, regions
282282

283-
def get_rule_params(rule_name, resource_properties):
283+
def get_rule_params(rule_name: str, resource_properties: dict) -> tuple[bool, list, list, dict]:
284284
"""Get rule parameters from event and return them in a tuple
285285
286286
Args:
@@ -339,7 +339,7 @@ def get_rule_params(rule_name, resource_properties):
339339
return False, [], [], {}
340340

341341

342-
def get_filter_params(filter_name, resource_properties):
342+
def get_filter_params(filter_name: str, resource_properties: dict) -> tuple[bool, list, list, dict]:
343343
"""Get filter parameters from event resource_properties and return them in a tuple
344344
345345
Args:
@@ -410,7 +410,7 @@ def build_s3_metric_filter_pattern(bucket_names: list, filter_pattern_template:
410410
s3_filter = s3_filter.replace('&& ($.requestParameters.bucketName = "<BUCKET_NAME_PLACEHOLDER>")', "")
411411
return s3_filter
412412

413-
def build_cloudwatch_dashboard(dashboard_template, solution, bedrock_accounts, regions):
413+
def build_cloudwatch_dashboard(dashboard_template: dict, solution: str, bedrock_accounts: list, regions: list) -> dict:
414414
i = 0
415415
for bedrock_account in bedrock_accounts:
416416
for region in regions:
@@ -433,7 +433,7 @@ def build_cloudwatch_dashboard(dashboard_template, solution, bedrock_accounts, r
433433
return dashboard_template[solution]
434434

435435

436-
def deploy_state_table():
436+
def deploy_state_table() -> None:
437437
global DRY_RUN_DATA
438438
global LIVE_RUN_DATA
439439
global CFN_RESPONSE_DATA
@@ -482,7 +482,7 @@ def deploy_state_table():
482482
DRY_RUN_DATA["StateTableCreate"] = f"DRY_RUN: Create the {STATE_TABLE} state table"
483483

484484

485-
def add_state_table_record(aws_service: str, component_state: str, description: str, component_type: str, resource_arn: str, account_id: str, region: str, component_name: str, key_id: str = ""):
485+
def add_state_table_record(aws_service: str, component_state: str, description: str, component_type: str, resource_arn: str, account_id: str, region: str, component_name: str, key_id: str = "") -> str:
486486
"""Add a record to the state table
487487
Args:
488488
aws_service (str): aws service
@@ -534,7 +534,7 @@ def add_state_table_record(aws_service: str, component_state: str, description:
534534
return sra_resource_record_id
535535

536536

537-
def remove_state_table_record(resource_arn):
537+
def remove_state_table_record(resource_arn: str) -> dict:
538538
"""Remove a record from the state table
539539
540540
Args:
@@ -566,7 +566,7 @@ def remove_state_table_record(resource_arn):
566566
response = {}
567567
return response
568568

569-
def update_state_table_record(record_id: str, update_data: dict):
569+
def update_state_table_record(record_id: str, update_data: dict) -> None:
570570
dynamodb.DYNAMODB_RESOURCE = sts.assume_role_resource(ssm_params.SRA_SECURITY_ACCT, sts.CONFIGURATION_ROLE, "dynamodb", sts.HOME_REGION)
571571

572572
try:
@@ -578,11 +578,10 @@ def update_state_table_record(record_id: str, update_data: dict):
578578
)
579579
except Exception as error:
580580
LOGGER.error(f"Error updating {record_id} record in {STATE_TABLE} dynamodb table: {error}")
581-
response = {}
582581
return
583582

584583

585-
def deploy_stage_config_rule_lambda_code():
584+
def deploy_stage_config_rule_lambda_code() -> None:
586585
global DRY_RUN_DATA
587586
global LIVE_RUN_DATA
588587
global CFN_RESPONSE_DATA
@@ -604,7 +603,7 @@ def deploy_stage_config_rule_lambda_code():
604603
LOGGER.info(f"DRY_RUN: Staging config rule code to the {s3.STAGING_BUCKET} staging bucket")
605604

606605

607-
def deploy_sns_configuration_topics(context):
606+
def deploy_sns_configuration_topics(context: Any) -> str:
608607
global DRY_RUN_DATA
609608
global LIVE_RUN_DATA
610609
global CFN_RESPONSE_DATA
@@ -652,7 +651,7 @@ def deploy_sns_configuration_topics(context):
652651

653652
return topic_arn
654653

655-
def deploy_config_rules(region, accounts, resource_properties):
654+
def deploy_config_rules(region: str, accounts: list, resource_properties: dict) -> None:
656655
global DRY_RUN_DATA
657656
global LIVE_RUN_DATA
658657
global CFN_RESPONSE_DATA
@@ -711,7 +710,7 @@ def deploy_config_rules(region, accounts, resource_properties):
711710

712711
# 3c) Deploy the config rule (requires config_org [non-CT] or config_mgmt [CT] solution)
713712
if DRY_RUN is False:
714-
config_rule_arn = deploy_config_rule(acct, rule_name, lambda_arn, region, rule_input_params)
713+
deploy_config_rule(acct, rule_name, lambda_arn, region, rule_input_params)
715714
LIVE_RUN_DATA[f"{rule_name}_{acct}_{region}_Config"] = "Deployed custom config rule"
716715
CFN_RESPONSE_DATA["deployment_info"]["action_count"] += 1
717716
CFN_RESPONSE_DATA["deployment_info"]["resources_deployed"] += 1
@@ -911,7 +910,7 @@ def deploy_metric_filters_and_alarms(region: str, accounts: list, resource_prope
911910
LOGGER.info(f"DRY_RUN: Filter deploy parameter is 'false'; Skip {filter_name} CloudWatch metric filter deployment")
912911
DRY_RUN_DATA[f"{filter_name}_CloudWatch"] = "DRY_RUN: Filter deploy parameter is 'false'; Skip CloudWatch metric filter deployment"
913912

914-
def deploy_central_cloudwatch_observability(event):
913+
def deploy_central_cloudwatch_observability(event: dict) -> None:
915914
global DRY_RUN_DATA
916915
global LIVE_RUN_DATA
917916
global CFN_RESPONSE_DATA
@@ -1063,7 +1062,7 @@ def deploy_central_cloudwatch_observability(event):
10631062
# add OAM link state table record
10641063
add_state_table_record("oam", "implemented", "oam link", "link", oam_link_arn, bedrock_account, bedrock_region, "oam_link")
10651064

1066-
def deploy_cloudwatch_dashboard(event):
1065+
def deploy_cloudwatch_dashboard(event: dict) -> None:
10671066
global DRY_RUN_DATA
10681067
global LIVE_RUN_DATA
10691068
global CFN_RESPONSE_DATA
@@ -1091,22 +1090,8 @@ def deploy_cloudwatch_dashboard(event):
10911090
else:
10921091
LOGGER.info(f"Cloudwatch dashboard already exists: {search_dashboard[1]}")
10931092
add_state_table_record("cloudwatch", "implemented", "cloudwatch dashboard", "dashboard", search_dashboard[1], ssm_params.SRA_SECURITY_ACCT, sts.HOME_REGION, SOLUTION_NAME)
1094-
# check_dashboard = cloudwatch.compare_dashboard(search_dashboard[1], cloudwatch_dashboard)
1095-
# if check_dashboard is False:
1096-
# if DRY_RUN is False:
1097-
# LOGGER.info("CloudWatch observability dashboard needs updating...")
1098-
# cloudwatch.create_dashboard(cloudwatch.SOLUTION_NAME, cloudwatch_dashboard)
1099-
# LIVE_RUN_DATA["OAMDashboardUpdate"] = "Updated CloudWatch observability dashboard"
1100-
# CFN_RESPONSE_DATA["deployment_info"]["action_count"] += 1
1101-
# CFN_RESPONSE_DATA["deployment_info"]["configuration_changes"] += 1
1102-
# LOGGER.info("Updated CloudWatch observability dashboard")
1103-
# else:
1104-
# LOGGER.info("DRY_RUN: CloudWatch observability dashboard needs updating...")
1105-
# DRY_RUN_DATA["OAMDashboardUpdate"] = "DRY_RUN: Update CloudWatch observability dashboard"
1106-
# else:
1107-
# LOGGER.info("CloudWatch observability dashboard is correct")
1108-
1109-
def remove_cloudwatch_dashboard():
1093+
1094+
def remove_cloudwatch_dashboard() -> None:
11101095
global DRY_RUN_DATA
11111096
global LIVE_RUN_DATA
11121097
global CFN_RESPONSE_DATA
@@ -1131,7 +1116,7 @@ def remove_cloudwatch_dashboard():
11311116
remove_state_table_record(f"arn:aws:cloudwatch::{ssm_params.SRA_SECURITY_ACCT}:dashboard/{SOLUTION_NAME}")
11321117

11331118

1134-
def create_event(event, context):
1119+
def create_event(event: dict, context: Any) -> str:
11351120
global DRY_RUN_DATA
11361121
global LIVE_RUN_DATA
11371122
global CFN_RESPONSE_DATA
@@ -1144,7 +1129,6 @@ def create_event(event, context):
11441129
LOGGER.info(event_info)
11451130
LOGGER.info(f"CFN_RESPONSE_DATA START: {CFN_RESPONSE_DATA}")
11461131
# Deploy state table
1147-
# TODO(liamschn): need to ensure the solution name for the state table record is sra-common-prerequisites (if it is created here), not bedrock
11481132
deploy_state_table()
11491133
LOGGER.info(f"CFN_RESPONSE_DATA POST deploy_state_table: {CFN_RESPONSE_DATA}")
11501134
# add IAM state table record for the lambda execution role
@@ -1197,23 +1181,15 @@ def create_event(event, context):
11971181
return CFN_RESOURCE_ID
11981182

11991183

1200-
def update_event(event, context):
1201-
# TODO(liamschn): handle CFN update events; use case: change from DRY_RUN = False to DRY_RUN = True or vice versa
1184+
def update_event(event: dict, context: Any) -> str:
12021185
# TODO(liamschn): handle CFN update events; use case: add additional config rules via new rules in code (i.e. ...\rules\new_rule\app.py)
12031186
# TODO(liamschn): handle CFN update events; use case: changing config rule parameters (i.e. deploy, accounts, regions, input_params)
1204-
# TODO(liamschn): handle CFN update events; use case: setting deploy = false should remove the config rule
12051187
global DRY_RUN_DATA
12061188
LOGGER.info("update event function")
1207-
# Temp calling create_event so that an update will actually do something; need to determine if this is the best way or not.
12081189
create_event(event, context)
1209-
# data = sra_s3.s3_resource_check()
1210-
# TODO(liamschn): update data dictionary
1211-
# data = {"data": "no info"}
1212-
# if RESOURCE_TYPE != "Other":
1213-
# cfnresponse.send(event, context, cfnresponse.SUCCESS, data, CFN_RESOURCE_ID)
12141190
return CFN_RESOURCE_ID
12151191

1216-
def delete_custom_config_rule(rule_name: str, acct: str, region: str):
1192+
def delete_custom_config_rule(rule_name: str, acct: str, region: str) -> None:
12171193
# Delete the config rule
12181194
config.CONFIG_CLIENT = sts.assume_role(acct, sts.CONFIGURATION_ROLE, "config", region)
12191195
config_rule_search = config.find_config_rule(rule_name)
@@ -1234,7 +1210,6 @@ def delete_custom_config_rule(rule_name: str, acct: str, region: str):
12341210
# Delete lambda for custom config rule
12351211
lambdas.LAMBDA_CLIENT = sts.assume_role(acct, sts.CONFIGURATION_ROLE, "lambda", region)
12361212
lambda_search = lambdas.find_lambda_function(rule_name)
1237-
# TODO(liamschn): this will be a mypy error - need to have lambda_search return string, not None
12381213
if lambda_search is not None:
12391214
if DRY_RUN is False:
12401215
LOGGER.info(f"Deleting {rule_name} lambda function for account {acct} in {region}")
@@ -1249,7 +1224,7 @@ def delete_custom_config_rule(rule_name: str, acct: str, region: str):
12491224
else:
12501225
LOGGER.info(f"{rule_name} lambda function for account {acct} in {region} does not exist.")
12511226

1252-
def delete_custom_config_iam_role(rule_name: str, acct: str):
1227+
def delete_custom_config_iam_role(rule_name: str, acct: str) -> None:
12531228
global DRY_RUN_DATA
12541229
global LIVE_RUN_DATA
12551230
global CFN_RESPONSE_DATA
@@ -1330,10 +1305,9 @@ def delete_custom_config_iam_role(rule_name: str, acct: str):
13301305
else:
13311306
LOGGER.info(f"{rule_name} IAM role for account {acct} in {region} does not exist.")
13321307

1333-
def delete_sns_topic_and_key(acct: str, region: str):
1308+
def delete_sns_topic_and_key(acct: str, region: str) -> None:
13341309
# Delete the alarm topic
13351310
sns.SNS_CLIENT = sts.assume_role(acct, sts.CONFIGURATION_ROLE, "sns", region)
1336-
# TODO(liamschn): this will be a mypy error - need to have alarm_topic_search (sns.find_sns_topic) return string, not None
13371311
alarm_topic_search = sns.find_sns_topic(f"{SOLUTION_NAME}-alarms", region, acct)
13381312
if alarm_topic_search is not None:
13391313
if DRY_RUN is False:
@@ -1380,7 +1354,7 @@ def delete_sns_topic_and_key(acct: str, region: str):
13801354
LOGGER.info(f"{ALARM_SNS_KEY_ALIAS} KMS key does not exist.")
13811355

13821356

1383-
def delete_metric_filter_and_alarm(filter_name: str, acct: str, region: str, filter_params: dict):
1357+
def delete_metric_filter_and_alarm(filter_name: str, acct: str, region: str, filter_params: dict) -> None:
13841358
cloudwatch.CWLOGS_CLIENT = sts.assume_role(acct, sts.CONFIGURATION_ROLE, "logs", region)
13851359
cloudwatch.CLOUDWATCH_CLIENT = sts.assume_role(acct, sts.CONFIGURATION_ROLE, "cloudwatch", region)
13861360
if DRY_RUN is False:
@@ -1419,7 +1393,7 @@ def delete_metric_filter_and_alarm(filter_name: str, acct: str, region: str, fil
14191393
LOGGER.info(f"DRY_RUN: Delete {filter_name} CloudWatch metric filter")
14201394
DRY_RUN_DATA[f"{filter_name}_CloudWatchDelete"] = f"DRY_RUN: Delete {filter_name} CloudWatch metric filter"
14211395

1422-
def delete_event(event, context):
1396+
def delete_event(event: dict, context: Any) -> None:
14231397
# TODO(liamschn): handle delete error if IAM policy is updated out-of-band - botocore.errorfactory.DeleteConflictException: An error occurred (DeleteConflict) when calling the DeletePolicy operation: This policy has more than one version. Before you delete a policy, you must delete the policy's versions. The default version is deleted with the policy.
14241398
# TODO(liamschn): move re-used delete event operation code to separate functions
14251399
global DRY_RUN_DATA
@@ -1436,7 +1410,6 @@ def delete_event(event, context):
14361410
# 1a) Delete configuration topic
14371411
sns.SNS_CLIENT = sts.assume_role(sts.MANAGEMENT_ACCOUNT, sts.CONFIGURATION_ROLE, "sns", sts.HOME_REGION)
14381412
topic_search = sns.find_sns_topic(f"{SOLUTION_NAME}-configuration")
1439-
# TODO(liamschn): this will be a mypy error: need to have topic_search (sns.find_sns_topic) return a str, not None
14401413
if topic_search is not None:
14411414
if DRY_RUN is False:
14421415
LOGGER.info(f"Deleting {SOLUTION_NAME}-configuration SNS topic")
@@ -1618,7 +1591,7 @@ def create_sns_messages(accounts: list, regions: list, sns_topic_arn: str, resou
16181591
DRY_RUN_DATA["SNSFanout"] = "DRY_RUN: Published SNS messages for regional fanout configuration. More dry run data in subsequent log streams."
16191592

16201593

1621-
def process_sns_records(event) -> None:
1594+
def process_sns_records(event: dict) -> None:
16221595
"""Process SNS records.
16231596
16241597
Args:
@@ -1875,7 +1848,7 @@ def deploy_config_rule(account_id: str, rule_name: str, lambda_arn: str, region:
18751848
add_state_table_record("config", "implemented", "config rule", "rule", config_rule_arn, account_id, region, rule_name)
18761849

18771850

1878-
def deploy_metric_filter(region: str, acct: str, log_group_name: str, filter_name: str, filter_pattern: str, metric_name: str, metric_namespace: str, metric_value: str):
1851+
def deploy_metric_filter(region: str, acct: str, log_group_name: str, filter_name: str, filter_pattern: str, metric_name: str, metric_namespace: str, metric_value: str) -> None:
18791852
"""Deploy metric filter.
18801853
18811854
Args:
@@ -1918,7 +1891,7 @@ def deploy_metric_alarm(
19181891
metric_comparison_operator: str,
19191892
metric_treat_missing_data: str,
19201893
alarm_actions: list,
1921-
):
1894+
) -> None:
19221895
"""Deploy metric alarm.
19231896
19241897
Args:
@@ -1964,7 +1937,7 @@ def deploy_metric_alarm(
19641937
add_state_table_record("cloudwatch", "implemented", "cloudwatch metric alarm", "alarm", alarm_arn, acct, region, alarm_name)
19651938

19661939

1967-
def lambda_handler(event, context):
1940+
def lambda_handler(event: dict, context: Any) -> dict:
19681941
global RESOURCE_TYPE
19691942
global LAMBDA_START
19701943
global LAMBDA_FINISH

aws_sra_examples/solutions/genai/bedrock_org/lambda/src/sra_dynamodb.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ def get_resources_for_solutions_by_account(self, table_name, solutions, account)
209209
query_results[solution] = response
210210
return query_results
211211

212-
def delete_item(self, table_name, solution_name, record_id):
212+
def delete_item(self, table_name: str, solution_name: str, record_id: str) -> dict:
213213
"""Delete an item from the dynamodb table
214214
215215
Args:

0 commit comments

Comments
 (0)