@dataparade/cli 0.0.3 → 0.0.5
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.
- package/README.md +24 -0
- package/dist/package.json +85 -0
- package/dist/src/ai-enrichment/agent-orchestrator.d.ts +2 -0
- package/dist/src/ai-enrichment/agent-orchestrator.js +8 -5
- package/dist/src/ai-enrichment/providers/hosted-worker-infer-provider.d.ts +10 -0
- package/dist/src/ai-enrichment/providers/hosted-worker-infer-provider.js +47 -0
- package/dist/src/cli.js +88 -1
- package/dist/src/config/env.js +2 -0
- package/dist/src/config/resolve.js +3 -0
- package/dist/src/config/scan-env.d.ts +1 -0
- package/dist/src/config/scan-env.js +5 -0
- package/dist/src/config/types.d.ts +1 -0
- package/dist/src/config/upload-env.d.ts +1 -0
- package/dist/src/config/upload-env.js +10 -0
- package/dist/src/config/validate-scan-ai.d.ts +1 -1
- package/dist/src/config/validate-scan-ai.js +5 -0
- package/dist/src/core/pipeline/ai-orchestrator-options.js +5 -0
- package/dist/src/core/schema/scan-config.schema.d.ts +2 -0
- package/dist/src/core/schema/scan-config.schema.js +2 -1
- package/dist/src/core/types/config.d.ts +3 -1
- package/dist/src/observability/scan-sentry.d.ts +1 -1
- package/dist/src/output/json.d.ts +4 -0
- package/dist/src/output/json.js +7 -2
- package/dist/src/platform-api/dataparade-app-base-url.d.ts +7 -0
- package/dist/src/platform-api/dataparade-app-base-url.js +14 -0
- package/dist/src/platform-api/upload-client.d.ts +3 -0
- package/dist/src/platform-api/upload-client.js +38 -0
- package/dist/src/platform-api/upload.types.d.ts +10 -0
- package/dist/src/platform-api/upload.types.js +2 -0
- package/dist/src/upload/build-preview-url.d.ts +1 -0
- package/dist/src/upload/build-preview-url.js +10 -0
- package/dist/src/upload/run-upload.d.ts +2 -0
- package/dist/src/upload/run-upload.js +18 -0
- package/dist/src/upload/types.d.ts +11 -0
- package/dist/src/upload/types.js +2 -0
- package/dist/tests/unit/cli/scan-quota-flow.spec.js +2 -0
- package/dist/tests/unit/config/upload-env.spec.d.ts +1 -0
- package/dist/tests/unit/config/upload-env.spec.js +12 -0
- package/dist/tests/unit/config/validate-scan-ai.spec.js +8 -0
- package/dist/tests/unit/core/output-json.spec.js +4 -1
- package/dist/tests/unit/platform-api/dataparade-app-base-url.spec.d.ts +1 -0
- package/dist/tests/unit/platform-api/dataparade-app-base-url.spec.js +13 -0
- package/dist/tests/unit/platform-api/upload-client.spec.d.ts +1 -0
- package/dist/tests/unit/platform-api/upload-client.spec.js +40 -0
- package/dist/tests/unit/publish-manifest.spec.d.ts +1 -0
- package/dist/tests/unit/publish-manifest.spec.js +18 -0
- package/dist/tests/unit/upload/build-preview-url.spec.d.ts +1 -0
- package/dist/tests/unit/upload/build-preview-url.spec.js +19 -0
- package/package.json +4 -3
- package/patterns/README.md +322 -0
- package/patterns/actor.patterns.yaml +51 -0
- package/patterns/aws-terraform-catalog.snapshot.json +1760 -0
- package/patterns/aws-terraform-service-hints.generated.json +1446 -0
- package/patterns/azure-terraform-catalog.snapshot.json +1195 -0
- package/patterns/azure-terraform-service-hints.generated.json +864 -0
- package/patterns/classifier/actors.classifier.yaml +17 -0
- package/patterns/classifier/components.classifier.yaml +110 -0
- package/patterns/classifier/third-party.classifier.yaml +169 -0
- package/patterns/kubernetes-terraform-catalog.snapshot.json +94 -0
- package/patterns/kubernetes-terraform-service-hints.generated.json +258 -0
- package/patterns/non-pii-signals.rules.yaml +84 -0
- package/patterns/pii-signals.rules.yaml +115 -0
- package/patterns/property.patterns.yaml +431 -0
- package/patterns/provider-topology.rules.yaml +765 -0
- package/patterns/python.md +211 -0
- package/patterns/python.patterns.yaml +160 -0
- package/patterns/terraform.md +37 -0
- package/patterns/terraform.patterns.yaml +495 -0
- package/patterns/third-party.patterns.yaml +167 -0
- package/patterns/typescript.patterns.yaml +139 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Python Patterns (CLI Scanner)
|
|
2
|
+
|
|
3
|
+
This document describes the Python-specific patterns implemented by the CLI codebase scanner for **DP-P0-CLI-703 – Python pattern detector**.
|
|
4
|
+
|
|
5
|
+
The Python analyzer emits `RawFinding[]` using the **shared pattern IDs** from `core/types/detection.ts`:
|
|
6
|
+
|
|
7
|
+
- `express_route`
|
|
8
|
+
- `database_connection`
|
|
9
|
+
- `external_api_call`
|
|
10
|
+
- `auth_middleware`
|
|
11
|
+
- `config_file`
|
|
12
|
+
- `env_variable`
|
|
13
|
+
|
|
14
|
+
These pattern IDs align with the TypeScript/JavaScript analyzer so that the classifier and data-flow detector can treat Python and TS/JS findings consistently.
|
|
15
|
+
|
|
16
|
+
## Route / Handler Detection (`express_route`)
|
|
17
|
+
|
|
18
|
+
The Python analyzer reuses the `express_route` pattern ID for web routes and handlers in common Python web frameworks.
|
|
19
|
+
|
|
20
|
+
### FastAPI
|
|
21
|
+
|
|
22
|
+
- **Detected when:**
|
|
23
|
+
- The module imports `FastAPI` or any symbol from `fastapi`.
|
|
24
|
+
- A function has a decorator starting with `app.get`, `app.post`, `app.put`, `app.delete`, or `app.patch`.
|
|
25
|
+
- **Emitted finding:**
|
|
26
|
+
- `pattern`: `express_route`
|
|
27
|
+
- `name`: `"<METHOD> <function_name>"` (e.g. `GET read_item`)
|
|
28
|
+
- `properties`:
|
|
29
|
+
- `framework`: `"fastapi"`
|
|
30
|
+
- `httpMethods`: `[ "<METHOD>" ]`
|
|
31
|
+
|
|
32
|
+
**Example:**
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from fastapi import FastAPI
|
|
36
|
+
|
|
37
|
+
app = FastAPI()
|
|
38
|
+
|
|
39
|
+
@app.get("/items/{item_id}")
|
|
40
|
+
async def read_item(item_id: int):
|
|
41
|
+
...
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Flask
|
|
45
|
+
|
|
46
|
+
- **Detected when:**
|
|
47
|
+
- The module imports from `flask` or imports `Flask`.
|
|
48
|
+
- A function has a decorator starting with `app.route`, `bp.route`, or `blueprint.route`.
|
|
49
|
+
- **Emitted finding:**
|
|
50
|
+
- `pattern`: `express_route`
|
|
51
|
+
- `name`: `"FLASK_ROUTE <function_name>"`
|
|
52
|
+
- `properties`:
|
|
53
|
+
- `framework`: `"flask"`
|
|
54
|
+
|
|
55
|
+
**Example:**
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from flask import Flask
|
|
59
|
+
|
|
60
|
+
app = Flask(__name__)
|
|
61
|
+
|
|
62
|
+
@app.route("/users", methods=["GET"])
|
|
63
|
+
def list_users():
|
|
64
|
+
...
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Django / Django REST Framework
|
|
68
|
+
|
|
69
|
+
- **Detected when:**
|
|
70
|
+
- The file path ends with `urls.py` or imports start with `django.`.
|
|
71
|
+
- A line contains `path("...")`, `re_path("...")`, or `url("...")`.
|
|
72
|
+
- **Emitted finding:**
|
|
73
|
+
- `pattern`: `express_route`
|
|
74
|
+
- `name`: `"DJANGO_ROUTE <path>"`
|
|
75
|
+
- `properties`:
|
|
76
|
+
- `framework`: `"django"`
|
|
77
|
+
- `path`: `"<route_path>"`
|
|
78
|
+
|
|
79
|
+
**Example (`urls.py`):**
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from django.urls import path
|
|
83
|
+
from . import views
|
|
84
|
+
|
|
85
|
+
urlpatterns = [
|
|
86
|
+
path("users/", views.user_list, name="user-list"),
|
|
87
|
+
]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Starlette
|
|
91
|
+
|
|
92
|
+
- **Detected when:**
|
|
93
|
+
- The module imports Starlette (module name contains `"starlette"`).
|
|
94
|
+
- A function has a decorator starting with `app.route`.
|
|
95
|
+
- **Emitted finding:**
|
|
96
|
+
- `pattern`: `express_route`
|
|
97
|
+
- `name`: `"STARLETTE_ROUTE <function_name>"`
|
|
98
|
+
- `properties`:
|
|
99
|
+
- `framework`: `"starlette"`
|
|
100
|
+
|
|
101
|
+
### Bottle
|
|
102
|
+
|
|
103
|
+
- **Detected when:**
|
|
104
|
+
- The module imports from `bottle` or imports `Bottle`.
|
|
105
|
+
- A function has decorators `@route`, `@get`, `@post`, `@put`, or `@delete`.
|
|
106
|
+
- **Emitted finding:**
|
|
107
|
+
- `pattern`: `express_route`
|
|
108
|
+
- `name`: `"BOTTLE_ROUTE <function_name>"`
|
|
109
|
+
- `properties`:
|
|
110
|
+
- `framework`: `"bottle"`
|
|
111
|
+
|
|
112
|
+
## Database / ORM Detection (`database_connection`)
|
|
113
|
+
|
|
114
|
+
The Python analyzer emits `database_connection` for database clients and ORM usage.
|
|
115
|
+
|
|
116
|
+
### psycopg2
|
|
117
|
+
|
|
118
|
+
- **Detected when:**
|
|
119
|
+
- The module imports from `psycopg2` / `psycopg`.
|
|
120
|
+
- A module-level call contains `connect` (e.g. `psycopg2.connect(...)`).
|
|
121
|
+
- **Properties:**
|
|
122
|
+
- `client`: `"psycopg2"`
|
|
123
|
+
- `databaseType`: `"postgres"`
|
|
124
|
+
|
|
125
|
+
### SQLAlchemy
|
|
126
|
+
|
|
127
|
+
- **Detected when:**
|
|
128
|
+
- The module imports from `sqlalchemy` or imports `create_engine`.
|
|
129
|
+
- A module-level call contains `create_engine`.
|
|
130
|
+
- **Properties:**
|
|
131
|
+
- `client`: `"sqlalchemy"`
|
|
132
|
+
- `databaseType`: `"sql"`
|
|
133
|
+
|
|
134
|
+
### Django ORM
|
|
135
|
+
|
|
136
|
+
- **Detected when:**
|
|
137
|
+
- The module imports from `django.db` or the content includes `.objects.`.
|
|
138
|
+
- **Properties:**
|
|
139
|
+
- `client`: `"django_orm"`
|
|
140
|
+
- `databaseType`: `"sql"`
|
|
141
|
+
|
|
142
|
+
## External HTTP / API Calls (`external_api_call`)
|
|
143
|
+
|
|
144
|
+
The Python analyzer emits `external_api_call` for HTTP clients and SDKs.
|
|
145
|
+
|
|
146
|
+
### HTTP client libraries
|
|
147
|
+
|
|
148
|
+
- **requests**
|
|
149
|
+
- Detected when the module imports `requests` and a module-level call starts with `requests.`.
|
|
150
|
+
- `name`: `"requests_call"`
|
|
151
|
+
- `properties.url`: first `http(s)` URL literal found in the file, if any.
|
|
152
|
+
|
|
153
|
+
- **httpx**
|
|
154
|
+
- Detected when the module imports `httpx` and a module-level call starts with `httpx.`.
|
|
155
|
+
- `name`: `"httpx_call"`
|
|
156
|
+
|
|
157
|
+
- **aiohttp**
|
|
158
|
+
- Detected when the module imports `aiohttp` or `ClientSession` and a module-level call references `ClientSession` or `.get`.
|
|
159
|
+
- `name`: `"aiohttp_call"`
|
|
160
|
+
|
|
161
|
+
### SDKs
|
|
162
|
+
|
|
163
|
+
The analyzer also emits `external_api_call` findings when the module imports:
|
|
164
|
+
|
|
165
|
+
- `boto3` → `name`: `"boto3_client"`, `serviceName`: `"aws"`
|
|
166
|
+
- `stripe` → `name`: `"stripe_sdk"`, `serviceName`: `"stripe"`
|
|
167
|
+
- `sendgrid` → `name`: `"sendgrid_sdk"`, `serviceName`: `"sendgrid"`
|
|
168
|
+
- `twilio` → `name`: `"twilio_sdk"`, `serviceName`: `"twilio"`
|
|
169
|
+
- `openai` → `name`: `"openai_sdk"`, `serviceName`: `"openai"`
|
|
170
|
+
|
|
171
|
+
## Auth Patterns (`auth_middleware`)
|
|
172
|
+
|
|
173
|
+
The Python analyzer emits `auth_middleware` findings for common auth patterns.
|
|
174
|
+
|
|
175
|
+
- **JWT-based auth**
|
|
176
|
+
- Detected when:
|
|
177
|
+
- The module imports a module containing `"jwt"`, imports `jwt`, or
|
|
178
|
+
- The content includes `jwt.encode(` or `jwt.decode(`.
|
|
179
|
+
- `name`: `"jwt_auth"`
|
|
180
|
+
- `properties.strategy`: `"jwt"`
|
|
181
|
+
|
|
182
|
+
- **Auth decorators / permissions**
|
|
183
|
+
- Detected when module-level calls reference `login_required` or `IsAuthenticated`.
|
|
184
|
+
- `name`: `"auth_decorator"`
|
|
185
|
+
|
|
186
|
+
- **Generic auth libraries**
|
|
187
|
+
- Detected when imports contain `"auth"` or `"authentication"`.
|
|
188
|
+
- `name`: `"auth_library"`
|
|
189
|
+
|
|
190
|
+
## Config and Environment (`config_file`, `env_variable`)
|
|
191
|
+
|
|
192
|
+
### Environment variables (`env_variable`)
|
|
193
|
+
|
|
194
|
+
- **Detected when:**
|
|
195
|
+
- The module imports `os`, and lines reference:
|
|
196
|
+
- `os.environ["KEY"]` or `os.environ['KEY']`
|
|
197
|
+
- `os.getenv("KEY")` or `os.getenv('KEY')`
|
|
198
|
+
- **Emitted finding:**
|
|
199
|
+
- `pattern`: `env_variable`
|
|
200
|
+
- `name`: `"os.environ[KEY]"`
|
|
201
|
+
- `properties.key`: `"KEY"`
|
|
202
|
+
|
|
203
|
+
### Config files (`config_file`)
|
|
204
|
+
|
|
205
|
+
- **Django settings**
|
|
206
|
+
- Detected when the file path ends with `settings.py`.
|
|
207
|
+
- `name`: `"django_settings"`
|
|
208
|
+
|
|
209
|
+
- **dotenv configuration**
|
|
210
|
+
- Detected when the module imports `os` and the content includes `load_dotenv(`.
|
|
211
|
+
- `name`: `"dotenv_config"`
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Python pattern config. All entries share: patternId, optional confidence (default 0.8).
|
|
2
|
+
|
|
3
|
+
db_clients:
|
|
4
|
+
- id: psycopg2
|
|
5
|
+
patternId: database_connection
|
|
6
|
+
databaseType: postgres
|
|
7
|
+
importModules:
|
|
8
|
+
- psycopg2
|
|
9
|
+
- psycopg
|
|
10
|
+
callNames:
|
|
11
|
+
- connect
|
|
12
|
+
confidence: 0.9
|
|
13
|
+
|
|
14
|
+
- id: sqlalchemy
|
|
15
|
+
patternId: database_connection
|
|
16
|
+
databaseType: sql
|
|
17
|
+
importModules:
|
|
18
|
+
- sqlalchemy
|
|
19
|
+
callNames:
|
|
20
|
+
- create_engine
|
|
21
|
+
confidence: 0.9
|
|
22
|
+
|
|
23
|
+
- id: django_orm
|
|
24
|
+
patternId: database_connection
|
|
25
|
+
databaseType: sql
|
|
26
|
+
importModules:
|
|
27
|
+
- django.db
|
|
28
|
+
heuristics:
|
|
29
|
+
usesObjectsAttribute: true
|
|
30
|
+
confidence: 0.85
|
|
31
|
+
|
|
32
|
+
auth:
|
|
33
|
+
jwt:
|
|
34
|
+
patternId: auth_middleware
|
|
35
|
+
importModules:
|
|
36
|
+
- jwt
|
|
37
|
+
contentRegexes:
|
|
38
|
+
- "jwt\\.encode\\("
|
|
39
|
+
- "jwt\\.decode\\("
|
|
40
|
+
strategy: jwt
|
|
41
|
+
confidence: 0.85
|
|
42
|
+
|
|
43
|
+
decorators:
|
|
44
|
+
- id: login_required
|
|
45
|
+
patternId: auth_middleware
|
|
46
|
+
callNames:
|
|
47
|
+
- login_required
|
|
48
|
+
confidence: 0.8
|
|
49
|
+
- id: is_authenticated
|
|
50
|
+
patternId: auth_middleware
|
|
51
|
+
callNames:
|
|
52
|
+
- IsAuthenticated
|
|
53
|
+
confidence: 0.8
|
|
54
|
+
|
|
55
|
+
routes:
|
|
56
|
+
frameworks:
|
|
57
|
+
- id: fastapi
|
|
58
|
+
patternId: express_route
|
|
59
|
+
importModules:
|
|
60
|
+
- fastapi
|
|
61
|
+
decoratorPrefixes:
|
|
62
|
+
- app.get
|
|
63
|
+
- app.post
|
|
64
|
+
- app.put
|
|
65
|
+
- app.delete
|
|
66
|
+
- app.patch
|
|
67
|
+
confidence: 0.9
|
|
68
|
+
|
|
69
|
+
- id: flask
|
|
70
|
+
patternId: express_route
|
|
71
|
+
importModules:
|
|
72
|
+
- flask
|
|
73
|
+
decoratorPrefixes:
|
|
74
|
+
- app.route
|
|
75
|
+
- bp.route
|
|
76
|
+
- blueprint.route
|
|
77
|
+
confidence: 0.9
|
|
78
|
+
|
|
79
|
+
- id: starlette
|
|
80
|
+
patternId: express_route
|
|
81
|
+
importModules:
|
|
82
|
+
- starlette
|
|
83
|
+
decoratorPrefixes:
|
|
84
|
+
- app.route
|
|
85
|
+
confidence: 0.85
|
|
86
|
+
|
|
87
|
+
- id: bottle
|
|
88
|
+
patternId: express_route
|
|
89
|
+
importModules:
|
|
90
|
+
- bottle
|
|
91
|
+
decoratorNames:
|
|
92
|
+
- route
|
|
93
|
+
- get
|
|
94
|
+
- post
|
|
95
|
+
- put
|
|
96
|
+
- delete
|
|
97
|
+
confidence: 0.85
|
|
98
|
+
|
|
99
|
+
- id: django_urls
|
|
100
|
+
patternId: express_route
|
|
101
|
+
importModules:
|
|
102
|
+
- django.
|
|
103
|
+
urlsFileSuffix: "urls.py"
|
|
104
|
+
pathRegex: "(path|re_path|url)\\(\\s*['\\\"]([^'\\\"]+)['\\\"]"
|
|
105
|
+
confidence: 0.9
|
|
106
|
+
|
|
107
|
+
env_config:
|
|
108
|
+
envVariable:
|
|
109
|
+
patternId: env_variable
|
|
110
|
+
regex: "os\\.(environ\\[['\\\"][^'\\\"]+['\\\"]\\]|getenv\\(\\s*['\\\"][^'\\\"]+['\\\"])"
|
|
111
|
+
confidence: 0.85
|
|
112
|
+
|
|
113
|
+
djangoSettings:
|
|
114
|
+
patternId: config_file
|
|
115
|
+
fileSuffix: "settings.py"
|
|
116
|
+
name: django_settings
|
|
117
|
+
confidence: 0.9
|
|
118
|
+
|
|
119
|
+
dotenvConfig:
|
|
120
|
+
patternId: config_file
|
|
121
|
+
requiresOsImport: true
|
|
122
|
+
contentSubstring: "load_dotenv("
|
|
123
|
+
name: dotenv_config
|
|
124
|
+
confidence: 0.85
|
|
125
|
+
|
|
126
|
+
external_apis:
|
|
127
|
+
httpClients:
|
|
128
|
+
- id: requests
|
|
129
|
+
patternId: external_api_call
|
|
130
|
+
clientName: requests
|
|
131
|
+
importModules:
|
|
132
|
+
- requests
|
|
133
|
+
urlRegex: "['\\\"](https?:\\/\\/[^\\s'\\\"]+)['\\\"]"
|
|
134
|
+
confidence: 0.85
|
|
135
|
+
|
|
136
|
+
- id: httpx
|
|
137
|
+
patternId: external_api_call
|
|
138
|
+
clientName: httpx
|
|
139
|
+
importModules:
|
|
140
|
+
- httpx
|
|
141
|
+
urlRegex: "['\\\"](https?:\\/\\/[^\\s'\\\"]+)['\\\"]"
|
|
142
|
+
confidence: 0.85
|
|
143
|
+
|
|
144
|
+
- id: aiohttp
|
|
145
|
+
patternId: external_api_call
|
|
146
|
+
clientName: aiohttp
|
|
147
|
+
importModules:
|
|
148
|
+
- aiohttp
|
|
149
|
+
urlRegex: "['\\\"](https?:\\/\\/[^\\s'\\\"]+)['\\\"]"
|
|
150
|
+
confidence: 0.85
|
|
151
|
+
|
|
152
|
+
- id: supabase_python
|
|
153
|
+
patternId: external_api_call
|
|
154
|
+
clientName: supabase
|
|
155
|
+
importModules:
|
|
156
|
+
- supabase
|
|
157
|
+
callNames:
|
|
158
|
+
- create_client
|
|
159
|
+
confidence: 0.85
|
|
160
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Terraform patterns (CLI)
|
|
2
|
+
|
|
3
|
+
The Terraform analyzer performs **static, best-effort** parsing of `.tf` and `.tfvars` files. It does **not** run `terraform` or evaluate full HCL2 (heredocs, complex expressions, and `dynamic` blocks may be incomplete).
|
|
4
|
+
|
|
5
|
+
**All matching rules** (block openers, cross-reference regexes, resource-type → `componentSubType` / `cloud_provider` hints, provider display names, and **satellite** resources folded into a parent) live in [`terraform.patterns.yaml`](terraform.patterns.yaml) and are loaded via `terraform-detection-config.ts`, consistent with `typescript.patterns.yaml` / `python.patterns.yaml`.
|
|
6
|
+
|
|
7
|
+
**AWS resource type coverage:** hand-written regex hints in YAML are merged with **`aws-terraform-service-hints.generated.json`**, produced from **`@cdktf/provider-aws`** (tracks HashiCorp **[`terraform-provider-aws`](https://github.com/hashicorp/terraform-provider-aws)** ~> 6.x) and listing **~1.7k** `aws_*` strings in **`aws-terraform-catalog.snapshot.json`**. Generated `^aws_<service>_` rows are inserted immediately before the generic `^aws_` rule so uncommon services get a sensible `componentSubType` instead of falling through to `application`.
|
|
8
|
+
|
|
9
|
+
**Azure (`azurerm`) resource type coverage:** **`azure-terraform-service-hints.generated.json`** + **`azure-terraform-catalog.snapshot.json`** come from **`@cdktf/provider-azurerm`** (~1.2k `azurerm_*` types), which tracks the upstream **[`hashicorp/terraform-provider-azurerm`](https://github.com/hashicorp/terraform-provider-azurerm)** Azure Resource Manager provider; hints are merged before **`azurerm_default_family`**. The **`azapi_*`** provider has no CDKTF package in this flow; it stays covered by the hand-written **`^azapi_`** rule in [`terraform.patterns.yaml`](terraform.patterns.yaml).
|
|
10
|
+
|
|
11
|
+
**Kubernetes resource type coverage:** **`kubernetes-terraform-service-hints.generated.json`** + **`kubernetes-terraform-catalog.snapshot.json`** come from **`@cdktf/provider-kubernetes`** (HashiCorp **`kubernetes_*`** resources for in-cluster workloads, services, ingress, secrets, PVCs, etc.); hints merge before **`kubernetes_default_family`**. Provider topology in **`provider-topology.rules.yaml`** maps **`provider "kubernetes"`** to managed nodes (workload, service, ingress, config, storage, namespace).
|
|
12
|
+
|
|
13
|
+
Regenerate all provider snapshots from `cli/` with **`pnpm run generate:terraform-provider-hints`** (or AWS / Azure / Kubernetes only — see **`cli/README.md`**).
|
|
14
|
+
|
|
15
|
+
## Pattern IDs
|
|
16
|
+
|
|
17
|
+
| Pattern ID | Meaning |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `terraform_resource` | `resource` or `data` block (address `type.name` or `data.type.name`). |
|
|
20
|
+
| `terraform_module` | `module` block. |
|
|
21
|
+
| `terraform_provider` | `provider` block (emitted as a `third_party` component). |
|
|
22
|
+
|
|
23
|
+
## Finding properties (representative)
|
|
24
|
+
|
|
25
|
+
- `terraform_address`: stable resource key used for cross-reference flow edges.
|
|
26
|
+
- `terraform_references`: other addresses referenced from the block body (string array), including references from **merged satellite** blocks (see below).
|
|
27
|
+
- `terraform_satellites` (optional): when a child resource is configured as a **satellite** of a primary resource in YAML (e.g. S3 ACL / ownership controls scoped by `bucket = …`), it is **not** emitted as its own node; metadata is attached here on the parent finding.
|
|
28
|
+
- `resource_type`, `block_name`, `cloud_provider`, `componentSubType` (classifier hint).
|
|
29
|
+
- `section_id` / `section_label`: derived from the file path for layout grouping.
|
|
30
|
+
- After **`applyDeterministicInferenceFallbacks`** (same pipeline step as TypeScript scans), matching AWS/Azure/Kubernetes/… resources may also have **`managed_by_provider`**, **`managed_service_key`**, and **`generated_by: "provider_topology_fallback"`** when they align with `provider-topology.rules.yaml` managed service nodes (e.g. labels **Aws S3**, **Aws Lambda**, **Kubernetes workload**). This mirrors TS SDK topology and enables the same provider→managed edge styling in graph export. Resources not covered by a managed node still get a **`provider → resource`** `api_call` via **`appendTerraformBareProviderAttachmentFlows`** inside that fallback pass.
|
|
31
|
+
|
|
32
|
+
## Provider topology (parity with TypeScript)
|
|
33
|
+
|
|
34
|
+
Static Terraform scans do **not** run a second topology engine. The **same** function, **`applyDeterministicInferenceFallbacks`** (`cli/src/ai-enrichment/fallbacks.ts`), loads **`cli/patterns/provider-topology.rules.yaml`**. For **TypeScript/JavaScript**, usage signals come from **`providerUsageCorpus(provider, flows)`**. For **Terraform on AWS**, each `managedServiceNode` lists **`terraformResourceTypePrefixes`** / **`terraformResourceTypes`** (HashiCorp `aws_*` resource type names, e.g. `aws_s3_bucket`, prefix `aws_lambda_`); matching uses **`resource_type` only**, not block labels like `lambda_bucket`. Providers without those fields (e.g. Supabase) still use legacy **`usageSignals`** matching on Terraform metadata. Shared helpers: **`cli/src/ai-enrichment/provider-topology-shared.ts`**. **`componentMatchesProvider`** treats Terraform’s **`provider_name`** (e.g. `aws`) as a match key so `provider "aws"` nodes participate in the AWS rule.
|
|
35
|
+
|
|
36
|
+
- References inside `module.*` outputs are not resolved.
|
|
37
|
+
- Optional merge from plan/state: **`terraform show -json`** via CLI `--terraform-json` / `--terraform-plan` (see `cli/README.md` and Epic 29 task DP-P0-CLI-906).
|