@mikarinneoracle/oci-cdk-code-only-preview 0.0.5 → 0.0.7
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/bin/deploy-code-only.js +8 -16
- package/bin/destroy-code-only.js +9 -10
- package/bin/ocdk.js +55 -2
- package/package.json +1 -1
package/bin/deploy-code-only.js
CHANGED
|
@@ -89,9 +89,13 @@ function createArchive() {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
function jsonOci(args) {
|
|
92
|
-
const output = runOci([...args, '--output', 'json']);
|
|
92
|
+
const output = runOci([...args, '--output', 'json']).trim();
|
|
93
|
+
const objectStart = output.indexOf('{');
|
|
94
|
+
const arrayStart = output.indexOf('[');
|
|
95
|
+
const start = objectStart !== -1 ? objectStart : arrayStart;
|
|
96
|
+
const end = Math.max(output.lastIndexOf('}'), output.lastIndexOf(']'));
|
|
93
97
|
try {
|
|
94
|
-
return JSON.parse(output);
|
|
98
|
+
return JSON.parse(start === -1 || end < start ? output : output.slice(start, end + 1));
|
|
95
99
|
} catch {
|
|
96
100
|
fail(`OCI CLI returned invalid JSON for: ${args.join(' ')}`);
|
|
97
101
|
}
|
|
@@ -101,16 +105,6 @@ function resourceDisplayName(resource) {
|
|
|
101
105
|
return resource.displayName || resource['display-name'] || '';
|
|
102
106
|
}
|
|
103
107
|
|
|
104
|
-
function findApplicationId(compartmentId, appName) {
|
|
105
|
-
const result = jsonOci(['fn', 'application', 'list', '--compartment-id', compartmentId, '--all']);
|
|
106
|
-
const matches = (result.data || []).filter((app) => resourceDisplayName(app) === appName);
|
|
107
|
-
if (matches.length === 0) {
|
|
108
|
-
fail(`Functions Application "${appName}" was not found. Code-only deploy requires an existing application.`);
|
|
109
|
-
}
|
|
110
|
-
if (matches.length > 1) fail(`multiple Functions Applications are named "${appName}"; use a unique application name.`);
|
|
111
|
-
return matches[0].id;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
108
|
function findFunctionId(applicationId, functionName) {
|
|
115
109
|
const result = jsonOci(['fn', 'function', 'list', '--application-id', applicationId, '--all']);
|
|
116
110
|
const matches = (result.data || []).filter((fn) => resourceDisplayName(fn) === functionName);
|
|
@@ -130,12 +124,10 @@ function verifyPreviewCli() {
|
|
|
130
124
|
function main() {
|
|
131
125
|
const unexpectedArgs = process.argv.slice(2).filter((arg) => arg !== '--auto-approve');
|
|
132
126
|
if (unexpectedArgs.length) fail(`unsupported code-only deploy option(s): ${unexpectedArgs.join(', ')}`);
|
|
133
|
-
const compartmentId = (process.env.OCI_COMPARTMENT_ID || process.env.OCI_COMPARTMENT_OCID || '').trim();
|
|
134
|
-
if (!compartmentId) fail('set OCI_COMPARTMENT_ID (or OCI_COMPARTMENT_OCID).');
|
|
135
|
-
|
|
136
127
|
verifyPreviewCli();
|
|
137
128
|
const metadata = readFunctionMetadata();
|
|
138
|
-
const applicationId =
|
|
129
|
+
const applicationId = (process.env.OCI_FUNCTION_APP_ID || '').trim();
|
|
130
|
+
if (!applicationId) fail('Terraform output OCI_FUNCTION_APP_ID is missing. Run through "ocdk deploy --code-only".');
|
|
139
131
|
const archive = createArchive();
|
|
140
132
|
try {
|
|
141
133
|
const functionId = findFunctionId(applicationId, metadata.functionName);
|
package/bin/destroy-code-only.js
CHANGED
|
@@ -24,8 +24,13 @@ function runOci(args) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
function jsonOci(args) {
|
|
27
|
+
const output = runOci([...args, '--output', 'json']).trim();
|
|
28
|
+
const objectStart = output.indexOf('{');
|
|
29
|
+
const arrayStart = output.indexOf('[');
|
|
30
|
+
const start = objectStart !== -1 ? objectStart : arrayStart;
|
|
31
|
+
const end = Math.max(output.lastIndexOf('}'), output.lastIndexOf(']'));
|
|
27
32
|
try {
|
|
28
|
-
return JSON.parse(
|
|
33
|
+
return JSON.parse(start === -1 || end < start ? output : output.slice(start, end + 1));
|
|
29
34
|
} catch (error) {
|
|
30
35
|
fail(`OCI CLI returned invalid JSON for: ${args.join(' ')} (${error.message})`);
|
|
31
36
|
}
|
|
@@ -41,23 +46,17 @@ function resourceDisplayName(resource) {
|
|
|
41
46
|
}
|
|
42
47
|
|
|
43
48
|
function main() {
|
|
44
|
-
const compartmentId = (process.env.OCI_COMPARTMENT_ID || process.env.OCI_COMPARTMENT_OCID || '').trim();
|
|
45
|
-
if (!compartmentId) fail('set OCI_COMPARTMENT_ID (or OCI_COMPARTMENT_OCID).');
|
|
46
49
|
const funcYamlPath = path.join(projectDir, 'func.yaml');
|
|
47
50
|
const yaml = fs.existsSync(funcYamlPath) ? fs.readFileSync(funcYamlPath, 'utf8') : '';
|
|
48
51
|
const functionName = (process.env.OCI_FUNCTION_NAME || yamlValue(yaml, 'name')).trim();
|
|
49
52
|
const appName = (process.env.OCI_FUNCTION_APP_NAME || functionName).trim();
|
|
50
53
|
if (!functionName) fail('set OCI_FUNCTION_NAME or add name: to func.yaml.');
|
|
51
54
|
if (!appName) fail('set OCI_FUNCTION_APP_NAME.');
|
|
55
|
+
const applicationId = (process.env.OCI_FUNCTION_APP_ID || '').trim();
|
|
56
|
+
if (!applicationId) fail('Terraform output OCI_FUNCTION_APP_ID is missing. Run through "ocdk destroy --code-only".');
|
|
52
57
|
|
|
53
58
|
const version = runOci(['--version']).trim();
|
|
54
|
-
const
|
|
55
|
-
const app = apps.find((item) => resourceDisplayName(item) === appName);
|
|
56
|
-
if (!app) {
|
|
57
|
-
console.log(`Functions Application ${appName} is absent; no code-only function needs deletion.`);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
const functions = jsonOci(['fn', 'function', 'list', '--application-id', app.id, '--all']).data || [];
|
|
59
|
+
const functions = jsonOci(['fn', 'function', 'list', '--application-id', applicationId, '--all']).data || [];
|
|
61
60
|
const matches = functions.filter((item) => resourceDisplayName(item) === functionName);
|
|
62
61
|
if (matches.length === 0) {
|
|
63
62
|
console.log(`Code-only function ${functionName} is absent; continuing with Terraform destroy.`);
|
package/bin/ocdk.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
const { spawnSync } = require('child_process');
|
|
8
8
|
const path = require('path');
|
|
9
|
+
const os = require('os');
|
|
9
10
|
|
|
10
11
|
const fs = require('fs');
|
|
11
12
|
const root = path.join(__dirname, '..');
|
|
@@ -18,6 +19,44 @@ const codeOnlyEnabled =
|
|
|
18
19
|
args.includes('-code-only') ||
|
|
19
20
|
args.includes('--code-only');
|
|
20
21
|
|
|
22
|
+
function findFunctionAppId(value) {
|
|
23
|
+
if (!value || typeof value !== 'object') return undefined;
|
|
24
|
+
if (Object.prototype.hasOwnProperty.call(value, 'function_app_id')) {
|
|
25
|
+
const output = value.function_app_id;
|
|
26
|
+
if (typeof output === 'string') return output;
|
|
27
|
+
if (output && typeof output === 'object' && typeof output.value === 'string') return output.value;
|
|
28
|
+
}
|
|
29
|
+
for (const child of Object.values(value)) {
|
|
30
|
+
const found = findFunctionAppId(child);
|
|
31
|
+
if (found) return found;
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function resolveCodeOnlyFunctionAppId(env) {
|
|
37
|
+
if (env.OCI_FUNCTION_APP_ID?.trim()) return env.OCI_FUNCTION_APP_ID.trim();
|
|
38
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ocdk-function-app-output-'));
|
|
39
|
+
const outputFile = path.join(tempDir, 'outputs.json');
|
|
40
|
+
const stackName = env.OCI_STACK_NAME || 'oci-stack';
|
|
41
|
+
try {
|
|
42
|
+
const result = spawnSync('npm', ['run', '--silent', 'cdktf', '--', 'output', stackName, '--outputs-file', outputFile], {
|
|
43
|
+
cwd: root,
|
|
44
|
+
env,
|
|
45
|
+
encoding: 'utf8',
|
|
46
|
+
shell: false,
|
|
47
|
+
});
|
|
48
|
+
if (result.status !== 0 || !fs.existsSync(outputFile)) {
|
|
49
|
+
const detail = (result.stderr || result.stdout || '').trim();
|
|
50
|
+
throw new Error(detail || 'cdktf output did not produce an output file.');
|
|
51
|
+
}
|
|
52
|
+
const appId = findFunctionAppId(JSON.parse(fs.readFileSync(outputFile, 'utf8')));
|
|
53
|
+
if (!appId) throw new Error('Terraform output "function_app_id" is missing.');
|
|
54
|
+
return appId;
|
|
55
|
+
} finally {
|
|
56
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
21
60
|
const npmRunCommands = ['deploy', 'diff', 'synth', 'destroy', 'list', 'get'];
|
|
22
61
|
|
|
23
62
|
if (!command || command.startsWith('-')) {
|
|
@@ -112,11 +151,18 @@ if (command === 'deploy' && codeOnlyEnabled) {
|
|
|
112
151
|
env,
|
|
113
152
|
});
|
|
114
153
|
if (infrastructure.status !== 0) process.exit(infrastructure.status ?? 1);
|
|
154
|
+
let functionAppId;
|
|
155
|
+
try {
|
|
156
|
+
functionAppId = resolveCodeOnlyFunctionAppId(env);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error(`Code-only deploy failed: could not read Terraform Function App output: ${error.message}`);
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
115
161
|
const result = spawnSync('node', [script], {
|
|
116
162
|
stdio: 'inherit',
|
|
117
163
|
cwd: projectDir,
|
|
118
164
|
shell: false,
|
|
119
|
-
env,
|
|
165
|
+
env: { ...env, OCI_FUNCTION_APP_ID: functionAppId },
|
|
120
166
|
});
|
|
121
167
|
process.exit(result.status ?? 1);
|
|
122
168
|
}
|
|
@@ -137,11 +183,18 @@ if (command === 'destroy' && codeOnlyEnabled) {
|
|
|
137
183
|
OCI_STACK_ACTION: 'function-only',
|
|
138
184
|
OCI_PROJECT_DIR: projectDir,
|
|
139
185
|
};
|
|
186
|
+
let functionAppId;
|
|
187
|
+
try {
|
|
188
|
+
functionAppId = resolveCodeOnlyFunctionAppId(env);
|
|
189
|
+
} catch (error) {
|
|
190
|
+
console.error(`Code-only destroy failed: could not read Terraform Function App output: ${error.message}`);
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
140
193
|
const functionDestroy = spawnSync('node', [script], {
|
|
141
194
|
stdio: 'inherit',
|
|
142
195
|
cwd: projectDir,
|
|
143
196
|
shell: false,
|
|
144
|
-
env,
|
|
197
|
+
env: { ...env, OCI_FUNCTION_APP_ID: functionAppId },
|
|
145
198
|
});
|
|
146
199
|
if (functionDestroy.status !== 0) process.exit(functionDestroy.status ?? 1);
|
|
147
200
|
const infrastructure = spawnSync('npm', ['run', '--silent', 'destroy', '--', ...passthroughArgs], {
|