runbooks 0.2.3__py3-none-any.whl → 0.6.1__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.template +2 -0
- jupyter-agent/.gitattributes +35 -0
- jupyter-agent/README.md +16 -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/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/__init__.py +88 -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/Inventory_Modules.py +6130 -0
- runbooks/inventory/LandingZone/delete_lz.py +1075 -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/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/script_test_data.py +0 -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 +785 -0
- runbooks/organizations/__init__.py +12 -0
- runbooks/organizations/manager.py +374 -0
- runbooks/security_baseline/README.md +324 -0
- runbooks/security_baseline/checklist/alternate_contacts.py +8 -1
- runbooks/security_baseline/checklist/bucket_public_access.py +4 -1
- runbooks/security_baseline/checklist/cloudwatch_alarm_configuration.py +9 -2
- runbooks/security_baseline/checklist/guardduty_enabled.py +9 -2
- runbooks/security_baseline/checklist/multi_region_instance_usage.py +5 -1
- runbooks/security_baseline/checklist/root_access_key.py +6 -1
- runbooks/security_baseline/config-origin.json +1 -1
- runbooks/security_baseline/config.json +1 -1
- runbooks/security_baseline/permission.json +1 -1
- runbooks/security_baseline/report_generator.py +10 -2
- runbooks/security_baseline/report_template_en.html +8 -8
- runbooks/security_baseline/report_template_jp.html +8 -8
- runbooks/security_baseline/report_template_kr.html +13 -13
- runbooks/security_baseline/report_template_vn.html +8 -8
- runbooks/security_baseline/requirements.txt +7 -0
- runbooks/security_baseline/run_script.py +8 -2
- runbooks/security_baseline/security_baseline_tester.py +10 -2
- runbooks/security_baseline/utils/common.py +5 -1
- runbooks/utils/__init__.py +204 -0
- runbooks-0.6.1.dist-info/METADATA +373 -0
- runbooks-0.6.1.dist-info/RECORD +237 -0
- {runbooks-0.2.3.dist-info → runbooks-0.6.1.dist-info}/WHEEL +1 -1
- runbooks-0.6.1.dist-info/entry_points.txt +7 -0
- runbooks-0.6.1.dist-info/licenses/LICENSE +201 -0
- runbooks-0.6.1.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.3.dist-info/METADATA +0 -435
- runbooks-0.2.3.dist-info/RECORD +0 -61
- runbooks-0.2.3.dist-info/entry_points.txt +0 -3
- runbooks-0.2.3.dist-info/top_level.txt +0 -1
@@ -0,0 +1,360 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
AWS SNS Topic Inventory Collection
|
4
|
+
|
5
|
+
A comprehensive SNS topic discovery tool for multi-account AWS Organizations that
|
6
|
+
provides detailed messaging infrastructure visibility across all accounts and regions.
|
7
|
+
Essential for event-driven architecture governance, compliance, and cost optimization.
|
8
|
+
|
9
|
+
**AWS API Mapping**: `boto3.client('sns').list_topics()`
|
10
|
+
|
11
|
+
Features:
|
12
|
+
- Multi-account SNS topic discovery via AWS Organizations
|
13
|
+
- Fragment-based topic filtering for targeted operations
|
14
|
+
- Cross-region messaging topology mapping
|
15
|
+
- Topic naming convention compliance validation
|
16
|
+
- Comprehensive error handling and logging
|
17
|
+
- Enterprise-grade inventory and reporting
|
18
|
+
|
19
|
+
Messaging Architecture Use Cases:
|
20
|
+
- Event-driven architecture documentation and governance
|
21
|
+
- Topic naming convention compliance auditing
|
22
|
+
- Cross-account messaging topology analysis
|
23
|
+
- Cost optimization through topic utilization assessment
|
24
|
+
- Security assessment of topic configurations and policies
|
25
|
+
- Migration planning for messaging infrastructure
|
26
|
+
|
27
|
+
Compatibility:
|
28
|
+
- AWS Organizations with cross-account roles
|
29
|
+
- AWS Control Tower managed accounts
|
30
|
+
- Standalone AWS accounts
|
31
|
+
- All AWS regions including opt-in regions
|
32
|
+
- All SNS topic types (Standard and FIFO)
|
33
|
+
|
34
|
+
Example:
|
35
|
+
Discover all SNS topics across organization:
|
36
|
+
```bash
|
37
|
+
python list_sns_topics.py --profile my-org-profile
|
38
|
+
```
|
39
|
+
|
40
|
+
Find topics with specific naming pattern:
|
41
|
+
```bash
|
42
|
+
python list_sns_topics.py --profile my-profile --fragment "alert"
|
43
|
+
```
|
44
|
+
|
45
|
+
Export topic inventory to file:
|
46
|
+
```bash
|
47
|
+
python list_sns_topics.py --profile my-profile \
|
48
|
+
--save sns_inventory.json --output json
|
49
|
+
```
|
50
|
+
|
51
|
+
Requirements:
|
52
|
+
- IAM permissions: `sns:ListTopics`, `sts:AssumeRole`
|
53
|
+
- AWS Organizations access (for multi-account scanning)
|
54
|
+
- Python 3.8+ with required dependencies
|
55
|
+
|
56
|
+
Author:
|
57
|
+
AWS Cloud Foundations Team
|
58
|
+
|
59
|
+
Version:
|
60
|
+
2023.11.08
|
61
|
+
"""
|
62
|
+
|
63
|
+
import logging
|
64
|
+
import sys
|
65
|
+
from queue import Queue
|
66
|
+
from threading import Thread
|
67
|
+
from time import time
|
68
|
+
|
69
|
+
import Inventory_Modules
|
70
|
+
from ArgumentsClass import CommonArguments
|
71
|
+
from botocore.exceptions import ClientError
|
72
|
+
from colorama import Fore, init
|
73
|
+
from Inventory_Modules import display_results, get_all_credentials
|
74
|
+
|
75
|
+
init()
|
76
|
+
__version__ = "2023.11.08"
|
77
|
+
begin_time = time()
|
78
|
+
|
79
|
+
|
80
|
+
def parse_args(args):
|
81
|
+
"""
|
82
|
+
Parse and validate command-line arguments for SNS topic inventory discovery.
|
83
|
+
|
84
|
+
Configures the argument parser with SNS-specific options for comprehensive
|
85
|
+
messaging infrastructure discovery across multi-account AWS environments.
|
86
|
+
Uses the standardized CommonArguments framework for consistency.
|
87
|
+
|
88
|
+
Args:
|
89
|
+
args (list): Command-line arguments to parse (typically sys.argv[1:])
|
90
|
+
|
91
|
+
Returns:
|
92
|
+
argparse.Namespace: Parsed arguments containing:
|
93
|
+
- Profiles: AWS profiles for multi-account messaging discovery
|
94
|
+
- Regions: Target AWS regions for SNS enumeration
|
95
|
+
- AccessRoles: Cross-account roles for Organizations access
|
96
|
+
- Fragment: Topic name fragment for targeted filtering
|
97
|
+
- pExact: Boolean flag for exact topic name matching
|
98
|
+
- RootOnly: Limit to Organization Management Accounts
|
99
|
+
- Filename: Output file prefix for topic inventory export
|
100
|
+
- Other standard framework arguments
|
101
|
+
|
102
|
+
Messaging Discovery Use Cases:
|
103
|
+
- Topic inventory: Complete SNS topic asset management
|
104
|
+
- Architecture documentation: Event-driven system mapping
|
105
|
+
- Compliance auditing: Topic naming and configuration validation
|
106
|
+
- Cost optimization: Topic utilization and subscription analysis
|
107
|
+
- Security assessment: Topic policy and access review
|
108
|
+
- Migration planning: Cross-account messaging architecture analysis
|
109
|
+
"""
|
110
|
+
parser = CommonArguments()
|
111
|
+
parser.my_parser.description = "Finding all the topics for the accounts we can find... "
|
112
|
+
parser.multiprofile()
|
113
|
+
parser.multiregion()
|
114
|
+
parser.extendedargs()
|
115
|
+
parser.rootOnly()
|
116
|
+
parser.fragment()
|
117
|
+
parser.save_to_file()
|
118
|
+
parser.timing()
|
119
|
+
parser.verbosity()
|
120
|
+
parser.version(__version__)
|
121
|
+
return parser.my_parser.parse_args(args)
|
122
|
+
|
123
|
+
|
124
|
+
def find_topics(CredentialList: list, ftopic_frag: str = None, fexact: bool = False) -> list:
|
125
|
+
"""
|
126
|
+
Execute multi-threaded SNS topic discovery across AWS accounts and regions.
|
127
|
+
|
128
|
+
This is the core messaging infrastructure discovery engine that performs concurrent
|
129
|
+
SNS topic enumeration across all provided AWS accounts and regions. Essential for
|
130
|
+
understanding event-driven architecture, message routing, and compliance assessment.
|
131
|
+
|
132
|
+
Args:
|
133
|
+
CredentialList (list): List of credential dictionaries containing:
|
134
|
+
- AccountId: AWS account identifier
|
135
|
+
- Region: AWS region name
|
136
|
+
- AccessKeyId, SecretAccessKey, SessionToken: AWS credentials
|
137
|
+
- MgmtAccount: Management account identifier
|
138
|
+
- Success: Boolean flag indicating credential validation status
|
139
|
+
|
140
|
+
ftopic_frag (str, optional): Topic name fragment for filtering:
|
141
|
+
- Enables targeted discovery of specific topic patterns
|
142
|
+
- Supports partial name matching for flexible searches
|
143
|
+
- Examples: "alert", "notification", "error"
|
144
|
+
|
145
|
+
fexact (bool, optional): Enable exact topic name matching:
|
146
|
+
- When True, requires precise topic name matches
|
147
|
+
- When False, performs substring matching
|
148
|
+
- Default: False for broader discovery scope
|
149
|
+
|
150
|
+
Returns:
|
151
|
+
list: Comprehensive SNS topic inventory with metadata:
|
152
|
+
- TopicName: SNS topic name or ARN
|
153
|
+
- AccountId: Source AWS account
|
154
|
+
- Region: Source AWS region
|
155
|
+
- MgmtAccount: Management account identifier
|
156
|
+
|
157
|
+
Threading Architecture:
|
158
|
+
- Uses Queue for thread-safe work distribution
|
159
|
+
- Worker thread pool (max 50) for concurrent topic discovery
|
160
|
+
- Comprehensive error handling for account access failures
|
161
|
+
- Progress tracking for large-scale messaging inventory
|
162
|
+
|
163
|
+
Messaging Analysis Features:
|
164
|
+
- Topic name pattern analysis and compliance validation
|
165
|
+
- Cross-account messaging topology mapping
|
166
|
+
- Regional topic distribution assessment
|
167
|
+
- Fragment-based filtering for targeted operations
|
168
|
+
- FIFO vs Standard topic classification
|
169
|
+
|
170
|
+
Enterprise Use Cases:
|
171
|
+
- Event-driven architecture documentation and governance
|
172
|
+
- Topic naming convention compliance auditing
|
173
|
+
- Cross-account messaging security assessment
|
174
|
+
- Cost optimization through topic utilization analysis
|
175
|
+
- Migration planning and messaging consolidation
|
176
|
+
- Disaster recovery and business continuity planning
|
177
|
+
"""
|
178
|
+
|
179
|
+
class FindTopics(Thread):
|
180
|
+
"""
|
181
|
+
Worker thread for concurrent SNS topic discovery across AWS accounts.
|
182
|
+
|
183
|
+
Each worker thread processes credential sets from the shared queue,
|
184
|
+
calls AWS SNS APIs to discover messaging topics, and performs detailed
|
185
|
+
metadata extraction including topic filtering and categorization.
|
186
|
+
|
187
|
+
Messaging Discovery Capabilities:
|
188
|
+
- SNS topic enumeration with comprehensive metadata
|
189
|
+
- Topic name pattern matching and filtering
|
190
|
+
- Cross-account messaging topology analysis
|
191
|
+
- Regional topic distribution assessment
|
192
|
+
- Multi-account messaging inventory aggregation
|
193
|
+
"""
|
194
|
+
|
195
|
+
def __init__(self, queue):
|
196
|
+
"""
|
197
|
+
Initialize worker thread with reference to shared work queue.
|
198
|
+
|
199
|
+
Args:
|
200
|
+
queue (Queue): Thread-safe queue containing SNS discovery work items
|
201
|
+
"""
|
202
|
+
Thread.__init__(self)
|
203
|
+
self.queue = queue
|
204
|
+
|
205
|
+
def run(self):
|
206
|
+
"""
|
207
|
+
Main worker thread execution loop for SNS topic discovery.
|
208
|
+
|
209
|
+
Continuously processes credential sets from queue, performs topic
|
210
|
+
discovery via AWS SNS APIs, and aggregates messaging infrastructure data
|
211
|
+
with comprehensive filtering and metadata extraction.
|
212
|
+
"""
|
213
|
+
while True:
|
214
|
+
# Get SNS discovery work item from thread-safe queue
|
215
|
+
c_account_credentials, c_topic_frag, c_exact, c_PlacesToLook, c_PlaceCount = self.queue.get()
|
216
|
+
logging.info(f"De-queued info for account {c_account_credentials['AccountId']}")
|
217
|
+
|
218
|
+
try:
|
219
|
+
logging.info(f"Attempting to connect to {c_account_credentials['AccountId']}")
|
220
|
+
|
221
|
+
# Call AWS SNS API to discover topics in this account/region
|
222
|
+
# find_sns_topics2() handles ListTopics API with optional filtering
|
223
|
+
account_topics = Inventory_Modules.find_sns_topics2(c_account_credentials, c_topic_frag, c_exact)
|
224
|
+
|
225
|
+
logging.info(f"Successfully connected to account {c_account_credentials['AccountId']}")
|
226
|
+
# Process discovered SNS topics with comprehensive metadata extraction
|
227
|
+
for topic in account_topics:
|
228
|
+
# Create comprehensive topic record for messaging inventory
|
229
|
+
topic_record = {
|
230
|
+
# Organizational context
|
231
|
+
"MgmtAccount": c_account_credentials["MgmtAccount"],
|
232
|
+
"AccountId": c_account_credentials["AccountId"],
|
233
|
+
"Region": c_account_credentials["Region"],
|
234
|
+
# Topic identification and metadata
|
235
|
+
"TopicName": topic,
|
236
|
+
}
|
237
|
+
|
238
|
+
# Add to global messaging inventory collection
|
239
|
+
AllTopics.append(topic_record)
|
240
|
+
except KeyError as my_Error:
|
241
|
+
# Handle credential or account access configuration errors
|
242
|
+
logging.error(f"Account Access failed - trying to access {c_account_credentials['AccountId']}")
|
243
|
+
logging.info(f"Actual Error: {my_Error}")
|
244
|
+
# Continue processing other accounts despite this failure
|
245
|
+
pass
|
246
|
+
|
247
|
+
except AttributeError as my_Error:
|
248
|
+
# Handle profile configuration or credential format errors
|
249
|
+
logging.error(f"Error: Likely that one of the supplied profiles was wrong")
|
250
|
+
logging.warning(my_Error)
|
251
|
+
continue
|
252
|
+
|
253
|
+
finally:
|
254
|
+
# Progress tracking for large-scale messaging inventory
|
255
|
+
# Commented out to avoid console clutter in production use
|
256
|
+
# print(f"{ERASE_LINE}Finished finding Topics in account {c_account_credentials['AccountId']} in region {c_account_credentials['Region']} - {c_PlaceCount} / {c_PlacesToLook}", end='\r')
|
257
|
+
|
258
|
+
# Always mark work item as complete for queue management
|
259
|
+
self.queue.task_done()
|
260
|
+
|
261
|
+
checkqueue = Queue()
|
262
|
+
|
263
|
+
AllTopics = []
|
264
|
+
PlaceCount = 0
|
265
|
+
PlacesToLook = len(CredentialList)
|
266
|
+
WorkerThreads = min(len(CredentialList), 50)
|
267
|
+
|
268
|
+
for x in range(WorkerThreads):
|
269
|
+
worker = FindTopics(checkqueue)
|
270
|
+
# Setting daemon to True will let the main thread exit even though the workers are blocking
|
271
|
+
worker.daemon = True
|
272
|
+
worker.start()
|
273
|
+
|
274
|
+
for credential in CredentialList:
|
275
|
+
logging.info(f"Connecting to account {credential['AccountId']}")
|
276
|
+
# for region in fRegionList:
|
277
|
+
try:
|
278
|
+
# print(f"{ERASE_LINE}Queuing account {credential['AccountId']} in region {region}", end='\r')
|
279
|
+
checkqueue.put((credential, ftopic_frag, fexact, PlacesToLook, PlaceCount))
|
280
|
+
PlaceCount += 1
|
281
|
+
except ClientError as my_Error:
|
282
|
+
if "AuthFailure" in str(my_Error):
|
283
|
+
logging.error(
|
284
|
+
f"Authorization Failure accessing account {credential['AccountId']} in {credential['Region']} region"
|
285
|
+
)
|
286
|
+
logging.warning(f"It's possible that the region {credential['Region']} hasn't been opted-into")
|
287
|
+
pass
|
288
|
+
checkqueue.join()
|
289
|
+
return AllTopics
|
290
|
+
|
291
|
+
|
292
|
+
def present_results(f_data_found: list):
|
293
|
+
"""
|
294
|
+
Description: Shows off results at the end
|
295
|
+
@param f_data_found: List of Topics found and their attributes.
|
296
|
+
"""
|
297
|
+
display_dict = {
|
298
|
+
"MgmtAccount": {"DisplayOrder": 1, "Heading": "Mgmt Acct"},
|
299
|
+
"AccountId": {"DisplayOrder": 2, "Heading": "Acct Number"},
|
300
|
+
"Region": {"DisplayOrder": 3, "Heading": "Region"},
|
301
|
+
"TopicName": {"DisplayOrder": 4, "Heading": "Topic Name"},
|
302
|
+
}
|
303
|
+
AccountNum = len(set([acct["AccountId"] for acct in AllCredentials]))
|
304
|
+
RegionNum = len(set([acct["Region"] for acct in AllCredentials]))
|
305
|
+
sorted_Topics_Found = sorted(
|
306
|
+
f_data_found, key=lambda x: (x["MgmtAccount"], x["AccountId"], x["Region"], x["TopicName"])
|
307
|
+
)
|
308
|
+
display_results(sorted_Topics_Found, display_dict, "None", pFilename)
|
309
|
+
print()
|
310
|
+
print(f"These accounts were skipped - as requested: {pSkipAccounts}") if pSkipAccounts is not None else ""
|
311
|
+
print(f"These profiles were skipped - as requested: {pSkipProfiles}") if pSkipProfiles is not None else ""
|
312
|
+
print(
|
313
|
+
f"The output has also been written to a file beginning with '{pFilename}' + the date and time"
|
314
|
+
) if pFilename is not None else ""
|
315
|
+
print()
|
316
|
+
print(f"Found {len(f_data_found)} topics across {AccountNum} accounts across {RegionNum} regions")
|
317
|
+
|
318
|
+
|
319
|
+
##########################
|
320
|
+
ERASE_LINE = "\x1b[2K"
|
321
|
+
|
322
|
+
if __name__ == "__main__":
|
323
|
+
args = parse_args(sys.argv[1:])
|
324
|
+
pProfiles = args.Profiles
|
325
|
+
pRegions = args.Regions
|
326
|
+
pAccounts = args.Accounts
|
327
|
+
pSkipAccounts = args.SkipAccounts
|
328
|
+
pSkipProfiles = args.SkipProfiles
|
329
|
+
pRootOnly = args.RootOnly
|
330
|
+
pExact = args.Exact
|
331
|
+
pTopicFrag = args.Fragments
|
332
|
+
pFilename = args.Filename
|
333
|
+
pTiming = args.Time
|
334
|
+
verbose = args.loglevel
|
335
|
+
logging.basicConfig(level=verbose, format="[%(filename)s:%(lineno)s - %(funcName)30s() ] %(message)s")
|
336
|
+
|
337
|
+
# Get credentials
|
338
|
+
AllCredentials = get_all_credentials(
|
339
|
+
pProfiles, pTiming, pSkipProfiles, pSkipAccounts, pRootOnly, pAccounts, pRegions
|
340
|
+
)
|
341
|
+
AllAccounts = list(set([x["AccountId"] for x in AllCredentials]))
|
342
|
+
AllRegions = list(set([x["Region"] for x in AllCredentials]))
|
343
|
+
print()
|
344
|
+
# RegionList = Inventory_Modules.get_ec2_regions3(aws_acct, pRegions)
|
345
|
+
# ChildAccounts = aws_acct.ChildAccounts
|
346
|
+
logging.info(f"# of Regions: {len(AllRegions)}")
|
347
|
+
logging.info(f"# of Child Accounts: {len(AllAccounts)}")
|
348
|
+
account_credentials = None
|
349
|
+
|
350
|
+
# Find topics
|
351
|
+
all_topics_found = find_topics(AllCredentials, pTopicFrag, pExact)
|
352
|
+
|
353
|
+
# Display data
|
354
|
+
present_results(all_topics_found)
|
355
|
+
|
356
|
+
print()
|
357
|
+
if pTiming:
|
358
|
+
print(f"{Fore.GREEN}This script completed in {time() - begin_time:.2f} seconds{Fore.RESET}")
|
359
|
+
print()
|
360
|
+
print("Thank you for using this script.")
|