arnmatch 2026.1.0__tar.gz → 2026.1.2__tar.gz
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.
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/CLAUDE.md +7 -5
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/PKG-INFO +12 -9
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/README.md +11 -8
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/codegen/codegen.py +19 -5
- arnmatch-2026.1.2/codegen/index_sdk.py +194 -0
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/src/arnmatch/__init__.py +14 -2
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/src/arnmatch/arn_patterns.py +366 -5
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/tests/test_arnmatch.py +11 -0
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/.github/workflows/workflow.yml +0 -0
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/.gitignore +0 -0
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/.python-version +0 -0
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/Makefile +0 -0
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/codegen/.gitignore +0 -0
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/codegen/scraper.py +0 -0
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/pyproject.toml +0 -0
- {arnmatch-2026.1.0 → arnmatch-2026.1.2}/uv.lock +0 -0
|
@@ -32,28 +32,30 @@ uv run arnmatch <arn>
|
|
|
32
32
|
### Core Library (`src/arnmatch/`)
|
|
33
33
|
|
|
34
34
|
- `__init__.py` - Main module with `arnmatch(arn)` function and `ARN` dataclass
|
|
35
|
-
- `arn_patterns.py` - Generated file containing compiled regex patterns indexed by service
|
|
35
|
+
- `arn_patterns.py` - Generated file containing compiled regex patterns indexed by service and AWS SDK services mapping
|
|
36
36
|
|
|
37
|
-
The `arnmatch()` function splits the ARN, looks up patterns by service, and returns an `ARN` with partition, service, region, account, resource_type, and captured groups. The `resource_id` and `resource_name` properties use heuristics (prefer groups ending in "Id" or "Name").
|
|
37
|
+
The `arnmatch()` function splits the ARN, looks up patterns by service, and returns an `ARN` with partition, service, region, account, resource_type, and captured groups. The `resource_id` and `resource_name` properties use heuristics (prefer groups ending in "Id" or "Name"). The `aws_sdk_services` property returns boto3 client names for the service.
|
|
38
38
|
|
|
39
39
|
### Code Generation (`codegen/`)
|
|
40
40
|
|
|
41
41
|
- `scraper.py` - Scrapes AWS service authorization reference pages, caches results with joblib
|
|
42
42
|
- `codegen.py` - Processes resources and generates `arn_patterns.py`
|
|
43
|
+
- `index_sdk.py` - Maps ARN service names to AWS SDK (boto3) client names
|
|
43
44
|
|
|
44
|
-
Data flow: AWS docs → `scraper.py` → raw resources → `codegen.py` → `codegen/build/arn_patterns.py` → (copied by `make build`) → `src/arnmatch/arn_patterns.py`
|
|
45
|
+
Data flow: AWS docs → `scraper.py` → raw resources → `codegen.py` + `index_sdk.py` → `codegen/build/arn_patterns.py` → (copied by `make build`) → `src/arnmatch/arn_patterns.py`
|
|
45
46
|
|
|
46
47
|
### Key Design Decisions
|
|
47
48
|
|
|
48
49
|
1. **Pattern ordering**: Patterns sorted by specificity (more literal segments first) for correct matching
|
|
49
50
|
2. **Service index**: O(1) lookup by service before pattern matching
|
|
50
51
|
3. **Overrides in codegen.py**: `PATTERN_OVERRIDES` fixes AWS docs that use wildcards instead of capture groups; `PATTERN_INCLUDES` adds patterns not in docs (EKS k8s resources, Inspector legacy)
|
|
51
|
-
4. **
|
|
52
|
+
4. **SDK service mapping**: `index_sdk.py` maps ARN service names to boto3 client names using botocore metadata (signingName/endpointPrefix), with manual overrides for edge cases and excludes for discontinued/console-only services
|
|
53
|
+
5. **Zero runtime dependencies**: Only codegen has external deps (requests, beautifulsoup4, joblib, boto3)
|
|
52
54
|
|
|
53
55
|
## Build Notes
|
|
54
56
|
|
|
55
57
|
- Uses `uv` for package management (not pip)
|
|
56
58
|
- Build system is hatchling with dynamic version from `src/arnmatch/__init__.py`
|
|
57
|
-
- **Versioning**: CalVer format `YYYY.
|
|
59
|
+
- **Versioning**: CalVer format `YYYY.0M.MICRO` (e.g., `2026.01.0`)
|
|
58
60
|
- Always run `make build` before publishing to ensure patterns are current
|
|
59
61
|
- Scraper cache lives in `.cache/` - delete if AWS docs change significantly
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: arnmatch
|
|
3
|
-
Version: 2026.1.
|
|
3
|
+
Version: 2026.1.2
|
|
4
4
|
Summary: Parse AWS ARNs into structured data (2000+ resource types)
|
|
5
5
|
Author-email: Andrey Gubarev <andrey@andreygubarev.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -37,6 +37,7 @@ pip install arnmatch
|
|
|
37
37
|
```bash
|
|
38
38
|
$ uvx arnmatch "arn:aws:lambda:us-east-1:123456789012:function:my-function"
|
|
39
39
|
aws_service: lambda
|
|
40
|
+
aws_sdk_services: lambda
|
|
40
41
|
aws_region: us-east-1
|
|
41
42
|
aws_account: 123456789012
|
|
42
43
|
resource_type: function
|
|
@@ -52,13 +53,14 @@ from arnmatch import arnmatch
|
|
|
52
53
|
arn = "arn:aws:lambda:us-east-1:123456789012:function:my-function"
|
|
53
54
|
result = arnmatch(arn)
|
|
54
55
|
|
|
55
|
-
print(result.aws_service)
|
|
56
|
-
print(result.
|
|
57
|
-
print(result.
|
|
58
|
-
print(result.
|
|
59
|
-
print(result.
|
|
60
|
-
print(result.
|
|
61
|
-
print(result.
|
|
56
|
+
print(result.aws_service) # lambda
|
|
57
|
+
print(result.aws_sdk_services) # ['lambda']
|
|
58
|
+
print(result.aws_region) # us-east-1
|
|
59
|
+
print(result.aws_account) # 123456789012
|
|
60
|
+
print(result.resource_type) # function
|
|
61
|
+
print(result.resource_id) # my-function
|
|
62
|
+
print(result.resource_name) # my-function
|
|
63
|
+
print(result.attributes) # {'Partition': 'aws', 'Region': 'us-east-1', ...}
|
|
62
64
|
```
|
|
63
65
|
|
|
64
66
|
## API Reference
|
|
@@ -89,6 +91,7 @@ Properties:
|
|
|
89
91
|
|----------|-------------|
|
|
90
92
|
| `resource_id` | Resource identifier (prefers groups ending in `Id`, falls back to `Name`, then last group) |
|
|
91
93
|
| `resource_name` | Resource name (prefers groups ending in `Name`, falls back to `resource_id`) |
|
|
94
|
+
| `aws_sdk_services` | List of boto3 client names for this service (e.g., `['elb', 'elbv2']` for elasticloadbalancing) |
|
|
92
95
|
|
|
93
96
|
### `ARNError`
|
|
94
97
|
|
|
@@ -96,7 +99,7 @@ Exception raised when ARN parsing fails. Inherits from `ValueError`.
|
|
|
96
99
|
|
|
97
100
|
## Versioning
|
|
98
101
|
|
|
99
|
-
This project uses [CalVer](https://calver.org/) with format `YYYY.
|
|
102
|
+
This project uses [CalVer](https://calver.org/) with format `YYYY.0M.MICRO` (e.g., `2026.01.0`).
|
|
100
103
|
|
|
101
104
|
## Development
|
|
102
105
|
|
|
@@ -29,6 +29,7 @@ pip install arnmatch
|
|
|
29
29
|
```bash
|
|
30
30
|
$ uvx arnmatch "arn:aws:lambda:us-east-1:123456789012:function:my-function"
|
|
31
31
|
aws_service: lambda
|
|
32
|
+
aws_sdk_services: lambda
|
|
32
33
|
aws_region: us-east-1
|
|
33
34
|
aws_account: 123456789012
|
|
34
35
|
resource_type: function
|
|
@@ -44,13 +45,14 @@ from arnmatch import arnmatch
|
|
|
44
45
|
arn = "arn:aws:lambda:us-east-1:123456789012:function:my-function"
|
|
45
46
|
result = arnmatch(arn)
|
|
46
47
|
|
|
47
|
-
print(result.aws_service)
|
|
48
|
-
print(result.
|
|
49
|
-
print(result.
|
|
50
|
-
print(result.
|
|
51
|
-
print(result.
|
|
52
|
-
print(result.
|
|
53
|
-
print(result.
|
|
48
|
+
print(result.aws_service) # lambda
|
|
49
|
+
print(result.aws_sdk_services) # ['lambda']
|
|
50
|
+
print(result.aws_region) # us-east-1
|
|
51
|
+
print(result.aws_account) # 123456789012
|
|
52
|
+
print(result.resource_type) # function
|
|
53
|
+
print(result.resource_id) # my-function
|
|
54
|
+
print(result.resource_name) # my-function
|
|
55
|
+
print(result.attributes) # {'Partition': 'aws', 'Region': 'us-east-1', ...}
|
|
54
56
|
```
|
|
55
57
|
|
|
56
58
|
## API Reference
|
|
@@ -81,6 +83,7 @@ Properties:
|
|
|
81
83
|
|----------|-------------|
|
|
82
84
|
| `resource_id` | Resource identifier (prefers groups ending in `Id`, falls back to `Name`, then last group) |
|
|
83
85
|
| `resource_name` | Resource name (prefers groups ending in `Name`, falls back to `resource_id`) |
|
|
86
|
+
| `aws_sdk_services` | List of boto3 client names for this service (e.g., `['elb', 'elbv2']` for elasticloadbalancing) |
|
|
84
87
|
|
|
85
88
|
### `ARNError`
|
|
86
89
|
|
|
@@ -88,7 +91,7 @@ Exception raised when ARN parsing fails. Inherits from `ValueError`.
|
|
|
88
91
|
|
|
89
92
|
## Versioning
|
|
90
93
|
|
|
91
|
-
This project uses [CalVer](https://calver.org/) with format `YYYY.
|
|
94
|
+
This project uses [CalVer](https://calver.org/) with format `YYYY.0M.MICRO` (e.g., `2026.01.0`).
|
|
92
95
|
|
|
93
96
|
## Development
|
|
94
97
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /// script
|
|
2
2
|
# requires-python = ">=3.10"
|
|
3
|
-
# dependencies = ["requests", "joblib", "beautifulsoup4"]
|
|
3
|
+
# dependencies = ["requests", "joblib", "beautifulsoup4", "boto3"]
|
|
4
4
|
# ///
|
|
5
5
|
|
|
6
6
|
import logging
|
|
@@ -8,6 +8,7 @@ import re
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
|
|
10
10
|
from scraper import AWSScraper
|
|
11
|
+
from index_sdk import SDKServiceIndexer
|
|
11
12
|
|
|
12
13
|
log = logging.getLogger(__name__)
|
|
13
14
|
|
|
@@ -233,8 +234,8 @@ class CodeGenerator:
|
|
|
233
234
|
("dms", "ReplicationSubnetGroup"): ["subgrp"],
|
|
234
235
|
}
|
|
235
236
|
|
|
236
|
-
def generate(self, resources, output_path):
|
|
237
|
-
"""Generate Python file with ARN patterns."""
|
|
237
|
+
def generate(self, resources, sdk_services_mapping, output_path):
|
|
238
|
+
"""Generate Python file with ARN patterns and SDK services mapping."""
|
|
238
239
|
# Group by service
|
|
239
240
|
by_service = {}
|
|
240
241
|
for r in resources:
|
|
@@ -258,9 +259,17 @@ class CodeGenerator:
|
|
|
258
259
|
f.write(f' (re.compile(r"{regex}"), {type_names!r}),\n')
|
|
259
260
|
f.write(" ],\n")
|
|
260
261
|
|
|
262
|
+
f.write("}\n\n")
|
|
263
|
+
|
|
264
|
+
# Write SDK services mapping
|
|
265
|
+
f.write("# Auto-generated mapping: ARN service -> AWS SDK client names\n")
|
|
266
|
+
f.write("AWS_SDK_SERVICES = {\n")
|
|
267
|
+
for arn_svc, clients in sorted(sdk_services_mapping.items()):
|
|
268
|
+
f.write(f" {arn_svc!r}: {clients!r},\n")
|
|
261
269
|
f.write("}\n")
|
|
262
270
|
|
|
263
271
|
log.info(f"Wrote {len(resources)} patterns for {len(by_service)} services to {output_path}")
|
|
272
|
+
log.info(f"Wrote SDK mapping for {len(sdk_services_mapping)} services")
|
|
264
273
|
|
|
265
274
|
def pattern_to_regex(self, arn_pattern):
|
|
266
275
|
"""Convert ARN pattern to regex with named capture groups."""
|
|
@@ -300,14 +309,19 @@ def main():
|
|
|
300
309
|
for svc in services:
|
|
301
310
|
resources.extend(scraper.get_resources(svc["href"]))
|
|
302
311
|
|
|
303
|
-
# Process
|
|
312
|
+
# Process ARN patterns
|
|
304
313
|
indexer = ARNIndexer()
|
|
305
314
|
resources = indexer.process(resources)
|
|
306
315
|
|
|
316
|
+
# Build SDK services mapping
|
|
317
|
+
arn_services = {r["arn_service"] for r in resources}
|
|
318
|
+
sdk_indexer = SDKServiceIndexer()
|
|
319
|
+
sdk_mapping = sdk_indexer.process(arn_services)
|
|
320
|
+
|
|
307
321
|
# Generate
|
|
308
322
|
BUILD_DIR.mkdir(exist_ok=True)
|
|
309
323
|
generator = CodeGenerator()
|
|
310
|
-
generator.generate(resources, BUILD_DIR / "arn_patterns.py")
|
|
324
|
+
generator.generate(resources, sdk_mapping, BUILD_DIR / "arn_patterns.py")
|
|
311
325
|
|
|
312
326
|
|
|
313
327
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# /// script
|
|
2
|
+
# requires-python = ">=3.10"
|
|
3
|
+
# dependencies = ["boto3"]
|
|
4
|
+
# ///
|
|
5
|
+
|
|
6
|
+
"""Maps ARN service names to AWS SDK (boto3) client names."""
|
|
7
|
+
|
|
8
|
+
import gzip
|
|
9
|
+
import json
|
|
10
|
+
import os
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SDKServiceIndexer:
|
|
15
|
+
"""Builds mapping from ARN service names to AWS SDK client names."""
|
|
16
|
+
|
|
17
|
+
# Phase 3: Manual overrides for services where botocore metadata doesn't match
|
|
18
|
+
# Format: "arn_service" -> ["sdk_client1", "sdk_client2", ...]
|
|
19
|
+
OVERRIDES = {
|
|
20
|
+
# AI DevOps uses aiops client
|
|
21
|
+
"aidevops": ["aiops"],
|
|
22
|
+
# AppMesh preview uses appmesh client
|
|
23
|
+
"appmesh-preview": ["appmesh"],
|
|
24
|
+
# Service Catalog uses 'catalog' in ARNs but 'servicecatalog' client
|
|
25
|
+
"catalog": ["servicecatalog"],
|
|
26
|
+
# CloudWatch uses 'monitoring' as endpointPrefix but 'cloudwatch' in ARNs
|
|
27
|
+
"cloudwatch": ["cloudwatch"],
|
|
28
|
+
# Partner Central has multiple sub-clients
|
|
29
|
+
"partnercentral": [
|
|
30
|
+
"partnercentral-account",
|
|
31
|
+
"partnercentral-benefits",
|
|
32
|
+
"partnercentral-channel",
|
|
33
|
+
"partnercentral-selling",
|
|
34
|
+
],
|
|
35
|
+
# AWS Private 5G uses privatenetworks client
|
|
36
|
+
"private-networks": ["privatenetworks"],
|
|
37
|
+
# RDS IAM auth uses rds client
|
|
38
|
+
"rds-db": ["rds"],
|
|
39
|
+
# Route53 recovery services
|
|
40
|
+
"route53-recovery-control": [
|
|
41
|
+
"route53-recovery-cluster",
|
|
42
|
+
"route53-recovery-control-config",
|
|
43
|
+
],
|
|
44
|
+
# S3 variants map to s3 client
|
|
45
|
+
"s3-object-lambda": ["s3"],
|
|
46
|
+
"s3express": ["s3"],
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Discontinued/EOL services
|
|
50
|
+
EXCLUDES_DISCONTINUED = {
|
|
51
|
+
"a4b", # Alexa for Business
|
|
52
|
+
"bugbust", # AWS BugBust
|
|
53
|
+
"codestar", # CodeStar
|
|
54
|
+
"elastic-inference", # EOL April 2024
|
|
55
|
+
"elastictranscoder", # Replaced by MediaConvert
|
|
56
|
+
"honeycode", # Honeycode
|
|
57
|
+
"iotfleethub", # EOL October 2025
|
|
58
|
+
"lookoutmetrics", # Lookout for Metrics
|
|
59
|
+
"lookoutvision", # Lookout for Vision
|
|
60
|
+
"monitron", # Monitron
|
|
61
|
+
"nimble", # Nimble Studio
|
|
62
|
+
"opsworks", # OpsWorks Stacks - EOL May 2024
|
|
63
|
+
"opsworks-cm", # OpsWorks Chef/Puppet - EOL 2024
|
|
64
|
+
"qldb", # QLDB - EOL 2025
|
|
65
|
+
"robomaker", # RoboMaker - EOL 2025
|
|
66
|
+
"worklink", # WorkLink
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# Console-only services (no SDK)
|
|
70
|
+
EXCLUDES_CONSOLE = {
|
|
71
|
+
"appstudio", # AWS App Studio
|
|
72
|
+
"cloudshell", # AWS CloudShell
|
|
73
|
+
"consoleapp", # Console Mobile App
|
|
74
|
+
"elemental-appliances-software", # Physical hardware
|
|
75
|
+
"elemental-support-cases", # Support tickets
|
|
76
|
+
"identity-sync", # Identity sync
|
|
77
|
+
"iq", # AWS IQ
|
|
78
|
+
"iq-permission", # AWS IQ
|
|
79
|
+
"mapcredits", # AWS MAP credits
|
|
80
|
+
"one", # Amazon One Enterprise (palm recognition)
|
|
81
|
+
"payments", # Billing payments
|
|
82
|
+
"pricingplanmanager", # Pricing plans
|
|
83
|
+
"purchase-orders", # Billing purchase orders
|
|
84
|
+
"securityagent", # AWS Security Agent (preview)
|
|
85
|
+
"sqlworkbench", # Redshift Query Editor
|
|
86
|
+
"ts", # AWS Diagnostic Tools
|
|
87
|
+
"vendor-insights", # Marketplace Vendor Insights
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
# Services using non-boto3 SDK (IDE plugins, CLI, OpenAI SDK, etc.)
|
|
91
|
+
EXCLUDES_NOSDK = {
|
|
92
|
+
"apptest", # AWS Application Testing
|
|
93
|
+
"bedrock-mantle", # Uses OpenAI SDK
|
|
94
|
+
"codewhisperer", # IDE extension (now Q Developer)
|
|
95
|
+
"freertos", # FreeRTOS device SDK
|
|
96
|
+
"qdeveloper", # IDE plugins only
|
|
97
|
+
"transform", # CLI only
|
|
98
|
+
"transform-custom", # CLI only
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
def __init__(self):
|
|
102
|
+
import botocore
|
|
103
|
+
self.botocore_data = Path(botocore.__file__).parent / "data"
|
|
104
|
+
|
|
105
|
+
def process(self, arn_services):
|
|
106
|
+
"""Build ARN service -> SDK clients mapping."""
|
|
107
|
+
# Get all boto3 client metadata
|
|
108
|
+
metadata = self.metadata_load()
|
|
109
|
+
|
|
110
|
+
result = {}
|
|
111
|
+
|
|
112
|
+
for arn_service in sorted(arn_services):
|
|
113
|
+
# Phase 3: Check manual overrides first
|
|
114
|
+
if arn_service in self.OVERRIDES:
|
|
115
|
+
result[arn_service] = self.OVERRIDES[arn_service]
|
|
116
|
+
continue
|
|
117
|
+
|
|
118
|
+
# Known no-SDK services
|
|
119
|
+
excludes = self.EXCLUDES_DISCONTINUED | self.EXCLUDES_CONSOLE | self.EXCLUDES_NOSDK
|
|
120
|
+
if arn_service in excludes:
|
|
121
|
+
result[arn_service] = []
|
|
122
|
+
continue
|
|
123
|
+
|
|
124
|
+
# Phase 1: Direct name match
|
|
125
|
+
if arn_service in metadata:
|
|
126
|
+
result[arn_service] = [arn_service]
|
|
127
|
+
# Also check for additional clients via metadata
|
|
128
|
+
additional = self.metadata_match(
|
|
129
|
+
arn_service, metadata, exclude={arn_service}
|
|
130
|
+
)
|
|
131
|
+
if additional:
|
|
132
|
+
result[arn_service].extend(sorted(additional))
|
|
133
|
+
continue
|
|
134
|
+
|
|
135
|
+
# Phase 2: Find via botocore metadata (signingName/endpointPrefix)
|
|
136
|
+
clients = self.metadata_match(arn_service, metadata)
|
|
137
|
+
if clients:
|
|
138
|
+
result[arn_service] = sorted(clients)
|
|
139
|
+
continue
|
|
140
|
+
|
|
141
|
+
# No mapping found
|
|
142
|
+
raise ValueError(f"No SDK client mapping for ARN service: {arn_service}")
|
|
143
|
+
|
|
144
|
+
return result
|
|
145
|
+
|
|
146
|
+
def metadata_load(self):
|
|
147
|
+
"""Load metadata for all boto3 clients."""
|
|
148
|
+
metadata = {}
|
|
149
|
+
|
|
150
|
+
for sdk_service in os.listdir(self.botocore_data):
|
|
151
|
+
client_path = self.botocore_data / sdk_service
|
|
152
|
+
if not client_path.is_dir():
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
# Find latest version
|
|
156
|
+
versions = sorted(
|
|
157
|
+
[d for d in os.listdir(client_path) if d[0].isdigit()],
|
|
158
|
+
reverse=True,
|
|
159
|
+
)
|
|
160
|
+
if not versions:
|
|
161
|
+
continue
|
|
162
|
+
|
|
163
|
+
# Load service metadata
|
|
164
|
+
service_file = client_path / versions[0] / "service-2.json.gz"
|
|
165
|
+
if not service_file.exists():
|
|
166
|
+
continue
|
|
167
|
+
|
|
168
|
+
with gzip.open(service_file) as f:
|
|
169
|
+
data = json.load(f)
|
|
170
|
+
metadata[sdk_service] = data.get("metadata", {})
|
|
171
|
+
|
|
172
|
+
return metadata
|
|
173
|
+
|
|
174
|
+
def metadata_match(self, arn_service, metadata, exclude=None):
|
|
175
|
+
"""Find SDK clients whose signingName or endpointPrefix matches ARN service."""
|
|
176
|
+
exclude = exclude or set()
|
|
177
|
+
matches = set()
|
|
178
|
+
|
|
179
|
+
for sdk_service, meta in metadata.items():
|
|
180
|
+
if sdk_service in exclude:
|
|
181
|
+
continue
|
|
182
|
+
|
|
183
|
+
# Check signingName first (more specific)
|
|
184
|
+
signing_name = meta.get("signingName")
|
|
185
|
+
if signing_name == arn_service:
|
|
186
|
+
matches.add(sdk_service)
|
|
187
|
+
continue
|
|
188
|
+
|
|
189
|
+
# Check endpointPrefix (fallback)
|
|
190
|
+
endpoint_prefix = meta.get("endpointPrefix")
|
|
191
|
+
if endpoint_prefix == arn_service:
|
|
192
|
+
matches.add(sdk_service)
|
|
193
|
+
|
|
194
|
+
return matches
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"""ARN pattern matching using regex patterns."""
|
|
2
2
|
|
|
3
|
-
__version__ = "2026.01.
|
|
3
|
+
__version__ = "2026.01.2"
|
|
4
4
|
|
|
5
5
|
import sys
|
|
6
6
|
from dataclasses import dataclass
|
|
7
7
|
from functools import cached_property
|
|
8
8
|
|
|
9
|
-
from .arn_patterns import ARN_PATTERNS
|
|
9
|
+
from .arn_patterns import ARN_PATTERNS, AWS_SDK_SERVICES
|
|
10
10
|
|
|
11
11
|
# Standard groups that are not resource-specific
|
|
12
12
|
STANDARD_GROUPS = {"Partition", "Region", "Account"}
|
|
@@ -77,6 +77,17 @@ class ARN:
|
|
|
77
77
|
# Fall back to resource_id
|
|
78
78
|
return self.resource_id
|
|
79
79
|
|
|
80
|
+
@cached_property
|
|
81
|
+
def aws_sdk_services(self):
|
|
82
|
+
"""Get AWS SDK (boto3) client names for this resource's service.
|
|
83
|
+
|
|
84
|
+
Returns list of client names that can interact with this resource type.
|
|
85
|
+
May return multiple clients for services with versioned APIs
|
|
86
|
+
(e.g., ['elb', 'elbv2'] for elasticloadbalancing).
|
|
87
|
+
Returns empty list if no SDK client exists.
|
|
88
|
+
"""
|
|
89
|
+
return AWS_SDK_SERVICES.get(self.aws_service, [])
|
|
90
|
+
|
|
80
91
|
|
|
81
92
|
def arnmatch(arn: str) -> ARN:
|
|
82
93
|
"""Match ARN against patterns.
|
|
@@ -121,6 +132,7 @@ def main() -> None:
|
|
|
121
132
|
try:
|
|
122
133
|
result = arnmatch(arn)
|
|
123
134
|
print(f"aws_service: {result.aws_service}")
|
|
135
|
+
print(f"aws_sdk_services: {','.join(result.aws_sdk_services)}")
|
|
124
136
|
print(f"aws_region: {result.aws_region}")
|
|
125
137
|
print(f"aws_account: {result.aws_account}")
|
|
126
138
|
print(f"resource_type: {result.resource_type}")
|
|
@@ -2414,15 +2414,17 @@ ARN_PATTERNS = {
|
|
|
2414
2414
|
(re.compile(r"^arn:(?P<Partition>[\w-]+):security-ir:(?P<Region>[\w-]*):(?P<Account>\d{12}):membership/(?P<MembershipId>.+?)$"), ['membership']),
|
|
2415
2415
|
],
|
|
2416
2416
|
'securityagent': [
|
|
2417
|
-
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):agent-
|
|
2418
|
-
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):agent-
|
|
2419
|
-
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):agent-
|
|
2420
|
-
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):agent-
|
|
2421
|
-
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):agent-
|
|
2417
|
+
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):agent-space/(?P<AgentId>.+?)/artifact/(?P<ArtifactId>.+?)$"), ['Artifact']),
|
|
2418
|
+
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):agent-space/(?P<AgentId>.+?)/finding/(?P<FindingId>.+?)$"), ['Finding']),
|
|
2419
|
+
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):agent-space/(?P<AgentId>.+?)/pentest/(?P<PentestId>.+?)$"), ['Pentest']),
|
|
2420
|
+
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):agent-space/(?P<AgentId>.+?)/pentest-job/(?P<JobId>.+?)$"), ['PentestJob']),
|
|
2421
|
+
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):agent-space/(?P<AgentId>.+?)/pentest-task/(?P<TaskId>.+?)$"), ['PentestTask']),
|
|
2422
2422
|
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):agent-instance/(?P<AgentId>.+?)$"), ['AgentInstance']),
|
|
2423
|
+
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):agent-space/(?P<AgentId>.+?)$"), ['AgentSpace']),
|
|
2423
2424
|
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):application/(?P<ApplicationId>.+?)$"), ['Application']),
|
|
2424
2425
|
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):control/(?P<ControlId>.+?)$"), ['Control']),
|
|
2425
2426
|
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):integration/(?P<IntegrationId>.+?)$"), ['Integration']),
|
|
2427
|
+
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityagent:(?P<Region>[\w-]*):(?P<Account>\d{12}):security-requirement/(?P<SecurityRequirementId>.+?)$"), ['SecurityRequirement']),
|
|
2426
2428
|
],
|
|
2427
2429
|
'securityhub': [
|
|
2428
2430
|
(re.compile(r"^arn:(?P<Partition>[\w-]+):securityhub:(?P<Region>[\w-]*):(?P<Account>\d{12}):product/(?P<Company>.+?)/(?P<ProductId>.+?)$"), ['product']),
|
|
@@ -2794,3 +2796,362 @@ ARN_PATTERNS = {
|
|
|
2794
2796
|
(re.compile(r"^arn:(?P<Partition>[\w-]+):xray:(?P<Region>[\w-]*):(?P<Account>\d{12}):sampling-rule/(?P<SamplingRuleName>.+?)$"), ['sampling-rule']),
|
|
2795
2797
|
],
|
|
2796
2798
|
}
|
|
2799
|
+
|
|
2800
|
+
# Auto-generated mapping: ARN service -> AWS SDK client names
|
|
2801
|
+
AWS_SDK_SERVICES = {
|
|
2802
|
+
'a4b': [],
|
|
2803
|
+
'access-analyzer': ['accessanalyzer'],
|
|
2804
|
+
'account': ['account'],
|
|
2805
|
+
'acm': ['acm'],
|
|
2806
|
+
'acm-pca': ['acm-pca'],
|
|
2807
|
+
'aidevops': ['aiops'],
|
|
2808
|
+
'aiops': ['aiops'],
|
|
2809
|
+
'airflow': ['mwaa'],
|
|
2810
|
+
'airflow-serverless': ['mwaa-serverless'],
|
|
2811
|
+
'amplify': ['amplify'],
|
|
2812
|
+
'amplifybackend': ['amplifybackend'],
|
|
2813
|
+
'amplifyuibuilder': ['amplifyuibuilder'],
|
|
2814
|
+
'aoss': ['opensearchserverless'],
|
|
2815
|
+
'apigateway': ['apigateway', 'apigatewayv2'],
|
|
2816
|
+
'app-integrations': ['appintegrations'],
|
|
2817
|
+
'appconfig': ['appconfig', 'appconfigdata'],
|
|
2818
|
+
'appfabric': ['appfabric'],
|
|
2819
|
+
'appflow': ['appflow'],
|
|
2820
|
+
'application-autoscaling': ['application-autoscaling'],
|
|
2821
|
+
'application-signals': ['application-signals'],
|
|
2822
|
+
'appmesh': ['appmesh'],
|
|
2823
|
+
'appmesh-preview': ['appmesh'],
|
|
2824
|
+
'apprunner': ['apprunner'],
|
|
2825
|
+
'appstream': ['appstream'],
|
|
2826
|
+
'appstudio': [],
|
|
2827
|
+
'appsync': ['appsync'],
|
|
2828
|
+
'apptest': [],
|
|
2829
|
+
'aps': ['amp'],
|
|
2830
|
+
'arc-region-switch': ['arc-region-switch'],
|
|
2831
|
+
'artifact': ['artifact'],
|
|
2832
|
+
'athena': ['athena'],
|
|
2833
|
+
'auditmanager': ['auditmanager'],
|
|
2834
|
+
'autoscaling': ['autoscaling'],
|
|
2835
|
+
'aws-marketplace': ['marketplace-agreement', 'marketplace-catalog', 'marketplace-deployment', 'marketplace-entitlement', 'marketplace-reporting', 'meteringmarketplace'],
|
|
2836
|
+
'b2bi': ['b2bi'],
|
|
2837
|
+
'backup': ['backup'],
|
|
2838
|
+
'backup-gateway': ['backup-gateway'],
|
|
2839
|
+
'backup-search': ['backupsearch'],
|
|
2840
|
+
'batch': ['batch'],
|
|
2841
|
+
'bcm-data-exports': ['bcm-data-exports'],
|
|
2842
|
+
'bcm-pricing-calculator': ['bcm-pricing-calculator'],
|
|
2843
|
+
'bedrock': ['bedrock', 'bedrock-agent', 'bedrock-agent-runtime', 'bedrock-data-automation', 'bedrock-data-automation-runtime', 'bedrock-runtime'],
|
|
2844
|
+
'bedrock-agentcore': ['bedrock-agentcore', 'bedrock-agentcore-control'],
|
|
2845
|
+
'bedrock-mantle': [],
|
|
2846
|
+
'billing': ['billing'],
|
|
2847
|
+
'billingconductor': ['billingconductor'],
|
|
2848
|
+
'braket': ['braket'],
|
|
2849
|
+
'budgets': ['budgets'],
|
|
2850
|
+
'bugbust': [],
|
|
2851
|
+
'cases': ['connectcases'],
|
|
2852
|
+
'cassandra': ['keyspaces', 'keyspacesstreams'],
|
|
2853
|
+
'catalog': ['servicecatalog'],
|
|
2854
|
+
'ce': ['ce'],
|
|
2855
|
+
'chatbot': ['chatbot'],
|
|
2856
|
+
'chime': ['chime', 'chime-sdk-identity', 'chime-sdk-media-pipelines', 'chime-sdk-meetings', 'chime-sdk-messaging', 'chime-sdk-voice'],
|
|
2857
|
+
'cleanrooms': ['cleanrooms'],
|
|
2858
|
+
'cleanrooms-ml': ['cleanroomsml'],
|
|
2859
|
+
'cloud9': ['cloud9'],
|
|
2860
|
+
'clouddirectory': ['clouddirectory'],
|
|
2861
|
+
'cloudformation': ['cloudformation'],
|
|
2862
|
+
'cloudfront': ['cloudfront'],
|
|
2863
|
+
'cloudhsm': ['cloudhsm', 'cloudhsmv2'],
|
|
2864
|
+
'cloudsearch': ['cloudsearch', 'cloudsearchdomain'],
|
|
2865
|
+
'cloudshell': [],
|
|
2866
|
+
'cloudtrail': ['cloudtrail'],
|
|
2867
|
+
'cloudwatch': ['cloudwatch'],
|
|
2868
|
+
'codeartifact': ['codeartifact'],
|
|
2869
|
+
'codebuild': ['codebuild'],
|
|
2870
|
+
'codecatalyst': ['codecatalyst'],
|
|
2871
|
+
'codecommit': ['codecommit'],
|
|
2872
|
+
'codeconnections': ['codeconnections'],
|
|
2873
|
+
'codedeploy': ['codedeploy'],
|
|
2874
|
+
'codeguru-profiler': ['codeguruprofiler'],
|
|
2875
|
+
'codeguru-reviewer': ['codeguru-reviewer'],
|
|
2876
|
+
'codeguru-security': ['codeguru-security'],
|
|
2877
|
+
'codepipeline': ['codepipeline'],
|
|
2878
|
+
'codestar': [],
|
|
2879
|
+
'codestar-connections': ['codestar-connections'],
|
|
2880
|
+
'codestar-notifications': ['codestar-notifications'],
|
|
2881
|
+
'codewhisperer': [],
|
|
2882
|
+
'cognito-identity': ['cognito-identity'],
|
|
2883
|
+
'cognito-idp': ['cognito-idp'],
|
|
2884
|
+
'cognito-sync': ['cognito-sync'],
|
|
2885
|
+
'comprehend': ['comprehend'],
|
|
2886
|
+
'compute-optimizer': ['compute-optimizer'],
|
|
2887
|
+
'config': ['config'],
|
|
2888
|
+
'connect': ['connect', 'connect-contact-lens'],
|
|
2889
|
+
'connect-campaigns': ['connectcampaigns', 'connectcampaignsv2'],
|
|
2890
|
+
'consoleapp': [],
|
|
2891
|
+
'controlcatalog': ['controlcatalog'],
|
|
2892
|
+
'controltower': ['controltower'],
|
|
2893
|
+
'cur': ['cur'],
|
|
2894
|
+
'databrew': ['databrew'],
|
|
2895
|
+
'dataexchange': ['dataexchange'],
|
|
2896
|
+
'datapipeline': ['datapipeline'],
|
|
2897
|
+
'datasync': ['datasync'],
|
|
2898
|
+
'datazone': ['datazone'],
|
|
2899
|
+
'dax': ['dax'],
|
|
2900
|
+
'deadline': ['deadline'],
|
|
2901
|
+
'detective': ['detective'],
|
|
2902
|
+
'devicefarm': ['devicefarm'],
|
|
2903
|
+
'directconnect': ['directconnect'],
|
|
2904
|
+
'dlm': ['dlm'],
|
|
2905
|
+
'dms': ['dms'],
|
|
2906
|
+
'docdb-elastic': ['docdb-elastic'],
|
|
2907
|
+
'drs': ['drs'],
|
|
2908
|
+
'ds': ['ds'],
|
|
2909
|
+
'dsql': ['dsql'],
|
|
2910
|
+
'dynamodb': ['dynamodb', 'dynamodbstreams'],
|
|
2911
|
+
'ec2': ['ec2'],
|
|
2912
|
+
'ecr': ['ecr'],
|
|
2913
|
+
'ecr-public': ['ecr-public'],
|
|
2914
|
+
'ecs': ['ecs'],
|
|
2915
|
+
'eks': ['eks'],
|
|
2916
|
+
'elastic-inference': [],
|
|
2917
|
+
'elasticache': ['elasticache'],
|
|
2918
|
+
'elasticbeanstalk': ['elasticbeanstalk'],
|
|
2919
|
+
'elasticfilesystem': ['efs'],
|
|
2920
|
+
'elasticloadbalancing': ['elb', 'elbv2'],
|
|
2921
|
+
'elasticmapreduce': ['emr'],
|
|
2922
|
+
'elastictranscoder': [],
|
|
2923
|
+
'elemental-appliances-software': [],
|
|
2924
|
+
'elemental-support-cases': [],
|
|
2925
|
+
'emr-containers': ['emr-containers'],
|
|
2926
|
+
'emr-serverless': ['emr-serverless'],
|
|
2927
|
+
'entityresolution': ['entityresolution'],
|
|
2928
|
+
'es': ['es', 'opensearch'],
|
|
2929
|
+
'events': ['events'],
|
|
2930
|
+
'evidently': ['evidently'],
|
|
2931
|
+
'evs': ['evs'],
|
|
2932
|
+
'execute-api': ['apigatewaymanagementapi', 'connectparticipant'],
|
|
2933
|
+
'finspace': ['finspace'],
|
|
2934
|
+
'finspace-api': ['finspace-data'],
|
|
2935
|
+
'firehose': ['firehose'],
|
|
2936
|
+
'fis': ['fis'],
|
|
2937
|
+
'fms': ['fms'],
|
|
2938
|
+
'forecast': ['forecast', 'forecastquery'],
|
|
2939
|
+
'frauddetector': ['frauddetector'],
|
|
2940
|
+
'freertos': [],
|
|
2941
|
+
'fsx': ['fsx'],
|
|
2942
|
+
'gamelift': ['gamelift'],
|
|
2943
|
+
'gameliftstreams': ['gameliftstreams'],
|
|
2944
|
+
'geo': ['location'],
|
|
2945
|
+
'geo-maps': ['geo-maps'],
|
|
2946
|
+
'geo-places': ['geo-places'],
|
|
2947
|
+
'geo-routes': ['geo-routes'],
|
|
2948
|
+
'glacier': ['glacier'],
|
|
2949
|
+
'globalaccelerator': ['globalaccelerator'],
|
|
2950
|
+
'glue': ['glue'],
|
|
2951
|
+
'grafana': ['grafana'],
|
|
2952
|
+
'greengrass': ['greengrass', 'greengrassv2'],
|
|
2953
|
+
'groundstation': ['groundstation'],
|
|
2954
|
+
'guardduty': ['guardduty'],
|
|
2955
|
+
'health': ['health'],
|
|
2956
|
+
'healthlake': ['healthlake'],
|
|
2957
|
+
'honeycode': [],
|
|
2958
|
+
'iam': ['iam'],
|
|
2959
|
+
'identity-sync': [],
|
|
2960
|
+
'identitystore': ['identitystore'],
|
|
2961
|
+
'imagebuilder': ['imagebuilder'],
|
|
2962
|
+
'inspector': ['inspector'],
|
|
2963
|
+
'inspector2': ['inspector2'],
|
|
2964
|
+
'internetmonitor': ['internetmonitor'],
|
|
2965
|
+
'invoicing': ['invoicing'],
|
|
2966
|
+
'iot': ['iot'],
|
|
2967
|
+
'iotanalytics': ['iotanalytics'],
|
|
2968
|
+
'iotdeviceadvisor': ['iotdeviceadvisor'],
|
|
2969
|
+
'iotevents': ['iotevents'],
|
|
2970
|
+
'iotfleethub': [],
|
|
2971
|
+
'iotfleetwise': ['iotfleetwise'],
|
|
2972
|
+
'iotmanagedintegrations': ['iot-managed-integrations'],
|
|
2973
|
+
'iotsitewise': ['iotsitewise'],
|
|
2974
|
+
'iottwinmaker': ['iottwinmaker'],
|
|
2975
|
+
'iotwireless': ['iotwireless'],
|
|
2976
|
+
'iq': [],
|
|
2977
|
+
'iq-permission': [],
|
|
2978
|
+
'ivs': ['ivs', 'ivs-realtime'],
|
|
2979
|
+
'ivschat': ['ivschat'],
|
|
2980
|
+
'kafka': ['kafka'],
|
|
2981
|
+
'kafkaconnect': ['kafkaconnect'],
|
|
2982
|
+
'kendra': ['kendra'],
|
|
2983
|
+
'kendra-ranking': ['kendra-ranking'],
|
|
2984
|
+
'kinesis': ['kinesis'],
|
|
2985
|
+
'kinesisanalytics': ['kinesisanalytics', 'kinesisanalyticsv2'],
|
|
2986
|
+
'kinesisvideo': ['kinesisvideo', 'kinesis-video-archived-media', 'kinesis-video-media', 'kinesis-video-signaling', 'kinesis-video-webrtc-storage'],
|
|
2987
|
+
'kms': ['kms'],
|
|
2988
|
+
'lambda': ['lambda'],
|
|
2989
|
+
'launchwizard': ['launch-wizard'],
|
|
2990
|
+
'lex': ['lex-models', 'lex-runtime', 'lexv2-models', 'lexv2-runtime'],
|
|
2991
|
+
'license-manager': ['license-manager'],
|
|
2992
|
+
'license-manager-linux-subscriptions': ['license-manager-linux-subscriptions'],
|
|
2993
|
+
'license-manager-user-subscriptions': ['license-manager-user-subscriptions'],
|
|
2994
|
+
'lightsail': ['lightsail'],
|
|
2995
|
+
'logs': ['logs'],
|
|
2996
|
+
'lookoutequipment': ['lookoutequipment'],
|
|
2997
|
+
'lookoutmetrics': [],
|
|
2998
|
+
'lookoutvision': [],
|
|
2999
|
+
'm2': ['m2'],
|
|
3000
|
+
'machinelearning': ['machinelearning'],
|
|
3001
|
+
'macie2': ['macie2'],
|
|
3002
|
+
'managedblockchain': ['managedblockchain'],
|
|
3003
|
+
'mapcredits': [],
|
|
3004
|
+
'mediaconnect': ['mediaconnect'],
|
|
3005
|
+
'mediaconvert': ['mediaconvert'],
|
|
3006
|
+
'medialive': ['medialive'],
|
|
3007
|
+
'mediapackage': ['mediapackage'],
|
|
3008
|
+
'mediapackage-vod': ['mediapackage-vod'],
|
|
3009
|
+
'mediapackagev2': ['mediapackagev2'],
|
|
3010
|
+
'mediastore': ['mediastore', 'mediastore-data'],
|
|
3011
|
+
'mediatailor': ['mediatailor'],
|
|
3012
|
+
'medical-imaging': ['medical-imaging'],
|
|
3013
|
+
'memorydb': ['memorydb'],
|
|
3014
|
+
'mgh': ['mgh', 'migrationhub-config'],
|
|
3015
|
+
'mgn': ['mgn'],
|
|
3016
|
+
'migrationhub-orchestrator': ['migrationhuborchestrator'],
|
|
3017
|
+
'mobiletargeting': ['pinpoint'],
|
|
3018
|
+
'monitron': [],
|
|
3019
|
+
'mpa': ['mpa'],
|
|
3020
|
+
'mq': ['mq'],
|
|
3021
|
+
'neptune-db': ['neptunedata'],
|
|
3022
|
+
'neptune-graph': ['neptune-graph'],
|
|
3023
|
+
'network-firewall': ['network-firewall'],
|
|
3024
|
+
'networkflowmonitor': ['networkflowmonitor'],
|
|
3025
|
+
'networkmanager': ['networkmanager'],
|
|
3026
|
+
'networkmonitor': ['networkmonitor'],
|
|
3027
|
+
'nimble': [],
|
|
3028
|
+
'notifications': ['notifications'],
|
|
3029
|
+
'notifications-contacts': ['notificationscontacts'],
|
|
3030
|
+
'nova-act': ['nova-act'],
|
|
3031
|
+
'oam': ['oam'],
|
|
3032
|
+
'observabilityadmin': ['observabilityadmin'],
|
|
3033
|
+
'odb': ['odb'],
|
|
3034
|
+
'omics': ['omics'],
|
|
3035
|
+
'one': [],
|
|
3036
|
+
'opensearch': ['opensearch'],
|
|
3037
|
+
'opsworks': [],
|
|
3038
|
+
'opsworks-cm': [],
|
|
3039
|
+
'organizations': ['organizations'],
|
|
3040
|
+
'osis': ['osis'],
|
|
3041
|
+
'outposts': ['outposts'],
|
|
3042
|
+
'panorama': ['panorama'],
|
|
3043
|
+
'partnercentral': ['partnercentral-account', 'partnercentral-benefits', 'partnercentral-channel', 'partnercentral-selling'],
|
|
3044
|
+
'payment-cryptography': ['payment-cryptography', 'payment-cryptography-data'],
|
|
3045
|
+
'payments': [],
|
|
3046
|
+
'pca-connector-ad': ['pca-connector-ad'],
|
|
3047
|
+
'pca-connector-scep': ['pca-connector-scep'],
|
|
3048
|
+
'pcs': ['pcs'],
|
|
3049
|
+
'personalize': ['personalize', 'personalize-events', 'personalize-runtime'],
|
|
3050
|
+
'pi': ['pi'],
|
|
3051
|
+
'pipes': ['pipes'],
|
|
3052
|
+
'polly': ['polly'],
|
|
3053
|
+
'pricingplanmanager': [],
|
|
3054
|
+
'private-networks': ['privatenetworks'],
|
|
3055
|
+
'profile': ['customer-profiles'],
|
|
3056
|
+
'proton': ['proton'],
|
|
3057
|
+
'purchase-orders': [],
|
|
3058
|
+
'qapps': ['qapps'],
|
|
3059
|
+
'qbusiness': ['qbusiness'],
|
|
3060
|
+
'qdeveloper': [],
|
|
3061
|
+
'qldb': [],
|
|
3062
|
+
'quicksight': ['quicksight'],
|
|
3063
|
+
'ram': ['ram'],
|
|
3064
|
+
'rbin': ['rbin'],
|
|
3065
|
+
'rds': ['rds', 'docdb', 'neptune'],
|
|
3066
|
+
'rds-db': ['rds'],
|
|
3067
|
+
'redshift': ['redshift'],
|
|
3068
|
+
'redshift-serverless': ['redshift-serverless'],
|
|
3069
|
+
'refactor-spaces': ['migration-hub-refactor-spaces'],
|
|
3070
|
+
'rekognition': ['rekognition'],
|
|
3071
|
+
'repostspace': ['repostspace'],
|
|
3072
|
+
'resiliencehub': ['resiliencehub'],
|
|
3073
|
+
'resource-explorer-2': ['resource-explorer-2'],
|
|
3074
|
+
'resource-groups': ['resource-groups'],
|
|
3075
|
+
'robomaker': [],
|
|
3076
|
+
'rolesanywhere': ['rolesanywhere'],
|
|
3077
|
+
'route53': ['route53'],
|
|
3078
|
+
'route53-recovery-control': ['route53-recovery-cluster', 'route53-recovery-control-config'],
|
|
3079
|
+
'route53-recovery-readiness': ['route53-recovery-readiness'],
|
|
3080
|
+
'route53globalresolver': ['route53globalresolver'],
|
|
3081
|
+
'route53profiles': ['route53profiles'],
|
|
3082
|
+
'route53resolver': ['route53resolver'],
|
|
3083
|
+
'rum': ['rum'],
|
|
3084
|
+
's3': ['s3', 's3control'],
|
|
3085
|
+
's3-object-lambda': ['s3'],
|
|
3086
|
+
's3-outposts': ['s3outposts'],
|
|
3087
|
+
's3express': ['s3'],
|
|
3088
|
+
's3tables': ['s3tables'],
|
|
3089
|
+
's3vectors': ['s3vectors'],
|
|
3090
|
+
'sagemaker': ['sagemaker', 'sagemaker-a2i-runtime', 'sagemaker-edge', 'sagemaker-featurestore-runtime', 'sagemaker-metrics', 'sagemaker-runtime'],
|
|
3091
|
+
'sagemaker-geospatial': ['sagemaker-geospatial'],
|
|
3092
|
+
'savingsplans': ['savingsplans'],
|
|
3093
|
+
'scheduler': ['scheduler'],
|
|
3094
|
+
'schemas': ['schemas'],
|
|
3095
|
+
'scn': ['supplychain'],
|
|
3096
|
+
'sdb': ['sdb'],
|
|
3097
|
+
'secretsmanager': ['secretsmanager'],
|
|
3098
|
+
'security-ir': ['security-ir'],
|
|
3099
|
+
'securityagent': [],
|
|
3100
|
+
'securityhub': ['securityhub'],
|
|
3101
|
+
'securitylake': ['securitylake'],
|
|
3102
|
+
'serverlessrepo': ['serverlessrepo'],
|
|
3103
|
+
'servicecatalog': ['servicecatalog', 'servicecatalog-appregistry'],
|
|
3104
|
+
'servicediscovery': ['servicediscovery'],
|
|
3105
|
+
'servicequotas': ['service-quotas'],
|
|
3106
|
+
'ses': ['ses', 'mailmanager', 'pinpoint-email', 'sesv2'],
|
|
3107
|
+
'shield': ['shield'],
|
|
3108
|
+
'signer': ['signer'],
|
|
3109
|
+
'simspaceweaver': ['simspaceweaver'],
|
|
3110
|
+
'sms-voice': ['sms-voice', 'pinpoint-sms-voice', 'pinpoint-sms-voice-v2'],
|
|
3111
|
+
'snow-device-management': ['snow-device-management'],
|
|
3112
|
+
'sns': ['sns'],
|
|
3113
|
+
'social-messaging': ['socialmessaging'],
|
|
3114
|
+
'sqlworkbench': [],
|
|
3115
|
+
'sqs': ['sqs'],
|
|
3116
|
+
'ssm': ['ssm'],
|
|
3117
|
+
'ssm-contacts': ['ssm-contacts'],
|
|
3118
|
+
'ssm-incidents': ['ssm-incidents'],
|
|
3119
|
+
'ssm-quicksetup': ['ssm-quicksetup'],
|
|
3120
|
+
'ssm-sap': ['ssm-sap'],
|
|
3121
|
+
'sso': ['sso', 'sso-admin'],
|
|
3122
|
+
'states': ['stepfunctions'],
|
|
3123
|
+
'storagegateway': ['storagegateway'],
|
|
3124
|
+
'sts': ['sts'],
|
|
3125
|
+
'swf': ['swf'],
|
|
3126
|
+
'synthetics': ['synthetics'],
|
|
3127
|
+
'textract': ['textract'],
|
|
3128
|
+
'thinclient': ['workspaces-thin-client'],
|
|
3129
|
+
'timestream': ['timestream-query', 'timestream-write'],
|
|
3130
|
+
'timestream-influxdb': ['timestream-influxdb'],
|
|
3131
|
+
'tnb': ['tnb'],
|
|
3132
|
+
'transcribe': ['transcribe'],
|
|
3133
|
+
'transfer': ['transfer'],
|
|
3134
|
+
'transform': [],
|
|
3135
|
+
'transform-custom': [],
|
|
3136
|
+
'translate': ['translate'],
|
|
3137
|
+
'trustedadvisor': ['trustedadvisor'],
|
|
3138
|
+
'ts': [],
|
|
3139
|
+
'vendor-insights': [],
|
|
3140
|
+
'verifiedpermissions': ['verifiedpermissions'],
|
|
3141
|
+
'voiceid': ['voice-id'],
|
|
3142
|
+
'vpc-lattice': ['vpc-lattice'],
|
|
3143
|
+
'waf': ['waf'],
|
|
3144
|
+
'waf-regional': ['waf-regional'],
|
|
3145
|
+
'wafv2': ['wafv2'],
|
|
3146
|
+
'wellarchitected': ['wellarchitected'],
|
|
3147
|
+
'wickr': ['wickr'],
|
|
3148
|
+
'wisdom': ['wisdom', 'qconnect'],
|
|
3149
|
+
'workdocs': ['workdocs'],
|
|
3150
|
+
'worklink': [],
|
|
3151
|
+
'workmail': ['workmail'],
|
|
3152
|
+
'workmailmessageflow': ['workmailmessageflow'],
|
|
3153
|
+
'workspaces': ['workspaces'],
|
|
3154
|
+
'workspaces-instances': ['workspaces-instances'],
|
|
3155
|
+
'workspaces-web': ['workspaces-web'],
|
|
3156
|
+
'xray': ['xray'],
|
|
3157
|
+
}
|
|
@@ -9,6 +9,7 @@ def test_acm():
|
|
|
9
9
|
)
|
|
10
10
|
assert result.resource_type == "certificate"
|
|
11
11
|
assert result.attributes["CertificateId"] == "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
|
|
12
|
+
assert result.aws_sdk_services == ["acm"]
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
def test_apigateway():
|
|
@@ -68,6 +69,8 @@ def test_cloudwatch():
|
|
|
68
69
|
result.attributes["AlarmName"]
|
|
69
70
|
== "CPU Utilization - High Warning - service-production-1"
|
|
70
71
|
)
|
|
72
|
+
# cloudwatch is a manual override (endpointPrefix is 'monitoring')
|
|
73
|
+
assert result.aws_sdk_services == ["cloudwatch"]
|
|
71
74
|
|
|
72
75
|
|
|
73
76
|
def test_codebuild():
|
|
@@ -212,6 +215,8 @@ def test_elasticfilesystem():
|
|
|
212
215
|
)
|
|
213
216
|
assert result.resource_type == "file-system"
|
|
214
217
|
assert result.attributes["FileSystemId"] == "fs-01234567"
|
|
218
|
+
# elasticfilesystem maps to efs via metadata
|
|
219
|
+
assert result.aws_sdk_services == ["efs"]
|
|
215
220
|
|
|
216
221
|
|
|
217
222
|
def test_elasticloadbalancing():
|
|
@@ -245,6 +250,8 @@ def test_elasticloadbalancing():
|
|
|
245
250
|
assert result.resource_type == "targetgroup"
|
|
246
251
|
assert result.attributes["TargetGroupName"] == "target-grp-1"
|
|
247
252
|
assert result.attributes["TargetGroupId"] == "0123456789abcdef"
|
|
253
|
+
# elasticloadbalancing maps to multiple SDK clients
|
|
254
|
+
assert result.aws_sdk_services == ["elb", "elbv2"]
|
|
248
255
|
|
|
249
256
|
|
|
250
257
|
def test_es():
|
|
@@ -307,6 +314,7 @@ def test_lambda():
|
|
|
307
314
|
)
|
|
308
315
|
assert result.resource_type == "function"
|
|
309
316
|
assert result.attributes["FunctionName"] == "ProcessDataHandler"
|
|
317
|
+
assert result.aws_sdk_services == ["lambda"]
|
|
310
318
|
|
|
311
319
|
|
|
312
320
|
def test_logs():
|
|
@@ -339,6 +347,8 @@ def test_rds():
|
|
|
339
347
|
)
|
|
340
348
|
assert result.resource_type == "snapshot"
|
|
341
349
|
assert result.attributes["SnapshotName"] == "final-database-backup-01234567"
|
|
350
|
+
# rds maps to multiple SDK clients (rds, docdb, neptune share ARN format)
|
|
351
|
+
assert result.aws_sdk_services == ["rds", "docdb", "neptune"]
|
|
342
352
|
|
|
343
353
|
|
|
344
354
|
def test_route53():
|
|
@@ -357,6 +367,7 @@ def test_s3():
|
|
|
357
367
|
result = arnmatch("arn:aws:s3:::example-bucket-01")
|
|
358
368
|
assert result.resource_type == "bucket"
|
|
359
369
|
assert result.attributes["BucketName"] == "example-bucket-01"
|
|
370
|
+
assert result.aws_sdk_services == ["s3", "s3control"]
|
|
360
371
|
|
|
361
372
|
|
|
362
373
|
def test_secretsmanager():
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|