runbooks 0.7.0__py3-none-any.whl → 0.7.6__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 (132) hide show
  1. runbooks/__init__.py +87 -37
  2. runbooks/cfat/README.md +300 -49
  3. runbooks/cfat/__init__.py +2 -2
  4. runbooks/finops/__init__.py +1 -1
  5. runbooks/finops/cli.py +1 -1
  6. runbooks/inventory/collectors/__init__.py +8 -0
  7. runbooks/inventory/collectors/aws_management.py +791 -0
  8. runbooks/inventory/collectors/aws_networking.py +3 -3
  9. runbooks/main.py +3389 -782
  10. runbooks/operate/__init__.py +207 -0
  11. runbooks/operate/base.py +311 -0
  12. runbooks/operate/cloudformation_operations.py +619 -0
  13. runbooks/operate/cloudwatch_operations.py +496 -0
  14. runbooks/operate/dynamodb_operations.py +812 -0
  15. runbooks/operate/ec2_operations.py +926 -0
  16. runbooks/operate/iam_operations.py +569 -0
  17. runbooks/operate/s3_operations.py +1211 -0
  18. runbooks/operate/tagging_operations.py +655 -0
  19. runbooks/remediation/CLAUDE.md +100 -0
  20. runbooks/remediation/DOME9.md +218 -0
  21. runbooks/remediation/README.md +26 -0
  22. runbooks/remediation/Tests/__init__.py +0 -0
  23. runbooks/remediation/Tests/update_policy.py +74 -0
  24. runbooks/remediation/__init__.py +95 -0
  25. runbooks/remediation/acm_cert_expired_unused.py +98 -0
  26. runbooks/remediation/acm_remediation.py +875 -0
  27. runbooks/remediation/api_gateway_list.py +167 -0
  28. runbooks/remediation/base.py +643 -0
  29. runbooks/remediation/cloudtrail_remediation.py +908 -0
  30. runbooks/remediation/cloudtrail_s3_modifications.py +296 -0
  31. runbooks/remediation/cognito_active_users.py +78 -0
  32. runbooks/remediation/cognito_remediation.py +856 -0
  33. runbooks/remediation/cognito_user_password_reset.py +163 -0
  34. runbooks/remediation/commons.py +455 -0
  35. runbooks/remediation/dynamodb_optimize.py +155 -0
  36. runbooks/remediation/dynamodb_remediation.py +744 -0
  37. runbooks/remediation/dynamodb_server_side_encryption.py +108 -0
  38. runbooks/remediation/ec2_public_ips.py +134 -0
  39. runbooks/remediation/ec2_remediation.py +892 -0
  40. runbooks/remediation/ec2_subnet_disable_auto_ip_assignment.py +72 -0
  41. runbooks/remediation/ec2_unattached_ebs_volumes.py +448 -0
  42. runbooks/remediation/ec2_unused_security_groups.py +202 -0
  43. runbooks/remediation/kms_enable_key_rotation.py +651 -0
  44. runbooks/remediation/kms_remediation.py +717 -0
  45. runbooks/remediation/lambda_list.py +243 -0
  46. runbooks/remediation/lambda_remediation.py +971 -0
  47. runbooks/remediation/multi_account.py +569 -0
  48. runbooks/remediation/rds_instance_list.py +199 -0
  49. runbooks/remediation/rds_remediation.py +873 -0
  50. runbooks/remediation/rds_snapshot_list.py +192 -0
  51. runbooks/remediation/requirements.txt +118 -0
  52. runbooks/remediation/s3_block_public_access.py +159 -0
  53. runbooks/remediation/s3_bucket_public_access.py +143 -0
  54. runbooks/remediation/s3_disable_static_website_hosting.py +74 -0
  55. runbooks/remediation/s3_downloader.py +215 -0
  56. runbooks/remediation/s3_enable_access_logging.py +562 -0
  57. runbooks/remediation/s3_encryption.py +526 -0
  58. runbooks/remediation/s3_force_ssl_secure_policy.py +143 -0
  59. runbooks/remediation/s3_list.py +141 -0
  60. runbooks/remediation/s3_object_search.py +201 -0
  61. runbooks/remediation/s3_remediation.py +816 -0
  62. runbooks/remediation/scan_for_phrase.py +425 -0
  63. runbooks/remediation/workspaces_list.py +220 -0
  64. runbooks/security/__init__.py +9 -10
  65. runbooks/security/security_baseline_tester.py +4 -2
  66. runbooks-0.7.6.dist-info/METADATA +608 -0
  67. {runbooks-0.7.0.dist-info → runbooks-0.7.6.dist-info}/RECORD +84 -76
  68. {runbooks-0.7.0.dist-info → runbooks-0.7.6.dist-info}/entry_points.txt +0 -1
  69. {runbooks-0.7.0.dist-info → runbooks-0.7.6.dist-info}/top_level.txt +0 -1
  70. jupyter-agent/.env +0 -2
  71. jupyter-agent/.env.template +0 -2
  72. jupyter-agent/.gitattributes +0 -35
  73. jupyter-agent/.gradio/certificate.pem +0 -31
  74. jupyter-agent/README.md +0 -16
  75. jupyter-agent/__main__.log +0 -8
  76. jupyter-agent/app.py +0 -256
  77. jupyter-agent/cloudops-agent.png +0 -0
  78. jupyter-agent/ds-system-prompt.txt +0 -154
  79. jupyter-agent/jupyter-agent.png +0 -0
  80. jupyter-agent/llama3_template.jinja +0 -123
  81. jupyter-agent/requirements.txt +0 -9
  82. jupyter-agent/tmp/4ojbs8a02ir/jupyter-agent.ipynb +0 -68
  83. jupyter-agent/tmp/cm5iasgpm3p/jupyter-agent.ipynb +0 -91
  84. jupyter-agent/tmp/crqbsseag5/jupyter-agent.ipynb +0 -91
  85. jupyter-agent/tmp/hohanq1u097/jupyter-agent.ipynb +0 -57
  86. jupyter-agent/tmp/jns1sam29wm/jupyter-agent.ipynb +0 -53
  87. jupyter-agent/tmp/jupyter-agent.ipynb +0 -27
  88. jupyter-agent/utils.py +0 -409
  89. runbooks/aws/__init__.py +0 -58
  90. runbooks/aws/dynamodb_operations.py +0 -231
  91. runbooks/aws/ec2_copy_image_cross-region.py +0 -195
  92. runbooks/aws/ec2_describe_instances.py +0 -202
  93. runbooks/aws/ec2_ebs_snapshots_delete.py +0 -186
  94. runbooks/aws/ec2_run_instances.py +0 -213
  95. runbooks/aws/ec2_start_stop_instances.py +0 -212
  96. runbooks/aws/ec2_terminate_instances.py +0 -143
  97. runbooks/aws/ec2_unused_eips.py +0 -196
  98. runbooks/aws/ec2_unused_volumes.py +0 -188
  99. runbooks/aws/s3_create_bucket.py +0 -142
  100. runbooks/aws/s3_list_buckets.py +0 -152
  101. runbooks/aws/s3_list_objects.py +0 -156
  102. runbooks/aws/s3_object_operations.py +0 -183
  103. runbooks/aws/tagging_lambda_handler.py +0 -183
  104. runbooks/inventory/FAILED_SCRIPTS_TROUBLESHOOTING.md +0 -619
  105. runbooks/inventory/PASSED_SCRIPTS_GUIDE.md +0 -738
  106. runbooks/inventory/aws_organization.png +0 -0
  107. runbooks/inventory/cfn_move_stack_instances.py +0 -1526
  108. runbooks/inventory/delete_s3_buckets_objects.py +0 -169
  109. runbooks/inventory/lockdown_cfn_stackset_role.py +0 -224
  110. runbooks/inventory/update_aws_actions.py +0 -173
  111. runbooks/inventory/update_cfn_stacksets.py +0 -1215
  112. runbooks/inventory/update_cloudwatch_logs_retention_policy.py +0 -294
  113. runbooks/inventory/update_iam_roles_cross_accounts.py +0 -478
  114. runbooks/inventory/update_s3_public_access_block.py +0 -539
  115. runbooks/organizations/__init__.py +0 -12
  116. runbooks/organizations/manager.py +0 -374
  117. runbooks-0.7.0.dist-info/METADATA +0 -375
  118. /runbooks/inventory/{tests → Tests}/common_test_data.py +0 -0
  119. /runbooks/inventory/{tests → Tests}/common_test_functions.py +0 -0
  120. /runbooks/inventory/{tests → Tests}/script_test_data.py +0 -0
  121. /runbooks/inventory/{tests → Tests}/setup.py +0 -0
  122. /runbooks/inventory/{tests → Tests}/src.py +0 -0
  123. /runbooks/inventory/{tests/test_inventory_modules.py → Tests/test_Inventory_Modules.py} +0 -0
  124. /runbooks/inventory/{tests → Tests}/test_cfn_describe_stacks.py +0 -0
  125. /runbooks/inventory/{tests → Tests}/test_ec2_describe_instances.py +0 -0
  126. /runbooks/inventory/{tests → Tests}/test_lambda_list_functions.py +0 -0
  127. /runbooks/inventory/{tests → Tests}/test_moto_integration_example.py +0 -0
  128. /runbooks/inventory/{tests → Tests}/test_org_list_accounts.py +0 -0
  129. /runbooks/inventory/{Inventory_Modules.py → inventory_modules.py} +0 -0
  130. /runbooks/{aws → operate}/tags.json +0 -0
  131. {runbooks-0.7.0.dist-info → runbooks-0.7.6.dist-info}/WHEEL +0 -0
  132. {runbooks-0.7.0.dist-info → runbooks-0.7.6.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,167 @@
1
+ """
2
+ API Gateway Inventory - List and analyze API Gateway configurations.
3
+ """
4
+
5
+ import logging
6
+ import re
7
+
8
+ import click
9
+ from botocore.exceptions import ClientError
10
+
11
+ from .commons import (
12
+ get_api_gateway_calls,
13
+ get_api_gateways,
14
+ get_client,
15
+ get_lambda_invocations,
16
+ get_log_group_from_lambda,
17
+ get_method_details,
18
+ get_resources,
19
+ get_stages,
20
+ write_to_csv,
21
+ )
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ @click.command()
27
+ @click.option("--output-file", default="api_gateway_inventory.csv", help="Output CSV file path")
28
+ def list_api_gateways(output_file):
29
+ """List all API Gateways and their configuration details."""
30
+ logger.info("Collecting API Gateway inventory")
31
+
32
+ try:
33
+ # Create API Gateway and Lambda clients
34
+ client_apigateway = get_client("apigateway")
35
+ client_lambda = get_client("lambda")
36
+
37
+ # Get all REST APIs
38
+ rest_apis = get_api_gateways(client_apigateway)
39
+
40
+ if not rest_apis:
41
+ logger.info("No API Gateways found")
42
+ return
43
+
44
+ logger.info(f"Found {len(rest_apis)} API Gateways to analyze")
45
+
46
+ data = []
47
+ for rest_api in rest_apis:
48
+ rest_api_id = rest_api["id"]
49
+ # logger.info(f"API Gateway: {rest_api['name']} ({rest_api_id})")
50
+
51
+ stages = get_stages(client_apigateway, rest_api_id)
52
+
53
+ for stage in stages:
54
+ stage_name = stage["stageName"]
55
+ # logger.info(f" Stage: {stage_name}")
56
+ # Retrieve stage-level logging configuration
57
+ log_group_arn = None
58
+ if stage.get("accessLogSettings"):
59
+ log_group_arn = stage["accessLogSettings"].get("destinationArn")
60
+
61
+ resources = get_resources(client_apigateway, rest_api_id)
62
+
63
+ for resource in resources:
64
+ resource_id = resource["id"]
65
+
66
+ integration_type = None
67
+ uri = None
68
+ integration_line = " - No Integration Found"
69
+ function_name = None
70
+ log_group = None
71
+ for http_method in [
72
+ "GET",
73
+ "POST",
74
+ "PUT",
75
+ "DELETE",
76
+ "OPTIONS", # Add more as needed
77
+ "HEAD",
78
+ "PATCH",
79
+ "ANY",
80
+ ]:
81
+ try:
82
+ response = client_apigateway.get_integration(
83
+ restApiId=rest_api_id, resourceId=resource_id, httpMethod=http_method
84
+ )
85
+
86
+ integration_type = response["type"] # Possible values: HTTP, AWS, MOCK, AWS_PROXY
87
+
88
+ if integration_type == "AWS":
89
+ # Lambda integration
90
+ uri = response["uri"]
91
+ if uri.startswith("arn:aws:apigateway:"):
92
+ match = re.search(r"function:(\w+-\w+)", uri)
93
+ function_name = match.group(1) if match else None
94
+ integration_line = f" - Lambda Integration: {function_name}"
95
+
96
+ elif integration_type == "HTTP" or integration_type == "AWS_PROXY":
97
+ # HTTP Endpoint or HTTP Proxy (could be S3, etc.)
98
+ uri = response["uri"]
99
+ match = re.search(r"function:(.+?)/", uri)
100
+ function_name = match.group(1) if match else None
101
+ integration_line = f" - HTTP/Proxy Integration: {uri}"
102
+
103
+ elif integration_type == "MOCK":
104
+ integration_line = f" - Mock Integration"
105
+
106
+ except client_apigateway.exceptions.NotFoundException:
107
+ pass
108
+
109
+ response = get_method_details(client_apigateway, rest_api_id, resource_id, http_method)
110
+
111
+ # Check caching status
112
+ if response and "methodResponses" in response and "200" in response["methodResponses"]:
113
+ caching_enabled = response["methodResponses"]["200"].get("cachingEnabled", False)
114
+ logger.info(f"API Gateway: {rest_api['name']} ({rest_api_id})")
115
+ logger.info(f" Stage: {stage_name}")
116
+ logger.info(
117
+ f" {http_method} Method (Resource: {resource['path']}) - Cache Enabled: {caching_enabled}"
118
+ )
119
+ logger.info(f"{integration_line}")
120
+ log_group_name = None
121
+ if log_group_arn:
122
+ log_group_name = log_group_arn.split(":")[-1] # Extract from ARN
123
+ logger.info(f" Access Log Group: {log_group_name}")
124
+
125
+ if function_name:
126
+ log_group = get_log_group_from_lambda(client_lambda, function_name)
127
+ if log_group:
128
+ logger.info(f" Log Group: {log_group}")
129
+ else:
130
+ logger.info(f" Log Group could not be determined from configuration.")
131
+
132
+ data.append(
133
+ {
134
+ "API Gateway": rest_api["name"],
135
+ "Rest API ID": rest_api_id, # Added rest api id to the output
136
+ "Resource": resource["path"], # Added resource path to the output
137
+ "Stage": stage_name,
138
+ "Method": http_method,
139
+ "Access Log Group": log_group_name,
140
+ "Cache Enabled": caching_enabled,
141
+ "Integration Type": integration_type,
142
+ "Integration details": integration_line.strip(), # Added integration details to the output
143
+ "URI": uri,
144
+ "Function Name": function_name,
145
+ "Log Group of Function": log_group,
146
+ "API gateway (includes all http methods) calls in last 360 days": get_api_gateway_calls(
147
+ rest_api["name"], 360
148
+ ),
149
+ "Lambda function invocations in last 360 days": get_lambda_invocations(
150
+ function_name, 360
151
+ )
152
+ if function_name
153
+ else None,
154
+ }
155
+ )
156
+
157
+ # Export results to CSV
158
+ write_to_csv(data, output_file)
159
+ logger.info(f"API Gateway inventory exported to: {output_file}")
160
+ logger.info(f"Processed {len(data)} API Gateway configurations")
161
+
162
+ except ClientError as e:
163
+ logger.error(f"Failed to collect API Gateway inventory: {e}")
164
+ raise
165
+ except Exception as e:
166
+ logger.error(f"Unexpected error: {e}")
167
+ raise