runbooks 0.2.5__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.
Files changed (221) hide show
  1. conftest.py +26 -0
  2. jupyter-agent/.env.template +2 -0
  3. jupyter-agent/.gitattributes +35 -0
  4. jupyter-agent/README.md +16 -0
  5. jupyter-agent/app.py +256 -0
  6. jupyter-agent/cloudops-agent.png +0 -0
  7. jupyter-agent/ds-system-prompt.txt +154 -0
  8. jupyter-agent/jupyter-agent.png +0 -0
  9. jupyter-agent/llama3_template.jinja +123 -0
  10. jupyter-agent/requirements.txt +9 -0
  11. jupyter-agent/utils.py +409 -0
  12. runbooks/__init__.py +71 -3
  13. runbooks/__main__.py +13 -0
  14. runbooks/aws/ec2_describe_instances.py +1 -1
  15. runbooks/aws/ec2_run_instances.py +8 -2
  16. runbooks/aws/ec2_start_stop_instances.py +17 -4
  17. runbooks/aws/ec2_unused_volumes.py +5 -1
  18. runbooks/aws/s3_create_bucket.py +4 -2
  19. runbooks/aws/s3_list_objects.py +6 -1
  20. runbooks/aws/tagging_lambda_handler.py +13 -2
  21. runbooks/aws/tags.json +12 -0
  22. runbooks/base.py +353 -0
  23. runbooks/cfat/README.md +49 -0
  24. runbooks/cfat/__init__.py +74 -0
  25. runbooks/cfat/app.ts +644 -0
  26. runbooks/cfat/assessment/__init__.py +40 -0
  27. runbooks/cfat/assessment/asana-import.csv +39 -0
  28. runbooks/cfat/assessment/cfat-checks.csv +31 -0
  29. runbooks/cfat/assessment/cfat.txt +520 -0
  30. runbooks/cfat/assessment/collectors.py +200 -0
  31. runbooks/cfat/assessment/jira-import.csv +39 -0
  32. runbooks/cfat/assessment/runner.py +387 -0
  33. runbooks/cfat/assessment/validators.py +290 -0
  34. runbooks/cfat/cli.py +103 -0
  35. runbooks/cfat/docs/asana-import.csv +24 -0
  36. runbooks/cfat/docs/cfat-checks.csv +31 -0
  37. runbooks/cfat/docs/cfat.txt +335 -0
  38. runbooks/cfat/docs/checks-output.png +0 -0
  39. runbooks/cfat/docs/cloudshell-console-run.png +0 -0
  40. runbooks/cfat/docs/cloudshell-download.png +0 -0
  41. runbooks/cfat/docs/cloudshell-output.png +0 -0
  42. runbooks/cfat/docs/downloadfile.png +0 -0
  43. runbooks/cfat/docs/jira-import.csv +24 -0
  44. runbooks/cfat/docs/open-cloudshell.png +0 -0
  45. runbooks/cfat/docs/report-header.png +0 -0
  46. runbooks/cfat/models.py +1026 -0
  47. runbooks/cfat/package-lock.json +5116 -0
  48. runbooks/cfat/package.json +38 -0
  49. runbooks/cfat/report.py +496 -0
  50. runbooks/cfat/reporting/__init__.py +46 -0
  51. runbooks/cfat/reporting/exporters.py +337 -0
  52. runbooks/cfat/reporting/formatters.py +496 -0
  53. runbooks/cfat/reporting/templates.py +135 -0
  54. runbooks/cfat/run-assessment.sh +23 -0
  55. runbooks/cfat/runner.py +69 -0
  56. runbooks/cfat/src/actions/check-cloudtrail-existence.ts +43 -0
  57. runbooks/cfat/src/actions/check-config-existence.ts +37 -0
  58. runbooks/cfat/src/actions/check-control-tower.ts +37 -0
  59. runbooks/cfat/src/actions/check-ec2-existence.ts +46 -0
  60. runbooks/cfat/src/actions/check-iam-users.ts +50 -0
  61. runbooks/cfat/src/actions/check-legacy-cur.ts +30 -0
  62. runbooks/cfat/src/actions/check-org-cloudformation.ts +30 -0
  63. runbooks/cfat/src/actions/check-vpc-existence.ts +43 -0
  64. runbooks/cfat/src/actions/create-asanaimport.ts +14 -0
  65. runbooks/cfat/src/actions/create-backlog.ts +372 -0
  66. runbooks/cfat/src/actions/create-jiraimport.ts +15 -0
  67. runbooks/cfat/src/actions/create-report.ts +616 -0
  68. runbooks/cfat/src/actions/define-account-type.ts +51 -0
  69. runbooks/cfat/src/actions/get-enabled-org-policy-types.ts +40 -0
  70. runbooks/cfat/src/actions/get-enabled-org-services.ts +26 -0
  71. runbooks/cfat/src/actions/get-idc-info.ts +34 -0
  72. runbooks/cfat/src/actions/get-org-da-accounts.ts +34 -0
  73. runbooks/cfat/src/actions/get-org-details.ts +35 -0
  74. runbooks/cfat/src/actions/get-org-member-accounts.ts +44 -0
  75. runbooks/cfat/src/actions/get-org-ous.ts +35 -0
  76. runbooks/cfat/src/actions/get-regions.ts +22 -0
  77. runbooks/cfat/src/actions/zip-assessment.ts +27 -0
  78. runbooks/cfat/src/types/index.d.ts +147 -0
  79. runbooks/cfat/tests/__init__.py +141 -0
  80. runbooks/cfat/tests/test_cli.py +340 -0
  81. runbooks/cfat/tests/test_integration.py +290 -0
  82. runbooks/cfat/tests/test_models.py +505 -0
  83. runbooks/cfat/tests/test_reporting.py +354 -0
  84. runbooks/cfat/tsconfig.json +16 -0
  85. runbooks/cfat/webpack.config.cjs +27 -0
  86. runbooks/config.py +260 -0
  87. runbooks/finops/__init__.py +88 -0
  88. runbooks/finops/aws_client.py +245 -0
  89. runbooks/finops/cli.py +151 -0
  90. runbooks/finops/cost_processor.py +410 -0
  91. runbooks/finops/dashboard_runner.py +448 -0
  92. runbooks/finops/helpers.py +355 -0
  93. runbooks/finops/main.py +14 -0
  94. runbooks/finops/profile_processor.py +174 -0
  95. runbooks/finops/types.py +66 -0
  96. runbooks/finops/visualisations.py +80 -0
  97. runbooks/inventory/.gitignore +354 -0
  98. runbooks/inventory/ArgumentsClass.py +261 -0
  99. runbooks/inventory/Inventory_Modules.py +6130 -0
  100. runbooks/inventory/LandingZone/delete_lz.py +1075 -0
  101. runbooks/inventory/README.md +1320 -0
  102. runbooks/inventory/__init__.py +62 -0
  103. runbooks/inventory/account_class.py +532 -0
  104. runbooks/inventory/all_my_instances_wrapper.py +123 -0
  105. runbooks/inventory/aws_decorators.py +201 -0
  106. runbooks/inventory/cfn_move_stack_instances.py +1526 -0
  107. runbooks/inventory/check_cloudtrail_compliance.py +614 -0
  108. runbooks/inventory/check_controltower_readiness.py +1107 -0
  109. runbooks/inventory/check_landingzone_readiness.py +711 -0
  110. runbooks/inventory/cloudtrail.md +727 -0
  111. runbooks/inventory/collectors/__init__.py +20 -0
  112. runbooks/inventory/collectors/aws_compute.py +518 -0
  113. runbooks/inventory/collectors/aws_networking.py +275 -0
  114. runbooks/inventory/collectors/base.py +222 -0
  115. runbooks/inventory/core/__init__.py +19 -0
  116. runbooks/inventory/core/collector.py +303 -0
  117. runbooks/inventory/core/formatter.py +296 -0
  118. runbooks/inventory/delete_s3_buckets_objects.py +169 -0
  119. runbooks/inventory/discovery.md +81 -0
  120. runbooks/inventory/draw_org_structure.py +748 -0
  121. runbooks/inventory/ec2_vpc_utils.py +341 -0
  122. runbooks/inventory/find_cfn_drift_detection.py +272 -0
  123. runbooks/inventory/find_cfn_orphaned_stacks.py +719 -0
  124. runbooks/inventory/find_cfn_stackset_drift.py +733 -0
  125. runbooks/inventory/find_ec2_security_groups.py +669 -0
  126. runbooks/inventory/find_landingzone_versions.py +201 -0
  127. runbooks/inventory/find_vpc_flow_logs.py +1221 -0
  128. runbooks/inventory/inventory.sh +659 -0
  129. runbooks/inventory/list_cfn_stacks.py +558 -0
  130. runbooks/inventory/list_cfn_stackset_operation_results.py +252 -0
  131. runbooks/inventory/list_cfn_stackset_operations.py +734 -0
  132. runbooks/inventory/list_cfn_stacksets.py +453 -0
  133. runbooks/inventory/list_config_recorders_delivery_channels.py +681 -0
  134. runbooks/inventory/list_ds_directories.py +354 -0
  135. runbooks/inventory/list_ec2_availability_zones.py +286 -0
  136. runbooks/inventory/list_ec2_ebs_volumes.py +244 -0
  137. runbooks/inventory/list_ec2_instances.py +425 -0
  138. runbooks/inventory/list_ecs_clusters_and_tasks.py +562 -0
  139. runbooks/inventory/list_elbs_load_balancers.py +411 -0
  140. runbooks/inventory/list_enis_network_interfaces.py +526 -0
  141. runbooks/inventory/list_guardduty_detectors.py +568 -0
  142. runbooks/inventory/list_iam_policies.py +404 -0
  143. runbooks/inventory/list_iam_roles.py +518 -0
  144. runbooks/inventory/list_iam_saml_providers.py +359 -0
  145. runbooks/inventory/list_lambda_functions.py +882 -0
  146. runbooks/inventory/list_org_accounts.py +446 -0
  147. runbooks/inventory/list_org_accounts_users.py +354 -0
  148. runbooks/inventory/list_rds_db_instances.py +406 -0
  149. runbooks/inventory/list_route53_hosted_zones.py +318 -0
  150. runbooks/inventory/list_servicecatalog_provisioned_products.py +575 -0
  151. runbooks/inventory/list_sns_topics.py +360 -0
  152. runbooks/inventory/list_ssm_parameters.py +402 -0
  153. runbooks/inventory/list_vpc_subnets.py +433 -0
  154. runbooks/inventory/list_vpcs.py +422 -0
  155. runbooks/inventory/lockdown_cfn_stackset_role.py +224 -0
  156. runbooks/inventory/models/__init__.py +24 -0
  157. runbooks/inventory/models/account.py +192 -0
  158. runbooks/inventory/models/inventory.py +309 -0
  159. runbooks/inventory/models/resource.py +247 -0
  160. runbooks/inventory/recover_cfn_stack_ids.py +205 -0
  161. runbooks/inventory/requirements.txt +12 -0
  162. runbooks/inventory/run_on_multi_accounts.py +211 -0
  163. runbooks/inventory/tests/common_test_data.py +3661 -0
  164. runbooks/inventory/tests/common_test_functions.py +204 -0
  165. runbooks/inventory/tests/script_test_data.py +0 -0
  166. runbooks/inventory/tests/setup.py +24 -0
  167. runbooks/inventory/tests/src.py +18 -0
  168. runbooks/inventory/tests/test_cfn_describe_stacks.py +208 -0
  169. runbooks/inventory/tests/test_ec2_describe_instances.py +162 -0
  170. runbooks/inventory/tests/test_inventory_modules.py +55 -0
  171. runbooks/inventory/tests/test_lambda_list_functions.py +86 -0
  172. runbooks/inventory/tests/test_moto_integration_example.py +273 -0
  173. runbooks/inventory/tests/test_org_list_accounts.py +49 -0
  174. runbooks/inventory/update_aws_actions.py +173 -0
  175. runbooks/inventory/update_cfn_stacksets.py +1215 -0
  176. runbooks/inventory/update_cloudwatch_logs_retention_policy.py +294 -0
  177. runbooks/inventory/update_iam_roles_cross_accounts.py +478 -0
  178. runbooks/inventory/update_s3_public_access_block.py +539 -0
  179. runbooks/inventory/utils/__init__.py +23 -0
  180. runbooks/inventory/utils/aws_helpers.py +510 -0
  181. runbooks/inventory/utils/threading_utils.py +493 -0
  182. runbooks/inventory/utils/validation.py +682 -0
  183. runbooks/inventory/verify_ec2_security_groups.py +1430 -0
  184. runbooks/main.py +785 -0
  185. runbooks/organizations/__init__.py +12 -0
  186. runbooks/organizations/manager.py +374 -0
  187. runbooks/security_baseline/README.md +324 -0
  188. runbooks/security_baseline/checklist/alternate_contacts.py +8 -1
  189. runbooks/security_baseline/checklist/bucket_public_access.py +4 -1
  190. runbooks/security_baseline/checklist/cloudwatch_alarm_configuration.py +9 -2
  191. runbooks/security_baseline/checklist/guardduty_enabled.py +9 -2
  192. runbooks/security_baseline/checklist/multi_region_instance_usage.py +5 -1
  193. runbooks/security_baseline/checklist/root_access_key.py +6 -1
  194. runbooks/security_baseline/config-origin.json +1 -1
  195. runbooks/security_baseline/config.json +1 -1
  196. runbooks/security_baseline/permission.json +1 -1
  197. runbooks/security_baseline/report_generator.py +10 -2
  198. runbooks/security_baseline/report_template_en.html +7 -7
  199. runbooks/security_baseline/report_template_jp.html +7 -7
  200. runbooks/security_baseline/report_template_kr.html +12 -12
  201. runbooks/security_baseline/report_template_vn.html +7 -7
  202. runbooks/security_baseline/requirements.txt +7 -0
  203. runbooks/security_baseline/run_script.py +8 -2
  204. runbooks/security_baseline/security_baseline_tester.py +10 -2
  205. runbooks/security_baseline/utils/common.py +5 -1
  206. runbooks/utils/__init__.py +204 -0
  207. runbooks-0.6.1.dist-info/METADATA +373 -0
  208. runbooks-0.6.1.dist-info/RECORD +237 -0
  209. {runbooks-0.2.5.dist-info → runbooks-0.6.1.dist-info}/WHEEL +1 -1
  210. runbooks-0.6.1.dist-info/entry_points.txt +7 -0
  211. runbooks-0.6.1.dist-info/licenses/LICENSE +201 -0
  212. runbooks-0.6.1.dist-info/top_level.txt +3 -0
  213. runbooks/python101/calculator.py +0 -34
  214. runbooks/python101/config.py +0 -1
  215. runbooks/python101/exceptions.py +0 -16
  216. runbooks/python101/file_manager.py +0 -218
  217. runbooks/python101/toolkit.py +0 -153
  218. runbooks-0.2.5.dist-info/METADATA +0 -439
  219. runbooks-0.2.5.dist-info/RECORD +0 -61
  220. runbooks-0.2.5.dist-info/entry_points.txt +0 -3
  221. runbooks-0.2.5.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.")