@@ -342,13 +342,7 @@ def configure_member_account(account_id: str, configuration_role_name: str, regi
342342
343343
344344def get_standard_dictionary (
345- account_id : str ,
346- region : str ,
347- aws_partition : str ,
348- sbp_version : str ,
349- cis_version : str ,
350- pci_version : str ,
351- nist_version : str ,
345+ account_id : str , region : str , aws_partition : str , sbp_version : str , cis_version : str , pci_version : str , nist_version : str
352346) -> dict :
353347 """Get Standard ARNs.
354348
@@ -359,7 +353,7 @@ def get_standard_dictionary(
359353 sbp_version: AWS Security Best Practices Standard Version
360354 cis_version: CIS Standard Version
361355 pci_version: PCI Standard Version
362- nist_version: NIST Standard
356+ nist_version: NIST version
363357
364358 Returns:
365359 Standard ARN Dictionary
@@ -419,18 +413,70 @@ def get_enabled_standards(securityhub_client: SecurityHubClient) -> list:
419413 return standards_subscriptions
420414
421415
422- def all_standards_in_status (standards_subscriptions : list , standards_status : str ) -> bool :
416+ def disable_then_enable_standard (securityhub_client : SecurityHubClient , standards_subscription_arn : str , standards_arn : str ) -> bool :
417+ """Disable and then re-enable standard.
418+
419+ Args:
420+ securityhub_client: Security Hub boto3 client
421+ standards_subscription_arn: Standard subscription ARN
422+ standards_arn: Standard ARN
423+
424+ Returns:
425+ bool: True if no error when re-enabling standard; false if there was a problem doing so.
426+ """
427+ LOGGER .info ("Entered disable_then_enable_standard function..." )
428+ LOGGER .info (f"...disabling { standards_subscription_arn } standard" )
429+ securityhub_client .batch_disable_standards (
430+ StandardsSubscriptionArns = [
431+ standards_subscription_arn ,
432+ ]
433+ )
434+ sleep (5 )
435+ standard_enable_retry_sleep = 5
436+ standard_enable_retry = 0
437+ while standard_enable_retry < 10 :
438+ try :
439+ LOGGER .info (f"...enabling { standards_subscription_arn } standard" )
440+ securityhub_client .batch_enable_standards (
441+ StandardsSubscriptionRequests = [
442+ {
443+ "StandardsArn" : standards_arn ,
444+ },
445+ ]
446+ )
447+ return True
448+ except securityhub_client .exceptions .InvalidInputException as error :
449+ standard_enable_retry = standard_enable_retry + 1
450+ LOGGER .error (
451+ f"Retry { standard_enable_retry } due to InvalidInputException "
452+ + f"while enabling standard: { error .response ['Error' ]['Code' ]} - { error .response ['Error' ]['Message' ]} "
453+ )
454+ sleep (standard_enable_retry_sleep )
455+ return False
456+
457+
458+ def all_standards_in_status (standards_subscriptions : list , standards_status : str , securityhub_client : SecurityHubClient ) -> bool :
423459 """All standards in status.
424460
425461 Args:
426462 standards_subscriptions: list of standards subscriptions
427463 standards_status: standards status 'PENDING'|'READY'|'FAILED'|'DELETING'|'INCOMPLETE'
464+ securityhub_client: Security hub boto3 client
428465
429466 Returns:
430- True or False
467+ bool: True or False
431468 """
432469 for standards_subscription in standards_subscriptions : # noqa: SIM111
433- if standards_subscription .get ("StandardsStatus" ) != standards_status :
470+ LOGGER .info ("entered all_standards_in_status function..." )
471+ LOGGER .info (f"standard - { standards_subscription } : { standards_subscription .get ('StandardsStatus' )} " )
472+ incomplete_status_resolved = True
473+ if standards_subscription .get ("StandardsStatus" ) == "INCOMPLETE" :
474+ incomplete_status_resolved = disable_then_enable_standard (
475+ securityhub_client , standards_subscription .get ("StandardsSubscriptionArn" ), standards_subscription .get ("StandardsArn" )
476+ )
477+ if standards_subscription .get ("StandardsStatus" ) != standards_status and standards_subscription .get ("StandardsStatus" ) != "INCOMPLETE" :
478+ return False
479+ if incomplete_status_resolved is False :
434480 return False
435481 return True
436482
@@ -446,7 +492,7 @@ def get_current_enabled_standards(securityhub_client: SecurityHubClient, standar
446492 Standard Dictionary
447493 """
448494 standards_subscriptions = get_enabled_standards (securityhub_client )
449- if all_standards_in_status (standards_subscriptions , "READY" ):
495+ if all_standards_in_status (standards_subscriptions , "READY" , securityhub_client ):
450496 for item in standards_subscriptions :
451497 if standard_dict ["sbp" ]["standard_arn" ] == item ["StandardsArn" ]:
452498 standard_dict ["sbp" ]["enabled" ] = True
@@ -470,7 +516,7 @@ def all_standards_ready(securityhub_client: SecurityHubClient) -> bool:
470516 """
471517 for i in range (10 ):
472518 standards_subscriptions = get_enabled_standards (securityhub_client )
473- if all_standards_in_status (standards_subscriptions , "READY" ):
519+ if all_standards_in_status (standards_subscriptions , "READY" , securityhub_client ):
474520 return True
475521 LOGGER .info (f"Waiting 20 seconds before checking if standards are in READY status. { i } of 10" )
476522 sleep (20 )
0 commit comments