@varde-flyt/vfac 0.1.0 → 0.2.0-rc.1
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/dist/vfac.mjs +281 -116
- package/package.json +6 -1
package/dist/vfac.mjs
CHANGED
|
@@ -7384,7 +7384,7 @@ var VALUED = /* @__PURE__ */ new Set([
|
|
|
7384
7384
|
"region",
|
|
7385
7385
|
"profile"
|
|
7386
7386
|
]);
|
|
7387
|
-
var BOOLEAN = /* @__PURE__ */ new Set(["help", "version", "yes"]);
|
|
7387
|
+
var BOOLEAN = /* @__PURE__ */ new Set(["help", "version", "yes", "wait"]);
|
|
7388
7388
|
var REPEATABLE = /* @__PURE__ */ new Set(["secret"]);
|
|
7389
7389
|
function parseArgs(argv) {
|
|
7390
7390
|
const command = [];
|
|
@@ -7471,6 +7471,10 @@ function sessionUsable(session, endpoint, now, keyId) {
|
|
|
7471
7471
|
}
|
|
7472
7472
|
|
|
7473
7473
|
// src/client.ts
|
|
7474
|
+
var REQUEST_TIMEOUT_MS = 6e4;
|
|
7475
|
+
function requestSignal() {
|
|
7476
|
+
return typeof AbortSignal !== "undefined" && typeof AbortSignal.timeout === "function" ? AbortSignal.timeout(REQUEST_TIMEOUT_MS) : void 0;
|
|
7477
|
+
}
|
|
7474
7478
|
async function call(args) {
|
|
7475
7479
|
const url = new URL(args.path, args.endpoint);
|
|
7476
7480
|
if (url.origin !== new URL(args.endpoint).origin) {
|
|
@@ -7488,7 +7492,8 @@ async function call(args) {
|
|
|
7488
7492
|
authorization: `Bearer ${args.token}`,
|
|
7489
7493
|
...args.body === void 0 ? {} : { "content-type": "application/json" }
|
|
7490
7494
|
},
|
|
7491
|
-
...args.body === void 0 ? {} : { body: JSON.stringify(args.body) }
|
|
7495
|
+
...args.body === void 0 ? {} : { body: JSON.stringify(args.body) },
|
|
7496
|
+
signal: requestSignal()
|
|
7492
7497
|
});
|
|
7493
7498
|
} catch (error) {
|
|
7494
7499
|
return {
|
|
@@ -7549,7 +7554,8 @@ async function signIn(args) {
|
|
|
7549
7554
|
method: "POST",
|
|
7550
7555
|
headers: { "content-type": "application/json" },
|
|
7551
7556
|
body: JSON.stringify(credential),
|
|
7552
|
-
redirect: "manual"
|
|
7557
|
+
redirect: "manual",
|
|
7558
|
+
signal: requestSignal()
|
|
7553
7559
|
});
|
|
7554
7560
|
} catch (error) {
|
|
7555
7561
|
return {
|
|
@@ -7634,7 +7640,8 @@ async function probeMachineApi(args) {
|
|
|
7634
7640
|
try {
|
|
7635
7641
|
response = await doFetch(new URL("/api/v1", args.endpoint), {
|
|
7636
7642
|
method: "GET",
|
|
7637
|
-
redirect: "manual"
|
|
7643
|
+
redirect: "manual",
|
|
7644
|
+
signal: requestSignal()
|
|
7638
7645
|
});
|
|
7639
7646
|
} catch (error) {
|
|
7640
7647
|
return {
|
|
@@ -7759,7 +7766,7 @@ async function ensureSession(args) {
|
|
|
7759
7766
|
if (!checked.ok) return { ok: false, message: checked.message };
|
|
7760
7767
|
const endpoint = checked.endpoint;
|
|
7761
7768
|
const credential = credentialFromEnvironment();
|
|
7762
|
-
if (sessionUsable(stored.session, endpoint, args.now ?? /* @__PURE__ */ new Date(), credential?.keyId)) {
|
|
7769
|
+
if (args.forceExchange !== true && sessionUsable(stored.session, endpoint, args.now ?? /* @__PURE__ */ new Date(), credential?.keyId)) {
|
|
7763
7770
|
return { ok: true, ready: { endpoint, token: stored.session.token, stored } };
|
|
7764
7771
|
}
|
|
7765
7772
|
const signedIn = await signIn({
|
|
@@ -7775,6 +7782,133 @@ function resolveProject(flag, stored) {
|
|
|
7775
7782
|
return flag ?? stored.context?.projectId ?? null;
|
|
7776
7783
|
}
|
|
7777
7784
|
|
|
7785
|
+
// src/operations.ts
|
|
7786
|
+
var OPERATION_STATUSES = [
|
|
7787
|
+
"PENDING",
|
|
7788
|
+
"RUNNING",
|
|
7789
|
+
"SUCCEEDED",
|
|
7790
|
+
"FAILED",
|
|
7791
|
+
"CANCELLED"
|
|
7792
|
+
];
|
|
7793
|
+
var TERMINAL_STATUSES = ["SUCCEEDED", "FAILED", "CANCELLED"];
|
|
7794
|
+
var POLL_INTERVAL_MS = 5e3;
|
|
7795
|
+
var MAX_WAIT_MS = 60 * 60 * 1e3;
|
|
7796
|
+
function withProject(path, projectId) {
|
|
7797
|
+
return projectId === null ? path : `${path}?project=${encodeURIComponent(projectId)}`;
|
|
7798
|
+
}
|
|
7799
|
+
function operationPath(operationId, projectId) {
|
|
7800
|
+
return withProject(`/api/v1/operations/${encodeURIComponent(operationId)}`, projectId);
|
|
7801
|
+
}
|
|
7802
|
+
function classify(data) {
|
|
7803
|
+
const status = data["status"];
|
|
7804
|
+
if (typeof status !== "string") return "unknown";
|
|
7805
|
+
if (TERMINAL_STATUSES.includes(status)) return "terminal";
|
|
7806
|
+
if (OPERATION_STATUSES.includes(status)) return "working";
|
|
7807
|
+
return "unknown";
|
|
7808
|
+
}
|
|
7809
|
+
async function readOperation(args) {
|
|
7810
|
+
const result = await call({
|
|
7811
|
+
endpoint: args.endpoint,
|
|
7812
|
+
path: operationPath(args.operationId, args.projectId),
|
|
7813
|
+
token: args.token,
|
|
7814
|
+
...args.fetchImpl ? { fetchImpl: args.fetchImpl } : {}
|
|
7815
|
+
});
|
|
7816
|
+
return result.ok ? { ok: true, data: result.data } : { ok: false, error: result.error };
|
|
7817
|
+
}
|
|
7818
|
+
async function waitForOperation(args) {
|
|
7819
|
+
const deps = args.deps ?? {};
|
|
7820
|
+
const sleep = deps.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
7821
|
+
const now = deps.now ?? (() => Date.now());
|
|
7822
|
+
const deadline = now() + MAX_WAIT_MS;
|
|
7823
|
+
let token = args.token;
|
|
7824
|
+
let refreshed = false;
|
|
7825
|
+
let last = null;
|
|
7826
|
+
for (; ; ) {
|
|
7827
|
+
const read = await readOperation({
|
|
7828
|
+
endpoint: args.endpoint,
|
|
7829
|
+
token,
|
|
7830
|
+
operationId: args.operationId,
|
|
7831
|
+
projectId: args.projectId,
|
|
7832
|
+
...deps.fetchImpl ? { fetchImpl: deps.fetchImpl } : {}
|
|
7833
|
+
});
|
|
7834
|
+
if (!read.ok) {
|
|
7835
|
+
if (read.error.status === 401 && !refreshed && deps.refreshToken) {
|
|
7836
|
+
refreshed = true;
|
|
7837
|
+
const next = await deps.refreshToken();
|
|
7838
|
+
if (next !== null) {
|
|
7839
|
+
token = next;
|
|
7840
|
+
continue;
|
|
7841
|
+
}
|
|
7842
|
+
}
|
|
7843
|
+
return { kind: "read-failed", error: read.error };
|
|
7844
|
+
}
|
|
7845
|
+
last = read.data;
|
|
7846
|
+
const verdict = classify(read.data);
|
|
7847
|
+
if (verdict === "terminal") {
|
|
7848
|
+
return { kind: "settled", status: String(read.data["status"]), data: read.data };
|
|
7849
|
+
}
|
|
7850
|
+
if (verdict === "unknown") {
|
|
7851
|
+
return { kind: "unknown-status", status: String(read.data["status"]), data: read.data };
|
|
7852
|
+
}
|
|
7853
|
+
args.onProgress?.(read.data);
|
|
7854
|
+
if (now() + POLL_INTERVAL_MS >= deadline) return { kind: "timed-out", data: last };
|
|
7855
|
+
await sleep(POLL_INTERVAL_MS);
|
|
7856
|
+
}
|
|
7857
|
+
}
|
|
7858
|
+
function renderOperation(operationId, data) {
|
|
7859
|
+
const status = String(data["status"] ?? "UNKNOWN");
|
|
7860
|
+
const phase = data["phase"];
|
|
7861
|
+
const lines = [
|
|
7862
|
+
typeof phase === "string" && phase !== "" ? `${operationId} ${status} (${phase})` : `${operationId} ${status}`
|
|
7863
|
+
];
|
|
7864
|
+
const type = data["type"];
|
|
7865
|
+
if (typeof type === "string") lines[0] += ` ${type}`;
|
|
7866
|
+
const steps = Array.isArray(data["steps"]) ? data["steps"] : [];
|
|
7867
|
+
if (steps.length > 0) {
|
|
7868
|
+
lines.push("");
|
|
7869
|
+
for (const step of steps) {
|
|
7870
|
+
const state = String(step["state"] ?? "");
|
|
7871
|
+
lines.push(` ${markerFor(state)} ${String(step["label"] ?? step["key"] ?? "")}`);
|
|
7872
|
+
}
|
|
7873
|
+
}
|
|
7874
|
+
const failure = asRecord(data["failure"]);
|
|
7875
|
+
if (failure) {
|
|
7876
|
+
lines.push("");
|
|
7877
|
+
const stage = failure["stage"];
|
|
7878
|
+
lines.push(` Failed${typeof stage === "string" ? ` at ${stage}` : ""}`);
|
|
7879
|
+
const summary = failure["summary"];
|
|
7880
|
+
if (typeof summary === "string") lines.push(` ${summary}`);
|
|
7881
|
+
const detail = failure["detail"];
|
|
7882
|
+
if (typeof detail === "string" && detail !== "") lines.push(` ${detail}`);
|
|
7883
|
+
const cause = failure["cause"];
|
|
7884
|
+
if (typeof cause === "string") lines.push(` cause: ${cause}`);
|
|
7885
|
+
const retryable = failure["retryable"];
|
|
7886
|
+
if (typeof retryable === "boolean") {
|
|
7887
|
+
lines.push(
|
|
7888
|
+
retryable ? " Another attempt can succeed: `vfac lifecycle reconcile <pri_\u2026>`." : " Another attempt will fail the same way. Change something first."
|
|
7889
|
+
);
|
|
7890
|
+
}
|
|
7891
|
+
}
|
|
7892
|
+
return lines.join("\n");
|
|
7893
|
+
}
|
|
7894
|
+
function markerFor(state) {
|
|
7895
|
+
switch (state) {
|
|
7896
|
+
case "completed":
|
|
7897
|
+
return "\u2713";
|
|
7898
|
+
case "failed":
|
|
7899
|
+
return "\u2717";
|
|
7900
|
+
case "active":
|
|
7901
|
+
return "\u203A";
|
|
7902
|
+
case "pending":
|
|
7903
|
+
return "\xB7";
|
|
7904
|
+
default:
|
|
7905
|
+
return "-";
|
|
7906
|
+
}
|
|
7907
|
+
}
|
|
7908
|
+
function asRecord(value) {
|
|
7909
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
7910
|
+
}
|
|
7911
|
+
|
|
7778
7912
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
|
|
7779
7913
|
var external_exports = {};
|
|
7780
7914
|
__export(external_exports, {
|
|
@@ -15407,7 +15541,7 @@ function printError(error, json) {
|
|
|
15407
15541
|
}
|
|
15408
15542
|
|
|
15409
15543
|
// src/commands/apply.ts
|
|
15410
|
-
async function runApply(verb, parsed) {
|
|
15544
|
+
async function runApply(verb, parsed, deps = {}) {
|
|
15411
15545
|
const file = parsed.flags["file"];
|
|
15412
15546
|
if (!file) {
|
|
15413
15547
|
process.stderr.write("Which manifest? Use -f <file>.\n");
|
|
@@ -15526,19 +15660,105 @@ Read the operation that failed: \`vfac get operation <id>\`, or \`vfac get produ
|
|
|
15526
15660
|
body: { verb: "apply", action, payload: envelope }
|
|
15527
15661
|
});
|
|
15528
15662
|
if (!applied.ok) return printError(applied.error, json);
|
|
15529
|
-
|
|
15530
|
-
|
|
15663
|
+
const key = manifestKeyOf(manifest.document) ?? planned.data.manifestKey ?? "(unnamed)";
|
|
15664
|
+
const rawOperationId = applied.data["operationId"];
|
|
15665
|
+
const operationId = typeof rawOperationId === "string" && rawOperationId !== "" ? rawOperationId : null;
|
|
15666
|
+
if (!parsed.booleans.has("wait")) {
|
|
15667
|
+
if (json) {
|
|
15668
|
+
process.stdout.write(`${JSON.stringify({ action, ...applied.data })}
|
|
15531
15669
|
`);
|
|
15670
|
+
return 0;
|
|
15671
|
+
}
|
|
15672
|
+
process.stdout.write(
|
|
15673
|
+
`${action} ${key}
|
|
15674
|
+
` + (operationId !== null ? `Operation ${operationId} \u2014 follow it with: vfac get operation ${operationId}
|
|
15675
|
+
` : "")
|
|
15676
|
+
);
|
|
15532
15677
|
return 0;
|
|
15533
15678
|
}
|
|
15534
|
-
const
|
|
15535
|
-
|
|
15536
|
-
|
|
15537
|
-
|
|
15538
|
-
|
|
15539
|
-
|
|
15540
|
-
|
|
15541
|
-
|
|
15679
|
+
const finish = (operation, code) => {
|
|
15680
|
+
if (json) {
|
|
15681
|
+
process.stdout.write(`${JSON.stringify({ action, ...applied.data, operation })}
|
|
15682
|
+
`);
|
|
15683
|
+
}
|
|
15684
|
+
return code;
|
|
15685
|
+
};
|
|
15686
|
+
if (operationId === null) {
|
|
15687
|
+
if (!json) {
|
|
15688
|
+
process.stderr.write(
|
|
15689
|
+
`${action} ${key} was accepted, but the platform named no operation to follow, so --wait cannot confirm it. Check the resource: \`vfac get product-instance <pri_\u2026>\`.
|
|
15690
|
+
`
|
|
15691
|
+
);
|
|
15692
|
+
}
|
|
15693
|
+
return finish(null, 1);
|
|
15694
|
+
}
|
|
15695
|
+
if (!json) {
|
|
15696
|
+
process.stdout.write(`${action} ${key}
|
|
15697
|
+
`);
|
|
15698
|
+
process.stderr.write(`Operation ${operationId} \u2014 waiting for it to settle\u2026
|
|
15699
|
+
`);
|
|
15700
|
+
}
|
|
15701
|
+
const outcome = await waitForOperation({
|
|
15702
|
+
endpoint: session.ready.endpoint,
|
|
15703
|
+
token: session.ready.token,
|
|
15704
|
+
operationId,
|
|
15705
|
+
projectId,
|
|
15706
|
+
...json ? {} : {
|
|
15707
|
+
onProgress: (data) => {
|
|
15708
|
+
const phase = data["phase"];
|
|
15709
|
+
process.stderr.write(
|
|
15710
|
+
` ${String(data["status"] ?? "UNKNOWN")}` + (typeof phase === "string" && phase !== "" ? ` (${phase})` : "") + "\n"
|
|
15711
|
+
);
|
|
15712
|
+
}
|
|
15713
|
+
},
|
|
15714
|
+
// THE SESSION CAN EXPIRE UNDER A LONG WAIT. It is exchanged once per command
|
|
15715
|
+
// and lasts eight hours while this loop may run for one, so the two do not
|
|
15716
|
+
// overlap today — but a wait that died because its own token aged out would
|
|
15717
|
+
// report "unauthenticated" for a deploy that was fine, which is the worst
|
|
15718
|
+
// sentence to print at the end of an hour.
|
|
15719
|
+
deps: {
|
|
15720
|
+
...deps,
|
|
15721
|
+
refreshToken: deps.refreshToken ?? (async () => {
|
|
15722
|
+
const again = await ensureSession({
|
|
15723
|
+
endpointFlag: parsed.flags["endpoint"],
|
|
15724
|
+
forceExchange: true
|
|
15725
|
+
});
|
|
15726
|
+
return again.ok ? again.ready.token : null;
|
|
15727
|
+
})
|
|
15728
|
+
}
|
|
15729
|
+
});
|
|
15730
|
+
switch (outcome.kind) {
|
|
15731
|
+
case "settled": {
|
|
15732
|
+
if (!json) process.stdout.write(`${renderOperation(operationId, outcome.data)}
|
|
15733
|
+
`);
|
|
15734
|
+
return finish(outcome.data, outcome.status === "SUCCEEDED" ? 0 : 1);
|
|
15735
|
+
}
|
|
15736
|
+
case "unknown-status": {
|
|
15737
|
+
if (!json) {
|
|
15738
|
+
process.stderr.write(
|
|
15739
|
+
`The platform answered status "${outcome.status}", which this version of vfac does not understand. Upgrade vfac, and read the operation: \`vfac get operation ${operationId}\`.
|
|
15740
|
+
`
|
|
15741
|
+
);
|
|
15742
|
+
}
|
|
15743
|
+
return finish(outcome.data, 1);
|
|
15744
|
+
}
|
|
15745
|
+
case "read-failed": {
|
|
15746
|
+
if (!json) process.stderr.write(`${outcome.error.message}
|
|
15747
|
+
`);
|
|
15748
|
+
return finish(null, 1);
|
|
15749
|
+
}
|
|
15750
|
+
case "timed-out": {
|
|
15751
|
+
if (!json) {
|
|
15752
|
+
const status = outcome.data?.["status"];
|
|
15753
|
+
const phase = outcome.data?.["phase"];
|
|
15754
|
+
process.stderr.write(
|
|
15755
|
+
`Gave up waiting for ${operationId} after an hour. It was last ${typeof status === "string" ? status : "UNKNOWN"}${typeof phase === "string" && phase !== "" ? ` (${phase})` : ""}. It is still running in the platform \u2014 this command stopped waiting, it did not cancel anything. Follow it with: vfac get operation ${operationId}
|
|
15756
|
+
`
|
|
15757
|
+
);
|
|
15758
|
+
}
|
|
15759
|
+
return finish(outcome.data, 1);
|
|
15760
|
+
}
|
|
15761
|
+
}
|
|
15542
15762
|
}
|
|
15543
15763
|
|
|
15544
15764
|
// src/commands/context.ts
|
|
@@ -15710,6 +15930,47 @@ function report(checks, json) {
|
|
|
15710
15930
|
|
|
15711
15931
|
// src/commands/export.ts
|
|
15712
15932
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
15933
|
+
async function runExport(parsed) {
|
|
15934
|
+
if (parsed.command[1] !== "product-instance" && parsed.command[1] !== "resource") {
|
|
15935
|
+
process.stderr.write("Usage: vfac export product-instance pri_\u2026\n");
|
|
15936
|
+
return 2;
|
|
15937
|
+
}
|
|
15938
|
+
const instanceId = parsed.command[2];
|
|
15939
|
+
if (!instanceId) {
|
|
15940
|
+
process.stderr.write("Which resource? vfac export product-instance pri_\u2026\n");
|
|
15941
|
+
return 2;
|
|
15942
|
+
}
|
|
15943
|
+
const session = await ensureSession({ endpointFlag: parsed.flags["endpoint"] });
|
|
15944
|
+
if (!session.ok) {
|
|
15945
|
+
process.stderr.write(`${session.message}
|
|
15946
|
+
`);
|
|
15947
|
+
return 1;
|
|
15948
|
+
}
|
|
15949
|
+
const result = await call({
|
|
15950
|
+
endpoint: session.ready.endpoint,
|
|
15951
|
+
path: withProject(
|
|
15952
|
+
`/api/v1/resources/${encodeURIComponent(instanceId)}/manifest`,
|
|
15953
|
+
resolveProject(parsed.flags["project"], session.ready.stored)
|
|
15954
|
+
),
|
|
15955
|
+
token: session.ready.token
|
|
15956
|
+
});
|
|
15957
|
+
if (!result.ok) return printError(result.error, parsed.flags["output"] === "json");
|
|
15958
|
+
process.stdout.write(
|
|
15959
|
+
parsed.flags["output"] === "json" ? `${JSON.stringify(result.data, null, 2)}
|
|
15960
|
+
` : (0, import_yaml2.stringify)(result.data)
|
|
15961
|
+
);
|
|
15962
|
+
const metadata = result.data["metadata"];
|
|
15963
|
+
const hasKey = typeof metadata === "object" && metadata !== null && "key" in metadata;
|
|
15964
|
+
if (!hasKey) {
|
|
15965
|
+
process.stderr.write(
|
|
15966
|
+
`
|
|
15967
|
+
This resource is not managed by a manifest yet, so the document has no "metadata.key". Applying it as-is would create a SECOND resource. Add a key and run:
|
|
15968
|
+
vfac apply -f <file> --adopt ${instanceId}
|
|
15969
|
+
`
|
|
15970
|
+
);
|
|
15971
|
+
}
|
|
15972
|
+
return 0;
|
|
15973
|
+
}
|
|
15713
15974
|
|
|
15714
15975
|
// src/paging.ts
|
|
15715
15976
|
var MAX_PAGES = 50;
|
|
@@ -15892,62 +16153,6 @@ This is one page. Continue with --cursor ${result.nextCursor ?? ""}
|
|
|
15892
16153
|
process.stderr.write("Usage: vfac get product-instances | vfac get operation op_\u2026\n");
|
|
15893
16154
|
return 2;
|
|
15894
16155
|
}
|
|
15895
|
-
function withProject(path, projectId) {
|
|
15896
|
-
return projectId === null ? path : `${path}?project=${encodeURIComponent(projectId)}`;
|
|
15897
|
-
}
|
|
15898
|
-
function renderOperation(operationId, data) {
|
|
15899
|
-
const status = String(data["status"] ?? "UNKNOWN");
|
|
15900
|
-
const phase = data["phase"];
|
|
15901
|
-
const lines = [
|
|
15902
|
-
typeof phase === "string" && phase !== "" ? `${operationId} ${status} (${phase})` : `${operationId} ${status}`
|
|
15903
|
-
];
|
|
15904
|
-
const type = data["type"];
|
|
15905
|
-
if (typeof type === "string") lines[0] += ` ${type}`;
|
|
15906
|
-
const steps = Array.isArray(data["steps"]) ? data["steps"] : [];
|
|
15907
|
-
if (steps.length > 0) {
|
|
15908
|
-
lines.push("");
|
|
15909
|
-
for (const step of steps) {
|
|
15910
|
-
const state = String(step["state"] ?? "");
|
|
15911
|
-
lines.push(` ${markerFor(state)} ${String(step["label"] ?? step["key"] ?? "")}`);
|
|
15912
|
-
}
|
|
15913
|
-
}
|
|
15914
|
-
const failure = asRecord(data["failure"]);
|
|
15915
|
-
if (failure) {
|
|
15916
|
-
lines.push("");
|
|
15917
|
-
const stage = failure["stage"];
|
|
15918
|
-
lines.push(` Failed${typeof stage === "string" ? ` at ${stage}` : ""}`);
|
|
15919
|
-
const summary = failure["summary"];
|
|
15920
|
-
if (typeof summary === "string") lines.push(` ${summary}`);
|
|
15921
|
-
const detail = failure["detail"];
|
|
15922
|
-
if (typeof detail === "string" && detail !== "") lines.push(` ${detail}`);
|
|
15923
|
-
const cause = failure["cause"];
|
|
15924
|
-
if (typeof cause === "string") lines.push(` cause: ${cause}`);
|
|
15925
|
-
const retryable = failure["retryable"];
|
|
15926
|
-
if (typeof retryable === "boolean") {
|
|
15927
|
-
lines.push(
|
|
15928
|
-
retryable ? " Another attempt can succeed: `vfac lifecycle reconcile <pri_\u2026>`." : " Another attempt will fail the same way. Change something first."
|
|
15929
|
-
);
|
|
15930
|
-
}
|
|
15931
|
-
}
|
|
15932
|
-
return lines.join("\n");
|
|
15933
|
-
}
|
|
15934
|
-
function markerFor(state) {
|
|
15935
|
-
switch (state) {
|
|
15936
|
-
case "completed":
|
|
15937
|
-
return "\u2713";
|
|
15938
|
-
case "failed":
|
|
15939
|
-
return "\u2717";
|
|
15940
|
-
case "active":
|
|
15941
|
-
return "\u203A";
|
|
15942
|
-
case "pending":
|
|
15943
|
-
return "\xB7";
|
|
15944
|
-
default:
|
|
15945
|
-
return "-";
|
|
15946
|
-
}
|
|
15947
|
-
}
|
|
15948
|
-
function asRecord(value) {
|
|
15949
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
15950
|
-
}
|
|
15951
16156
|
function wrapOutput(text, width) {
|
|
15952
16157
|
const out = [];
|
|
15953
16158
|
let current = "";
|
|
@@ -15963,49 +16168,6 @@ function wrapOutput(text, width) {
|
|
|
15963
16168
|
return out;
|
|
15964
16169
|
}
|
|
15965
16170
|
|
|
15966
|
-
// src/commands/export.ts
|
|
15967
|
-
async function runExport(parsed) {
|
|
15968
|
-
if (parsed.command[1] !== "product-instance" && parsed.command[1] !== "resource") {
|
|
15969
|
-
process.stderr.write("Usage: vfac export product-instance pri_\u2026\n");
|
|
15970
|
-
return 2;
|
|
15971
|
-
}
|
|
15972
|
-
const instanceId = parsed.command[2];
|
|
15973
|
-
if (!instanceId) {
|
|
15974
|
-
process.stderr.write("Which resource? vfac export product-instance pri_\u2026\n");
|
|
15975
|
-
return 2;
|
|
15976
|
-
}
|
|
15977
|
-
const session = await ensureSession({ endpointFlag: parsed.flags["endpoint"] });
|
|
15978
|
-
if (!session.ok) {
|
|
15979
|
-
process.stderr.write(`${session.message}
|
|
15980
|
-
`);
|
|
15981
|
-
return 1;
|
|
15982
|
-
}
|
|
15983
|
-
const result = await call({
|
|
15984
|
-
endpoint: session.ready.endpoint,
|
|
15985
|
-
path: withProject(
|
|
15986
|
-
`/api/v1/resources/${encodeURIComponent(instanceId)}/manifest`,
|
|
15987
|
-
resolveProject(parsed.flags["project"], session.ready.stored)
|
|
15988
|
-
),
|
|
15989
|
-
token: session.ready.token
|
|
15990
|
-
});
|
|
15991
|
-
if (!result.ok) return printError(result.error, parsed.flags["output"] === "json");
|
|
15992
|
-
process.stdout.write(
|
|
15993
|
-
parsed.flags["output"] === "json" ? `${JSON.stringify(result.data, null, 2)}
|
|
15994
|
-
` : (0, import_yaml2.stringify)(result.data)
|
|
15995
|
-
);
|
|
15996
|
-
const metadata = result.data["metadata"];
|
|
15997
|
-
const hasKey = typeof metadata === "object" && metadata !== null && "key" in metadata;
|
|
15998
|
-
if (!hasKey) {
|
|
15999
|
-
process.stderr.write(
|
|
16000
|
-
`
|
|
16001
|
-
This resource is not managed by a manifest yet, so the document has no "metadata.key". Applying it as-is would create a SECOND resource. Add a key and run:
|
|
16002
|
-
vfac apply -f <file> --adopt ${instanceId}
|
|
16003
|
-
`
|
|
16004
|
-
);
|
|
16005
|
-
}
|
|
16006
|
-
return 0;
|
|
16007
|
-
}
|
|
16008
|
-
|
|
16009
16171
|
// src/commands/product.ts
|
|
16010
16172
|
async function runProduct(parsed) {
|
|
16011
16173
|
const json = parsed.flags["output"] === "json";
|
|
@@ -16622,7 +16784,7 @@ var USAGE = `vfac \u2014 deploy Varde Flyt resources from a manifest
|
|
|
16622
16784
|
[--region <region>] [--profile <profile>]
|
|
16623
16785
|
vfac validate -f resource.yaml
|
|
16624
16786
|
vfac plan -f resource.yaml
|
|
16625
|
-
vfac apply -f resource.yaml [--secret NAME=env:VAR] [--adopt pri_\u2026]
|
|
16787
|
+
vfac apply -f resource.yaml [--secret NAME=env:VAR] [--adopt pri_\u2026] [--wait]
|
|
16626
16788
|
vfac get product-instances
|
|
16627
16789
|
vfac get product-instance pri_\u2026 what it is, and its outputs
|
|
16628
16790
|
vfac get operation op_\u2026
|
|
@@ -16632,6 +16794,9 @@ var USAGE = `vfac \u2014 deploy Varde Flyt resources from a manifest
|
|
|
16632
16794
|
|
|
16633
16795
|
Options
|
|
16634
16796
|
-f, --file the manifest to read. YAML or JSON
|
|
16797
|
+
--wait apply: wait for the operation to settle, and exit non-zero if it
|
|
16798
|
+
fails. Without it, apply exits once the change is ACCEPTED \u2014
|
|
16799
|
+
which a pipeline reads as success before the deploy has happened
|
|
16635
16800
|
--project the Project to act in. Defaults to the stored context
|
|
16636
16801
|
--endpoint your organization's portal. Defaults to VFAC_ENDPOINT, then the
|
|
16637
16802
|
stored context
|
package/package.json
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@varde-flyt/vfac",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-rc.1",
|
|
4
4
|
"description": "Deploy and manage Varde Flyt Products from a manifest.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/digital-verdi/Varde-flyt-ai-cloud.git",
|
|
8
|
+
"directory": "packages/cli"
|
|
9
|
+
},
|
|
5
10
|
"type": "module",
|
|
6
11
|
"bin": {
|
|
7
12
|
"vfac": "./dist/vfac.mjs"
|