aws-inventory-manager 0.13.2__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.
Potentially problematic release.
This version of aws-inventory-manager might be problematic. Click here for more details.
- aws_inventory_manager-0.13.2.dist-info/LICENSE +21 -0
- aws_inventory_manager-0.13.2.dist-info/METADATA +1226 -0
- aws_inventory_manager-0.13.2.dist-info/RECORD +145 -0
- aws_inventory_manager-0.13.2.dist-info/WHEEL +5 -0
- aws_inventory_manager-0.13.2.dist-info/entry_points.txt +2 -0
- aws_inventory_manager-0.13.2.dist-info/top_level.txt +1 -0
- src/__init__.py +3 -0
- src/aws/__init__.py +11 -0
- src/aws/client.py +128 -0
- src/aws/credentials.py +191 -0
- src/aws/rate_limiter.py +177 -0
- src/cli/__init__.py +12 -0
- src/cli/config.py +130 -0
- src/cli/main.py +3626 -0
- src/config_service/__init__.py +21 -0
- src/config_service/collector.py +346 -0
- src/config_service/detector.py +256 -0
- src/config_service/resource_type_mapping.py +328 -0
- src/cost/__init__.py +5 -0
- src/cost/analyzer.py +226 -0
- src/cost/explorer.py +209 -0
- src/cost/reporter.py +237 -0
- src/delta/__init__.py +5 -0
- src/delta/calculator.py +206 -0
- src/delta/differ.py +185 -0
- src/delta/formatters.py +272 -0
- src/delta/models.py +154 -0
- src/delta/reporter.py +234 -0
- src/models/__init__.py +21 -0
- src/models/config_diff.py +135 -0
- src/models/cost_report.py +87 -0
- src/models/deletion_operation.py +104 -0
- src/models/deletion_record.py +97 -0
- src/models/delta_report.py +122 -0
- src/models/efs_resource.py +80 -0
- src/models/elasticache_resource.py +90 -0
- src/models/group.py +318 -0
- src/models/inventory.py +133 -0
- src/models/protection_rule.py +123 -0
- src/models/report.py +288 -0
- src/models/resource.py +111 -0
- src/models/security_finding.py +102 -0
- src/models/snapshot.py +122 -0
- src/restore/__init__.py +20 -0
- src/restore/audit.py +175 -0
- src/restore/cleaner.py +461 -0
- src/restore/config.py +209 -0
- src/restore/deleter.py +976 -0
- src/restore/dependency.py +254 -0
- src/restore/safety.py +115 -0
- src/security/__init__.py +0 -0
- src/security/checks/__init__.py +0 -0
- src/security/checks/base.py +56 -0
- src/security/checks/ec2_checks.py +88 -0
- src/security/checks/elasticache_checks.py +149 -0
- src/security/checks/iam_checks.py +102 -0
- src/security/checks/rds_checks.py +140 -0
- src/security/checks/s3_checks.py +95 -0
- src/security/checks/secrets_checks.py +96 -0
- src/security/checks/sg_checks.py +142 -0
- src/security/cis_mapper.py +97 -0
- src/security/models.py +53 -0
- src/security/reporter.py +174 -0
- src/security/scanner.py +87 -0
- src/snapshot/__init__.py +6 -0
- src/snapshot/capturer.py +451 -0
- src/snapshot/filter.py +259 -0
- src/snapshot/inventory_storage.py +236 -0
- src/snapshot/report_formatter.py +250 -0
- src/snapshot/reporter.py +189 -0
- src/snapshot/resource_collectors/__init__.py +5 -0
- src/snapshot/resource_collectors/apigateway.py +140 -0
- src/snapshot/resource_collectors/backup.py +136 -0
- src/snapshot/resource_collectors/base.py +81 -0
- src/snapshot/resource_collectors/cloudformation.py +55 -0
- src/snapshot/resource_collectors/cloudwatch.py +109 -0
- src/snapshot/resource_collectors/codebuild.py +69 -0
- src/snapshot/resource_collectors/codepipeline.py +82 -0
- src/snapshot/resource_collectors/dynamodb.py +65 -0
- src/snapshot/resource_collectors/ec2.py +240 -0
- src/snapshot/resource_collectors/ecs.py +215 -0
- src/snapshot/resource_collectors/efs_collector.py +102 -0
- src/snapshot/resource_collectors/eks.py +200 -0
- src/snapshot/resource_collectors/elasticache_collector.py +79 -0
- src/snapshot/resource_collectors/elb.py +126 -0
- src/snapshot/resource_collectors/eventbridge.py +156 -0
- src/snapshot/resource_collectors/iam.py +188 -0
- src/snapshot/resource_collectors/kms.py +111 -0
- src/snapshot/resource_collectors/lambda_func.py +139 -0
- src/snapshot/resource_collectors/rds.py +109 -0
- src/snapshot/resource_collectors/route53.py +86 -0
- src/snapshot/resource_collectors/s3.py +105 -0
- src/snapshot/resource_collectors/secretsmanager.py +70 -0
- src/snapshot/resource_collectors/sns.py +68 -0
- src/snapshot/resource_collectors/sqs.py +82 -0
- src/snapshot/resource_collectors/ssm.py +160 -0
- src/snapshot/resource_collectors/stepfunctions.py +74 -0
- src/snapshot/resource_collectors/vpcendpoints.py +79 -0
- src/snapshot/resource_collectors/waf.py +159 -0
- src/snapshot/storage.py +351 -0
- src/storage/__init__.py +21 -0
- src/storage/audit_store.py +419 -0
- src/storage/database.py +294 -0
- src/storage/group_store.py +749 -0
- src/storage/inventory_store.py +320 -0
- src/storage/resource_store.py +413 -0
- src/storage/schema.py +288 -0
- src/storage/snapshot_store.py +346 -0
- src/utils/__init__.py +12 -0
- src/utils/export.py +305 -0
- src/utils/hash.py +60 -0
- src/utils/logging.py +63 -0
- src/utils/pagination.py +41 -0
- src/utils/paths.py +51 -0
- src/utils/progress.py +41 -0
- src/utils/unsupported_resources.py +306 -0
- src/web/__init__.py +5 -0
- src/web/app.py +97 -0
- src/web/dependencies.py +69 -0
- src/web/routes/__init__.py +1 -0
- src/web/routes/api/__init__.py +18 -0
- src/web/routes/api/charts.py +156 -0
- src/web/routes/api/cleanup.py +186 -0
- src/web/routes/api/filters.py +253 -0
- src/web/routes/api/groups.py +305 -0
- src/web/routes/api/inventories.py +80 -0
- src/web/routes/api/queries.py +202 -0
- src/web/routes/api/resources.py +379 -0
- src/web/routes/api/snapshots.py +314 -0
- src/web/routes/api/views.py +260 -0
- src/web/routes/pages.py +198 -0
- src/web/services/__init__.py +1 -0
- src/web/templates/base.html +949 -0
- src/web/templates/components/navbar.html +31 -0
- src/web/templates/components/sidebar.html +104 -0
- src/web/templates/pages/audit_logs.html +86 -0
- src/web/templates/pages/cleanup.html +279 -0
- src/web/templates/pages/dashboard.html +227 -0
- src/web/templates/pages/diff.html +175 -0
- src/web/templates/pages/error.html +30 -0
- src/web/templates/pages/groups.html +721 -0
- src/web/templates/pages/queries.html +246 -0
- src/web/templates/pages/resources.html +2251 -0
- src/web/templates/pages/snapshot_detail.html +271 -0
- src/web/templates/pages/snapshots.html +429 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}{{ snapshot.name }} - AWS Inventory Browser{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block content %}
|
|
6
|
+
<div class="space-y-6">
|
|
7
|
+
<!-- Header -->
|
|
8
|
+
<div class="md:flex md:items-center md:justify-between">
|
|
9
|
+
<div class="min-w-0 flex-1">
|
|
10
|
+
<nav class="flex mb-2" aria-label="Breadcrumb">
|
|
11
|
+
<ol class="flex items-center space-x-2">
|
|
12
|
+
<li>
|
|
13
|
+
<a href="/snapshots" class="text-sm text-gray-500 hover:text-gray-700">Snapshots</a>
|
|
14
|
+
</li>
|
|
15
|
+
<li class="flex items-center">
|
|
16
|
+
<svg class="flex-shrink-0 h-5 w-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
|
|
17
|
+
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/>
|
|
18
|
+
</svg>
|
|
19
|
+
<span class="ml-2 text-sm font-medium text-gray-900">{{ snapshot.name }}</span>
|
|
20
|
+
</li>
|
|
21
|
+
</ol>
|
|
22
|
+
</nav>
|
|
23
|
+
<div class="flex items-center">
|
|
24
|
+
<h1 class="text-2xl font-bold leading-7 text-gray-900 sm:truncate sm:text-3xl">{{ snapshot.name }}</h1>
|
|
25
|
+
{% if snapshot.is_active %}
|
|
26
|
+
<span class="ml-3 inline-flex items-center px-3 py-0.5 rounded-full text-sm font-medium bg-green-100 text-green-800">
|
|
27
|
+
Active Baseline
|
|
28
|
+
</span>
|
|
29
|
+
{% endif %}
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="mt-4 flex md:mt-0 md:ml-4 space-x-3">
|
|
33
|
+
{% if not snapshot.is_active %}
|
|
34
|
+
<button hx-post="/api/snapshots/{{ snapshot.name }}/activate"
|
|
35
|
+
hx-swap="none"
|
|
36
|
+
hx-on::after-request="window.location.reload()"
|
|
37
|
+
class="inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50">
|
|
38
|
+
Set as Active
|
|
39
|
+
</button>
|
|
40
|
+
{% endif %}
|
|
41
|
+
<a href="/diff?snapshot1={{ snapshot.name }}"
|
|
42
|
+
class="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700">
|
|
43
|
+
Compare
|
|
44
|
+
</a>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<!-- Metadata Grid -->
|
|
49
|
+
<div class="grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-4">
|
|
50
|
+
<div class="bg-white overflow-hidden shadow rounded-lg">
|
|
51
|
+
<div class="p-5">
|
|
52
|
+
<div class="flex items-center">
|
|
53
|
+
<div class="flex-shrink-0 bg-blue-500 rounded-md p-3">
|
|
54
|
+
<svg class="h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
55
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"/>
|
|
56
|
+
</svg>
|
|
57
|
+
</div>
|
|
58
|
+
<div class="ml-5 w-0 flex-1">
|
|
59
|
+
<dl>
|
|
60
|
+
<dt class="text-sm font-medium text-gray-500 truncate">Total Resources</dt>
|
|
61
|
+
<dd class="text-2xl font-semibold text-gray-900">{{ snapshot.resource_count | format_number }}</dd>
|
|
62
|
+
</dl>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<div class="bg-white overflow-hidden shadow rounded-lg">
|
|
69
|
+
<div class="p-5">
|
|
70
|
+
<div class="flex items-center">
|
|
71
|
+
<div class="flex-shrink-0 bg-green-500 rounded-md p-3">
|
|
72
|
+
<svg class="h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
73
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
|
74
|
+
</svg>
|
|
75
|
+
</div>
|
|
76
|
+
<div class="ml-5 w-0 flex-1">
|
|
77
|
+
<dl>
|
|
78
|
+
<dt class="text-sm font-medium text-gray-500 truncate">Created</dt>
|
|
79
|
+
<dd class="text-lg font-semibold text-gray-900">{{ snapshot.created_at }}</dd>
|
|
80
|
+
</dl>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<div class="bg-white overflow-hidden shadow rounded-lg">
|
|
87
|
+
<div class="p-5">
|
|
88
|
+
<div class="flex items-center">
|
|
89
|
+
<div class="flex-shrink-0 bg-purple-500 rounded-md p-3">
|
|
90
|
+
<svg class="h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
91
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/>
|
|
92
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/>
|
|
93
|
+
</svg>
|
|
94
|
+
</div>
|
|
95
|
+
<div class="ml-5 w-0 flex-1">
|
|
96
|
+
<dl>
|
|
97
|
+
<dt class="text-sm font-medium text-gray-500 truncate">Regions</dt>
|
|
98
|
+
<dd class="text-lg font-semibold text-gray-900">{{ snapshot.regions | join(', ') if snapshot.regions else 'N/A' }}</dd>
|
|
99
|
+
</dl>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<div class="bg-white overflow-hidden shadow rounded-lg">
|
|
106
|
+
<div class="p-5">
|
|
107
|
+
<div class="flex items-center">
|
|
108
|
+
<div class="flex-shrink-0 bg-amber-500 rounded-md p-3">
|
|
109
|
+
<svg class="h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
110
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
|
|
111
|
+
</svg>
|
|
112
|
+
</div>
|
|
113
|
+
<div class="ml-5 w-0 flex-1">
|
|
114
|
+
<dl>
|
|
115
|
+
<dt class="text-sm font-medium text-gray-500 truncate">Account ID</dt>
|
|
116
|
+
<dd class="text-lg font-semibold text-gray-900">{{ snapshot.account_id }}</dd>
|
|
117
|
+
</dl>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
|
|
125
|
+
<!-- Resources by Type -->
|
|
126
|
+
<div class="bg-white shadow rounded-lg p-6">
|
|
127
|
+
<h3 class="text-lg font-medium text-gray-900 mb-4">Resources by Type</h3>
|
|
128
|
+
<div class="h-64">
|
|
129
|
+
<canvas id="chart-by-type"></canvas>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<!-- Resources by Region -->
|
|
134
|
+
<div class="bg-white shadow rounded-lg p-6">
|
|
135
|
+
<h3 class="text-lg font-medium text-gray-900 mb-4">Resources by Region</h3>
|
|
136
|
+
<div class="h-64">
|
|
137
|
+
<canvas id="chart-by-region"></canvas>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<!-- Resource Table -->
|
|
143
|
+
<div class="bg-white shadow rounded-lg overflow-hidden">
|
|
144
|
+
<div class="px-4 py-5 border-b border-gray-200 sm:px-6 flex items-center justify-between">
|
|
145
|
+
<h3 class="text-lg font-medium text-gray-900">Resources</h3>
|
|
146
|
+
<a href="/resources?snapshot={{ snapshot.name }}" class="text-sm text-blue-600 hover:text-blue-500">
|
|
147
|
+
View all in Resource Explorer
|
|
148
|
+
</a>
|
|
149
|
+
</div>
|
|
150
|
+
<div id="resource-table"
|
|
151
|
+
hx-get="/api/snapshots/{{ snapshot.name }}/resources?limit=20"
|
|
152
|
+
hx-trigger="load"
|
|
153
|
+
hx-swap="innerHTML">
|
|
154
|
+
<div class="p-8 text-center text-gray-500">
|
|
155
|
+
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto"></div>
|
|
156
|
+
<p class="mt-2">Loading resources...</p>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
{% endblock %}
|
|
162
|
+
|
|
163
|
+
{% block scripts %}
|
|
164
|
+
<script>
|
|
165
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
166
|
+
// Load charts with snapshot-specific data
|
|
167
|
+
fetch('/api/charts/resources-by-type?snapshot={{ snapshot.name }}')
|
|
168
|
+
.then(r => r.json())
|
|
169
|
+
.then(data => {
|
|
170
|
+
new Chart(document.getElementById('chart-by-type'), {
|
|
171
|
+
type: 'doughnut',
|
|
172
|
+
data: data,
|
|
173
|
+
options: {
|
|
174
|
+
responsive: true,
|
|
175
|
+
maintainAspectRatio: false,
|
|
176
|
+
plugins: {
|
|
177
|
+
legend: {
|
|
178
|
+
position: 'right',
|
|
179
|
+
labels: { boxWidth: 12 }
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
fetch('/api/charts/resources-by-region?snapshot={{ snapshot.name }}')
|
|
187
|
+
.then(r => r.json())
|
|
188
|
+
.then(data => {
|
|
189
|
+
new Chart(document.getElementById('chart-by-region'), {
|
|
190
|
+
type: 'bar',
|
|
191
|
+
data: data,
|
|
192
|
+
options: {
|
|
193
|
+
responsive: true,
|
|
194
|
+
maintainAspectRatio: false,
|
|
195
|
+
plugins: {
|
|
196
|
+
legend: { display: false }
|
|
197
|
+
},
|
|
198
|
+
scales: {
|
|
199
|
+
y: { beginAtZero: true }
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Handle resource table response
|
|
207
|
+
document.body.addEventListener('htmx:afterSwap', function(evt) {
|
|
208
|
+
if (evt.detail.target.id === 'resource-table') {
|
|
209
|
+
const data = JSON.parse(evt.detail.xhr.responseText);
|
|
210
|
+
renderResourceTable(data, evt.detail.target);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
function renderResourceTable(data, target) {
|
|
215
|
+
if (!data.resources || data.resources.length === 0) {
|
|
216
|
+
target.innerHTML = `
|
|
217
|
+
<div class="p-8 text-center text-gray-500">
|
|
218
|
+
<p>No resources in this snapshot.</p>
|
|
219
|
+
</div>
|
|
220
|
+
`;
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
let html = `
|
|
225
|
+
<table class="min-w-full divide-y divide-gray-200">
|
|
226
|
+
<thead class="bg-gray-50">
|
|
227
|
+
<tr>
|
|
228
|
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Name</th>
|
|
229
|
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th>
|
|
230
|
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Region</th>
|
|
231
|
+
</tr>
|
|
232
|
+
</thead>
|
|
233
|
+
<tbody class="bg-white divide-y divide-gray-200">
|
|
234
|
+
`;
|
|
235
|
+
|
|
236
|
+
data.resources.forEach(r => {
|
|
237
|
+
html += `
|
|
238
|
+
<tr class="hover:bg-gray-50">
|
|
239
|
+
<td class="px-6 py-4 whitespace-nowrap">
|
|
240
|
+
<div class="text-sm font-medium text-gray-900">${r.name || 'N/A'}</div>
|
|
241
|
+
<div class="text-xs text-gray-500 truncate max-w-xs" title="${r.arn}">${r.arn}</div>
|
|
242
|
+
</td>
|
|
243
|
+
<td class="px-6 py-4 whitespace-nowrap">
|
|
244
|
+
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
|
|
245
|
+
${r.resource_type}
|
|
246
|
+
</span>
|
|
247
|
+
</td>
|
|
248
|
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${r.region}</td>
|
|
249
|
+
</tr>
|
|
250
|
+
`;
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
html += `
|
|
254
|
+
</tbody>
|
|
255
|
+
</table>
|
|
256
|
+
`;
|
|
257
|
+
|
|
258
|
+
if (data.count > data.resources.length) {
|
|
259
|
+
html += `
|
|
260
|
+
<div class="bg-gray-50 px-4 py-3 text-center border-t border-gray-200">
|
|
261
|
+
<a href="/resources?snapshot={{ snapshot.name }}" class="text-sm text-blue-600 hover:text-blue-500">
|
|
262
|
+
View all ${data.count} resources
|
|
263
|
+
</a>
|
|
264
|
+
</div>
|
|
265
|
+
`;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
target.innerHTML = html;
|
|
269
|
+
}
|
|
270
|
+
</script>
|
|
271
|
+
{% endblock %}
|