Skip to content

Commit 26acd75

Browse files
Peter HaugeCopilot
andcommitted
chore: remove unimplemented --otel option
The --otel CLI option for OpenTelemetry integration was spec'd but never implemented. Since issue #11 has been closed without implementation, this commit removes all references from: - Source code (index.ts, config.ts, config-loader.ts) - Specs (cli-commands.md, data-model.md, spec.md, research.md, tasks.md) Historical references in .squad/ decision records are preserved as they document what was intentionally not implemented. Closes #11 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 2a9d632 commit 26acd75

8 files changed

Lines changed: 7 additions & 57 deletions

File tree

specs/contracts/cli-commands.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ These flags are available on **all** commands (`extract`, `publish`, `init`).
1515
| `--api-version <version>` | string | no | `2024-05-01` | APIM REST API version |
1616
| `--format <mode>` | string | no | `text` | Output format: `text` (human-readable) or `json` (machine-readable) |
1717
| `--verbose` | boolean | no | `false` | Enable debug-level output |
18-
| `--otel <path>` | string | no || OpenTelemetry configuration YAML file |
1918
| `--client-id <id>` | string | no || Service principal client ID (sets `AZURE_CLIENT_ID` for DefaultAzureCredential) |
2019
| `--client-secret <secret>` | string | no || Service principal client secret (sets `AZURE_CLIENT_SECRET`) |
2120
| `--tenant-id <id>` | string | no || Azure AD tenant ID (sets `AZURE_TENANT_ID`) |
@@ -108,8 +107,6 @@ Initialize repository structure and CI/CD pipeline configuration.
108107
| `AZURE_SUBSCRIPTION_ID` | Azure subscription (fallback for `--subscription-id`) | extract, publish |
109108
| `AZURE_API_VERSION` | Override APIM REST API version (default: `2024-05-01`) | extract, publish |
110109
| `COMMIT_ID` | Git SHA for incremental publish | publish |
111-
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTel exporter endpoint (used by OTel SDK) | extract, publish |
112-
| `APPLICATIONINSIGHTS_CONNECTION_STRING` | Azure Monitor connection string | extract, publish |
113110

114111
---
115112

specs/data-model.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ interface ExtractConfig {
151151
filter?: FilterConfig;
152152
includeTransitive: boolean; // Default: true; false when --no-transitive
153153
verbose: boolean;
154-
otelConfigPath?: string;
155154
}
156155
```
157156

@@ -203,7 +202,6 @@ interface PublishConfig {
203202
deleteUnmatched: boolean; // Default: false; true when --delete-unmatched
204203
commitId?: string; // From COMMIT_ID env var; triggers incremental publish
205204
verbose: boolean;
206-
otelConfigPath?: string;
207205
}
208206
```
209207

specs/research.md

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@ program
242242
.option('--api-version <version>', 'APIM REST API version', '2024-05-01')
243243
.option('--format <mode>', 'Output format (text|json)', 'text')
244244
.option('--verbose', 'Enable verbose output')
245-
.option('--otel <path>', 'OpenTelemetry configuration file')
246245
.option('--client-id <id>', 'Service principal client ID')
247246
.option('--client-secret <secret>', 'Service principal client secret')
248247
.option('--tenant-id <id>', 'Azure AD tenant ID')
@@ -294,25 +293,6 @@ program.command('init')
294293

295294
---
296295

297-
## R9: OpenTelemetry Integration
298-
299-
**Decision**: `@opentelemetry/sdk-node` with auto-instrumentation for HTTP; `--otel <path>` accepts standard OTel config YAML file.
300-
301-
**Rationale**:
302-
- spec requires structured logging to stderr + optional OTel export (clarification C5)
303-
- Standard OTel env vars (`OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_EXPORTER_OTLP_HEADERS`) for server config
304-
- Config file can set resource attributes, exporter endpoint, and custom headers
305-
- `--otel <path>` flag consistent with `--filter <path>` and `--overrides <path>` pattern
306-
307-
**Implementation**:
308-
- When `--otel` not specified: No OTel SDK initialized, no overhead
309-
- When `--otel <path>` specified: Read YAML config, initialize `NodeSDK` with OTLP exporter
310-
- Traces: One span per resource type extraction/publish, child spans per individual resource
311-
- Metrics: Resource count, duration, error count
312-
- Azure Monitor: Users set `APPLICATIONINSIGHTS_CONNECTION_STRING` env var + use Azure Monitor OTel exporter in config
313-
314-
---
315-
316296
## R10: Testing Strategy
317297

318298
**Decision**: Vitest with three test tiers — unit, integration, contract.

specs/spec.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
- Q: What progress feedback should the tool provide during long-running operations? → A: Per-resource status lines by default (e.g., `✓ apis/orders-api`). A `--log-level debug` option adds additional diagnostic output (HTTP requests, timing, retry details) useful for debugging.
1616
- Q: How should the tool handle API revisions during extract and publish? → A: Extract all revisions, stored as sub-folders under each API. Publish recreates all revisions in the correct order (root API first, then revisions with forced revision numbers).
1717
- Q: How should the tool parallelize extraction? → A: Cross-type parallel where safe (independent resource types extracted concurrently; resources within each type also concurrent). Publish remains dependency-ordered.
18-
- Q: Should the CLI emit structured telemetry/logging? → A: Structured logging to stderr by default. An `--otel <path>` flag accepts a standard OpenTelemetry configuration YAML file to enable trace and metric export. Credentials (API keys, connection strings) live in the OTel config file or environment variables, never as CLI flags.
1918

2019
### User Story 1 — Extract APIM Configuration (Priority: P1)
2120

@@ -35,7 +34,7 @@ A platform engineer wants to capture the current state of an Azure API Managemen
3534

3635
3. **Given** the user only wants a subset of resources, **When** the user provides a filter configuration file via `--filter filter.yaml`, **Then** only the resources matching the allowlist in the configuration file are extracted, along with any resources those filtered resources transitively depend on (e.g., backends, named values, loggers referenced in policies). The user can suppress transitive inclusion with `--no-transitive`.
3736

38-
4. **Given** an APIM instance, **When** the user runs `apiops extract --format json`, **Then** machine-readable JSON progress output is written to stdout (resource counts, file paths written) suitable for CI/CD pipeline consumption.
37+
5. **Given** an APIM instance, **When** the user runs `apiops extract --format json`, **Then** machine-readable JSON progress output is written to stdout (resource counts, file paths written) suitable for CI/CD pipeline consumption.
3938

4039
7. **Given** an APIM instance with APIs that have multiple revisions (e.g., `orders-api;rev=1`, `orders-api;rev=2`), **When** the user runs `apiops extract`, **Then** all revisions are extracted as sub-folders under the API directory, preserving revision numbers and metadata.
4140

@@ -161,7 +160,7 @@ The development team wants the CLI to support adding new top-level commands (e.g
161160
- **FR-012**: System MUST support configuring the APIM REST API version per invocation via a CLI flag or configuration file.
162161
- **FR-024**: System MUST extract all API revisions as sub-folders under each API directory, preserving revision numbers. During publish, the tool MUST create the root API first, then apply revisions in order with forced revision numbers to prevent APIM from auto-assigning.
163162
- **FR-025**: During extraction, the system MUST parallelize across independent resource types (e.g., backends and loggers concurrently) and across resources within each type. Dependencies between types (e.g., APIs depend on version sets) MUST be respected. During publish, resource types MUST be processed in dependency order.
164-
- **FR-026**: All commands MUST emit structured log output to stderr by default (timestamps, log levels, resource context). An `--otel <path>` flag MUST accept a standard OpenTelemetry configuration YAML file to enable trace and metric export. The tool MUST pass this file to the OTel SDK (equivalent to setting `OTEL_CONFIG_FILE`). If `--otel` is not provided, no telemetry is exported. Credentials (API keys, connection strings) MUST NOT be accepted as separate CLI flags — they MUST reside in the OTel config file or environment variables.
163+
- **FR-026**: All commands MUST emit structured log output to stderr by default (timestamps, log levels, resource context).
165164
- **FR-013**: System MUST provide `--format json|text` on all commands for machine-readable output suitable for CI/CD pipeline consumption. The default format is `text` (human-readable). `--format json` writes structured JSON to stdout. This flag is independent of `--output` (extract directory) and `--source` (publish directory).
166165
- **FR-014**: System MUST handle paginated Azure REST API responses by following `nextLink` continuation tokens.
167166
- **FR-015**: System MUST implement retry logic with exponential backoff for transient HTTP failures and 429 rate-limit responses.

specs/tasks.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@
4242
- [x] T012 Implement resource descriptor ↔ ARM URI mapping in src/lib/resource-uri.ts (builds full ARM URL from ApimServiceContext + ResourceDescriptor, including workspace prefix)
4343
- [x] T013 Implement resource descriptor ↔ artifact file path mapping in src/lib/resource-path.ts (maps descriptor to directory/file paths per data-model.md artifact conventions)
4444
- [x] T014 [P] Implement structured logger in src/lib/logger.ts (stderr output, timestamps, log levels, --verbose support per FR-023/FR-026)
45-
- [x] T015 [P] Implement YAML config loader in src/lib/config-loader.ts (parse filter YAML, override YAML, OTel config with js-yaml; validate against FilterConfig/OverrideConfig schemas)
45+
- [x] T015 [P] Implement YAML config loader in src/lib/config-loader.ts (parse filter YAML, override YAML with js-yaml; validate against FilterConfig/OverrideConfig schemas)
4646
- [x] T016 Implement Azure REST HTTP client in src/clients/apim-client.ts (implements IApimClient: DefaultAzureCredential auth, nextLink pagination, Retry-After/429 handling, exponential backoff, provisioningState polling per research.md R1)
4747
- [x] T017 Implement filesystem artifact store in src/clients/artifact-store.ts (implements IArtifactStore: read/write resource JSON, policy XML, API specs, association files, wiki markdown; UTF-8 encoding; directory creation per contracts/iartifact-store.md)
4848
- [x] T018 [P] Implement parallel execution runner in src/lib/parallel-runner.ts (p-limit based concurrency control, Promise.allSettled, configurable concurrency per research.md R8)
49-
- [x] T019 Set up Commander program entry point in src/cli/index.ts (program name, version, global options --verbose/--otel/--format/--subscription-id/--cloud, subcommand registration pattern per FR-018)
49+
- [x] T019 Set up Commander program entry point in src/cli/index.ts (program name, version, global options --verbose/--format/--subscription-id/--cloud, subcommand registration pattern per FR-018)
5050

5151
**Checkpoint**: Foundation ready — user story implementation can now begin
5252

@@ -145,7 +145,7 @@
145145
### Implementation for User Story 5
146146

147147
- [ ] T052 [US5] Implement command auto-discovery in src/cli/index.ts (scan src/cli/*-command.ts files or use explicit registration array; new commands appear in --help automatically per FR-018/SC-007)
148-
- [ ] T053 [US5] Extract shared command infrastructure in src/cli/shared.ts (common option builders for --resource-group/--service-name/--subscription-id/--verbose/--otel; shared APIM client factory; shared artifact store factory)
148+
- [ ] T053 [US5] Extract shared command infrastructure in src/cli/shared.ts (common option builders for --resource-group/--service-name/--subscription-id/--verbose; shared APIM client factory; shared artifact store factory)
149149
- [ ] T054 [US5] Create command developer guide in src/cli/README.md (document how to add a new command: file naming, interface shape, option reuse, testing pattern)
150150

151151
**Checkpoint**: Adding a new command requires only creating one file in src/cli/
@@ -156,7 +156,6 @@
156156

157157
**Purpose**: Improvements that affect multiple user stories
158158

159-
- [ ] T055 [P] Implement OTel integration in src/lib/otel-setup.ts (load --otel config YAML, initialize NodeSDK with OTLP exporter, create spans per resource type/resource, metrics for counts/duration per research.md R9)
160159
- [ ] T056 [P] Add --api-version global flag support in src/cli/index.ts and src/clients/apim-client.ts (override default 2024-05-01 per FR-012)
161160
- [ ] T058 Run quickstart.md validation (execute each quickstart command against a test APIM instance, verify expected outputs)
162161
- [ ] T059 Add bin entry to package.json and shebang to src/cli/index.ts for global npm install (`npx apiops` / `npm install -g`)
@@ -247,4 +246,4 @@ T029: JSON output mode → src/cli/extract-command.ts
247246
4. Add US3 (CI/CD) → Test in GitHub Actions pipeline
248247
5. Add US4 (Init) → Test scaffold generation in empty repo
249248
6. Add US5 (Extensibility) → Verify new command pattern
250-
7. Polish → OTel, quickstart validation
249+
7. Polish → quickstart validation

src/cli/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ program
3232
.choices(['debug', 'info', 'warn', 'error'])
3333
.default('info'),
3434
)
35-
.option('--otel <path>', 'Path to OpenTelemetry config YAML')
3635
.option('--format <type>', 'Output format: text or json', 'text')
3736
.option('--subscription-id <id>', 'Azure subscription ID')
3837
.option('--cloud <name>', 'Sovereign cloud: public, china, usgov, germany', 'public')

src/lib/config-loader.ts

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the MIT license.
33
/**
44
* YAML config loader with validation
5-
* Parse filter YAML, override YAML, and OTel config files
5+
* Parse filter YAML and override YAML config files
66
*/
77

88
import * as fs from 'node:fs/promises';
@@ -428,23 +428,3 @@ function isPlainObject(value: unknown): value is Record<string, unknown> {
428428
Object.prototype.toString.call(value) === '[object Object]'
429429
);
430430
}
431-
432-
/**
433-
* Load and parse an OpenTelemetry configuration YAML file.
434-
* Returns undefined if file doesn't exist.
435-
*/
436-
export async function loadOTelConfig(filePath: string): Promise<Record<string, unknown> | undefined> {
437-
try {
438-
const content = await fs.readFile(filePath, 'utf-8');
439-
const parsed = (yaml.load(content) ?? {}) as Record<string, unknown>;
440-
441-
logger.debug(`Loaded OTel config from ${filePath}`);
442-
return parsed;
443-
} catch (error) {
444-
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
445-
logger.debug(`OTel config file not found: ${filePath}`);
446-
return undefined;
447-
}
448-
throw new Error(`Failed to load OTel config from ${filePath}: ${(error as Error).message}`, { cause: error });
449-
}
450-
}

src/models/config.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ export interface ExtractConfig {
1414
filter?: FilterConfig;
1515
includeTransitive: boolean;
1616
logLevel: LogLevel;
17-
otelConfigPath?: string;
1817
}
1918

2019
/**
@@ -81,7 +80,6 @@ export interface PublishConfig {
8180
deleteUnmatched: boolean;
8281
commitId?: string;
8382
logLevel: LogLevel;
84-
otelConfigPath?: string;
8583
}
8684

8785
/**

0 commit comments

Comments
 (0)