runbooks 0.2.5__py3-none-any.whl → 0.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- conftest.py +26 -0
- jupyter-agent/.env +2 -0
- jupyter-agent/.env.template +2 -0
- jupyter-agent/.gitattributes +35 -0
- jupyter-agent/.gradio/certificate.pem +31 -0
- jupyter-agent/README.md +16 -0
- jupyter-agent/__main__.log +8 -0
- jupyter-agent/app.py +256 -0
- jupyter-agent/cloudops-agent.png +0 -0
- jupyter-agent/ds-system-prompt.txt +154 -0
- jupyter-agent/jupyter-agent.png +0 -0
- jupyter-agent/llama3_template.jinja +123 -0
- jupyter-agent/requirements.txt +9 -0
- jupyter-agent/tmp/4ojbs8a02ir/jupyter-agent.ipynb +68 -0
- jupyter-agent/tmp/cm5iasgpm3p/jupyter-agent.ipynb +91 -0
- jupyter-agent/tmp/crqbsseag5/jupyter-agent.ipynb +91 -0
- jupyter-agent/tmp/hohanq1u097/jupyter-agent.ipynb +57 -0
- jupyter-agent/tmp/jns1sam29wm/jupyter-agent.ipynb +53 -0
- jupyter-agent/tmp/jupyter-agent.ipynb +27 -0
- jupyter-agent/utils.py +409 -0
- runbooks/__init__.py +71 -3
- runbooks/__main__.py +13 -0
- runbooks/aws/ec2_describe_instances.py +1 -1
- runbooks/aws/ec2_run_instances.py +8 -2
- runbooks/aws/ec2_start_stop_instances.py +17 -4
- runbooks/aws/ec2_unused_volumes.py +5 -1
- runbooks/aws/s3_create_bucket.py +4 -2
- runbooks/aws/s3_list_objects.py +6 -1
- runbooks/aws/tagging_lambda_handler.py +13 -2
- runbooks/aws/tags.json +12 -0
- runbooks/base.py +353 -0
- runbooks/cfat/README.md +49 -0
- runbooks/cfat/__init__.py +74 -0
- runbooks/cfat/app.ts +644 -0
- runbooks/cfat/assessment/__init__.py +40 -0
- runbooks/cfat/assessment/asana-import.csv +39 -0
- runbooks/cfat/assessment/cfat-checks.csv +31 -0
- runbooks/cfat/assessment/cfat.txt +520 -0
- runbooks/cfat/assessment/collectors.py +200 -0
- runbooks/cfat/assessment/jira-import.csv +39 -0
- runbooks/cfat/assessment/runner.py +387 -0
- runbooks/cfat/assessment/validators.py +290 -0
- runbooks/cfat/cli.py +103 -0
- runbooks/cfat/docs/asana-import.csv +24 -0
- runbooks/cfat/docs/cfat-checks.csv +31 -0
- runbooks/cfat/docs/cfat.txt +335 -0
- runbooks/cfat/docs/checks-output.png +0 -0
- runbooks/cfat/docs/cloudshell-console-run.png +0 -0
- runbooks/cfat/docs/cloudshell-download.png +0 -0
- runbooks/cfat/docs/cloudshell-output.png +0 -0
- runbooks/cfat/docs/downloadfile.png +0 -0
- runbooks/cfat/docs/jira-import.csv +24 -0
- runbooks/cfat/docs/open-cloudshell.png +0 -0
- runbooks/cfat/docs/report-header.png +0 -0
- runbooks/cfat/models.py +1026 -0
- runbooks/cfat/package-lock.json +5116 -0
- runbooks/cfat/package.json +38 -0
- runbooks/cfat/report.py +496 -0
- runbooks/cfat/reporting/__init__.py +46 -0
- runbooks/cfat/reporting/exporters.py +337 -0
- runbooks/cfat/reporting/formatters.py +496 -0
- runbooks/cfat/reporting/templates.py +135 -0
- runbooks/cfat/run-assessment.sh +23 -0
- runbooks/cfat/runner.py +69 -0
- runbooks/cfat/src/actions/check-cloudtrail-existence.ts +43 -0
- runbooks/cfat/src/actions/check-config-existence.ts +37 -0
- runbooks/cfat/src/actions/check-control-tower.ts +37 -0
- runbooks/cfat/src/actions/check-ec2-existence.ts +46 -0
- runbooks/cfat/src/actions/check-iam-users.ts +50 -0
- runbooks/cfat/src/actions/check-legacy-cur.ts +30 -0
- runbooks/cfat/src/actions/check-org-cloudformation.ts +30 -0
- runbooks/cfat/src/actions/check-vpc-existence.ts +43 -0
- runbooks/cfat/src/actions/create-asanaimport.ts +14 -0
- runbooks/cfat/src/actions/create-backlog.ts +372 -0
- runbooks/cfat/src/actions/create-jiraimport.ts +15 -0
- runbooks/cfat/src/actions/create-report.ts +616 -0
- runbooks/cfat/src/actions/define-account-type.ts +51 -0
- runbooks/cfat/src/actions/get-enabled-org-policy-types.ts +40 -0
- runbooks/cfat/src/actions/get-enabled-org-services.ts +26 -0
- runbooks/cfat/src/actions/get-idc-info.ts +34 -0
- runbooks/cfat/src/actions/get-org-da-accounts.ts +34 -0
- runbooks/cfat/src/actions/get-org-details.ts +35 -0
- runbooks/cfat/src/actions/get-org-member-accounts.ts +44 -0
- runbooks/cfat/src/actions/get-org-ous.ts +35 -0
- runbooks/cfat/src/actions/get-regions.ts +22 -0
- runbooks/cfat/src/actions/zip-assessment.ts +27 -0
- runbooks/cfat/src/types/index.d.ts +147 -0
- runbooks/cfat/tests/__init__.py +141 -0
- runbooks/cfat/tests/test_cli.py +340 -0
- runbooks/cfat/tests/test_integration.py +290 -0
- runbooks/cfat/tests/test_models.py +505 -0
- runbooks/cfat/tests/test_reporting.py +354 -0
- runbooks/cfat/tsconfig.json +16 -0
- runbooks/cfat/webpack.config.cjs +27 -0
- runbooks/config.py +260 -0
- runbooks/finops/README.md +337 -0
- runbooks/finops/__init__.py +86 -0
- runbooks/finops/aws_client.py +245 -0
- runbooks/finops/cli.py +151 -0
- runbooks/finops/cost_processor.py +410 -0
- runbooks/finops/dashboard_runner.py +448 -0
- runbooks/finops/helpers.py +355 -0
- runbooks/finops/main.py +14 -0
- runbooks/finops/profile_processor.py +174 -0
- runbooks/finops/types.py +66 -0
- runbooks/finops/visualisations.py +80 -0
- runbooks/inventory/.gitignore +354 -0
- runbooks/inventory/ArgumentsClass.py +261 -0
- runbooks/inventory/FAILED_SCRIPTS_TROUBLESHOOTING.md +619 -0
- runbooks/inventory/Inventory_Modules.py +6130 -0
- runbooks/inventory/LandingZone/delete_lz.py +1075 -0
- runbooks/inventory/PASSED_SCRIPTS_GUIDE.md +738 -0
- runbooks/inventory/README.md +1320 -0
- runbooks/inventory/__init__.py +62 -0
- runbooks/inventory/account_class.py +532 -0
- runbooks/inventory/all_my_instances_wrapper.py +123 -0
- runbooks/inventory/aws_decorators.py +201 -0
- runbooks/inventory/aws_organization.png +0 -0
- runbooks/inventory/cfn_move_stack_instances.py +1526 -0
- runbooks/inventory/check_cloudtrail_compliance.py +614 -0
- runbooks/inventory/check_controltower_readiness.py +1107 -0
- runbooks/inventory/check_landingzone_readiness.py +711 -0
- runbooks/inventory/cloudtrail.md +727 -0
- runbooks/inventory/collectors/__init__.py +20 -0
- runbooks/inventory/collectors/aws_compute.py +518 -0
- runbooks/inventory/collectors/aws_networking.py +275 -0
- runbooks/inventory/collectors/base.py +222 -0
- runbooks/inventory/core/__init__.py +19 -0
- runbooks/inventory/core/collector.py +303 -0
- runbooks/inventory/core/formatter.py +296 -0
- runbooks/inventory/delete_s3_buckets_objects.py +169 -0
- runbooks/inventory/discovery.md +81 -0
- runbooks/inventory/draw_org_structure.py +748 -0
- runbooks/inventory/ec2_vpc_utils.py +341 -0
- runbooks/inventory/find_cfn_drift_detection.py +272 -0
- runbooks/inventory/find_cfn_orphaned_stacks.py +719 -0
- runbooks/inventory/find_cfn_stackset_drift.py +733 -0
- runbooks/inventory/find_ec2_security_groups.py +669 -0
- runbooks/inventory/find_landingzone_versions.py +201 -0
- runbooks/inventory/find_vpc_flow_logs.py +1221 -0
- runbooks/inventory/inventory.sh +659 -0
- runbooks/inventory/list_cfn_stacks.py +558 -0
- runbooks/inventory/list_cfn_stackset_operation_results.py +252 -0
- runbooks/inventory/list_cfn_stackset_operations.py +734 -0
- runbooks/inventory/list_cfn_stacksets.py +453 -0
- runbooks/inventory/list_config_recorders_delivery_channels.py +681 -0
- runbooks/inventory/list_ds_directories.py +354 -0
- runbooks/inventory/list_ec2_availability_zones.py +286 -0
- runbooks/inventory/list_ec2_ebs_volumes.py +244 -0
- runbooks/inventory/list_ec2_instances.py +425 -0
- runbooks/inventory/list_ecs_clusters_and_tasks.py +562 -0
- runbooks/inventory/list_elbs_load_balancers.py +411 -0
- runbooks/inventory/list_enis_network_interfaces.py +526 -0
- runbooks/inventory/list_guardduty_detectors.py +568 -0
- runbooks/inventory/list_iam_policies.py +404 -0
- runbooks/inventory/list_iam_roles.py +518 -0
- runbooks/inventory/list_iam_saml_providers.py +359 -0
- runbooks/inventory/list_lambda_functions.py +882 -0
- runbooks/inventory/list_org_accounts.py +446 -0
- runbooks/inventory/list_org_accounts_users.py +354 -0
- runbooks/inventory/list_rds_db_instances.py +406 -0
- runbooks/inventory/list_route53_hosted_zones.py +318 -0
- runbooks/inventory/list_servicecatalog_provisioned_products.py +575 -0
- runbooks/inventory/list_sns_topics.py +360 -0
- runbooks/inventory/list_ssm_parameters.py +402 -0
- runbooks/inventory/list_vpc_subnets.py +433 -0
- runbooks/inventory/list_vpcs.py +422 -0
- runbooks/inventory/lockdown_cfn_stackset_role.py +224 -0
- runbooks/inventory/models/__init__.py +24 -0
- runbooks/inventory/models/account.py +192 -0
- runbooks/inventory/models/inventory.py +309 -0
- runbooks/inventory/models/resource.py +247 -0
- runbooks/inventory/recover_cfn_stack_ids.py +205 -0
- runbooks/inventory/requirements.txt +12 -0
- runbooks/inventory/run_on_multi_accounts.py +211 -0
- runbooks/inventory/tests/common_test_data.py +3661 -0
- runbooks/inventory/tests/common_test_functions.py +204 -0
- runbooks/inventory/tests/setup.py +24 -0
- runbooks/inventory/tests/src.py +18 -0
- runbooks/inventory/tests/test_cfn_describe_stacks.py +208 -0
- runbooks/inventory/tests/test_ec2_describe_instances.py +162 -0
- runbooks/inventory/tests/test_inventory_modules.py +55 -0
- runbooks/inventory/tests/test_lambda_list_functions.py +86 -0
- runbooks/inventory/tests/test_moto_integration_example.py +273 -0
- runbooks/inventory/tests/test_org_list_accounts.py +49 -0
- runbooks/inventory/update_aws_actions.py +173 -0
- runbooks/inventory/update_cfn_stacksets.py +1215 -0
- runbooks/inventory/update_cloudwatch_logs_retention_policy.py +294 -0
- runbooks/inventory/update_iam_roles_cross_accounts.py +478 -0
- runbooks/inventory/update_s3_public_access_block.py +539 -0
- runbooks/inventory/utils/__init__.py +23 -0
- runbooks/inventory/utils/aws_helpers.py +510 -0
- runbooks/inventory/utils/threading_utils.py +493 -0
- runbooks/inventory/utils/validation.py +682 -0
- runbooks/inventory/verify_ec2_security_groups.py +1430 -0
- runbooks/main.py +1004 -0
- runbooks/organizations/__init__.py +12 -0
- runbooks/organizations/manager.py +374 -0
- runbooks/security/README.md +447 -0
- runbooks/security/__init__.py +71 -0
- runbooks/{security_baseline → security}/checklist/alternate_contacts.py +8 -1
- runbooks/{security_baseline → security}/checklist/bucket_public_access.py +4 -1
- runbooks/{security_baseline → security}/checklist/cloudwatch_alarm_configuration.py +9 -2
- runbooks/{security_baseline → security}/checklist/guardduty_enabled.py +9 -2
- runbooks/{security_baseline → security}/checklist/multi_region_instance_usage.py +5 -1
- runbooks/{security_baseline → security}/checklist/root_access_key.py +6 -1
- runbooks/{security_baseline → security}/config-origin.json +1 -1
- runbooks/{security_baseline → security}/config.json +1 -1
- runbooks/{security_baseline → security}/permission.json +1 -1
- runbooks/{security_baseline → security}/report_generator.py +10 -2
- runbooks/{security_baseline → security}/report_template_en.html +7 -7
- runbooks/{security_baseline → security}/report_template_jp.html +7 -7
- runbooks/{security_baseline → security}/report_template_kr.html +12 -12
- runbooks/{security_baseline → security}/report_template_vn.html +7 -7
- runbooks/{security_baseline → security}/run_script.py +8 -2
- runbooks/{security_baseline → security}/security_baseline_tester.py +12 -4
- runbooks/{security_baseline → security}/utils/common.py +5 -1
- runbooks/utils/__init__.py +204 -0
- runbooks-0.7.0.dist-info/METADATA +375 -0
- runbooks-0.7.0.dist-info/RECORD +249 -0
- {runbooks-0.2.5.dist-info → runbooks-0.7.0.dist-info}/WHEEL +1 -1
- runbooks-0.7.0.dist-info/entry_points.txt +7 -0
- runbooks-0.7.0.dist-info/licenses/LICENSE +201 -0
- runbooks-0.7.0.dist-info/top_level.txt +3 -0
- runbooks/python101/calculator.py +0 -34
- runbooks/python101/config.py +0 -1
- runbooks/python101/exceptions.py +0 -16
- runbooks/python101/file_manager.py +0 -218
- runbooks/python101/toolkit.py +0 -153
- runbooks-0.2.5.dist-info/METADATA +0 -439
- runbooks-0.2.5.dist-info/RECORD +0 -61
- runbooks-0.2.5.dist-info/entry_points.txt +0 -3
- runbooks-0.2.5.dist-info/top_level.txt +0 -1
- /runbooks/{security_baseline/__init__.py → inventory/tests/script_test_data.py} +0 -0
- /runbooks/{security_baseline → security}/checklist/__init__.py +0 -0
- /runbooks/{security_baseline → security}/checklist/account_level_bucket_public_access.py +0 -0
- /runbooks/{security_baseline → security}/checklist/direct_attached_policy.py +0 -0
- /runbooks/{security_baseline → security}/checklist/iam_password_policy.py +0 -0
- /runbooks/{security_baseline → security}/checklist/iam_user_mfa.py +0 -0
- /runbooks/{security_baseline → security}/checklist/multi_region_trail.py +0 -0
- /runbooks/{security_baseline → security}/checklist/root_mfa.py +0 -0
- /runbooks/{security_baseline → security}/checklist/root_usage.py +0 -0
- /runbooks/{security_baseline → security}/checklist/trail_enabled.py +0 -0
- /runbooks/{security_baseline → security}/checklist/trusted_advisor.py +0 -0
- /runbooks/{security_baseline → security}/utils/__init__.py +0 -0
- /runbooks/{security_baseline → security}/utils/enums.py +0 -0
- /runbooks/{security_baseline → security}/utils/language.py +0 -0
- /runbooks/{security_baseline → security}/utils/level_const.py +0 -0
- /runbooks/{security_baseline → security}/utils/permission_list.py +0 -0
@@ -0,0 +1,568 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
|
3
|
+
"""
|
4
|
+
AWS GuardDuty Detector Discovery and Management Script
|
5
|
+
|
6
|
+
This script provides comprehensive discovery, inventory, and management capabilities for
|
7
|
+
AWS GuardDuty detectors and invitations across multiple accounts and regions. It's designed
|
8
|
+
for enterprise security teams who need visibility into GuardDuty deployment status,
|
9
|
+
detector configuration, and administrative relationships across large-scale AWS environments.
|
10
|
+
|
11
|
+
Key Features:
|
12
|
+
- Multi-account GuardDuty detector discovery using assume role capabilities
|
13
|
+
- Multi-region scanning with GuardDuty-enabled region targeting
|
14
|
+
- GuardDuty invitation tracking and management for organizational security
|
15
|
+
- Administrative account detection with member account relationship mapping
|
16
|
+
- Detector deletion capabilities with safety controls for cleanup operations
|
17
|
+
- Enterprise reporting with detailed detector and invitation analysis
|
18
|
+
- Profile-based authentication with support for federated access
|
19
|
+
|
20
|
+
Enterprise Use Cases:
|
21
|
+
- Security posture assessment and GuardDuty deployment validation
|
22
|
+
- GuardDuty administrative relationship mapping across organizations
|
23
|
+
- Security service cleanup and consolidation during account transitions
|
24
|
+
- Compliance reporting for threat detection service coverage
|
25
|
+
- Multi-account security governance and standardization
|
26
|
+
- GuardDuty cost optimization through detector lifecycle management
|
27
|
+
- Security incident response planning with detector coverage analysis
|
28
|
+
|
29
|
+
GuardDuty Management Features:
|
30
|
+
- Detector enumeration with administrative status identification
|
31
|
+
- Member account relationship tracking for security hierarchy mapping
|
32
|
+
- Invitation discovery and cleanup for organizational security management
|
33
|
+
- Multi-region detector coverage analysis for comprehensive protection
|
34
|
+
- Administrative account detection with member count reporting
|
35
|
+
- Detector deletion with safety controls and confirmation mechanisms
|
36
|
+
|
37
|
+
Security Considerations:
|
38
|
+
- Uses IAM assume role capabilities for cross-account GuardDuty access
|
39
|
+
- Implements proper error handling for authorization failures
|
40
|
+
- Supports both read-only discovery and controlled deletion operations
|
41
|
+
- Respects GuardDuty service permissions and regional availability constraints
|
42
|
+
- Provides comprehensive audit trail through detailed logging
|
43
|
+
- Implements safety controls for destructive operations with confirmation prompts
|
44
|
+
|
45
|
+
GuardDuty Administrative Analysis:
|
46
|
+
- Administrative account identification and member relationship mapping
|
47
|
+
- Invitation status tracking for organizational security coordination
|
48
|
+
- Detector configuration analysis across organizational boundaries
|
49
|
+
- Security service coverage assessment for compliance validation
|
50
|
+
- Multi-account threat detection architecture documentation
|
51
|
+
|
52
|
+
Deletion and Cleanup Features:
|
53
|
+
- Safe detector deletion with confirmation mechanisms
|
54
|
+
- Invitation cleanup for organizational security management
|
55
|
+
- Member disassociation handling for administrative relationship changes
|
56
|
+
- Comprehensive error handling for cleanup operation failures
|
57
|
+
- Audit logging for all deletion and modification operations
|
58
|
+
|
59
|
+
Performance Considerations:
|
60
|
+
- Sequential processing for reliable GuardDuty API operations
|
61
|
+
- Progress tracking for operational visibility during large-scale operations
|
62
|
+
- Efficient credential management for cross-account security access
|
63
|
+
- Region-aware processing optimized for GuardDuty service availability
|
64
|
+
- Memory-optimized data structures for large security inventories
|
65
|
+
|
66
|
+
Dependencies:
|
67
|
+
- boto3/botocore for AWS GuardDuty API interactions
|
68
|
+
- Inventory_Modules for common utility functions and credential management
|
69
|
+
- ArgumentsClass for standardized CLI argument parsing
|
70
|
+
- account_class for AWS account access and session management
|
71
|
+
- colorama for enhanced output formatting
|
72
|
+
|
73
|
+
Safety and Compliance:
|
74
|
+
- Confirmation prompts for destructive operations
|
75
|
+
- Comprehensive logging for security audit trails
|
76
|
+
- Error handling for failed deletion operations
|
77
|
+
- Member account protection during administrative cleanup
|
78
|
+
- Force deletion capability with additional safety controls
|
79
|
+
|
80
|
+
Future Enhancements:
|
81
|
+
- GuardDuty finding analysis and threat intelligence integration
|
82
|
+
- Automated detector configuration compliance checking
|
83
|
+
- Integration with AWS Config for security service drift detection
|
84
|
+
- Cost analysis and optimization recommendations for GuardDuty usage
|
85
|
+
|
86
|
+
Author: AWS CloudOps Team
|
87
|
+
Version: 2023.07.18
|
88
|
+
"""
|
89
|
+
|
90
|
+
import logging
|
91
|
+
import sys
|
92
|
+
|
93
|
+
import boto3
|
94
|
+
import Inventory_Modules
|
95
|
+
from account_class import aws_acct_access
|
96
|
+
from ArgumentsClass import CommonArguments
|
97
|
+
from botocore.exceptions import ClientError
|
98
|
+
from colorama import Fore, init
|
99
|
+
from Inventory_Modules import get_all_credentials
|
100
|
+
|
101
|
+
init()
|
102
|
+
__version__ = "2023.07.18"
|
103
|
+
|
104
|
+
# Parse enterprise command-line arguments with GuardDuty-specific security management options
|
105
|
+
parser = CommonArguments()
|
106
|
+
parser.singleprofile() # Single profile mode for focused GuardDuty operations
|
107
|
+
parser.multiregion_nodefault() # Multi-region scanning without default region assumptions
|
108
|
+
parser.extendedargs() # Extended arguments for advanced filtering and account selection
|
109
|
+
parser.deletion() # Deletion capabilities with safety controls for GuardDuty cleanup
|
110
|
+
parser.rootOnly() # Organization root account limitation for security governance
|
111
|
+
parser.rolestouse() # Cross-account roles for Organizations GuardDuty access
|
112
|
+
parser.timing() # Performance timing for operational optimization
|
113
|
+
parser.verbosity() # Logging verbosity for security operations audit trail
|
114
|
+
parser.version(__version__) # Version information for operational documentation
|
115
|
+
|
116
|
+
# Add GuardDuty-specific deletion and management arguments
|
117
|
+
parser.my_parser.add_argument(
|
118
|
+
"+delete",
|
119
|
+
"+forreal",
|
120
|
+
"+fix",
|
121
|
+
dest="flagDelete",
|
122
|
+
action="store_true",
|
123
|
+
help="Enable GuardDuty detector deletion operations - DESTRUCTIVE ACTION with confirmation prompts for security cleanup",
|
124
|
+
)
|
125
|
+
|
126
|
+
# Parse all command-line arguments for GuardDuty security management operations
|
127
|
+
args = parser.my_parser.parse_args()
|
128
|
+
|
129
|
+
# Extract configuration parameters for multi-account GuardDuty security management
|
130
|
+
pProfile = args.Profile # AWS profile for GuardDuty administrative access
|
131
|
+
pRegions = args.Regions # Target regions for GuardDuty detector enumeration
|
132
|
+
pSkipAccounts = args.SkipAccounts # Account exclusion list for organizational policy compliance
|
133
|
+
pSkipProfiles = args.SkipProfiles # Profile exclusion for credential optimization
|
134
|
+
pAccounts = args.Accounts # Specific account targeting for focused security analysis
|
135
|
+
pRootOnly = args.RootOnly # Organization root account limitation flag
|
136
|
+
pRolesToUse = args.AccessRoles # Cross-account roles for Organizations security access
|
137
|
+
verbose = args.loglevel # Logging verbosity for security operations visibility
|
138
|
+
DeletionRun = args.flagDelete # Enable detector deletion operations - CRITICAL SECURITY FLAG
|
139
|
+
ForceDelete = args.Force # Override safety confirmations for automated security workflows
|
140
|
+
pTiming = args.Time # Performance timing for operational optimization
|
141
|
+
|
142
|
+
# Configure enterprise logging infrastructure for GuardDuty operations audit trail
|
143
|
+
logging.basicConfig(level=verbose, format="[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s")
|
144
|
+
logging.getLogger("boto3").setLevel(logging.CRITICAL)
|
145
|
+
logging.getLogger("botocore").setLevel(logging.CRITICAL)
|
146
|
+
logging.getLogger("s3transfer").setLevel(logging.CRITICAL)
|
147
|
+
logging.getLogger("urllib3").setLevel(logging.CRITICAL)
|
148
|
+
|
149
|
+
##########################
|
150
|
+
# Initialize enterprise GuardDuty discovery and security management operations
|
151
|
+
##########################
|
152
|
+
|
153
|
+
ERASE_LINE = "\x1b[2K"
|
154
|
+
|
155
|
+
# Initialize AWS account access for GuardDuty administrative operations
|
156
|
+
aws_acct = aws_acct_access(pProfile)
|
157
|
+
|
158
|
+
# Initialize enterprise GuardDuty inventory tracking and metrics
|
159
|
+
NumObjectsFound = 0 # Total detector count across all accounts and regions
|
160
|
+
session_gd = aws_acct.session # Primary session for GuardDuty administrative operations
|
161
|
+
all_gd_detectors = [] # Comprehensive detector inventory with administrative relationships
|
162
|
+
all_gd_invites = [] # GuardDuty invitation tracking for organizational security coordination
|
163
|
+
GD_Admin_Accounts = [] # Administrative account tracking for security hierarchy mapping
|
164
|
+
|
165
|
+
# Configure GuardDuty-enabled regions for comprehensive threat detection coverage
|
166
|
+
# This validation ensures we only scan regions where GuardDuty service is available and enabled
|
167
|
+
if pRegions is None:
|
168
|
+
pRegions = ["all"] # Default to all available GuardDuty regions for comprehensive security coverage
|
169
|
+
|
170
|
+
# Discover GuardDuty-enabled regions across organizational accounts
|
171
|
+
gd_regions = Inventory_Modules.get_regions3(aws_acct, pRegions)
|
172
|
+
|
173
|
+
# Execute enterprise credential discovery and validation across organizational GuardDuty infrastructure
|
174
|
+
AllCredentials = get_all_credentials(
|
175
|
+
pProfile, pTiming, pSkipProfiles, pSkipAccounts, pRootOnly, pAccounts, gd_regions, pRolesToUse
|
176
|
+
)
|
177
|
+
|
178
|
+
# Calculate organizational scope for executive security management reporting
|
179
|
+
RegionList = list(set([x["Region"] for x in AllCredentials]))
|
180
|
+
AccountList = list(set([x["AccountId"] for x in AllCredentials]))
|
181
|
+
print(f"Searching {len(AccountList)} accounts and {len(RegionList)} regions for GuardDuty detectors")
|
182
|
+
|
183
|
+
# Initialize STS session for cross-account credential validation and security token management
|
184
|
+
sts_session = aws_acct.session
|
185
|
+
sts_client = sts_session.client("sts")
|
186
|
+
|
187
|
+
# Execute comprehensive GuardDuty detector and invitation discovery across organizational accounts
|
188
|
+
places_to_try = len(AllCredentials) # Progress tracking for operational visibility
|
189
|
+
|
190
|
+
# Main GuardDuty discovery loop - Sequential processing for reliable security service enumeration
|
191
|
+
for credential in AllCredentials:
|
192
|
+
logging.info(f"Checking Account: {credential['AccountId']}")
|
193
|
+
|
194
|
+
# Legacy credential access pattern (commented out for reference)
|
195
|
+
# This was the original approach for cross-account access before credential pre-processing
|
196
|
+
# try:
|
197
|
+
# account_credentials = Inventory_Modules.get_child_access3(aws_acct, account['AccountId'])
|
198
|
+
# except ClientError as my_Error:
|
199
|
+
# if "AuthFailure" in str(my_Error):
|
200
|
+
# print(f"Authorization Failure for account {account['AccountId']}")
|
201
|
+
# sys.exit("Credentials failure")
|
202
|
+
|
203
|
+
logging.info(f"Checking Region: {credential['Region']}")
|
204
|
+
places_to_try -= 1 # Decrement progress counter for operational tracking
|
205
|
+
|
206
|
+
try:
|
207
|
+
# Establish AWS session for GuardDuty API operations using pre-validated credentials
|
208
|
+
# This session enables cross-account GuardDuty detector and invitation discovery
|
209
|
+
session_aws = boto3.Session(
|
210
|
+
aws_access_key_id=credential["AccessKeyId"],
|
211
|
+
aws_secret_access_key=credential["SecretAccessKey"],
|
212
|
+
aws_session_token=credential["SessionToken"],
|
213
|
+
region_name=credential["Region"],
|
214
|
+
)
|
215
|
+
|
216
|
+
# Initialize GuardDuty client for security service API operations
|
217
|
+
client_aws = session_aws.client("guardduty")
|
218
|
+
logging.debug(f"Token Info: {credential} in region {credential['Region']}")
|
219
|
+
|
220
|
+
# Execute GuardDuty invitation discovery for organizational security coordination
|
221
|
+
# Invitations represent pending or active administrative relationships between accounts
|
222
|
+
logging.info(f"Finding any invites for account: {credential['AccountId']} in region {credential['Region']}")
|
223
|
+
response = client_aws.list_invitations()
|
224
|
+
logging.debug(
|
225
|
+
f"Finished listing invites for account: {credential['AccountId']} in region {credential['Region']}"
|
226
|
+
)
|
227
|
+
|
228
|
+
except ClientError as my_Error:
|
229
|
+
# Handle AWS API authorization failures with comprehensive error analysis
|
230
|
+
if "AuthFailure" in str(my_Error):
|
231
|
+
print(f"{credential['AccountId']}: Authorization Failure for account {credential['AccountId']}")
|
232
|
+
continue # Skip this account/region combination but continue processing others
|
233
|
+
|
234
|
+
# Handle invalid security token errors typically caused by region opt-in issues
|
235
|
+
if str(my_Error).find("security token included in the request is invalid") > 0:
|
236
|
+
logging.error(
|
237
|
+
f"Account #:{credential['AccountId']} - The region you're trying '{credential['Region']}' isn't enabled for your account"
|
238
|
+
)
|
239
|
+
continue # Skip disabled regions but continue with other regions
|
240
|
+
|
241
|
+
except Exception as my_Error:
|
242
|
+
# Handle unexpected errors during GuardDuty API operations
|
243
|
+
print(my_Error)
|
244
|
+
continue # Continue processing despite unexpected errors for operational resilience
|
245
|
+
# Process discovered GuardDuty invitations for organizational security coordination
|
246
|
+
try:
|
247
|
+
if "Invitations" in response.keys():
|
248
|
+
# Process each invitation to build comprehensive security relationship mapping
|
249
|
+
for i in range(len(response["Invitations"])):
|
250
|
+
# Create invitation record with credentials for future management operations
|
251
|
+
invitation_record = {
|
252
|
+
"AccountId": response["Invitations"][i]["AccountId"], # Administrative account identifier
|
253
|
+
"InvitationId": response["Invitations"][i]["InvitationId"], # Unique invitation identifier
|
254
|
+
"Region": credential["Region"], # Regional context for security coordination
|
255
|
+
"AccessKeyId": credential["AccessKeyId"], # Credentials for invitation management
|
256
|
+
"SecretAccessKey": credential["SecretAccessKey"], # Security credentials for API operations
|
257
|
+
"SessionToken": credential["SessionToken"], # Session token for temporary access
|
258
|
+
}
|
259
|
+
|
260
|
+
# Add to enterprise GuardDuty invitation inventory for administrative tracking
|
261
|
+
all_gd_invites.append(invitation_record)
|
262
|
+
|
263
|
+
# Log invitation discovery for security audit trail and organizational visibility
|
264
|
+
logging.error(
|
265
|
+
f"Found invite ID {response['Invitations'][i]['InvitationId']} in account {response['Invitations'][i]['AccountId']} in region {credential['Region']}"
|
266
|
+
)
|
267
|
+
except NameError:
|
268
|
+
# Handle cases where response variable is undefined due to API errors
|
269
|
+
# This ensures graceful handling of failed invitation discovery operations
|
270
|
+
pass
|
271
|
+
# Execute comprehensive GuardDuty detector discovery with administrative relationship analysis
|
272
|
+
try:
|
273
|
+
# Display progress information for operational visibility during large-scale security operations
|
274
|
+
print(
|
275
|
+
f"{ERASE_LINE}Trying account {credential['AccountId']} in region {credential['Region']} -- {places_to_try} left of {len(AllCredentials)}",
|
276
|
+
end="\r",
|
277
|
+
)
|
278
|
+
|
279
|
+
# Execute GuardDuty detector enumeration for security service inventory
|
280
|
+
response = client_aws.list_detectors()
|
281
|
+
|
282
|
+
# Process discovered detectors with comprehensive metadata extraction and administrative analysis
|
283
|
+
if len(response["DetectorIds"]) > 0:
|
284
|
+
# Update enterprise security service metrics and tracking
|
285
|
+
NumObjectsFound = NumObjectsFound + len(response["DetectorIds"])
|
286
|
+
|
287
|
+
# Analyze administrative relationships and member account associations
|
288
|
+
# This is critical for understanding GuardDuty security hierarchy and governance structure
|
289
|
+
admin_acct_response = client_aws.list_members(
|
290
|
+
DetectorId=str(response["DetectorIds"][0]),
|
291
|
+
OnlyAssociated="False", # Include both associated and pending member accounts
|
292
|
+
)
|
293
|
+
|
294
|
+
# Log detector discovery for security audit trail and operational tracking
|
295
|
+
logging.warning(
|
296
|
+
f"Found another detector {str(response['DetectorIds'][0])} in account {credential['AccountId']} in region {credential['Region']} bringing the total found to {str(NumObjectsFound)}"
|
297
|
+
)
|
298
|
+
|
299
|
+
# Classify detector as administrative account based on member relationships
|
300
|
+
if len(admin_acct_response["Members"]) > 0:
|
301
|
+
# Create comprehensive administrative account record for security governance
|
302
|
+
admin_detector_record = {
|
303
|
+
"AccountId": credential["AccountId"], # Administrative account identifier
|
304
|
+
"Region": credential["Region"], # Regional context for security operations
|
305
|
+
"DetectorIds": response["DetectorIds"], # GuardDuty detector identifiers
|
306
|
+
"AccessKeyId": credential["AccessKeyId"], # Administrative credentials for management
|
307
|
+
"SecretAccessKey": credential["SecretAccessKey"], # Security credentials for detector operations
|
308
|
+
"SessionToken": credential["SessionToken"], # Session token for administrative access
|
309
|
+
"GD_Admin_Accounts": admin_acct_response[
|
310
|
+
"Members"
|
311
|
+
], # Member account relationships for hierarchy mapping
|
312
|
+
}
|
313
|
+
|
314
|
+
# Add to enterprise GuardDuty administrative account inventory
|
315
|
+
all_gd_detectors.append(admin_detector_record)
|
316
|
+
|
317
|
+
# Log administrative account discovery for security governance visibility
|
318
|
+
logging.error(
|
319
|
+
f"Found account {credential['AccountId']} in region {credential['Region']} to be a GuardDuty Admin account."
|
320
|
+
f"It has {len(admin_acct_response['Members'])} member accounts connected to detector {response['DetectorIds'][0]}"
|
321
|
+
)
|
322
|
+
else:
|
323
|
+
# Create standard detector record for non-administrative accounts
|
324
|
+
standard_detector_record = {
|
325
|
+
"AccountId": credential["AccountId"], # Standard account identifier
|
326
|
+
"Region": credential["Region"], # Regional context for security coverage
|
327
|
+
"DetectorIds": response["DetectorIds"], # GuardDuty detector identifiers
|
328
|
+
"AccessKeyId": credential["AccessKeyId"], # Account credentials for detector management
|
329
|
+
"SecretAccessKey": credential["SecretAccessKey"], # Security credentials for API operations
|
330
|
+
"SessionToken": credential["SessionToken"], # Session token for detector access
|
331
|
+
"GD_Admin_Accounts": "Not an Admin Account", # Administrative status flag for classification
|
332
|
+
}
|
333
|
+
|
334
|
+
# Add to enterprise GuardDuty detector inventory for comprehensive security tracking
|
335
|
+
all_gd_detectors.append(standard_detector_record)
|
336
|
+
else:
|
337
|
+
# Display progress for accounts without GuardDuty detectors for operational visibility
|
338
|
+
print(
|
339
|
+
ERASE_LINE,
|
340
|
+
f"{Fore.RED}No luck in account: {credential['AccountId']} in region {credential['Region']}{Fore.RESET} -- {places_to_try} of {len(AllCredentials)}",
|
341
|
+
end="\r",
|
342
|
+
)
|
343
|
+
except ClientError as my_Error:
|
344
|
+
# Handle AWS API authorization failures during detector discovery operations
|
345
|
+
if "AuthFailure" in str(my_Error):
|
346
|
+
print(f"Authorization Failure for account {credential['AccountId']}")
|
347
|
+
|
348
|
+
# Configure enterprise GuardDuty report display formatting and column organization
|
349
|
+
display_dict = {
|
350
|
+
"ParentProfile": {
|
351
|
+
"DisplayOrder": 1,
|
352
|
+
"Heading": "Parent Profile",
|
353
|
+
}, # AWS profile context for organizational hierarchy
|
354
|
+
"MgmtAccount": {"DisplayOrder": 2, "Heading": "Mgmt Acct"}, # Management account identifier for security governance
|
355
|
+
"AccountId": {"DisplayOrder": 3, "Heading": "Acct Number"}, # Target account containing GuardDuty detectors
|
356
|
+
"Region": {
|
357
|
+
"DisplayOrder": 4,
|
358
|
+
"Heading": "Region",
|
359
|
+
"Condition": ["us-east-2"],
|
360
|
+
}, # AWS region for geographic security coverage
|
361
|
+
"DetectorIds": {
|
362
|
+
"DisplayOrder": 5,
|
363
|
+
"Heading": "DetectorId",
|
364
|
+
"Condition": ["Never"],
|
365
|
+
}, # GuardDuty detector identifiers for management
|
366
|
+
"DG_Admin_Accounts": {
|
367
|
+
"DisplayOrder": 6,
|
368
|
+
"Heading": "Admin Accounts",
|
369
|
+
}, # Administrative account relationships for security hierarchy
|
370
|
+
"Size": {"DisplayOrder": 7, "Heading": "Size (Bytes)"},
|
371
|
+
}
|
372
|
+
|
373
|
+
# Generate detailed GuardDuty detector report with administrative relationship analysis
|
374
|
+
if args.loglevel < 50:
|
375
|
+
print()
|
376
|
+
# Configure table formatting for enterprise GuardDuty security reporting
|
377
|
+
fmt = "%-20s %-15s %-35s %-25s"
|
378
|
+
print(fmt % ("Account", "Region", "DetectorId", "Admin Status"))
|
379
|
+
print(fmt % ("----------", "------", "-----------", "--------------------"))
|
380
|
+
|
381
|
+
# Display comprehensive GuardDuty detector inventory with administrative relationships
|
382
|
+
for i in range(len(all_gd_detectors)):
|
383
|
+
try:
|
384
|
+
# Process administrative GuardDuty accounts with member account relationships
|
385
|
+
if "AccountId" in all_gd_detectors[i]["GD_Admin_Accounts"][0].keys():
|
386
|
+
print(
|
387
|
+
fmt
|
388
|
+
% (
|
389
|
+
all_gd_detectors[i]["AccountId"], # Administrative account identifier
|
390
|
+
all_gd_detectors[i]["Region"], # Regional security coverage context
|
391
|
+
all_gd_detectors[i]["DetectorIds"], # GuardDuty detector identifiers for management
|
392
|
+
f"{len(all_gd_detectors[i]['GD_Admin_Accounts'])} Member Accounts", # Member account count for hierarchy mapping
|
393
|
+
)
|
394
|
+
)
|
395
|
+
except AttributeError:
|
396
|
+
# Display standard GuardDuty detectors without administrative relationships
|
397
|
+
print(
|
398
|
+
fmt
|
399
|
+
% (
|
400
|
+
all_gd_detectors[i]["AccountId"], # Standard account identifier
|
401
|
+
all_gd_detectors[i]["Region"], # Regional security coverage context
|
402
|
+
all_gd_detectors[i]["DetectorIds"], # GuardDuty detector identifiers
|
403
|
+
"Not an Admin Account", # Administrative status classification
|
404
|
+
)
|
405
|
+
)
|
406
|
+
|
407
|
+
# Display comprehensive GuardDuty discovery summary for enterprise security reporting
|
408
|
+
print(ERASE_LINE)
|
409
|
+
print(
|
410
|
+
f"We scanned {len(AccountList)} accounts and {len(RegionList)} regions totalling {len(AllCredentials)} possible areas for resources."
|
411
|
+
)
|
412
|
+
print(f"Found {len(all_gd_invites)} Invites and {NumObjectsFound} Detectors")
|
413
|
+
print()
|
414
|
+
|
415
|
+
# Execute GuardDuty detector deletion workflow with comprehensive safety controls
|
416
|
+
# CRITICAL SECURITY OPERATION: Detector deletion is irreversible and impacts organizational security
|
417
|
+
if DeletionRun and not ForceDelete:
|
418
|
+
# Interactive confirmation for safe GuardDuty detector deletion operations
|
419
|
+
# This mandatory confirmation prevents accidental security service disruption
|
420
|
+
ReallyDelete = input("Deletion of Guard Duty detectors has been requested. Are you still sure? (y/n): ") == "y"
|
421
|
+
else:
|
422
|
+
ReallyDelete = False # Default to safe mode preventing accidental deletions
|
423
|
+
|
424
|
+
# Execute comprehensive GuardDuty cleanup operations with safety controls and audit logging
|
425
|
+
if DeletionRun and (ReallyDelete or ForceDelete):
|
426
|
+
MemberList = [] # Initialize member account tracking for deletion operations
|
427
|
+
|
428
|
+
# Begin GuardDuty invitation cleanup for organizational security coordination
|
429
|
+
logging.warning("Deleting all invites")
|
430
|
+
|
431
|
+
# Process all discovered GuardDuty invitations for comprehensive cleanup operations
|
432
|
+
for y in range(len(all_gd_invites)):
|
433
|
+
# Establish AWS session for GuardDuty invitation deletion operations
|
434
|
+
# Using pre-validated credentials from invitation discovery phase
|
435
|
+
session_gd_child = boto3.Session(
|
436
|
+
aws_access_key_id=all_gd_invites[y]["AccessKeyId"], # Account credentials for invitation management
|
437
|
+
aws_secret_access_key=all_gd_invites[y]["SecretAccessKey"], # Security credentials for API operations
|
438
|
+
aws_session_token=all_gd_invites[y]["SessionToken"], # Session token for temporary access
|
439
|
+
region_name=all_gd_invites[y]["Region"], # Regional context for invitation operations
|
440
|
+
)
|
441
|
+
|
442
|
+
# Initialize GuardDuty client for invitation deletion API operations
|
443
|
+
client_gd_child = session_gd_child.client("guardduty")
|
444
|
+
|
445
|
+
# Execute GuardDuty invitation deletion with comprehensive error handling and audit logging
|
446
|
+
try:
|
447
|
+
# Display progress for invitation deletion operations with real-time visibility
|
448
|
+
print(ERASE_LINE, f"Deleting invite for Account {all_gd_invites[y]['AccountId']}", end="\r")
|
449
|
+
|
450
|
+
# Execute invitation deletion API operation with security audit logging
|
451
|
+
Output = client_gd_child.delete_invitations(AccountIds=[all_gd_invites[y]["AccountId"]])
|
452
|
+
|
453
|
+
except Exception as e:
|
454
|
+
# Handle expected BadRequest exceptions during invitation cleanup operations
|
455
|
+
if e.response["Error"]["Code"] == "BadRequestException":
|
456
|
+
logging.warning("Caught exception 'BadRequestException', handling the exception...")
|
457
|
+
pass # Continue processing remaining invitations despite individual failures
|
458
|
+
else:
|
459
|
+
# Handle unexpected errors during GuardDuty invitation deletion operations
|
460
|
+
print("Caught unexpected error regarding deleting invites")
|
461
|
+
print(e)
|
462
|
+
sys.exit(9) # Exit with error code for operational failure handling
|
463
|
+
|
464
|
+
# Report invitation deletion completion for security audit trail
|
465
|
+
print(f"Removed {len(all_gd_invites)} GuardDuty Invites")
|
466
|
+
|
467
|
+
# Begin comprehensive GuardDuty detector deletion operations
|
468
|
+
num_of_gd_detectors = len(all_gd_detectors)
|
469
|
+
|
470
|
+
# Process all discovered GuardDuty detectors for systematic cleanup operations
|
471
|
+
for y in range(len(all_gd_detectors)):
|
472
|
+
# Log detector deletion initiation for comprehensive security audit trail
|
473
|
+
logging.info(
|
474
|
+
f"Deleting detector-id: {all_gd_detectors[y]['DetectorIds']} from account {all_gd_detectors[y]['AccountId']} in region {all_gd_detectors[y]['Region']}"
|
475
|
+
)
|
476
|
+
|
477
|
+
# Display progress for detector deletion operations with operational visibility
|
478
|
+
print(
|
479
|
+
f"Deleting detector in account {all_gd_detectors[y]['AccountId']} in region {all_gd_detectors[y]['Region']} {num_of_gd_detectors}/{len(all_gd_detectors)}"
|
480
|
+
)
|
481
|
+
|
482
|
+
# Establish AWS session for GuardDuty detector deletion operations with pre-validated credentials
|
483
|
+
session_gd_child = boto3.Session(
|
484
|
+
aws_access_key_id=all_gd_detectors[y]["AccessKeyId"], # Account credentials for detector management
|
485
|
+
aws_secret_access_key=all_gd_detectors[y]["SecretAccessKey"], # Security credentials for API operations
|
486
|
+
aws_session_token=all_gd_detectors[y]["SessionToken"], # Session token for temporary access
|
487
|
+
region_name=all_gd_detectors[y]["Region"], # Regional context for detector operations
|
488
|
+
)
|
489
|
+
|
490
|
+
# Initialize GuardDuty client for detector deletion API operations
|
491
|
+
client_gd_child = session_gd_child.client("guardduty")
|
492
|
+
|
493
|
+
# Execute member account discovery for comprehensive administrative relationship cleanup
|
494
|
+
# This is critical for proper GuardDuty hierarchy dismantling before detector deletion
|
495
|
+
Member_Dict = client_gd_child.list_members(
|
496
|
+
DetectorId=str(all_gd_detectors[y]["DetectorIds"][0]), # Primary detector identifier for member enumeration
|
497
|
+
OnlyAssociated="FALSE", # Include both associated and pending member accounts for complete cleanup
|
498
|
+
)["Members"]
|
499
|
+
|
500
|
+
# Aggregate member account list for batch disassociation operations
|
501
|
+
for i in range(len(Member_Dict)):
|
502
|
+
MemberList.append(Member_Dict[i]["AccountId"]) # Collect member accounts for comprehensive cleanup
|
503
|
+
|
504
|
+
try:
|
505
|
+
# Initialize deletion operation status tracking for operational monitoring
|
506
|
+
Output = 0
|
507
|
+
|
508
|
+
# Execute master account disassociation for proper GuardDuty hierarchy cleanup
|
509
|
+
# This critical step must precede detector deletion to prevent orphaned relationships
|
510
|
+
client_gd_child.disassociate_from_master_account(DetectorId=str(all_gd_detectors[y]["DetectorIds"][0]))
|
511
|
+
except Exception as e:
|
512
|
+
# Handle expected BadRequest exceptions during master account disassociation
|
513
|
+
if e.response["Error"]["Code"] == "BadRequestException":
|
514
|
+
logging.warning("Caught exception 'BadRequestException', handling the exception...")
|
515
|
+
pass # Continue with member disassociation despite master account errors
|
516
|
+
|
517
|
+
# Execute comprehensive member account disassociation for administrative relationship cleanup
|
518
|
+
# Critical step for proper GuardDuty hierarchy dismantling before detector deletion
|
519
|
+
if MemberList: # Process member accounts only when administrative relationships exist
|
520
|
+
# Disassociate member accounts from administrative detector for proper cleanup
|
521
|
+
client_gd_child.disassociate_members(
|
522
|
+
AccountIds=MemberList, # Member account list for batch disassociation
|
523
|
+
DetectorId=str(all_gd_detectors[y]["DetectorIds"][0]), # Administrative detector identifier
|
524
|
+
)
|
525
|
+
|
526
|
+
# Log member disassociation completion for security audit trail
|
527
|
+
logging.warning(
|
528
|
+
f"Account {str(all_gd_detectors[y]['AccountId'])} has been disassociated from master account"
|
529
|
+
)
|
530
|
+
|
531
|
+
# Execute member account deletion from administrative detector for complete cleanup
|
532
|
+
client_gd_child.delete_members(
|
533
|
+
AccountIds=[all_gd_detectors[y]["AccountId"]], # Target account for member deletion
|
534
|
+
DetectorId=str(all_gd_detectors[y]["DetectorIds"][0]), # Administrative detector context
|
535
|
+
)
|
536
|
+
|
537
|
+
# Log member deletion completion for comprehensive security audit trail
|
538
|
+
logging.warning(f"Account {str(all_gd_detectors[y]['AccountId'])} has been deleted from master account")
|
539
|
+
|
540
|
+
# Execute final GuardDuty detector deletion after all relationships are properly cleaned up
|
541
|
+
# This is the terminal operation that permanently removes the GuardDuty detector
|
542
|
+
client_gd_child.delete_detector(DetectorId=str(all_gd_detectors[y]["DetectorIds"][0]))
|
543
|
+
|
544
|
+
# Log detector deletion completion for comprehensive security audit trail and operational confirmation
|
545
|
+
logging.warning(
|
546
|
+
f"Detector {str(all_gd_detectors[y]['DetectorIds'][0])} has been deleted from child account "
|
547
|
+
f"{str(all_gd_detectors[y]['AccountId'])}"
|
548
|
+
)
|
549
|
+
|
550
|
+
# Update progress counter for operational visibility during large-scale cleanup operations
|
551
|
+
num_of_gd_detectors -= 1
|
552
|
+
# Legacy CloudFormation stack deletion code (commented out for reference)
|
553
|
+
# This was the original approach for GuardDuty cleanup via CloudFormation stacks
|
554
|
+
# Replaced with direct GuardDuty API operations for more granular control
|
555
|
+
"""
|
556
|
+
if StacksFound[y][3] == 'DELETE_FAILED':
|
557
|
+
response=Inventory_Modules.delete_stack(StacksFound[y][0],StacksFound[y][1],StacksFound[y][2],RetainResources=True,ResourcesToRetain=["MasterDetector"])
|
558
|
+
else:
|
559
|
+
response=Inventory_Modules.delete_stack(StacksFound[y][0],StacksFound[y][1],StacksFound[y][2])
|
560
|
+
"""
|
561
|
+
|
562
|
+
# Handle non-deletion scenarios with appropriate user messaging for operational clarity
|
563
|
+
elif not DeletionRun or (DeletionRun and not ReallyDelete):
|
564
|
+
print("Client didn't want to delete detectors... ")
|
565
|
+
|
566
|
+
print()
|
567
|
+
print("Thank you for using this tool")
|
568
|
+
print()
|