@codiac.io/codiac-cli 1.3.267 → 1.3.273
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 +359 -171
- package/dist/commands/ai/agent/csp/add.d.ts +50 -0
- package/dist/commands/ai/agent/csp/add.js +157 -0
- package/dist/commands/ai/agent/csp/add.js.map +1 -0
- package/dist/commands/ai/agent/csp/delete.d.ts +43 -0
- package/dist/commands/ai/agent/csp/delete.js +137 -0
- package/dist/commands/ai/agent/csp/delete.js.map +1 -0
- package/dist/commands/ai/agent/csp/list.d.ts +36 -0
- package/dist/commands/ai/agent/csp/list.js +102 -0
- package/dist/commands/ai/agent/csp/list.js.map +1 -0
- package/dist/commands/ai/agent/install.d.ts +86 -0
- package/dist/commands/ai/agent/install.js +245 -3
- package/dist/commands/ai/agent/install.js.map +1 -1
- package/dist/commands/ai/model/install.d.ts +16 -0
- package/dist/commands/ai/model/install.js +28 -4
- package/dist/commands/ai/model/install.js.map +1 -1
- package/dist/commands/cluster/agent/install.js +7 -2
- package/dist/commands/cluster/agent/install.js.map +1 -1
- package/dist/uilogic/agent-csp-credentials.d.ts +47 -0
- package/dist/uilogic/agent-csp-credentials.js +67 -0
- package/dist/uilogic/agent-csp-credentials.js.map +1 -0
- package/oclif.manifest.json +200 -2
- package/package.json +1 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { RootMap } from '../../../../apis/codiac-api/contracts';
|
|
2
|
+
import { CommandBaseExec, IEnterpriseEntity } from '../../../../command-base-exec';
|
|
3
|
+
export type IAgentCspAddRequest = IEnterpriseEntity & {
|
|
4
|
+
enterprise: string;
|
|
5
|
+
cabinet: string;
|
|
6
|
+
agent: string;
|
|
7
|
+
/** Cloud this login authenticates against. */
|
|
8
|
+
provider: string;
|
|
9
|
+
/** Name distinguishing this login from the agent's others; part of the setting keys. */
|
|
10
|
+
login: string;
|
|
11
|
+
/** Secret store the values are written to. */
|
|
12
|
+
secretStore?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Adds one cloud login to an existing agent.
|
|
16
|
+
*
|
|
17
|
+
* The values are written to a secret store by the relay, and the asset config
|
|
18
|
+
* keeps only references — the same path `cod ai agent install` uses, driven by the
|
|
19
|
+
* same prompting, so a login added here is identical to one added at install time.
|
|
20
|
+
*
|
|
21
|
+
* Implemented over the provisioning endpoint rather than a bespoke one: applying
|
|
22
|
+
* a credential means re-rendering the agent's chart, which IS a redeploy, and the
|
|
23
|
+
* provisioning pipeline is idempotent (chart repo, operator and ingress all skip
|
|
24
|
+
* when already in place). A dedicated endpoint would have to do the same work.
|
|
25
|
+
*/
|
|
26
|
+
export default class AiAgentCspAdd extends CommandBaseExec<IAgentCspAddRequest> {
|
|
27
|
+
static description: string;
|
|
28
|
+
static examples: {
|
|
29
|
+
description: string;
|
|
30
|
+
command: string;
|
|
31
|
+
}[];
|
|
32
|
+
static flags: {
|
|
33
|
+
help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
|
|
34
|
+
enterprise: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
35
|
+
cabinet: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
36
|
+
agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
37
|
+
provider: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
38
|
+
login: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
39
|
+
store: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
40
|
+
silent: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
41
|
+
};
|
|
42
|
+
/** Collected at execute time and never placed on the candidate — the candidate is
|
|
43
|
+
* echoed by --echo/--to-script, and a password must not land in a shell history. */
|
|
44
|
+
private _inputs;
|
|
45
|
+
captureArgs(): Promise<[Partial<IAgentCspAddRequest>, boolean, Partial<IAgentCspAddRequest>?]>;
|
|
46
|
+
buildCandidate_silently(partial: Partial<IAgentCspAddRequest>): Promise<IAgentCspAddRequest>;
|
|
47
|
+
buildCandidate_interactively(partial: Partial<IAgentCspAddRequest>, rootMap: RootMap, takeDefaults: boolean): Promise<IAgentCspAddRequest>;
|
|
48
|
+
buildCommandString(candidate: IAgentCspAddRequest, cmd: string[]): string[];
|
|
49
|
+
executeTask(candidate: IAgentCspAddRequest): Promise<void>;
|
|
50
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
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 _ = require("lodash");
|
|
6
|
+
const command_base_exec_1 = require("../../../../command-base-exec");
|
|
7
|
+
const agent_csp_credentials_1 = require("../../../../uilogic/agent-csp-credentials");
|
|
8
|
+
/**
|
|
9
|
+
* Adds one cloud login to an existing agent.
|
|
10
|
+
*
|
|
11
|
+
* The values are written to a secret store by the relay, and the asset config
|
|
12
|
+
* keeps only references — the same path `cod ai agent install` uses, driven by the
|
|
13
|
+
* same prompting, so a login added here is identical to one added at install time.
|
|
14
|
+
*
|
|
15
|
+
* Implemented over the provisioning endpoint rather than a bespoke one: applying
|
|
16
|
+
* a credential means re-rendering the agent's chart, which IS a redeploy, and the
|
|
17
|
+
* provisioning pipeline is idempotent (chart repo, operator and ingress all skip
|
|
18
|
+
* when already in place). A dedicated endpoint would have to do the same work.
|
|
19
|
+
*/
|
|
20
|
+
class AiAgentCspAdd extends command_base_exec_1.CommandBaseExec {
|
|
21
|
+
constructor() {
|
|
22
|
+
super(...arguments);
|
|
23
|
+
/** Collected at execute time and never placed on the candidate — the candidate is
|
|
24
|
+
* echoed by --echo/--to-script, and a password must not land in a shell history. */
|
|
25
|
+
this._inputs = {};
|
|
26
|
+
}
|
|
27
|
+
captureArgs() {
|
|
28
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
const { flags } = yield this.parse(AiAgentCspAdd);
|
|
30
|
+
const partial = {};
|
|
31
|
+
const explicit = {};
|
|
32
|
+
if (flags.enterprise)
|
|
33
|
+
partial.enterprise = flags.enterprise;
|
|
34
|
+
if (flags.cabinet) {
|
|
35
|
+
partial.cabinet = flags.cabinet;
|
|
36
|
+
explicit.cabinet = flags.cabinet;
|
|
37
|
+
}
|
|
38
|
+
if (flags.agent) {
|
|
39
|
+
partial.agent = flags.agent;
|
|
40
|
+
explicit.agent = flags.agent;
|
|
41
|
+
}
|
|
42
|
+
if (flags.provider) {
|
|
43
|
+
partial.provider = flags.provider;
|
|
44
|
+
explicit.provider = flags.provider;
|
|
45
|
+
}
|
|
46
|
+
if (flags.login) {
|
|
47
|
+
partial.login = flags.login;
|
|
48
|
+
explicit.login = flags.login;
|
|
49
|
+
}
|
|
50
|
+
if (flags.store) {
|
|
51
|
+
partial.secretStore = flags.store;
|
|
52
|
+
explicit.secretStore = flags.store;
|
|
53
|
+
}
|
|
54
|
+
return [partial, false, explicit];
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
buildCandidate_silently(partial) {
|
|
58
|
+
var _a;
|
|
59
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
if (!partial.agent || _.isEmpty(partial.agent))
|
|
61
|
+
throw new Error("Must specify agent.");
|
|
62
|
+
if (!partial.cabinet || _.isEmpty(partial.cabinet))
|
|
63
|
+
throw new Error("Must specify cabinet.");
|
|
64
|
+
if (!partial.provider || _.isEmpty(partial.provider))
|
|
65
|
+
throw new Error("Must specify provider.");
|
|
66
|
+
return {
|
|
67
|
+
enterprise: partial.enterprise,
|
|
68
|
+
cabinet: partial.cabinet,
|
|
69
|
+
agent: partial.agent,
|
|
70
|
+
provider: partial.provider,
|
|
71
|
+
login: (_a = partial.login) !== null && _a !== void 0 ? _a : partial.provider,
|
|
72
|
+
secretStore: partial.secretStore,
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
buildCandidate_interactively(partial, rootMap, takeDefaults) {
|
|
77
|
+
var _a, _b, _c;
|
|
78
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
if (!partial.cabinet) {
|
|
80
|
+
const [cab] = yield this.rootMapUtils.promptForCabinet(partial.enterprise, rootMap, partial.cabinet, takeDefaults);
|
|
81
|
+
partial.cabinet = cab.name;
|
|
82
|
+
}
|
|
83
|
+
if (!partial.agent) {
|
|
84
|
+
const ent = rootMap.enterprises.find(e => e.name === partial.enterprise);
|
|
85
|
+
const [selected] = yield this.rootMapUtils.promptForAsset((_a = ent === null || ent === void 0 ? void 0 : ent.assets) !== null && _a !== void 0 ? _a : [], partial.agent, true);
|
|
86
|
+
partial.agent = selected;
|
|
87
|
+
}
|
|
88
|
+
if (!partial.provider) {
|
|
89
|
+
partial.provider = (_b = yield this._ui.promptSelect('provider', 'Cloud:', agent_csp_credentials_1.SUPPORTED_CSPS.map(p => ({ name: p, value: p })))) !== null && _b !== void 0 ? _b : undefined;
|
|
90
|
+
}
|
|
91
|
+
if (!partial.login) {
|
|
92
|
+
const suggested = (_c = partial.provider) !== null && _c !== void 0 ? _c : 'csp';
|
|
93
|
+
const raw = yield this._ui.prompt('login', `Name for this login [${suggested}]:`, false);
|
|
94
|
+
partial.login = (String(raw !== null && raw !== void 0 ? raw : '').trim() || suggested).replace(/[^A-Za-z0-9-]/g, '-');
|
|
95
|
+
}
|
|
96
|
+
return yield this.buildCandidate_silently(partial);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
buildCommandString(candidate, cmd) {
|
|
100
|
+
cmd.push("-e", candidate.enterprise);
|
|
101
|
+
cmd.push("-c", candidate.cabinet);
|
|
102
|
+
cmd.push("-a", candidate.agent);
|
|
103
|
+
cmd.push("-p", candidate.provider);
|
|
104
|
+
cmd.push("-l", candidate.login);
|
|
105
|
+
if (candidate.secretStore)
|
|
106
|
+
cmd.push("-s", candidate.secretStore);
|
|
107
|
+
// Credentials are never echoed — they are prompted at execute time.
|
|
108
|
+
cmd.push("--silent");
|
|
109
|
+
return cmd;
|
|
110
|
+
}
|
|
111
|
+
executeTask(candidate) {
|
|
112
|
+
var _a, _b, _c;
|
|
113
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
114
|
+
this._inputs = {};
|
|
115
|
+
if (candidate.secretStore)
|
|
116
|
+
this._inputs['secretStore'] = candidate.secretStore;
|
|
117
|
+
const captured = yield (0, agent_csp_credentials_1.promptForCspLogin)(this._ui, this._inputs, candidate.login, candidate.provider);
|
|
118
|
+
if (captured.length === 0) {
|
|
119
|
+
this._ui.userMessage(this._styler.colorWarning('No values entered — nothing stored.'));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
this._ui.userMessage(`Storing ${captured.length} field(s) for ${this._styler.hilite(candidate.login)} (${candidate.provider})...`);
|
|
123
|
+
const request = {
|
|
124
|
+
enterprise: candidate.enterprise,
|
|
125
|
+
cabinet: candidate.cabinet,
|
|
126
|
+
framework: 'hermes',
|
|
127
|
+
name: candidate.agent,
|
|
128
|
+
inputs: this._inputs,
|
|
129
|
+
};
|
|
130
|
+
const result = yield this.watcher.triggerAndWatch((correlationId, socketId) => this.genRelayClient.Call.aiAgentProvision(Object.assign(Object.assign({}, request), { correlationId, socketId })));
|
|
131
|
+
if (result.error || !result.success) {
|
|
132
|
+
const msg = `Error adding cloud login [${candidate.login}] to [${candidate.agent}]: ${(_a = result.message) !== null && _a !== void 0 ? _a : ''} ${(_c = (_b = result.error) === null || _b === void 0 ? void 0 : _b.message) !== null && _c !== void 0 ? _c : ''}`.trimEnd();
|
|
133
|
+
this.logger.error(msg, result.error);
|
|
134
|
+
this._ui.userMessage(`${this._styler.colorCritical("ERROR!")} ${msg}`);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
this._ui.userMessage(`${this._styler.colorGood("SUCCESS!")} Cloud login [${this._styler.hilite(candidate.login)}] added to ${candidate.agent}.`);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.default = AiAgentCspAdd;
|
|
142
|
+
AiAgentCspAdd.description = "Adds a cloud (CSP) login to an agent, storing the credentials in a secret store and redeploying the agent to pick them up.";
|
|
143
|
+
AiAgentCspAdd.examples = [
|
|
144
|
+
{ description: 'Add a cloud login to an agent.', command: '<%= config.bin %> <%= command.id %> --agent hermes-agent --cabinet bens-agent' },
|
|
145
|
+
{ description: 'Add a second, named login.', command: '<%= config.bin %> <%= command.id %> --agent hermes-agent --cabinet bens-agent --login data-aws --provider aws' },
|
|
146
|
+
];
|
|
147
|
+
AiAgentCspAdd.flags = {
|
|
148
|
+
help: core_1.Flags.help({ char: 'h' }),
|
|
149
|
+
enterprise: core_1.Flags.string({ char: 'e', description: 'Enterprise the agent belongs to.' }),
|
|
150
|
+
cabinet: core_1.Flags.string({ char: 'c', description: 'Cabinet the agent is deployed into.' }),
|
|
151
|
+
agent: core_1.Flags.string({ char: 'a', description: 'Name of the agent asset.' }),
|
|
152
|
+
provider: core_1.Flags.string({ char: 'p', options: agent_csp_credentials_1.SUPPORTED_CSPS, description: 'Cloud this login authenticates against.' }),
|
|
153
|
+
login: core_1.Flags.string({ char: 'l', description: 'Name for this login (defaults to the provider). Lets an agent hold several.' }),
|
|
154
|
+
store: core_1.Flags.string({ char: 's', description: 'Secret store to write the credentials to.' }),
|
|
155
|
+
silent: core_1.Flags.boolean({ description: 'Non-Interactive mode; executes without any user interaction and fails on any missing or invalid arguments.' }),
|
|
156
|
+
};
|
|
157
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../../../../src/commands/ai/agent/csp/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { RootMap } from '../../../../apis/codiac-api/contracts';
|
|
2
|
+
import { CommandBaseExec, IEnterpriseEntity } from '../../../../command-base-exec';
|
|
3
|
+
export type IAgentCspDeleteRequest = IEnterpriseEntity & {
|
|
4
|
+
enterprise: string;
|
|
5
|
+
agent: string;
|
|
6
|
+
/** Name of the login to remove, as shown by `ai agent csp list`. */
|
|
7
|
+
login: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Removes one cloud login from an agent.
|
|
11
|
+
*
|
|
12
|
+
* Drops the asset's settings for that login — the references, and the plain
|
|
13
|
+
* `provider` marker. The secret itself is left in the store on purpose: the store
|
|
14
|
+
* is the customer's, other things may reference the same secret, and a CLI that
|
|
15
|
+
* silently reaches into a key vault to destroy material is a worse default than
|
|
16
|
+
* one that leaves an unreferenced entry behind. The removal is reported so it can
|
|
17
|
+
* be cleaned up deliberately.
|
|
18
|
+
*
|
|
19
|
+
* The agent keeps running with its current credentials until it is redeployed —
|
|
20
|
+
* this changes configuration, not the live pod.
|
|
21
|
+
*/
|
|
22
|
+
export default class AiAgentCspDelete extends CommandBaseExec<IAgentCspDeleteRequest> {
|
|
23
|
+
static description: string;
|
|
24
|
+
static aliases: string[];
|
|
25
|
+
static examples: {
|
|
26
|
+
description: string;
|
|
27
|
+
command: string;
|
|
28
|
+
}[];
|
|
29
|
+
static flags: {
|
|
30
|
+
help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
|
|
31
|
+
enterprise: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
32
|
+
agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
33
|
+
login: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
34
|
+
silent: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
35
|
+
};
|
|
36
|
+
captureArgs(): Promise<[Partial<IAgentCspDeleteRequest>, boolean, Partial<IAgentCspDeleteRequest>?]>;
|
|
37
|
+
buildCandidate_silently(partial: Partial<IAgentCspDeleteRequest>): Promise<IAgentCspDeleteRequest>;
|
|
38
|
+
buildCandidate_interactively(partial: Partial<IAgentCspDeleteRequest>, rootMap: RootMap): Promise<IAgentCspDeleteRequest>;
|
|
39
|
+
buildCommandString(candidate: IAgentCspDeleteRequest, cmd: string[]): string[];
|
|
40
|
+
executeTask(candidate: IAgentCspDeleteRequest): Promise<void>;
|
|
41
|
+
private settingsFor;
|
|
42
|
+
private loginNames;
|
|
43
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
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 _ = require("lodash");
|
|
6
|
+
const command_base_exec_1 = require("../../../../command-base-exec");
|
|
7
|
+
/**
|
|
8
|
+
* Removes one cloud login from an agent.
|
|
9
|
+
*
|
|
10
|
+
* Drops the asset's settings for that login — the references, and the plain
|
|
11
|
+
* `provider` marker. The secret itself is left in the store on purpose: the store
|
|
12
|
+
* is the customer's, other things may reference the same secret, and a CLI that
|
|
13
|
+
* silently reaches into a key vault to destroy material is a worse default than
|
|
14
|
+
* one that leaves an unreferenced entry behind. The removal is reported so it can
|
|
15
|
+
* be cleaned up deliberately.
|
|
16
|
+
*
|
|
17
|
+
* The agent keeps running with its current credentials until it is redeployed —
|
|
18
|
+
* this changes configuration, not the live pod.
|
|
19
|
+
*/
|
|
20
|
+
class AiAgentCspDelete extends command_base_exec_1.CommandBaseExec {
|
|
21
|
+
captureArgs() {
|
|
22
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
const { flags } = yield this.parse(AiAgentCspDelete);
|
|
24
|
+
const partial = {};
|
|
25
|
+
const explicit = {};
|
|
26
|
+
if (flags.enterprise)
|
|
27
|
+
partial.enterprise = flags.enterprise;
|
|
28
|
+
if (flags.agent) {
|
|
29
|
+
partial.agent = flags.agent;
|
|
30
|
+
explicit.agent = flags.agent;
|
|
31
|
+
}
|
|
32
|
+
if (flags.login) {
|
|
33
|
+
partial.login = flags.login;
|
|
34
|
+
explicit.login = flags.login;
|
|
35
|
+
}
|
|
36
|
+
return [partial, false, explicit];
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
buildCandidate_silently(partial) {
|
|
40
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
41
|
+
if (!partial.agent || _.isEmpty(partial.agent))
|
|
42
|
+
throw new Error("Must specify agent.");
|
|
43
|
+
if (!partial.login || _.isEmpty(partial.login))
|
|
44
|
+
throw new Error("Must specify login.");
|
|
45
|
+
return { enterprise: partial.enterprise, agent: partial.agent, login: partial.login };
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
buildCandidate_interactively(partial, rootMap) {
|
|
49
|
+
var _a, _b;
|
|
50
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
if (!partial.agent) {
|
|
52
|
+
const ent = rootMap.enterprises.find(e => e.name === partial.enterprise);
|
|
53
|
+
const [selected] = yield this.rootMapUtils.promptForAsset((_a = ent === null || ent === void 0 ? void 0 : ent.assets) !== null && _a !== void 0 ? _a : [], partial.agent, true);
|
|
54
|
+
partial.agent = selected;
|
|
55
|
+
}
|
|
56
|
+
if (!partial.login) {
|
|
57
|
+
// Offer the logins that actually exist rather than taking a free-typed name
|
|
58
|
+
// that would silently match nothing.
|
|
59
|
+
const names = yield this.loginNames(partial.enterprise, partial.agent);
|
|
60
|
+
if (names.length === 0)
|
|
61
|
+
throw new Error(`Agent [${partial.agent}] has no cloud logins to remove.`);
|
|
62
|
+
partial.login = (_b = yield this._ui.promptSelect('login', 'Cloud login to remove:', names.map(n => ({ name: n, value: n })))) !== null && _b !== void 0 ? _b : undefined;
|
|
63
|
+
}
|
|
64
|
+
return yield this.buildCandidate_silently(partial);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
buildCommandString(candidate, cmd) {
|
|
68
|
+
cmd.push("-e", candidate.enterprise);
|
|
69
|
+
cmd.push("-a", candidate.agent);
|
|
70
|
+
cmd.push("-l", candidate.login);
|
|
71
|
+
cmd.push("--silent");
|
|
72
|
+
return cmd;
|
|
73
|
+
}
|
|
74
|
+
executeTask(candidate) {
|
|
75
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
const settings = yield this.settingsFor(candidate.enterprise, candidate.agent);
|
|
77
|
+
const prefix = candidate.login === 'csp' ? 'csp.' : `csp.${candidate.login}.`;
|
|
78
|
+
const mine = settings.filter(s => {
|
|
79
|
+
var _a;
|
|
80
|
+
const key = (_a = s.setting) !== null && _a !== void 0 ? _a : '';
|
|
81
|
+
if (!key.startsWith(prefix))
|
|
82
|
+
return false;
|
|
83
|
+
// The bare form is 2 segments; a named login is 3. Without this, deleting
|
|
84
|
+
// "csp" would also take every named login with it.
|
|
85
|
+
return candidate.login === 'csp' ? key.split('.').length === 2 : true;
|
|
86
|
+
});
|
|
87
|
+
if (mine.length === 0) {
|
|
88
|
+
this._ui.userMessage(`No cloud login named [${this._styler.hilite(candidate.login)}] on agent [${candidate.agent}].`);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const stores = new Set(mine.map(s => { var _a; return (_a = s.source) === null || _a === void 0 ? void 0 : _a.name; }).filter(Boolean));
|
|
92
|
+
for (const s of mine) {
|
|
93
|
+
yield this._codiacApi.ScopedSetting.delete({ id: s.id });
|
|
94
|
+
}
|
|
95
|
+
this._ui.userMessage(`${this._styler.colorGood("SUCCESS!")} Removed cloud login [${this._styler.hilite(candidate.login)}] from ${candidate.agent} (${mine.length} setting(s)).`);
|
|
96
|
+
if (stores.size > 0) {
|
|
97
|
+
this._ui.userMessage(this._styler.dim(`The secret values remain in ${[...stores].join(', ')}; remove them there if they are no longer needed.`));
|
|
98
|
+
}
|
|
99
|
+
this._ui.userMessage(this._styler.dim(`Redeploy the agent for this to take effect.`));
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
settingsFor(enterprise, agent) {
|
|
103
|
+
var _a;
|
|
104
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
105
|
+
return (_a = yield this._codiacApi.ScopedSetting.readMany({ asset: agent, enterprise }, { throwNotFound: false })) !== null && _a !== void 0 ? _a : [];
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
loginNames(enterprise, agent) {
|
|
109
|
+
var _a;
|
|
110
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
const settings = yield this.settingsFor(enterprise, agent);
|
|
112
|
+
const names = new Set();
|
|
113
|
+
for (const s of settings) {
|
|
114
|
+
const key = (_a = s.setting) !== null && _a !== void 0 ? _a : '';
|
|
115
|
+
if (!key.startsWith('csp.'))
|
|
116
|
+
continue;
|
|
117
|
+
const parts = key.split('.');
|
|
118
|
+
names.add(parts.length === 3 ? parts[1] : 'csp');
|
|
119
|
+
}
|
|
120
|
+
return [...names];
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.default = AiAgentCspDelete;
|
|
125
|
+
AiAgentCspDelete.description = "Removes a cloud (CSP) login from an agent's configuration. The secret is left in its store.";
|
|
126
|
+
AiAgentCspDelete.aliases = ["ai:agent:csp:remove", "ai:agent:csp:rm"];
|
|
127
|
+
AiAgentCspDelete.examples = [
|
|
128
|
+
{ description: 'Remove a named cloud login from an agent.', command: '<%= config.bin %> <%= command.id %> --agent hermes-agent --login prod-az' },
|
|
129
|
+
];
|
|
130
|
+
AiAgentCspDelete.flags = {
|
|
131
|
+
help: core_1.Flags.help({ char: 'h' }),
|
|
132
|
+
enterprise: core_1.Flags.string({ char: 'e', description: 'Enterprise the agent belongs to.' }),
|
|
133
|
+
agent: core_1.Flags.string({ char: 'a', description: 'Name of the agent asset.' }),
|
|
134
|
+
login: core_1.Flags.string({ char: 'l', description: 'Name of the cloud login to remove (see `cod ai agent csp list`).' }),
|
|
135
|
+
silent: core_1.Flags.boolean({ description: 'Non-Interactive mode; executes without any user interaction and fails on any missing or invalid arguments.' }),
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../../../src/commands/ai/agent/csp/delete.ts"],"names":[],"mappings":";;;AAAA,sCAAoC;AACpC,4BAA6B;AAG7B,qEAAmF;AASnF;;;;;;;;;;;;GAYG;AACH,MAAqB,gBAAiB,SAAQ,mCAAuC;IAkBtE,WAAW;;YACtB,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YACrD,MAAM,OAAO,GAAoC,EAAE,CAAC;YACpD,MAAM,QAAQ,GAAoC,EAAE,CAAC;YACrD,IAAI,KAAK,CAAC,UAAU;gBAAE,OAAO,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;YAC5D,IAAI,KAAK,CAAC,KAAK,EAAE;gBAAE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;gBAAC,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;aAAE;YAC/E,IAAI,KAAK,CAAC,KAAK,EAAE;gBAAE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;gBAAC,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;aAAE;YAC/E,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QACpC,CAAC;KAAA;IAEY,uBAAuB,CAAC,OAAwC;;YAC3E,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACvF,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACvF,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,UAAW,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;QACzF,CAAC;KAAA;IAEY,4BAA4B,CACvC,OAAwC,EAAE,OAAgB;;;YAE1D,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;gBAClB,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;gBACzE,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,MAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,MAAM,mCAAI,EAAE,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBAClG,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;aAC1B;YACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;gBAClB,4EAA4E;gBAC5E,qCAAqC;gBACrC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,UAAW,EAAE,OAAO,CAAC,KAAM,CAAC,CAAC;gBACzE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,CAAC,KAAK,kCAAkC,CAAC,CAAC;gBACnG,OAAO,CAAC,KAAK,GAAG,MAAA,MAAM,IAAI,CAAC,GAAG,CAAC,YAAY,CAAS,OAAO,EAAE,wBAAwB,EACnF,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,mCAAI,SAAS,CAAC;aACzD;YACD,OAAO,MAAM,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;;KACpD;IAEM,kBAAkB,CAAC,SAAiC,EAAE,GAAa;QACxE,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;QACrC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrB,OAAO,GAAG,CAAC;IACb,CAAC;IAEY,WAAW,CAAC,SAAiC;;YACxD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;YAC/E,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,KAAK,GAAG,CAAC;YAC9E,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;;gBAC/B,MAAM,GAAG,GAAW,MAAC,CAAS,CAAC,OAAO,mCAAI,EAAE,CAAC;gBAC7C,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;oBAAE,OAAO,KAAK,CAAC;gBAC1C,0EAA0E;gBAC1E,mDAAmD;gBACnD,OAAO,SAAS,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACxE,CAAC,CAAC,CAAC;YAEH,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;gBACrB,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,yBAAyB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,eAAe,SAAS,CAAC,KAAK,IAAI,CAAC,CAAC;gBACtH,OAAO;aACR;YAED,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,WAAC,OAAA,MAAC,CAAS,CAAC,MAAM,0CAAE,IAAI,CAAA,EAAA,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAC/E,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE;gBACpB,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,EAAE,EAAG,CAAS,CAAC,EAAE,EAAS,CAAC,CAAC;aAC1E;YAED,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,yBAAyB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,SAAS,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,eAAe,CAAC,CAAC;YACjL,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE;gBACnB,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC,CAAC;aAClJ;YACD,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC;QACxF,CAAC;KAAA;IAEa,WAAW,CAAC,UAAkB,EAAE,KAAa;;;YACzD,OAAO,MAAA,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,QAAQ,CACjD,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAS,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,mCAAI,EAAE,CAAC;;KACxE;IAEa,UAAU,CAAC,UAAkB,EAAE,KAAa;;;YACxD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAC3D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;YAChC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE;gBACxB,MAAM,GAAG,GAAW,MAAC,CAAS,CAAC,OAAO,mCAAI,EAAE,CAAC;gBAC7C,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;oBAAE,SAAS;gBACtC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC7B,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;aAClD;YACD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;;KACnB;;AAxGH,mCAyGC;AAvGQ,4BAAW,GAAG,6FAA6F,CAAC;AAE5G,wBAAO,GAAG,CAAC,qBAAqB,EAAE,iBAAiB,CAAC,CAAC;AAErD,yBAAQ,GAAG;IAChB,EAAE,WAAW,EAAE,2CAA2C,EAAE,OAAO,EAAE,0EAA0E,EAAE;CAClJ,CAAC;AAEK,sBAAK,GAAG;IACb,IAAI,EAAE,YAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IAC/B,UAAU,EAAE,YAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,kCAAkC,EAAE,CAAC;IACxF,KAAK,EAAE,YAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAC;IAC3E,KAAK,EAAE,YAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,kEAAkE,EAAE,CAAC;IACnH,MAAM,EAAE,YAAK,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,4GAA4G,EAAE,CAAC;CACrJ,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { AtLeast } from '@codiac.io/codiac-common/contracts';
|
|
2
|
+
import { RootMap } from '../../../../apis/codiac-api/contracts';
|
|
3
|
+
import { CommandBaseExec, IEnterpriseEntity } from '../../../../command-base-exec';
|
|
4
|
+
export type IAgentCspListRequest = IEnterpriseEntity & {
|
|
5
|
+
enterprise: string;
|
|
6
|
+
/** Agent asset whose cloud logins to show. */
|
|
7
|
+
agent: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Shows which cloud logins an agent holds — WITHOUT reading any secret.
|
|
11
|
+
*
|
|
12
|
+
* The values live in a secret store; the asset config holds only references to
|
|
13
|
+
* them. This reads the config, so it can report which logins exist, which cloud
|
|
14
|
+
* each targets, which fields are set and where they are stored, while never
|
|
15
|
+
* touching the store itself. That is deliberate: listing credentials should not
|
|
16
|
+
* require permission to read them.
|
|
17
|
+
*/
|
|
18
|
+
export default class AiAgentCspList extends CommandBaseExec<IAgentCspListRequest> {
|
|
19
|
+
static description: string;
|
|
20
|
+
static aliases: string[];
|
|
21
|
+
static examples: {
|
|
22
|
+
description: string;
|
|
23
|
+
command: string;
|
|
24
|
+
}[];
|
|
25
|
+
static flags: {
|
|
26
|
+
help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
|
|
27
|
+
enterprise: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
28
|
+
agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
29
|
+
silent: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
30
|
+
};
|
|
31
|
+
captureArgs(): Promise<[Partial<IAgentCspListRequest>, boolean, Partial<IAgentCspListRequest>?]>;
|
|
32
|
+
buildCandidate_silently(partial: AtLeast<IAgentCspListRequest, "enterprise">): Promise<IAgentCspListRequest>;
|
|
33
|
+
buildCandidate_interactively(partial: AtLeast<IAgentCspListRequest, "enterprise">, rootMap: RootMap): Promise<IAgentCspListRequest>;
|
|
34
|
+
buildCommandString(candidate: IAgentCspListRequest, cmd: string[]): string[];
|
|
35
|
+
executeTask(candidate: IAgentCspListRequest): Promise<void>;
|
|
36
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
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 _ = require("lodash");
|
|
6
|
+
const command_base_exec_1 = require("../../../../command-base-exec");
|
|
7
|
+
/**
|
|
8
|
+
* Shows which cloud logins an agent holds — WITHOUT reading any secret.
|
|
9
|
+
*
|
|
10
|
+
* The values live in a secret store; the asset config holds only references to
|
|
11
|
+
* them. This reads the config, so it can report which logins exist, which cloud
|
|
12
|
+
* each targets, which fields are set and where they are stored, while never
|
|
13
|
+
* touching the store itself. That is deliberate: listing credentials should not
|
|
14
|
+
* require permission to read them.
|
|
15
|
+
*/
|
|
16
|
+
class AiAgentCspList extends command_base_exec_1.CommandBaseExec {
|
|
17
|
+
captureArgs() {
|
|
18
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
const { flags } = yield this.parse(AiAgentCspList);
|
|
20
|
+
const partial = {};
|
|
21
|
+
const explicit = {};
|
|
22
|
+
if (flags.enterprise)
|
|
23
|
+
partial.enterprise = flags.enterprise;
|
|
24
|
+
if (flags.agent) {
|
|
25
|
+
partial.agent = flags.agent;
|
|
26
|
+
explicit.agent = flags.agent;
|
|
27
|
+
}
|
|
28
|
+
return [partial, false, explicit];
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
buildCandidate_silently(partial) {
|
|
32
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
33
|
+
if (!partial.agent || _.isEmpty(partial.agent))
|
|
34
|
+
throw new Error("Must specify agent.");
|
|
35
|
+
return { enterprise: partial.enterprise, agent: partial.agent };
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
buildCandidate_interactively(partial, rootMap) {
|
|
39
|
+
var _a;
|
|
40
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
41
|
+
if (!partial.agent) {
|
|
42
|
+
const ent = rootMap.enterprises.find(e => e.name === partial.enterprise);
|
|
43
|
+
const [selected] = yield this.rootMapUtils.promptForAsset((_a = ent === null || ent === void 0 ? void 0 : ent.assets) !== null && _a !== void 0 ? _a : [], partial.agent, true);
|
|
44
|
+
partial.agent = selected;
|
|
45
|
+
}
|
|
46
|
+
return yield this.buildCandidate_silently(partial);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
buildCommandString(candidate, cmd) {
|
|
50
|
+
cmd.push("-e", candidate.enterprise);
|
|
51
|
+
cmd.push("-a", candidate.agent);
|
|
52
|
+
cmd.push("--silent");
|
|
53
|
+
return cmd;
|
|
54
|
+
}
|
|
55
|
+
executeTask(candidate) {
|
|
56
|
+
var _a, _b, _c, _d, _e, _f;
|
|
57
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
58
|
+
const settings = (_a = yield this._codiacApi.ScopedSetting.readMany({ asset: candidate.agent, enterprise: candidate.enterprise }, { throwNotFound: false })) !== null && _a !== void 0 ? _a : [];
|
|
59
|
+
// Group the flat `csp.<login>.<field>` settings back into logins. The bare
|
|
60
|
+
// `csp.<field>` form (a single unnamed login) groups under "csp".
|
|
61
|
+
const logins = new Map();
|
|
62
|
+
for (const s of settings) {
|
|
63
|
+
const key = (_b = s.setting) !== null && _b !== void 0 ? _b : '';
|
|
64
|
+
if (!key.startsWith('csp.'))
|
|
65
|
+
continue;
|
|
66
|
+
const parts = key.split('.');
|
|
67
|
+
const [name, field] = parts.length === 3 ? [parts[1], parts[2]] : ['csp', parts[1]];
|
|
68
|
+
const entry = (_c = logins.get(name)) !== null && _c !== void 0 ? _c : { fields: [] };
|
|
69
|
+
if (field === 'provider')
|
|
70
|
+
entry.provider = s.value;
|
|
71
|
+
else {
|
|
72
|
+
entry.fields.push(field);
|
|
73
|
+
entry.store = (_d = entry.store) !== null && _d !== void 0 ? _d : (_e = s.source) === null || _e === void 0 ? void 0 : _e.name;
|
|
74
|
+
}
|
|
75
|
+
logins.set(name, entry);
|
|
76
|
+
}
|
|
77
|
+
if (logins.size === 0) {
|
|
78
|
+
this._ui.userMessage(`No cloud logins configured for agent [${this._styler.hilite(candidate.agent)}].`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
this._ui.userMessage(`Cloud logins for ${this._styler.hilite(candidate.agent)}:`);
|
|
82
|
+
for (const [name, e] of logins) {
|
|
83
|
+
const store = e.store ? this._styler.dim(` in ${e.store}`) : this._styler.colorWarning(' (no secret store — value stored inline?)');
|
|
84
|
+
const provider = (_f = e.provider) !== null && _f !== void 0 ? _f : this._styler.colorWarning('unknown cloud');
|
|
85
|
+
this._ui.userMessage(` ${this._styler.hilite(name)} ${provider} ${e.fields.sort().join(', ')}${store}`);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.default = AiAgentCspList;
|
|
91
|
+
AiAgentCspList.description = "Lists the cloud (CSP) logins configured for an agent, without revealing any secret values.";
|
|
92
|
+
AiAgentCspList.aliases = ["ai:agent:csp:ls"];
|
|
93
|
+
AiAgentCspList.examples = [
|
|
94
|
+
{ description: 'List the cloud logins on an agent.', command: '<%= config.bin %> <%= command.id %> --agent hermes-agent' },
|
|
95
|
+
];
|
|
96
|
+
AiAgentCspList.flags = {
|
|
97
|
+
help: core_1.Flags.help({ char: 'h' }),
|
|
98
|
+
enterprise: core_1.Flags.string({ char: 'e', description: 'Enterprise the agent belongs to.' }),
|
|
99
|
+
agent: core_1.Flags.string({ char: 'a', description: 'Name of the agent asset.' }),
|
|
100
|
+
silent: core_1.Flags.boolean({ description: 'Non-Interactive mode; executes without any user interaction and fails on any missing or invalid arguments.' }),
|
|
101
|
+
};
|
|
102
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../../src/commands/ai/agent/csp/list.ts"],"names":[],"mappings":"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"}
|