@peterhauge/apiops-cli 0.1.3-alpha.0
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/LICENSE.md +21 -0
- package/README.md +135 -0
- package/dist/cli/extract-command.d.ts +12 -0
- package/dist/cli/extract-command.d.ts.map +1 -0
- package/dist/cli/extract-command.js +157 -0
- package/dist/cli/extract-command.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +74 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init-command.d.ts +11 -0
- package/dist/cli/init-command.d.ts.map +1 -0
- package/dist/cli/init-command.js +87 -0
- package/dist/cli/init-command.js.map +1 -0
- package/dist/cli/publish-command.d.ts +12 -0
- package/dist/cli/publish-command.d.ts.map +1 -0
- package/dist/cli/publish-command.js +159 -0
- package/dist/cli/publish-command.js.map +1 -0
- package/dist/clients/apim-client.d.ts +110 -0
- package/dist/clients/apim-client.d.ts.map +1 -0
- package/dist/clients/apim-client.js +586 -0
- package/dist/clients/apim-client.js.map +1 -0
- package/dist/clients/artifact-store.d.ts +23 -0
- package/dist/clients/artifact-store.d.ts.map +1 -0
- package/dist/clients/artifact-store.js +188 -0
- package/dist/clients/artifact-store.js.map +1 -0
- package/dist/clients/iapim-client.d.ts +52 -0
- package/dist/clients/iapim-client.d.ts.map +1 -0
- package/dist/clients/iapim-client.js +6 -0
- package/dist/clients/iapim-client.js.map +1 -0
- package/dist/clients/iartifact-store.d.ts +50 -0
- package/dist/clients/iartifact-store.d.ts.map +1 -0
- package/dist/clients/iartifact-store.js +6 -0
- package/dist/clients/iartifact-store.js.map +1 -0
- package/dist/lib/auto-generated.d.ts +27 -0
- package/dist/lib/auto-generated.d.ts.map +1 -0
- package/dist/lib/auto-generated.js +34 -0
- package/dist/lib/auto-generated.js.map +1 -0
- package/dist/lib/cloud-config.d.ts +29 -0
- package/dist/lib/cloud-config.d.ts.map +1 -0
- package/dist/lib/cloud-config.js +60 -0
- package/dist/lib/cloud-config.js.map +1 -0
- package/dist/lib/config-loader.d.ts +21 -0
- package/dist/lib/config-loader.d.ts.map +1 -0
- package/dist/lib/config-loader.js +131 -0
- package/dist/lib/config-loader.js.map +1 -0
- package/dist/lib/dependency-graph.d.ts +43 -0
- package/dist/lib/dependency-graph.d.ts.map +1 -0
- package/dist/lib/dependency-graph.js +163 -0
- package/dist/lib/dependency-graph.js.map +1 -0
- package/dist/lib/exit-codes.d.ts +27 -0
- package/dist/lib/exit-codes.d.ts.map +1 -0
- package/dist/lib/exit-codes.js +33 -0
- package/dist/lib/exit-codes.js.map +1 -0
- package/dist/lib/logger.d.ts +39 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +128 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/parallel-runner.d.ts +38 -0
- package/dist/lib/parallel-runner.d.ts.map +1 -0
- package/dist/lib/parallel-runner.js +70 -0
- package/dist/lib/parallel-runner.js.map +1 -0
- package/dist/lib/resource-path.d.ts +205 -0
- package/dist/lib/resource-path.d.ts.map +1 -0
- package/dist/lib/resource-path.js +401 -0
- package/dist/lib/resource-path.js.map +1 -0
- package/dist/lib/resource-uri.d.ts +40 -0
- package/dist/lib/resource-uri.d.ts.map +1 -0
- package/dist/lib/resource-uri.js +86 -0
- package/dist/lib/resource-uri.js.map +1 -0
- package/dist/lib/user-agent.d.ts +2 -0
- package/dist/lib/user-agent.d.ts.map +1 -0
- package/dist/lib/user-agent.js +5 -0
- package/dist/lib/user-agent.js.map +1 -0
- package/dist/models/config.d.ts +83 -0
- package/dist/models/config.d.ts.map +1 -0
- package/dist/models/config.js +6 -0
- package/dist/models/config.js.map +1 -0
- package/dist/models/resource-types.d.ts +66 -0
- package/dist/models/resource-types.d.ts.map +1 -0
- package/dist/models/resource-types.js +243 -0
- package/dist/models/resource-types.js.map +1 -0
- package/dist/models/types.d.ts +47 -0
- package/dist/models/types.d.ts.map +1 -0
- package/dist/models/types.js +6 -0
- package/dist/models/types.js.map +1 -0
- package/dist/services/api-extractor.d.ts +36 -0
- package/dist/services/api-extractor.d.ts.map +1 -0
- package/dist/services/api-extractor.js +319 -0
- package/dist/services/api-extractor.js.map +1 -0
- package/dist/services/api-publisher.d.ts +18 -0
- package/dist/services/api-publisher.d.ts.map +1 -0
- package/dist/services/api-publisher.js +290 -0
- package/dist/services/api-publisher.js.map +1 -0
- package/dist/services/delete-unmatched-service.d.ts +17 -0
- package/dist/services/delete-unmatched-service.d.ts.map +1 -0
- package/dist/services/delete-unmatched-service.js +143 -0
- package/dist/services/delete-unmatched-service.js.map +1 -0
- package/dist/services/dry-run-reporter.d.ts +30 -0
- package/dist/services/dry-run-reporter.d.ts.map +1 -0
- package/dist/services/dry-run-reporter.js +111 -0
- package/dist/services/dry-run-reporter.js.map +1 -0
- package/dist/services/extract-service.d.ts +47 -0
- package/dist/services/extract-service.d.ts.map +1 -0
- package/dist/services/extract-service.js +374 -0
- package/dist/services/extract-service.js.map +1 -0
- package/dist/services/filter-service.d.ts +29 -0
- package/dist/services/filter-service.d.ts.map +1 -0
- package/dist/services/filter-service.js +143 -0
- package/dist/services/filter-service.js.map +1 -0
- package/dist/services/git-diff-service.d.ts +23 -0
- package/dist/services/git-diff-service.d.ts.map +1 -0
- package/dist/services/git-diff-service.js +135 -0
- package/dist/services/git-diff-service.js.map +1 -0
- package/dist/services/identity-guide-service.d.ts +11 -0
- package/dist/services/identity-guide-service.d.ts.map +1 -0
- package/dist/services/identity-guide-service.js +227 -0
- package/dist/services/identity-guide-service.js.map +1 -0
- package/dist/services/init-service.d.ts +16 -0
- package/dist/services/init-service.d.ts.map +1 -0
- package/dist/services/init-service.js +304 -0
- package/dist/services/init-service.js.map +1 -0
- package/dist/services/keyvault-checker.d.ts +58 -0
- package/dist/services/keyvault-checker.d.ts.map +1 -0
- package/dist/services/keyvault-checker.js +390 -0
- package/dist/services/keyvault-checker.js.map +1 -0
- package/dist/services/override-merger.d.ts +20 -0
- package/dist/services/override-merger.d.ts.map +1 -0
- package/dist/services/override-merger.js +102 -0
- package/dist/services/override-merger.js.map +1 -0
- package/dist/services/product-extractor.d.ts +26 -0
- package/dist/services/product-extractor.d.ts.map +1 -0
- package/dist/services/product-extractor.js +141 -0
- package/dist/services/product-extractor.js.map +1 -0
- package/dist/services/product-publisher.d.ts +15 -0
- package/dist/services/product-publisher.d.ts.map +1 -0
- package/dist/services/product-publisher.js +113 -0
- package/dist/services/product-publisher.js.map +1 -0
- package/dist/services/prompt-service.d.ts +13 -0
- package/dist/services/prompt-service.d.ts.map +1 -0
- package/dist/services/prompt-service.js +69 -0
- package/dist/services/prompt-service.js.map +1 -0
- package/dist/services/publish-service.d.ts +31 -0
- package/dist/services/publish-service.d.ts.map +1 -0
- package/dist/services/publish-service.js +445 -0
- package/dist/services/publish-service.js.map +1 -0
- package/dist/services/resource-extractor.d.ts +52 -0
- package/dist/services/resource-extractor.d.ts.map +1 -0
- package/dist/services/resource-extractor.js +168 -0
- package/dist/services/resource-extractor.js.map +1 -0
- package/dist/services/resource-publisher.d.ts +23 -0
- package/dist/services/resource-publisher.d.ts.map +1 -0
- package/dist/services/resource-publisher.js +349 -0
- package/dist/services/resource-publisher.js.map +1 -0
- package/dist/services/secret-redactor.d.ts +20 -0
- package/dist/services/secret-redactor.d.ts.map +1 -0
- package/dist/services/secret-redactor.js +45 -0
- package/dist/services/secret-redactor.js.map +1 -0
- package/dist/services/transitive-resolver.d.ts +45 -0
- package/dist/services/transitive-resolver.d.ts.map +1 -0
- package/dist/services/transitive-resolver.js +177 -0
- package/dist/services/transitive-resolver.js.map +1 -0
- package/dist/services/workspace-extractor.d.ts +34 -0
- package/dist/services/workspace-extractor.d.ts.map +1 -0
- package/dist/services/workspace-extractor.js +120 -0
- package/dist/services/workspace-extractor.js.map +1 -0
- package/dist/templates/azure-devops/extract-pipeline.d.ts +9 -0
- package/dist/templates/azure-devops/extract-pipeline.d.ts.map +1 -0
- package/dist/templates/azure-devops/extract-pipeline.js +95 -0
- package/dist/templates/azure-devops/extract-pipeline.js.map +1 -0
- package/dist/templates/azure-devops/publish-pipeline.d.ts +10 -0
- package/dist/templates/azure-devops/publish-pipeline.d.ts.map +1 -0
- package/dist/templates/azure-devops/publish-pipeline.js +100 -0
- package/dist/templates/azure-devops/publish-pipeline.js.map +1 -0
- package/dist/templates/configs/filter-config.d.ts +6 -0
- package/dist/templates/configs/filter-config.d.ts.map +1 -0
- package/dist/templates/configs/filter-config.js +51 -0
- package/dist/templates/configs/filter-config.js.map +1 -0
- package/dist/templates/configs/override-config.d.ts +6 -0
- package/dist/templates/configs/override-config.d.ts.map +1 -0
- package/dist/templates/configs/override-config.js +45 -0
- package/dist/templates/configs/override-config.js.map +1 -0
- package/dist/templates/configs/package-json.d.ts +10 -0
- package/dist/templates/configs/package-json.d.ts.map +1 -0
- package/dist/templates/configs/package-json.js +19 -0
- package/dist/templates/configs/package-json.js.map +1 -0
- package/dist/templates/copilot/identity-setup-prompt.d.ts +13 -0
- package/dist/templates/copilot/identity-setup-prompt.d.ts.map +1 -0
- package/dist/templates/copilot/identity-setup-prompt.js +279 -0
- package/dist/templates/copilot/identity-setup-prompt.js.map +1 -0
- package/dist/templates/github-actions/extract-workflow.d.ts +9 -0
- package/dist/templates/github-actions/extract-workflow.d.ts.map +1 -0
- package/dist/templates/github-actions/extract-workflow.js +126 -0
- package/dist/templates/github-actions/extract-workflow.js.map +1 -0
- package/dist/templates/github-actions/publish-workflow.d.ts +10 -0
- package/dist/templates/github-actions/publish-workflow.d.ts.map +1 -0
- package/dist/templates/github-actions/publish-workflow.js +105 -0
- package/dist/templates/github-actions/publish-workflow.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T042 & T051: Init orchestrator service
|
|
3
|
+
* Coordinates interactive prompts or flag-based config, generates scaffold files,
|
|
4
|
+
* and detects existing file conflicts
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'fs/promises';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import { logger } from '../lib/logger.js';
|
|
9
|
+
import { promptService } from './prompt-service.js';
|
|
10
|
+
import { identityGuideService } from './identity-guide-service.js';
|
|
11
|
+
import { generateExtractWorkflow, } from '../templates/github-actions/extract-workflow.js';
|
|
12
|
+
import { generatePublishWorkflow, } from '../templates/github-actions/publish-workflow.js';
|
|
13
|
+
import { generateExtractPipeline, } from '../templates/azure-devops/extract-pipeline.js';
|
|
14
|
+
import { generatePublishPipeline, } from '../templates/azure-devops/publish-pipeline.js';
|
|
15
|
+
import { generateFilterConfig } from '../templates/configs/filter-config.js';
|
|
16
|
+
import { generateOverrideConfig } from '../templates/configs/override-config.js';
|
|
17
|
+
import { generatePackageJson } from '../templates/configs/package-json.js';
|
|
18
|
+
import { generateIdentitySetupPrompt } from '../templates/copilot/identity-setup-prompt.js';
|
|
19
|
+
/** Placeholder values used in generated identity setup guides */
|
|
20
|
+
const PLACEHOLDER_SUBSCRIPTION_ID = '<your-subscription-id>';
|
|
21
|
+
const PLACEHOLDER_RESOURCE_GROUP = '<your-resource-group>';
|
|
22
|
+
class InitServiceImpl {
|
|
23
|
+
async run(config) {
|
|
24
|
+
logger.info('Starting APIM repository initialization...');
|
|
25
|
+
// Validate that the CLI package tarball exists
|
|
26
|
+
await this.validateCliPackage(config.cliPackage);
|
|
27
|
+
// Gather configuration (interactive or from flags)
|
|
28
|
+
const finalConfig = await this.gatherConfiguration(config);
|
|
29
|
+
logger.debug('Final configuration:', finalConfig);
|
|
30
|
+
// Detect conflicts
|
|
31
|
+
await this.detectConflicts(finalConfig);
|
|
32
|
+
// Generate files
|
|
33
|
+
const generatedFiles = await this.generateFiles(finalConfig);
|
|
34
|
+
// Output identity setup guide
|
|
35
|
+
await this.outputIdentityGuide(finalConfig, generatedFiles);
|
|
36
|
+
return generatedFiles;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Validate that the CLI package tarball exists and looks like a .tgz
|
|
40
|
+
*/
|
|
41
|
+
async validateCliPackage(cliPackagePath) {
|
|
42
|
+
const resolvedPath = path.resolve(cliPackagePath);
|
|
43
|
+
if (!await this.fileExists(resolvedPath)) {
|
|
44
|
+
throw new Error(`CLI package not found: ${resolvedPath}`);
|
|
45
|
+
}
|
|
46
|
+
if (!resolvedPath.endsWith('.tgz')) {
|
|
47
|
+
throw new Error(`CLI package must be a .tgz tarball (got: ${path.basename(resolvedPath)})`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Gather configuration from interactive prompts or flags
|
|
52
|
+
*/
|
|
53
|
+
async gatherConfiguration(config) {
|
|
54
|
+
let ciProvider = config.ciProvider;
|
|
55
|
+
let artifactDir = config.artifactDir;
|
|
56
|
+
let environments = config.environments;
|
|
57
|
+
// Interactive mode
|
|
58
|
+
if (!config.nonInteractive && promptService.isTTY()) {
|
|
59
|
+
logger.info('Running in interactive mode. Press Ctrl+C to cancel.\n');
|
|
60
|
+
if (!ciProvider) {
|
|
61
|
+
ciProvider = await promptService.askCIProvider();
|
|
62
|
+
}
|
|
63
|
+
artifactDir = await promptService.askArtifactDir(artifactDir);
|
|
64
|
+
environments = await promptService.askEnvironments(environments);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// Non-interactive mode
|
|
68
|
+
if (!ciProvider) {
|
|
69
|
+
throw new Error('Non-interactive mode requires --ci flag (github-actions or azure-devops)');
|
|
70
|
+
}
|
|
71
|
+
logger.info('Running in non-interactive mode');
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
ciProvider,
|
|
75
|
+
nonInteractive: config.nonInteractive,
|
|
76
|
+
artifactDir,
|
|
77
|
+
environments,
|
|
78
|
+
outputDir: config.outputDir,
|
|
79
|
+
cliPackage: config.cliPackage,
|
|
80
|
+
force: config.force,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Detect existing pipeline/config files and block unless --force is set
|
|
85
|
+
*/
|
|
86
|
+
async detectConflicts(config) {
|
|
87
|
+
const conflictingFiles = [];
|
|
88
|
+
// Check for pipeline files based on CI provider
|
|
89
|
+
if (config.ciProvider === 'github-actions') {
|
|
90
|
+
const extractWorkflow = path.join(config.outputDir, '.github/workflows/run-apim-extractor.yml');
|
|
91
|
+
const publishWorkflow = path.join(config.outputDir, '.github/workflows/run-apim-publisher.yml');
|
|
92
|
+
const promptFile = path.join(config.outputDir, '.github/prompts/apiops-setup-identity.prompt.md');
|
|
93
|
+
const identityGuide = path.join(config.outputDir, 'IDENTITY-SETUP-GITHUB.md');
|
|
94
|
+
if (await this.fileExists(extractWorkflow)) {
|
|
95
|
+
conflictingFiles.push(extractWorkflow);
|
|
96
|
+
}
|
|
97
|
+
if (await this.fileExists(publishWorkflow)) {
|
|
98
|
+
conflictingFiles.push(publishWorkflow);
|
|
99
|
+
}
|
|
100
|
+
if (await this.fileExists(promptFile)) {
|
|
101
|
+
conflictingFiles.push(promptFile);
|
|
102
|
+
}
|
|
103
|
+
if (await this.fileExists(identityGuide)) {
|
|
104
|
+
conflictingFiles.push(identityGuide);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else if (config.ciProvider === 'azure-devops') {
|
|
108
|
+
const extractPipeline = path.join(config.outputDir, '.azdo/pipelines/run-apim-extractor.yml');
|
|
109
|
+
const publishPipeline = path.join(config.outputDir, '.azdo/pipelines/run-apim-publisher.yml');
|
|
110
|
+
const identityGuide = path.join(config.outputDir, 'IDENTITY-SETUP-AZDO.md');
|
|
111
|
+
if (await this.fileExists(extractPipeline)) {
|
|
112
|
+
conflictingFiles.push(extractPipeline);
|
|
113
|
+
}
|
|
114
|
+
if (await this.fileExists(publishPipeline)) {
|
|
115
|
+
conflictingFiles.push(publishPipeline);
|
|
116
|
+
}
|
|
117
|
+
if (await this.fileExists(identityGuide)) {
|
|
118
|
+
conflictingFiles.push(identityGuide);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Check for package.json
|
|
122
|
+
const packageJsonPath = path.join(config.outputDir, 'package.json');
|
|
123
|
+
if (await this.fileExists(packageJsonPath)) {
|
|
124
|
+
conflictingFiles.push(packageJsonPath);
|
|
125
|
+
}
|
|
126
|
+
// Check for config files
|
|
127
|
+
const filterConfig = path.join(config.outputDir, 'configuration.extract.yaml');
|
|
128
|
+
if (await this.fileExists(filterConfig)) {
|
|
129
|
+
conflictingFiles.push(filterConfig);
|
|
130
|
+
}
|
|
131
|
+
for (const env of config.environments) {
|
|
132
|
+
const overrideConfig = path.join(config.outputDir, `configuration.${env}.yaml`);
|
|
133
|
+
if (await this.fileExists(overrideConfig)) {
|
|
134
|
+
conflictingFiles.push(overrideConfig);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Block or warn based on --force flag
|
|
138
|
+
if (conflictingFiles.length > 0) {
|
|
139
|
+
if (config.force) {
|
|
140
|
+
logger.warn('⚠ The following files already exist and will be overwritten:');
|
|
141
|
+
conflictingFiles.forEach((file) => {
|
|
142
|
+
logger.warn(` - ${path.relative(config.outputDir, file)}`);
|
|
143
|
+
});
|
|
144
|
+
logger.warn('');
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
const fileList = conflictingFiles
|
|
148
|
+
.map((file) => ` - ${path.relative(config.outputDir, file)}`)
|
|
149
|
+
.join('\n');
|
|
150
|
+
throw new Error(`The following files already exist:\n${fileList}\n\nUse --force to overwrite existing files.`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Generate all scaffold files
|
|
156
|
+
*/
|
|
157
|
+
async generateFiles(config) {
|
|
158
|
+
const generatedFiles = {
|
|
159
|
+
pipelines: [],
|
|
160
|
+
configs: [],
|
|
161
|
+
directories: [],
|
|
162
|
+
};
|
|
163
|
+
// Create artifact directory
|
|
164
|
+
const artifactPath = path.join(config.outputDir, config.artifactDir);
|
|
165
|
+
await fs.mkdir(artifactPath, { recursive: true });
|
|
166
|
+
// Create .gitkeep to ensure directory is tracked
|
|
167
|
+
const gitkeepPath = path.join(artifactPath, '.gitkeep');
|
|
168
|
+
await fs.writeFile(gitkeepPath, '');
|
|
169
|
+
generatedFiles.directories.push(config.artifactDir);
|
|
170
|
+
// Copy CLI tarball into .apiops/ directory
|
|
171
|
+
const apiopsDir = path.join(config.outputDir, '.apiops');
|
|
172
|
+
await fs.mkdir(apiopsDir, { recursive: true });
|
|
173
|
+
const tarballFilename = path.basename(config.cliPackage);
|
|
174
|
+
const tarballDest = path.join(apiopsDir, tarballFilename);
|
|
175
|
+
await fs.copyFile(path.resolve(config.cliPackage), tarballDest);
|
|
176
|
+
generatedFiles.directories.push('.apiops');
|
|
177
|
+
// Generate package.json with local tarball dependency
|
|
178
|
+
const tarballRelPath = path.join('.apiops', tarballFilename);
|
|
179
|
+
const packageJsonContent = generatePackageJson({ tarballRelPath });
|
|
180
|
+
const packageJsonPath = path.join(config.outputDir, 'package.json');
|
|
181
|
+
await fs.writeFile(packageJsonPath, packageJsonContent);
|
|
182
|
+
generatedFiles.configs.push('package.json');
|
|
183
|
+
// Generate pipeline files
|
|
184
|
+
if (config.ciProvider === 'github-actions') {
|
|
185
|
+
await this.generateGitHubActionsWorkflows(config, generatedFiles);
|
|
186
|
+
}
|
|
187
|
+
else if (config.ciProvider === 'azure-devops') {
|
|
188
|
+
await this.generateAzureDevOpsPipelines(config, generatedFiles);
|
|
189
|
+
}
|
|
190
|
+
// Generate config files
|
|
191
|
+
await this.generateConfigFiles(config, generatedFiles);
|
|
192
|
+
return generatedFiles;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Generate GitHub Actions workflow files
|
|
196
|
+
*/
|
|
197
|
+
async generateGitHubActionsWorkflows(config, generatedFiles) {
|
|
198
|
+
const workflowsDir = path.join(config.outputDir, '.github/workflows');
|
|
199
|
+
await fs.mkdir(workflowsDir, { recursive: true });
|
|
200
|
+
// Extract workflow
|
|
201
|
+
const extractWorkflowConfig = {
|
|
202
|
+
artifactDir: config.artifactDir,
|
|
203
|
+
};
|
|
204
|
+
const extractContent = generateExtractWorkflow(extractWorkflowConfig);
|
|
205
|
+
const extractPath = path.join(workflowsDir, 'run-apim-extractor.yml');
|
|
206
|
+
await fs.writeFile(extractPath, extractContent);
|
|
207
|
+
generatedFiles.pipelines.push('.github/workflows/run-apim-extractor.yml');
|
|
208
|
+
// Publish workflow
|
|
209
|
+
const publishWorkflowConfig = {
|
|
210
|
+
artifactDir: config.artifactDir,
|
|
211
|
+
environments: config.environments,
|
|
212
|
+
};
|
|
213
|
+
const publishContent = generatePublishWorkflow(publishWorkflowConfig);
|
|
214
|
+
const publishPath = path.join(workflowsDir, 'run-apim-publisher.yml');
|
|
215
|
+
await fs.writeFile(publishPath, publishContent);
|
|
216
|
+
generatedFiles.pipelines.push('.github/workflows/run-apim-publisher.yml');
|
|
217
|
+
// Copilot identity setup prompt — goes in .github/prompts/
|
|
218
|
+
const promptContent = generateIdentitySetupPrompt({
|
|
219
|
+
environments: config.environments,
|
|
220
|
+
});
|
|
221
|
+
const promptsDir = path.join(config.outputDir, '.github/prompts');
|
|
222
|
+
await fs.mkdir(promptsDir, { recursive: true });
|
|
223
|
+
const promptPath = path.join(promptsDir, 'apiops-setup-identity.prompt.md');
|
|
224
|
+
await fs.writeFile(promptPath, promptContent);
|
|
225
|
+
generatedFiles.configs.push('.github/prompts/apiops-setup-identity.prompt.md');
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Generate Azure DevOps pipeline files
|
|
229
|
+
*/
|
|
230
|
+
async generateAzureDevOpsPipelines(config, generatedFiles) {
|
|
231
|
+
const pipelinesDir = path.join(config.outputDir, '.azdo/pipelines');
|
|
232
|
+
await fs.mkdir(pipelinesDir, { recursive: true });
|
|
233
|
+
// Extract pipeline
|
|
234
|
+
const extractPipelineConfig = {
|
|
235
|
+
artifactDir: config.artifactDir,
|
|
236
|
+
};
|
|
237
|
+
const extractContent = generateExtractPipeline(extractPipelineConfig);
|
|
238
|
+
const extractPath = path.join(pipelinesDir, 'run-apim-extractor.yml');
|
|
239
|
+
await fs.writeFile(extractPath, extractContent);
|
|
240
|
+
generatedFiles.pipelines.push('.azdo/pipelines/run-apim-extractor.yml');
|
|
241
|
+
// Publish pipeline
|
|
242
|
+
const publishPipelineConfig = {
|
|
243
|
+
artifactDir: config.artifactDir,
|
|
244
|
+
environments: config.environments,
|
|
245
|
+
};
|
|
246
|
+
const publishContent = generatePublishPipeline(publishPipelineConfig);
|
|
247
|
+
const publishPath = path.join(pipelinesDir, 'run-apim-publisher.yml');
|
|
248
|
+
await fs.writeFile(publishPath, publishContent);
|
|
249
|
+
generatedFiles.pipelines.push('.azdo/pipelines/run-apim-publisher.yml');
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Generate configuration files
|
|
253
|
+
*/
|
|
254
|
+
async generateConfigFiles(config, generatedFiles) {
|
|
255
|
+
// Filter config
|
|
256
|
+
const filterContent = generateFilterConfig();
|
|
257
|
+
const filterPath = path.join(config.outputDir, 'configuration.extract.yaml');
|
|
258
|
+
await fs.writeFile(filterPath, filterContent);
|
|
259
|
+
generatedFiles.configs.push('configuration.extract.yaml');
|
|
260
|
+
// Override configs for each environment
|
|
261
|
+
for (const env of config.environments) {
|
|
262
|
+
const overrideContent = generateOverrideConfig(env);
|
|
263
|
+
const overridePath = path.join(config.outputDir, `configuration.${env}.yaml`);
|
|
264
|
+
await fs.writeFile(overridePath, overrideContent);
|
|
265
|
+
generatedFiles.configs.push(`configuration.${env}.yaml`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Save identity setup guide to file and tell user where to find it
|
|
270
|
+
*/
|
|
271
|
+
async outputIdentityGuide(config, generatedFiles) {
|
|
272
|
+
// Use placeholder values for the guide — users replace these with their actual Azure details
|
|
273
|
+
const subscriptionId = PLACEHOLDER_SUBSCRIPTION_ID;
|
|
274
|
+
const resourceGroup = PLACEHOLDER_RESOURCE_GROUP;
|
|
275
|
+
let guide;
|
|
276
|
+
if (config.ciProvider === 'github-actions') {
|
|
277
|
+
guide = identityGuideService.generateGitHubActionsGuide(subscriptionId, resourceGroup, config.environments);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
guide = identityGuideService.generateAzureDevOpsGuide(subscriptionId, resourceGroup, config.environments);
|
|
281
|
+
}
|
|
282
|
+
// Save guide to file
|
|
283
|
+
const guideFileName = config.ciProvider === 'github-actions'
|
|
284
|
+
? 'IDENTITY-SETUP-GITHUB.md'
|
|
285
|
+
: 'IDENTITY-SETUP-AZDO.md';
|
|
286
|
+
const guidePath = path.join(config.outputDir, guideFileName);
|
|
287
|
+
await fs.writeFile(guidePath, guide);
|
|
288
|
+
generatedFiles.configs.push(guideFileName);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Check if a file exists
|
|
292
|
+
*/
|
|
293
|
+
async fileExists(filePath) {
|
|
294
|
+
try {
|
|
295
|
+
await fs.access(filePath);
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
export const initService = new InitServiceImpl();
|
|
304
|
+
//# sourceMappingURL=init-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-service.js","sourceRoot":"","sources":["../../src/services/init-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Key Vault access pre-flight check for KeyVault-backed NamedValues.
|
|
3
|
+
*
|
|
4
|
+
* Validates that the APIM service's managed identity has been granted access
|
|
5
|
+
* to the Key Vault secret. Uses Azure ARM APIs to:
|
|
6
|
+
* 1. Retrieve the APIM service identity (system- or user-assigned)
|
|
7
|
+
* 2. Locate the Key Vault resource in the subscription
|
|
8
|
+
* 3. Check RBAC role assignments or access policies
|
|
9
|
+
*
|
|
10
|
+
* This check is best-effort when infrastructure queries fail (ARM token,
|
|
11
|
+
* vault in another subscription, etc.) — a warning is logged and the check
|
|
12
|
+
* is skipped. Hard errors are raised only for definitive misconfigurations
|
|
13
|
+
* such as "APIM has no managed identity" or "no matching RBAC / access policy".
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Error thrown when the APIM managed identity clearly lacks access to
|
|
17
|
+
* Key Vault, or the APIM service is missing the required identity
|
|
18
|
+
* configuration. Signals that the publish should fail immediately.
|
|
19
|
+
*/
|
|
20
|
+
export declare class KeyVaultAccessError extends Error {
|
|
21
|
+
constructor(message: string, options?: ErrorOptions);
|
|
22
|
+
}
|
|
23
|
+
/** APIM service context needed by the ARM-based check. */
|
|
24
|
+
export interface KeyVaultCheckContext {
|
|
25
|
+
subscriptionId: string;
|
|
26
|
+
resourceGroup: string;
|
|
27
|
+
serviceName: string;
|
|
28
|
+
}
|
|
29
|
+
/** Minimal response shape from an ARM HTTP call. */
|
|
30
|
+
export interface ArmResponse {
|
|
31
|
+
status: number;
|
|
32
|
+
json(): Promise<unknown>;
|
|
33
|
+
}
|
|
34
|
+
/** Injectable ARM HTTP call — production uses `fetch`, tests supply a stub. */
|
|
35
|
+
export type ArmRequestFn = (url: string, token: string) => Promise<ArmResponse>;
|
|
36
|
+
/** Provides ARM bearer tokens. */
|
|
37
|
+
export interface TokenProvider {
|
|
38
|
+
getToken(scopes: string | string[]): Promise<{
|
|
39
|
+
token: string;
|
|
40
|
+
}>;
|
|
41
|
+
}
|
|
42
|
+
/** Factory for creating token providers (injectable for testing). */
|
|
43
|
+
export type TokenProviderFactory = () => TokenProvider;
|
|
44
|
+
/**
|
|
45
|
+
* Verify that the APIM service's managed identity has access to the
|
|
46
|
+
* specified Key Vault secret via ARM RBAC or access policies.
|
|
47
|
+
*
|
|
48
|
+
* @param secretIdentifier Full Key Vault secret URI, e.g.
|
|
49
|
+
* `https://myvault.vault.azure.net/secrets/my-secret[/version]`
|
|
50
|
+
* @param identityClientId Client ID of the user-assigned managed identity
|
|
51
|
+
* that APIM will use. Omit for system-assigned identity.
|
|
52
|
+
* @param apimContext Subscription / resource-group / service-name of the
|
|
53
|
+
* APIM instance.
|
|
54
|
+
* @param tokenProviderFactory (testing) Override the ARM credential.
|
|
55
|
+
* @param armRequest (testing) Override the HTTP call.
|
|
56
|
+
*/
|
|
57
|
+
export declare function checkKeyVaultSecretAccess(secretIdentifier: string, identityClientId: string | undefined, apimContext: KeyVaultCheckContext, tokenProviderFactory?: TokenProviderFactory, armRequest?: ArmRequestFn): Promise<void>;
|
|
58
|
+
//# sourceMappingURL=keyvault-checker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyvault-checker.d.ts","sourceRoot":"","sources":["../../src/services/keyvault-checker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAiCH;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD;AAED,0DAA0D;AAC1D,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,oDAAoD;AACpD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1B;AAED,+EAA+E;AAC/E,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAEhF,kCAAkC;AAClC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjE;AAED,qEAAqE;AACrE,MAAM,MAAM,oBAAoB,GAAG,MAAM,aAAa,CAAC;AA0BvD;;;;;;;;;;;;GAYG;AACH,wBAAsB,yBAAyB,CAC7C,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,WAAW,EAAE,oBAAoB,EACjC,oBAAoB,GAAE,oBAAkD,EACxE,UAAU,GAAE,YAAgC,GAC3C,OAAO,CAAC,IAAI,CAAC,CAkFf"}
|