Skip to content

Commit 99fbd6a

Browse files
Peter HaugeCopilot
andcommitted
feat: full Toolkit config parity for filters and overrides
- Generic OverrideEntry model with recursive children (max 3 levels) - All 14 Toolkit override sections supported (apis, backends, diagnostics, etc.) - Nested API sub-resource filtering (operations, diagnostics, schemas, releases) - Nested override children (ApiDiagnostic, ApiOperation, ApiPolicy, etc.) - 3-level grandchild overrides (ApiOperationPolicy) - Policy override support in publish path - Workspace filter empty-array semantics fix - Duplicate override name warnings - Case-insensitive override matching - Updated docs, templates, and 18 new tests (953 total) Closes #114 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent a179430 commit 99fbd6a

15 files changed

Lines changed: 1360 additions & 181 deletions

docs/guides/environment-overrides.md

Lines changed: 106 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ apiops publish \
2727

2828
`apiops-cli` uses the [APIOps Toolkit](https://github.com/Azure/apiops) override layout:
2929

30-
- Top-level resource sections: `namedValues`, `backends`, `apis`, `diagnostics`, `loggers`
31-
> **Note:** Gateway and subscription overrides are not currently supported.
30+
- Top-level resource sections: `namedValues`, `backends`, `apis`, `diagnostics`, `loggers`, `policies`, `gateways`, `versionSets`, `groups`, `subscriptions`, `products`, `tags`, `policyFragments`, `workspaces`
3231
- Each section is a list
3332
- Each list item contains `name` and `properties`
3433

@@ -53,6 +52,14 @@ apis:
5352
- name: petstore-api
5453
properties:
5554
serviceUrl: "https://petstore.contoso.com/v1"
55+
diagnostics:
56+
- name: applicationinsights
57+
properties:
58+
loggerId: "/subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.ApiManagement/service/<apim>/loggers/prod-appinsights"
59+
policies:
60+
- name: policy
61+
properties:
62+
format: rawxml
5663

5764
diagnostics:
5865
- name: applicationinsights
@@ -65,10 +72,47 @@ loggers:
6572
resourceId: "/subscriptions/<sub-id>/resourceGroups/<rg>/providers/microsoft.insights/components/prod-appinsights"
6673
credentials:
6774
instrumentationKey: "prod-key"
75+
76+
# Additional override sections (all APIOps Toolkit sections are supported):
77+
# policies:
78+
# - name: policy
79+
# properties:
80+
# format: rawxml
81+
# gateways:
82+
# - name: my-gateway
83+
# properties:
84+
# locationData:
85+
# name: "gateway location"
86+
# versionSets:
87+
# - name: my-version-set
88+
# properties:
89+
# displayName: "My Version Set"
90+
# groups:
91+
# - name: my-group
92+
# properties:
93+
# displayName: "My Group"
94+
# subscriptions:
95+
# - name: my-subscription
96+
# properties:
97+
# displayName: "My Subscription"
98+
# products:
99+
# - name: my-product
100+
# properties:
101+
# displayName: "My Product"
102+
# tags:
103+
# - name: my-tag
104+
# properties:
105+
# displayName: "My Tag"
106+
# policyFragments:
107+
# - name: my-fragment
108+
# properties:
109+
# description: "My Policy Fragment"
68110
```
69111

70112
## Override capabilities by resource type
71113

114+
Override properties are generic — any ARM resource property can be overridden. The examples below show common use cases per resource type, but you're not limited to these properties.
115+
72116
### Named values
73117

74118
```yaml
@@ -83,73 +127,108 @@ namedValues:
83127
identityClientId: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
84128
```
85129
86-
| Property | Type | Description |
87-
|----------|------|-------------|
88-
| `value` | `string` | Plain-text value |
89-
| `displayName` | `string` | Display name in the portal |
90-
| `tags` | `string[]` | Resource tags |
91-
| `keyVault.secretIdentifier` | `string` | Key Vault secret URI |
92-
| `keyVault.identityClientId` | `string` | Managed identity client ID for Key Vault access |
93-
94130
### Backends
95131
96132
```yaml
97133
backends:
98134
- name: petstore-backend
99135
properties:
100136
url: "https://petstore-prod.contoso.com"
137+
resourceId: "/subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.Web/sites/prod-backend"
101138
credentials:
102139
header:
103140
x-api-key:
104141
- "prod-backend-key"
105142
```
106143
107-
| Property | Type | Description |
108-
|----------|------|-------------|
109-
| `url` | `string` | Backend service URL |
110-
| `credentials` | `object` | Authentication credentials (headers, query params, certificates) |
111-
112144
### APIs
113145
114146
```yaml
115147
apis:
116148
- name: petstore-api
117149
properties:
118150
serviceUrl: "https://petstore-prod.contoso.com/v1"
151+
displayName: "Petstore API (Production)"
119152
```
120153
121-
| Property | Type | Description |
122-
|----------|------|-------------|
123-
| `serviceUrl` | `string` | Backend service URL for the API |
154+
### APIs with nested sub-resource overrides
124155
125-
### Diagnostics
156+
API entries support nested sub-resource overrides for diagnostics, operations, policies, and releases:
157+
158+
```yaml
159+
apis:
160+
- name: petstore-api
161+
properties:
162+
serviceUrl: "https://petstore-prod.contoso.com/v1"
163+
diagnostics:
164+
- name: applicationinsights
165+
properties:
166+
loggerId: "/subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.ApiManagement/service/<apim>/loggers/prod-appinsights"
167+
verbosity: Error
168+
operations:
169+
- name: get-pets
170+
policies:
171+
- name: policy
172+
properties:
173+
format: rawxml
174+
policies:
175+
- name: policy
176+
properties:
177+
format: rawxml
178+
releases:
179+
- name: v1-release
180+
properties:
181+
notes: "Production release"
182+
```
183+
184+
### Diagnostics (service-level)
126185
127186
```yaml
128187
diagnostics:
129188
- name: applicationinsights
130189
properties:
131190
loggerId: "/subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.ApiManagement/service/<apim>/loggers/prod-appinsights"
191+
verbosity: Error
132192
```
133193
134-
| Property | Type | Description |
135-
|----------|------|-------------|
136-
| `loggerId` | `string` | Full resource ID of the target logger |
137-
138194
### Loggers
139195
140196
```yaml
141197
loggers:
142198
- name: appinsights-logger
143199
properties:
200+
loggerType: applicationInsights
144201
resourceId: "/subscriptions/<sub-id>/resourceGroups/<rg>/providers/microsoft.insights/components/prod-appinsights"
145202
credentials:
146203
instrumentationKey: "prod-instrumentation-key"
204+
isBuffered: true
147205
```
148206
149-
| Property | Type | Description |
150-
|----------|------|-------------|
151-
| `resourceId` | `string` | Azure resource ID of the logging target (for example, Application Insights) |
152-
| `credentials` | `object` | Credentials for the logging service |
207+
### Service-level policies
208+
209+
```yaml
210+
policies:
211+
- name: policy
212+
properties:
213+
format: rawxml
214+
```
215+
216+
### All other resource types
217+
218+
Overrides are also supported for: `gateways`, `versionSets`, `groups`, `subscriptions`, `products`, `tags`, `policyFragments`, and `workspaces`. Each uses the same `name` + `properties` format:
219+
220+
```yaml
221+
gateways:
222+
- name: on-prem-gateway
223+
properties:
224+
locationData:
225+
name: "On-premises datacenter"
226+
227+
products:
228+
- name: starter-product
229+
properties:
230+
displayName: "Starter (Production)"
231+
```
153232

154233
## Override rules
155234

docs/guides/filtering-resources.md

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,57 @@ namedValues:
6969

7070
**Rules:**
7171
- Each field is optional — omit it to extract all resources of that type
72-
- Each field must be an array of strings (validated at load time)
73-
- Names are case-sensitive and must match the APIM resource name exactly
72+
- Simple fields must be an array of strings
73+
- `apis` and `workspaces` also accept nested object entries for sub-resource filtering (see below)
74+
- Names are matched case-insensitively against APIM resource names
7475
- An empty file extracts everything (same as no filter)
76+
- An empty array (`[]`) excludes ALL resources of that type
77+
78+
---
79+
80+
## Nested Sub-Resource Filtering
81+
82+
### API sub-resource filters
83+
84+
For APIs, you can control which sub-resources (operations, diagnostics, schemas, releases) are extracted. Use an object entry instead of a plain string:
85+
86+
```yaml
87+
apis:
88+
- petstore-api # Simple: include all sub-resources
89+
- orders-api: # Nested: control sub-resources
90+
operations:
91+
- get-order
92+
- create-order
93+
diagnostics:
94+
- applicationinsights
95+
schemas: [] # Empty = exclude ALL schemas
96+
releases:
97+
- v1-release
98+
```
99+
100+
**Sub-filter rules:**
101+
- If a sub-resource key is **omitted**, all sub-resources of that type are included
102+
- If a sub-resource key is an **empty array** (`[]`), all sub-resources of that type are excluded
103+
- If a sub-resource key lists **names**, only those sub-resources are included
104+
105+
### Workspace sub-resource filters
106+
107+
For workspaces, you can specify which workspace-scoped resources to extract:
108+
109+
```yaml
110+
workspaces:
111+
- team-a-workspace: # Nested: control workspace resources
112+
apis:
113+
- team-api-1
114+
- team-api-2
115+
backends:
116+
- team-backend
117+
namedValues:
118+
- team-api-key
119+
- team-b-workspace # Simple: extract all resources
120+
```
121+
122+
Supported workspace sub-filter keys: `apis`, `backends`, `diagnostics`, `groups`, `loggers`, `namedValues`, `policyFragments`, `products`, `subscriptions`, `tags`, `versionSets`.
75123

76124
---
77125

@@ -224,8 +272,8 @@ There is no "exclude" syntax. To extract everything except certain resources, li
224272
- **Start broad, narrow later** — Begin with no filter to see what's in your APIM instance, then create a filter for your team's slice
225273
- **One filter per team** — In multi-team setups, each team maintains its own `configuration.extractor.yaml`
226274
- **Commit the filter file** — Keep it in version control alongside your artifacts so CI/CD pipelines can use it
227-
- **Case-sensitive names** — Filter values must match APIM resource names exactly (usually lowercase with hyphens)
228-
- **Validate early** — The config loader validates that each filter field is an array of strings and will throw `Failed to load filter config` on invalid YAML
275+
- **Case-insensitive matching** — Filter values are matched case-insensitively against APIM resource names
276+
- **Validate early** — The config loader validates filter entries and will throw `Failed to load filter config` on invalid YAML. Unknown top-level keys produce a warning.
229277

230278
---
231279

0 commit comments

Comments
 (0)