@codiac.io/codiac-cli 1.3.254 → 1.3.256
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/README.md +222 -170
- package/dist/command-base-enterprise.d.ts +10 -2
- package/dist/command-base-enterprise.js +12 -2
- package/dist/command-base-enterprise.js.map +1 -1
- package/dist/command-base-exec.js +22 -1
- package/dist/command-base-exec.js.map +1 -1
- package/dist/commands/asset/create.js +5 -4
- package/dist/commands/asset/create.js.map +1 -1
- package/dist/commands/asset/edit.d.ts +9 -0
- package/dist/commands/asset/edit.js +38 -0
- package/dist/commands/asset/edit.js.map +1 -1
- package/dist/commands/imageRegistry/edit.d.ts +47 -0
- package/dist/commands/imageRegistry/edit.js +163 -0
- package/dist/commands/imageRegistry/edit.js.map +1 -0
- package/dist/uilogic/registry-resolver.d.ts +21 -0
- package/dist/uilogic/registry-resolver.js +42 -0
- package/dist/uilogic/registry-resolver.js.map +1 -0
- package/oclif.manifest.json +103 -1
- package/package.json +1 -1
- package/skill/references/cli-reference.md +1 -1
- package/skill/references/concepts.md +26 -3
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
5
|
+
const contracts_1 = require("../../apis/codiac-api/contracts");
|
|
6
|
+
const command_base_exec_tenant_1 = require("../../command-base-exec-tenant");
|
|
7
|
+
const prettify_1 = require("../../prettify");
|
|
8
|
+
const cloud_resource_configurator_factory_1 = require("../../uilogic/cloud-resource-configurator-factory");
|
|
9
|
+
const cloud_provider_contextualizer_1 = require("../../uilogic/cloud-provider-contextualizer");
|
|
10
|
+
const image_registry_contextualizer_1 = require("../../uilogic/image-registry-contextualizer");
|
|
11
|
+
const image_contextualizer_1 = require("../../uilogic/image-contextualizer");
|
|
12
|
+
const registry_resolver_1 = require("../../uilogic/registry-resolver");
|
|
13
|
+
/**
|
|
14
|
+
* Edits the mutable attributes of an existing container-registry reference.
|
|
15
|
+
*
|
|
16
|
+
* WHY this exists: `imageRegistry capture` is create-only (it throws if the code already
|
|
17
|
+
* exists), so a fat-fingered registry url had no in-CLI fix — you had to `forget` and
|
|
18
|
+
* re-`capture`, which orphans every asset that referenced the old code. This command
|
|
19
|
+
* updates the record in place, keeping the code (the join key assets resolve against)
|
|
20
|
+
* stable so those assets keep resolving.
|
|
21
|
+
*
|
|
22
|
+
* The `code`, `provider`, and `type` are the record's identity and the relay's client
|
|
23
|
+
* selector, so they are immutable here; a change to any of those is a different registry
|
|
24
|
+
* (capture a new one). Only `url` and the private/public flag are editable.
|
|
25
|
+
*
|
|
26
|
+
* NOTE: assets carry a denormalized copy of `image.registry` from create time, and the
|
|
27
|
+
* deploy path reads that copy — so after fixing a registry url here, existing assets also
|
|
28
|
+
* need `cod asset edit --registry <code>` to re-resolve their embedded reference.
|
|
29
|
+
*/
|
|
30
|
+
class ImageRegistryEdit extends command_base_exec_tenant_1.CommandBaseExecTenant {
|
|
31
|
+
bootstrap() {
|
|
32
|
+
super.bootstrap();
|
|
33
|
+
cloud_provider_contextualizer_1.CloudProviderContextualizer.bootstrap(this.ioc);
|
|
34
|
+
this.ioc.bind(image_registry_contextualizer_1.ImageRegistryContextualizer).toSelf();
|
|
35
|
+
this.ioc.bind(image_contextualizer_1.ImageContextualizer).toSelf();
|
|
36
|
+
}
|
|
37
|
+
// --------------------------------------------------------------------
|
|
38
|
+
// Lazy-loaded properties
|
|
39
|
+
get uiRegistry() {
|
|
40
|
+
if (this._uiRegistry_backer === undefined) {
|
|
41
|
+
this._uiRegistry_backer = this.ioc.get(image_registry_contextualizer_1.ImageRegistryContextualizer);
|
|
42
|
+
}
|
|
43
|
+
return this._uiRegistry_backer;
|
|
44
|
+
}
|
|
45
|
+
// --------------------------------------------------------------------
|
|
46
|
+
captureArgs() {
|
|
47
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
const { flags } = yield this.parse(ImageRegistryEdit);
|
|
49
|
+
// partial.code identifies WHICH registry (immutable); partial.url / pullRequiresAuth
|
|
50
|
+
// carry the requested edits. private is only assigned when the user passed a --private
|
|
51
|
+
// or --no-private, so an omitted flag leaves the stored value untouched.
|
|
52
|
+
let partial = {};
|
|
53
|
+
if (flags.registry)
|
|
54
|
+
partial.code = flags.registry;
|
|
55
|
+
if (flags.url)
|
|
56
|
+
partial.url = flags.url.trim();
|
|
57
|
+
if (flags.private !== undefined)
|
|
58
|
+
partial.pullRequiresAuth = flags.private;
|
|
59
|
+
return [partial, false];
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
buildCandidate_silently(partial, _rootMap) {
|
|
63
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
64
|
+
if (!partial.code)
|
|
65
|
+
throw new Error("A registry code must be set (use --registry <code> to identify the registry to edit; run `cod imageRegistry list` for codes).");
|
|
66
|
+
const all = yield this._codiacApi.ImageRegistry.readMany({ all: true }, { throwNotFound: false });
|
|
67
|
+
const existing = (0, registry_resolver_1.resolveRegistryByCodeOrThrow)(all !== null && all !== void 0 ? all : [], partial.code, "--registry");
|
|
68
|
+
return this.applyEdits(existing, partial);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
buildCandidate_interactively(partial, _takeDefaults, _rootMap) {
|
|
72
|
+
var _a;
|
|
73
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
74
|
+
cloud_resource_configurator_factory_1.RegistryConfiguratorFactory.bootstrap(this.ioc);
|
|
75
|
+
const all = yield this._codiacApi.ImageRegistry.readMany({ all: true }, { throwNotFound: false });
|
|
76
|
+
if (!all || all.length === 0)
|
|
77
|
+
throw new Error("Cannot edit: no image registries are defined yet.");
|
|
78
|
+
// Resolve the target: honor --registry if given & valid, otherwise let the user pick.
|
|
79
|
+
let existing = partial.code ? all.find(r => r.code === partial.code) : undefined;
|
|
80
|
+
if (!existing) {
|
|
81
|
+
existing = yield this.uiRegistry.promptForExistingRegistry(contracts_1.PackageType.container, false, all);
|
|
82
|
+
}
|
|
83
|
+
if (!existing)
|
|
84
|
+
throw new Error("No registry selected.");
|
|
85
|
+
this._ui.userMessage(`Editing ${existing.type} image registry ${this._styler.bold(this._styler.hilite(existing.code))} ${this._styler.dim(`(current url: ${existing.url})`)}`);
|
|
86
|
+
// URL — default to the current value so pressing enter leaves it unchanged.
|
|
87
|
+
if (partial.url === undefined) {
|
|
88
|
+
partial.url = yield this._ui.prompt("url", "Registry url:", true, existing.url);
|
|
89
|
+
}
|
|
90
|
+
// Private/public — default to the current value.
|
|
91
|
+
if (partial.pullRequiresAuth === undefined) {
|
|
92
|
+
partial.pullRequiresAuth = yield this._ui.promptConfirm("private", "Requires authentication to pull (private)?", (_a = existing.pullRequiresAuth) !== null && _a !== void 0 ? _a : true);
|
|
93
|
+
}
|
|
94
|
+
const candidate = this.applyEdits(existing, partial);
|
|
95
|
+
this._ui.userMessage("About to save:");
|
|
96
|
+
this._ui.userMessage((0, prettify_1.prettify)(candidate));
|
|
97
|
+
const confirmed = yield this._ui.promptConfirm("confirm", "Save changes?", false);
|
|
98
|
+
if (!confirmed)
|
|
99
|
+
return undefined;
|
|
100
|
+
return candidate;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/** Overlays the requested edits onto the existing record, keeping every other field intact.
|
|
104
|
+
* Throws if the caller asked for no change at all. */
|
|
105
|
+
applyEdits(existing, partial) {
|
|
106
|
+
const candidate = Object.assign({}, existing);
|
|
107
|
+
let changed = false;
|
|
108
|
+
if (partial.url !== undefined && partial.url.length > 0 && partial.url !== existing.url) {
|
|
109
|
+
candidate.url = partial.url;
|
|
110
|
+
changed = true;
|
|
111
|
+
}
|
|
112
|
+
if (partial.pullRequiresAuth !== undefined && partial.pullRequiresAuth !== existing.pullRequiresAuth) {
|
|
113
|
+
candidate.pullRequiresAuth = partial.pullRequiresAuth;
|
|
114
|
+
changed = true;
|
|
115
|
+
}
|
|
116
|
+
if (!changed)
|
|
117
|
+
throw new Error(`Nothing to edit for [${existing.code}]. Provide --url and/or --private/--no-private with a value different from the current one.`);
|
|
118
|
+
return candidate;
|
|
119
|
+
}
|
|
120
|
+
buildCommandString(candidate, cmd) {
|
|
121
|
+
cmd.push("--registry", candidate.code);
|
|
122
|
+
cmd.push("--url", candidate.url);
|
|
123
|
+
cmd.push(candidate.pullRequiresAuth === false ? "--no-private" : "--private");
|
|
124
|
+
cmd.push("--silent");
|
|
125
|
+
return cmd;
|
|
126
|
+
}
|
|
127
|
+
executeTask(candidate) {
|
|
128
|
+
var _a;
|
|
129
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
130
|
+
const result = yield this._codiacApi.ImageRegistry.tryUpdate(candidate);
|
|
131
|
+
if (result.success) {
|
|
132
|
+
this._ui.userMessage(`Successfully updated ${candidate.type} image registry [${this._styler.hilite(candidate.code)}] — url: ${this._styler.hilite(candidate.url)}`);
|
|
133
|
+
}
|
|
134
|
+
else if (result.error) {
|
|
135
|
+
this._ui.userMessage(`${this._styler.colorCritical("Error")} updating ${candidate.type} image registry [${candidate.code}]: ${result.error.name} ${(_a = result.error.message) !== null && _a !== void 0 ? _a : result.error.stack}`);
|
|
136
|
+
throw result.error;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
this._ui.userMessage(`Failed to update image registry [${candidate.code}]. Check logs for details.`);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.default = ImageRegistryEdit;
|
|
145
|
+
ImageRegistryEdit.description = 'Changes the mutable attributes (url, private/public) of an existing container registry reference. The code, provider, and type are immutable.';
|
|
146
|
+
ImageRegistryEdit.aliases = [];
|
|
147
|
+
ImageRegistryEdit.examples = [
|
|
148
|
+
{ description: "Edit a registry interactively (select it, then change its url).", command: "<%= config.bin %> <%= command.id %>" },
|
|
149
|
+
{ description: "Correct a registry's url (identified by its Codiac code, not its url).", command: "<%= config.bin %> <%= command.id %> --registry devCodiacContainers --url newname.azurecr.io --silent" },
|
|
150
|
+
{ description: "Flip a registry to public (no pull authentication).", command: "<%= config.bin %> <%= command.id %> --registry 'Other|ghcr' --no-private --silent" },
|
|
151
|
+
{ description: "Render the equivalent silent command without executing it.", command: "<%= config.bin %> <%= command.id %> --registry devCodiacContainers --url newname.azurecr.io --to-script" },
|
|
152
|
+
];
|
|
153
|
+
ImageRegistryEdit.flags = {
|
|
154
|
+
help: core_1.Flags.help({ char: 'h' }),
|
|
155
|
+
registry: core_1.Flags.string({ char: 'r', required: false, description: "The Codiac code identifying the registry to edit (NOT its url). Run `cod imageRegistry list` to see codes." }),
|
|
156
|
+
url: core_1.Flags.string({ char: 'u', required: false, description: "The corrected container registry url." }),
|
|
157
|
+
private: core_1.Flags.boolean({ allowNo: true, description: 'Whether pulling from this registry requires authentication. Pass --private or --no-private only to change it; omit to leave it unchanged.' }),
|
|
158
|
+
silent: core_1.Flags.boolean({ exclusive: ["echo", "to-script"], description: 'Executes without any user interaction; fails on missing or invalid arguments.' }),
|
|
159
|
+
echo: core_1.Flags.boolean({ exclusive: ["to-script", "silent"], description: 'Renders the equivalent non-interactive command for future use before executing.' }),
|
|
160
|
+
"to-script": core_1.Flags.boolean({ exclusive: ["echo", "silent"], description: 'Renders the equivalent non-interactive command without executing it.' }),
|
|
161
|
+
};
|
|
162
|
+
ImageRegistryEdit.args = {};
|
|
163
|
+
//# sourceMappingURL=edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/commands/imageRegistry/edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ImageRegistry } from '../apis/codiac-api/contracts';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves an image registry from a pre-fetched list by its Codiac **code**, throwing a
|
|
4
|
+
* message that steers the user back on track when the lookup fails.
|
|
5
|
+
*
|
|
6
|
+
* WHY this exists: `-r`/`--registry` (and `--chart-repo`) match `ImageRegistry.code`
|
|
7
|
+
* (e.g. `devCodiacContainers`, `DockerHub|codiacimages`), NOT the registry URL. Users
|
|
8
|
+
* routinely paste the URL (`devcodiaccontainers.azurecr.io`) and get a bare "not found"
|
|
9
|
+
* that reads like the registry was never registered at all. When the miss looks like a
|
|
10
|
+
* pasted URL, we detect the registry it actually belongs to and name its code instead.
|
|
11
|
+
*
|
|
12
|
+
* Callers pass the full registry list (a single `readMany({ all: true })`) so the by-URL
|
|
13
|
+
* suggestion can be computed without a second round-trip.
|
|
14
|
+
*
|
|
15
|
+
* @param all Every registry reference for the tenant (from `ImageRegistry.readMany`).
|
|
16
|
+
* @param codeHint The value the user supplied to `--registry` / `--chart-repo`.
|
|
17
|
+
* @param flagLabel The flag name to name in the error (e.g. `--registry`, `--chart-repo`).
|
|
18
|
+
* @returns The matching `ImageRegistry`.
|
|
19
|
+
* @throws If no registry has that code (message suggests the right code when the hint is a URL).
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveRegistryByCodeOrThrow(all: ImageRegistry[], codeHint: string, flagLabel: string): ImageRegistry;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveRegistryByCodeOrThrow = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Resolves an image registry from a pre-fetched list by its Codiac **code**, throwing a
|
|
6
|
+
* message that steers the user back on track when the lookup fails.
|
|
7
|
+
*
|
|
8
|
+
* WHY this exists: `-r`/`--registry` (and `--chart-repo`) match `ImageRegistry.code`
|
|
9
|
+
* (e.g. `devCodiacContainers`, `DockerHub|codiacimages`), NOT the registry URL. Users
|
|
10
|
+
* routinely paste the URL (`devcodiaccontainers.azurecr.io`) and get a bare "not found"
|
|
11
|
+
* that reads like the registry was never registered at all. When the miss looks like a
|
|
12
|
+
* pasted URL, we detect the registry it actually belongs to and name its code instead.
|
|
13
|
+
*
|
|
14
|
+
* Callers pass the full registry list (a single `readMany({ all: true })`) so the by-URL
|
|
15
|
+
* suggestion can be computed without a second round-trip.
|
|
16
|
+
*
|
|
17
|
+
* @param all Every registry reference for the tenant (from `ImageRegistry.readMany`).
|
|
18
|
+
* @param codeHint The value the user supplied to `--registry` / `--chart-repo`.
|
|
19
|
+
* @param flagLabel The flag name to name in the error (e.g. `--registry`, `--chart-repo`).
|
|
20
|
+
* @returns The matching `ImageRegistry`.
|
|
21
|
+
* @throws If no registry has that code (message suggests the right code when the hint is a URL).
|
|
22
|
+
*/
|
|
23
|
+
function resolveRegistryByCodeOrThrow(all, codeHint, flagLabel) {
|
|
24
|
+
const found = (all !== null && all !== void 0 ? all : []).find(r => r.code === codeHint);
|
|
25
|
+
if (found)
|
|
26
|
+
return found;
|
|
27
|
+
// Miss. Did they paste a URL instead of a code? Match against known registry urls,
|
|
28
|
+
// tolerating a missing scheme (index.docker.io vs https://index.docker.io).
|
|
29
|
+
const bare = codeHint.replace(/^[a-z]+:\/\//i, "");
|
|
30
|
+
const byUrl = (all !== null && all !== void 0 ? all : []).find(r => {
|
|
31
|
+
var _a;
|
|
32
|
+
const rBare = ((_a = r.url) !== null && _a !== void 0 ? _a : "").replace(/^[a-z]+:\/\//i, "");
|
|
33
|
+
return r.url === codeHint || rBare === bare || (bare.length > 3 && rBare.includes(bare));
|
|
34
|
+
});
|
|
35
|
+
const lead = `No image registry has code [${codeHint}]. The ${flagLabel} flag takes the registry CODE, not its URL.`;
|
|
36
|
+
const tail = byUrl
|
|
37
|
+
? ` That looks like a URL — did you mean code [${byUrl.code}] (its url is ${byUrl.url})?`
|
|
38
|
+
: ` Run \`cod imageRegistry list\` to see the available codes (e.g. 'devCodiacContainers', not 'devcodiaccontainers.azurecr.io').`;
|
|
39
|
+
throw new Error(lead + tail);
|
|
40
|
+
}
|
|
41
|
+
exports.resolveRegistryByCodeOrThrow = resolveRegistryByCodeOrThrow;
|
|
42
|
+
//# sourceMappingURL=registry-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-resolver.js","sourceRoot":"","sources":["../../src/uilogic/registry-resolver.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,4BAA4B,CAAC,GAAoB,EAAE,QAAgB,EAAE,SAAiB;IACpG,MAAM,KAAK,GAAG,CAAC,GAAG,aAAH,GAAG,cAAH,GAAG,GAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACzD,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IAExB,mFAAmF;IACnF,4EAA4E;IAC5E,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,CAAC,GAAG,aAAH,GAAG,cAAH,GAAG,GAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;;QACjC,MAAM,KAAK,GAAG,CAAC,MAAA,CAAC,CAAC,GAAG,mCAAI,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QACzD,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,+BAA+B,QAAQ,UAAU,SAAS,6CAA6C,CAAC;IACrH,MAAM,IAAI,GAAG,KAAK;QAChB,CAAC,CAAC,+CAA+C,KAAK,CAAC,IAAI,iBAAiB,KAAK,CAAC,GAAG,IAAI;QACzF,CAAC,CAAC,gIAAgI,CAAC;IACrI,MAAM,IAAI,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AAC/B,CAAC;AAjBD,oEAiBC"}
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.3.
|
|
2
|
+
"version": "1.3.256",
|
|
3
3
|
"commands": {
|
|
4
4
|
"branch": {
|
|
5
5
|
"id": "branch",
|
|
@@ -2017,6 +2017,10 @@
|
|
|
2017
2017
|
{
|
|
2018
2018
|
"description": "Remove a deploy condition so the asset always deploys.",
|
|
2019
2019
|
"command": "<%= config.bin %> <%= command.id %> -e myEnterprise -n my-api --remove-deploy-condition --silent"
|
|
2020
|
+
},
|
|
2021
|
+
{
|
|
2022
|
+
"description": "Re-point an asset at a corrected registry (by its Codiac code, not its url).",
|
|
2023
|
+
"command": "<%= config.bin %> <%= command.id %> -e myEnterprise -n my-api --registry devCodiacContainers --silent"
|
|
2020
2024
|
}
|
|
2021
2025
|
],
|
|
2022
2026
|
"flags": {
|
|
@@ -2044,6 +2048,14 @@
|
|
|
2044
2048
|
"required": false,
|
|
2045
2049
|
"multiple": false
|
|
2046
2050
|
},
|
|
2051
|
+
"registry": {
|
|
2052
|
+
"name": "registry",
|
|
2053
|
+
"type": "option",
|
|
2054
|
+
"char": "r",
|
|
2055
|
+
"description": "Re-point this asset at a different container registry, given by its Codiac registry CODE (run `cod imageRegistry list`; NOT the registry url). Re-resolves the asset's embedded registry reference — use this after correcting a registry url so the asset picks up the fix.",
|
|
2056
|
+
"required": false,
|
|
2057
|
+
"multiple": false
|
|
2058
|
+
},
|
|
2047
2059
|
"deploy-condition": {
|
|
2048
2060
|
"name": "deploy-condition",
|
|
2049
2061
|
"type": "option",
|
|
@@ -7445,6 +7457,96 @@
|
|
|
7445
7457
|
},
|
|
7446
7458
|
"args": {}
|
|
7447
7459
|
},
|
|
7460
|
+
"imageRegistry:edit": {
|
|
7461
|
+
"id": "imageRegistry:edit",
|
|
7462
|
+
"description": "Changes the mutable attributes (url, private/public) of an existing container registry reference. The code, provider, and type are immutable.",
|
|
7463
|
+
"strict": true,
|
|
7464
|
+
"pluginName": "@codiac.io/codiac-cli",
|
|
7465
|
+
"pluginAlias": "@codiac.io/codiac-cli",
|
|
7466
|
+
"pluginType": "core",
|
|
7467
|
+
"aliases": [],
|
|
7468
|
+
"hiddenAliases": [],
|
|
7469
|
+
"examples": [
|
|
7470
|
+
{
|
|
7471
|
+
"description": "Edit a registry interactively (select it, then change its url).",
|
|
7472
|
+
"command": "<%= config.bin %> <%= command.id %>"
|
|
7473
|
+
},
|
|
7474
|
+
{
|
|
7475
|
+
"description": "Correct a registry's url (identified by its Codiac code, not its url).",
|
|
7476
|
+
"command": "<%= config.bin %> <%= command.id %> --registry devCodiacContainers --url newname.azurecr.io --silent"
|
|
7477
|
+
},
|
|
7478
|
+
{
|
|
7479
|
+
"description": "Flip a registry to public (no pull authentication).",
|
|
7480
|
+
"command": "<%= config.bin %> <%= command.id %> --registry 'Other|ghcr' --no-private --silent"
|
|
7481
|
+
},
|
|
7482
|
+
{
|
|
7483
|
+
"description": "Render the equivalent silent command without executing it.",
|
|
7484
|
+
"command": "<%= config.bin %> <%= command.id %> --registry devCodiacContainers --url newname.azurecr.io --to-script"
|
|
7485
|
+
}
|
|
7486
|
+
],
|
|
7487
|
+
"flags": {
|
|
7488
|
+
"help": {
|
|
7489
|
+
"name": "help",
|
|
7490
|
+
"type": "boolean",
|
|
7491
|
+
"char": "h",
|
|
7492
|
+
"description": "Show CLI help.",
|
|
7493
|
+
"allowNo": false
|
|
7494
|
+
},
|
|
7495
|
+
"registry": {
|
|
7496
|
+
"name": "registry",
|
|
7497
|
+
"type": "option",
|
|
7498
|
+
"char": "r",
|
|
7499
|
+
"description": "The Codiac code identifying the registry to edit (NOT its url). Run `cod imageRegistry list` to see codes.",
|
|
7500
|
+
"required": false,
|
|
7501
|
+
"multiple": false
|
|
7502
|
+
},
|
|
7503
|
+
"url": {
|
|
7504
|
+
"name": "url",
|
|
7505
|
+
"type": "option",
|
|
7506
|
+
"char": "u",
|
|
7507
|
+
"description": "The corrected container registry url.",
|
|
7508
|
+
"required": false,
|
|
7509
|
+
"multiple": false
|
|
7510
|
+
},
|
|
7511
|
+
"private": {
|
|
7512
|
+
"name": "private",
|
|
7513
|
+
"type": "boolean",
|
|
7514
|
+
"description": "Whether pulling from this registry requires authentication. Pass --private or --no-private only to change it; omit to leave it unchanged.",
|
|
7515
|
+
"allowNo": true
|
|
7516
|
+
},
|
|
7517
|
+
"silent": {
|
|
7518
|
+
"name": "silent",
|
|
7519
|
+
"type": "boolean",
|
|
7520
|
+
"description": "Executes without any user interaction; fails on missing or invalid arguments.",
|
|
7521
|
+
"allowNo": false,
|
|
7522
|
+
"exclusive": [
|
|
7523
|
+
"echo",
|
|
7524
|
+
"to-script"
|
|
7525
|
+
]
|
|
7526
|
+
},
|
|
7527
|
+
"echo": {
|
|
7528
|
+
"name": "echo",
|
|
7529
|
+
"type": "boolean",
|
|
7530
|
+
"description": "Renders the equivalent non-interactive command for future use before executing.",
|
|
7531
|
+
"allowNo": false,
|
|
7532
|
+
"exclusive": [
|
|
7533
|
+
"to-script",
|
|
7534
|
+
"silent"
|
|
7535
|
+
]
|
|
7536
|
+
},
|
|
7537
|
+
"to-script": {
|
|
7538
|
+
"name": "to-script",
|
|
7539
|
+
"type": "boolean",
|
|
7540
|
+
"description": "Renders the equivalent non-interactive command without executing it.",
|
|
7541
|
+
"allowNo": false,
|
|
7542
|
+
"exclusive": [
|
|
7543
|
+
"echo",
|
|
7544
|
+
"silent"
|
|
7545
|
+
]
|
|
7546
|
+
}
|
|
7547
|
+
},
|
|
7548
|
+
"args": {}
|
|
7549
|
+
},
|
|
7448
7550
|
"imageRegistry:forget": {
|
|
7449
7551
|
"id": "imageRegistry:forget",
|
|
7450
7552
|
"description": "Removes the reference to the given container registry for the tenant. Does NOT delete the registry itself.",
|
package/package.json
CHANGED
|
@@ -33,7 +33,7 @@ Top-level: `branch`, `build`, `cli`, `commit`, `deploy`, `dep`, `identity`, `ini
|
|
|
33
33
|
- **filestore**: `capture`, `forget`, `list`
|
|
34
34
|
- **host**: `map`, `list`, `view`, `delete`
|
|
35
35
|
- **identity**: `list`, `delete`
|
|
36
|
-
- **imageRegistry**: `capture`, `forget`, `list`; `pullSecret set/unset`
|
|
36
|
+
- **imageRegistry**: `capture`, `edit`, `forget`, `list`; `pullSecret set/unset` *(`-r`/`--registry` and `--chart-repo` take the registry **code**, e.g. `devCodiacContainers`, NOT its url; `edit` fixes an existing registry's url in place)*
|
|
37
37
|
- **images**: `add`, `list`, `patch`, `remove`, `version`, `version bump`
|
|
38
38
|
- **import**: `cluster`
|
|
39
39
|
- **kit**: `create`
|
|
@@ -74,9 +74,32 @@ Lifecycle:
|
|
|
74
74
|
4. Inspect/operate: `cod asset list`, `cod asset view` (logs/term/exec/env/config/status),
|
|
75
75
|
`cod asset undeploy`, `cod asset recycle`.
|
|
76
76
|
|
|
77
|
-
**Image registries
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
**Image registries.** Never AWS ECR — images live in **Docker Hub** or **Azure Container
|
|
78
|
+
Registry (ACR)** (plus generic OCI registries like ghcr/quay/Harbor via provider `other`).
|
|
79
|
+
A registry is a first-class object with two fields you must **not** conflate:
|
|
80
|
+
|
|
81
|
+
- **`code`** — the Codiac identifier you reference everywhere: `-r`/`--registry` on
|
|
82
|
+
`asset create`, `--chart-repo`, `asset edit --registry`. Its shape depends on how it was
|
|
83
|
+
captured — Azure ACR → the resource name (`devCodiacContainers`); Docker Hub →
|
|
84
|
+
`DockerHub|<org>` (`DockerHub|codiacimages`); generic OCI → `Other|<label>` (`Other|ghcr`);
|
|
85
|
+
Helm repo → `helm|<provider>|<name>` (`helm|artifactHub|hermes-agent`).
|
|
86
|
+
- **`url`** — the registry endpoint (`devCodiacContainers.azurecr.io`, `index.docker.io`).
|
|
87
|
+
|
|
88
|
+
`-r`/`--registry` matches the **code**, never the url. Passing the url
|
|
89
|
+
(`devCodiacContainers.azurecr.io`) fails with *"No image registry has code […]"* — which
|
|
90
|
+
reads like it was never registered. **Always `cod imageRegistry list` first** to read the
|
|
91
|
+
exact code.
|
|
92
|
+
|
|
93
|
+
Managing them: `cod imageRegistry capture` (add — create-only; it *throws* if the code already
|
|
94
|
+
exists), `cod imageRegistry edit` (fix an existing registry's **url** or private/public in
|
|
95
|
+
place — `code`/`provider`/`type` are immutable), `cod imageRegistry forget` (drop the
|
|
96
|
+
reference), `cod imageRegistry list`, and `cod imageRegistry pullSecret set/unset` for auth.
|
|
97
|
+
`cod secretStore ...` holds the pull secrets themselves.
|
|
98
|
+
|
|
99
|
+
**Gotcha — assets snapshot their registry.** An asset stores a *copy* of `image.registry`
|
|
100
|
+
(url included) at create time, and the deploy path reads that copy, not the registry record.
|
|
101
|
+
So after `cod imageRegistry edit` corrects a url, already-created assets still carry the old
|
|
102
|
+
one — run `cod asset edit --registry <code>` on each to re-resolve its embedded reference.
|
|
80
103
|
|
|
81
104
|
The `type` of an asset (`helm` vs `service`) changes which config `targetFile`s apply (see §3):
|
|
82
105
|
`[helm]` values for charts, `[env]`/`[footprint]`/etc. for services.
|