geni-bioinfo 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth.d.ts +8 -0
- package/dist/auth.js +76 -0
- package/dist/aws/clients.d.ts +18 -0
- package/dist/aws/clients.js +34 -0
- package/dist/commands/activate.d.ts +2 -0
- package/dist/commands/activate.js +20 -0
- package/dist/commands/activity-log.d.ts +2 -0
- package/dist/commands/activity-log.js +31 -0
- package/dist/commands/api-token.d.ts +2 -0
- package/dist/commands/api-token.js +96 -0
- package/dist/commands/auth.d.ts +2 -0
- package/dist/commands/auth.js +55 -0
- package/dist/commands/engine.d.ts +2 -0
- package/dist/commands/engine.js +83 -0
- package/dist/commands/environment.d.ts +2 -0
- package/dist/commands/environment.js +69 -0
- package/dist/commands/image.d.ts +2 -0
- package/dist/commands/image.js +40 -0
- package/dist/commands/instance.d.ts +2 -0
- package/dist/commands/instance.js +39 -0
- package/dist/commands/log.d.ts +3 -0
- package/dist/commands/log.js +43 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +24 -0
- package/dist/commands/plugin.d.ts +2 -0
- package/dist/commands/plugin.js +80 -0
- package/dist/commands/queue.d.ts +2 -0
- package/dist/commands/queue.js +74 -0
- package/dist/commands/registry.d.ts +2 -0
- package/dist/commands/registry.js +72 -0
- package/dist/commands/setup/create.d.ts +2 -0
- package/dist/commands/setup/create.js +254 -0
- package/dist/commands/setup/delete.d.ts +2 -0
- package/dist/commands/setup/delete.js +97 -0
- package/dist/commands/setup/status.d.ts +2 -0
- package/dist/commands/setup/status.js +46 -0
- package/dist/commands/setup.d.ts +2 -0
- package/dist/commands/setup.js +13 -0
- package/dist/commands/storage.d.ts +2 -0
- package/dist/commands/storage.js +67 -0
- package/dist/commands/submission.d.ts +2 -0
- package/dist/commands/submission.js +87 -0
- package/dist/commands/task.d.ts +2 -0
- package/dist/commands/task.js +21 -0
- package/dist/commands/tenant.d.ts +2 -0
- package/dist/commands/tenant.js +68 -0
- package/dist/commands/user.d.ts +2 -0
- package/dist/commands/user.js +82 -0
- package/dist/commands/workflow.d.ts +2 -0
- package/dist/commands/workflow.js +80 -0
- package/dist/errors.d.ts +38 -0
- package/dist/errors.js +194 -0
- package/dist/format.d.ts +22 -0
- package/dist/format.js +155 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +91 -0
- package/dist/templates/setup.yaml +503 -0
- package/package.json +49 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCommand = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const commander_1 = require("commander");
|
|
7
|
+
const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
|
|
8
|
+
const client_iam_1 = require("@aws-sdk/client-iam");
|
|
9
|
+
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
10
|
+
const clients_1 = require("../../aws/clients");
|
|
11
|
+
const errors_1 = require("../../errors");
|
|
12
|
+
const STACK_NAME = 'geni-setup';
|
|
13
|
+
function parseBucketList(value) {
|
|
14
|
+
if (!value)
|
|
15
|
+
return [];
|
|
16
|
+
return value.split(',').map(b => b.trim()).filter(Boolean);
|
|
17
|
+
}
|
|
18
|
+
function buildBucketPolicy(bucket, mode, account) {
|
|
19
|
+
const condition = {
|
|
20
|
+
StringEquals: {
|
|
21
|
+
'aws:PrincipalAccount': account,
|
|
22
|
+
},
|
|
23
|
+
StringLike: {
|
|
24
|
+
'aws:PrincipalTag/GeniName': [
|
|
25
|
+
'geni-engine-*',
|
|
26
|
+
'geni-batch-*',
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
const statements = [];
|
|
31
|
+
if (mode === 'read-write' || mode === 'read-only') {
|
|
32
|
+
statements.push({
|
|
33
|
+
Sid: 'GeniListBucket',
|
|
34
|
+
Effect: 'Allow',
|
|
35
|
+
Principal: '*',
|
|
36
|
+
Action: 's3:ListBucket',
|
|
37
|
+
Resource: `arn:aws:s3:::${bucket}`,
|
|
38
|
+
Condition: condition,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const actions = [];
|
|
42
|
+
if (mode === 'read-write') {
|
|
43
|
+
actions.push('s3:GetObject', 's3:PutObject', 's3:DeleteObject');
|
|
44
|
+
}
|
|
45
|
+
else if (mode === 'read-only') {
|
|
46
|
+
actions.push('s3:GetObject');
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
actions.push('s3:PutObject', 's3:DeleteObject');
|
|
50
|
+
}
|
|
51
|
+
statements.push({
|
|
52
|
+
Sid: 'GeniObjectAccess',
|
|
53
|
+
Effect: 'Allow',
|
|
54
|
+
Principal: '*',
|
|
55
|
+
Action: actions,
|
|
56
|
+
Resource: `arn:aws:s3:::${bucket}/*`,
|
|
57
|
+
Condition: condition,
|
|
58
|
+
});
|
|
59
|
+
return JSON.stringify({ Version: '2012-10-17', Statement: statements });
|
|
60
|
+
}
|
|
61
|
+
exports.createCommand = new commander_1.Command('create')
|
|
62
|
+
.alias('activate')
|
|
63
|
+
.description('Create IAM roles and policies for Geni cross-account access')
|
|
64
|
+
.argument('<uri>', 'Target AWS account URI (aws://<account>/<region>)')
|
|
65
|
+
.option('--geni-account <account>', 'Geni AWS account ID to trust', '880420038460')
|
|
66
|
+
.option('--trust <account>', 'Alias for --geni-account')
|
|
67
|
+
.option('--read-write-buckets <buckets>', 'Comma-separated list of existing S3 buckets to grant read-write access')
|
|
68
|
+
.option('--read-only-buckets <buckets>', 'Comma-separated list of existing S3 buckets to grant read-only access')
|
|
69
|
+
.option('--write-only-buckets <buckets>', 'Comma-separated list of existing S3 buckets to grant write-only access')
|
|
70
|
+
.option('--profile <profile>', 'AWS profile to use for credentials')
|
|
71
|
+
.action(async (uri, options) => {
|
|
72
|
+
const { account, region } = (0, clients_1.parseAwsUri)(uri);
|
|
73
|
+
const { cfn, iam, s3, sts } = (0, clients_1.createClients)(region, options.profile);
|
|
74
|
+
const identity = await (0, clients_1.getCallerIdentity)(sts);
|
|
75
|
+
console.log(`Authenticated as ${identity.arn} (account ${identity.account})`);
|
|
76
|
+
if (identity.account !== account) {
|
|
77
|
+
console.warn(`Warning: Current account (${identity.account}) does not match target (${account}). ` +
|
|
78
|
+
`Ensure you have credentials for the target account.`);
|
|
79
|
+
}
|
|
80
|
+
const templateBody = (0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../../templates/setup.yaml'), 'utf-8');
|
|
81
|
+
const trustedAccount = options.trust ?? options.geniAccount;
|
|
82
|
+
const parameters = [
|
|
83
|
+
{ ParameterKey: 'GeniAccount', ParameterValue: trustedAccount },
|
|
84
|
+
];
|
|
85
|
+
const tags = [{ Key: 'CreatedBy', Value: 'GENI' }];
|
|
86
|
+
let needsPoll = null;
|
|
87
|
+
let stackAlreadyUpToDate = false;
|
|
88
|
+
try {
|
|
89
|
+
await cfn.send(new client_cloudformation_1.CreateStackCommand({
|
|
90
|
+
StackName: STACK_NAME,
|
|
91
|
+
TemplateBody: templateBody,
|
|
92
|
+
Capabilities: ['CAPABILITY_NAMED_IAM'],
|
|
93
|
+
Parameters: parameters,
|
|
94
|
+
Tags: tags,
|
|
95
|
+
}));
|
|
96
|
+
console.log(`Creating stack ${STACK_NAME}...`);
|
|
97
|
+
needsPoll = 'CREATE';
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
if (err.name === 'AlreadyExistsException') {
|
|
101
|
+
try {
|
|
102
|
+
await cfn.send(new client_cloudformation_1.UpdateStackCommand({
|
|
103
|
+
StackName: STACK_NAME,
|
|
104
|
+
TemplateBody: templateBody,
|
|
105
|
+
Capabilities: ['CAPABILITY_NAMED_IAM'],
|
|
106
|
+
Parameters: parameters,
|
|
107
|
+
Tags: tags,
|
|
108
|
+
}));
|
|
109
|
+
console.log(`Updating stack ${STACK_NAME}...`);
|
|
110
|
+
needsPoll = 'UPDATE';
|
|
111
|
+
}
|
|
112
|
+
catch (updateErr) {
|
|
113
|
+
const message = updateErr instanceof Error ? updateErr.message : '';
|
|
114
|
+
if (message.includes('No updates are to be performed')) {
|
|
115
|
+
console.log(`Stack ${STACK_NAME} is already up to date.`);
|
|
116
|
+
stackAlreadyUpToDate = true;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
throw updateErr;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// Stack does not exist in this region. IAM roles are global — if they already
|
|
125
|
+
// exist they were created via a stack in another region; skip silently.
|
|
126
|
+
const iamRolesExist = await checkIAMRolesExist(iam);
|
|
127
|
+
if (iamRolesExist) {
|
|
128
|
+
console.log('\nIAM roles already exist in this account (GeniCrossAccountRole, GeniCfnServiceRole).\n' +
|
|
129
|
+
'Skipping CloudFormation stack — IAM roles are global and shared across all regions.\n' +
|
|
130
|
+
'To update role permissions, run this command against the region where the stack was first created.');
|
|
131
|
+
console.log(`\n GeniCrossAccountRole: arn:aws:iam::${account}:role/GeniCrossAccountRole`);
|
|
132
|
+
console.log(` GeniCfnServiceRole: arn:aws:iam::${account}:role/GeniCfnServiceRole`);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (needsPoll) {
|
|
140
|
+
const outputs = await pollStack(cfn, STACK_NAME, needsPoll);
|
|
141
|
+
console.log('\nSetup complete:');
|
|
142
|
+
printRoleArns(outputs);
|
|
143
|
+
for (const output of outputs) {
|
|
144
|
+
console.log(` ${output.OutputKey}: ${output.OutputValue}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else if (stackAlreadyUpToDate) {
|
|
148
|
+
const outputs = await getStackOutputs(cfn, STACK_NAME);
|
|
149
|
+
if (outputs.length > 0) {
|
|
150
|
+
console.log('\nExisting role ARNs:');
|
|
151
|
+
printRoleArns(outputs);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const bucketConfigs = [
|
|
155
|
+
...parseBucketList(options.readWriteBuckets).map(b => ({ bucket: b, mode: 'read-write' })),
|
|
156
|
+
...parseBucketList(options.readOnlyBuckets).map(b => ({ bucket: b, mode: 'read-only' })),
|
|
157
|
+
...parseBucketList(options.writeOnlyBuckets).map(b => ({ bucket: b, mode: 'write-only' })),
|
|
158
|
+
];
|
|
159
|
+
if (bucketConfigs.length > 0) {
|
|
160
|
+
console.log('\nConfiguring bucket permissions...');
|
|
161
|
+
const bucketFailures = [];
|
|
162
|
+
for (const { bucket, mode } of bucketConfigs) {
|
|
163
|
+
try {
|
|
164
|
+
let existingTags = [];
|
|
165
|
+
try {
|
|
166
|
+
const tagging = await s3.send(new client_s3_1.GetBucketTaggingCommand({ Bucket: bucket }));
|
|
167
|
+
existingTags = tagging.TagSet ?? [];
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
if (err.name !== 'NoSuchTagSet')
|
|
171
|
+
throw err;
|
|
172
|
+
}
|
|
173
|
+
const filteredTags = existingTags.filter(t => t.Key !== 'CreatedBy' && t.Key !== 'GeniPermission');
|
|
174
|
+
filteredTags.push({ Key: 'CreatedBy', Value: 'GENI' }, { Key: 'GeniPermission', Value: mode });
|
|
175
|
+
await s3.send(new client_s3_1.PutBucketTaggingCommand({
|
|
176
|
+
Bucket: bucket,
|
|
177
|
+
Tagging: { TagSet: filteredTags },
|
|
178
|
+
}));
|
|
179
|
+
const policy = buildBucketPolicy(bucket, mode, account);
|
|
180
|
+
await s3.send(new client_s3_1.PutBucketPolicyCommand({ Bucket: bucket, Policy: policy }));
|
|
181
|
+
console.log(` ${bucket}: ${mode}`);
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
185
|
+
console.error(` ${bucket}: FAILED - ${message}`);
|
|
186
|
+
bucketFailures.push({ bucket, mode, message });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (bucketFailures.length > 0) {
|
|
190
|
+
throw new errors_1.CliError({
|
|
191
|
+
code: 'UPSTREAM',
|
|
192
|
+
message: `Failed to configure ${bucketFailures.length} bucket permission update(s).`,
|
|
193
|
+
hint: 'Fix failed bucket permissions and rerun `geni setup create`.',
|
|
194
|
+
exitCode: 5,
|
|
195
|
+
details: { failures: bucketFailures },
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
async function checkIAMRolesExist(iam) {
|
|
201
|
+
try {
|
|
202
|
+
await iam.send(new client_iam_1.GetRoleCommand({ RoleName: 'GeniCrossAccountRole' }));
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
if (err.name === 'NoSuchEntityException') {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
throw err;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
async function pollStack(cfn, stackName, operation) {
|
|
213
|
+
const successState = `${operation}_COMPLETE`;
|
|
214
|
+
const failureStates = [
|
|
215
|
+
`${operation}_FAILED`,
|
|
216
|
+
'ROLLBACK_COMPLETE',
|
|
217
|
+
'ROLLBACK_FAILED',
|
|
218
|
+
'UPDATE_ROLLBACK_COMPLETE',
|
|
219
|
+
'UPDATE_ROLLBACK_FAILED',
|
|
220
|
+
];
|
|
221
|
+
for (;;) {
|
|
222
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
223
|
+
const { Stacks } = await cfn.send(new client_cloudformation_1.DescribeStacksCommand({ StackName: stackName }));
|
|
224
|
+
const stack = Stacks?.[0];
|
|
225
|
+
if (!stack) {
|
|
226
|
+
throw new Error(`Stack ${stackName} not found`);
|
|
227
|
+
}
|
|
228
|
+
const status = stack.StackStatus ?? '';
|
|
229
|
+
process.stdout.write(` Status: ${status}\n`);
|
|
230
|
+
if (status === successState) {
|
|
231
|
+
return stack.Outputs ?? [];
|
|
232
|
+
}
|
|
233
|
+
if (failureStates.includes(status)) {
|
|
234
|
+
throw new Error(`Stack ${stackName} reached failure state: ${status}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
async function getStackOutputs(cfn, stackName) {
|
|
239
|
+
const { Stacks } = await cfn.send(new client_cloudformation_1.DescribeStacksCommand({ StackName: stackName }));
|
|
240
|
+
return Stacks?.[0]?.Outputs ?? [];
|
|
241
|
+
}
|
|
242
|
+
function printRoleArns(outputs) {
|
|
243
|
+
const roleArns = [
|
|
244
|
+
{ key: 'CrossAccountRoleArn', label: 'GeniCrossAccountRole' },
|
|
245
|
+
{ key: 'CfnServiceRoleArn', label: 'GeniCfnServiceRole' },
|
|
246
|
+
];
|
|
247
|
+
for (const roleArn of roleArns) {
|
|
248
|
+
const output = outputs.find(o => o.OutputKey === roleArn.key);
|
|
249
|
+
if (output?.OutputValue) {
|
|
250
|
+
console.log(` ${roleArn.label}: ${output.OutputValue}`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL3NldHVwL2NyZWF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQkFBa0M7QUFDbEMsK0JBQTRCO0FBQzVCLHlDQUFvQztBQUNwQywwRUFJd0M7QUFDeEMsb0RBQXFEO0FBQ3JELGtEQUk0QjtBQUM1QiwrQ0FBa0Y7QUFDbEYseUNBQXdDO0FBRXhDLE1BQU0sVUFBVSxHQUFHLFlBQVksQ0FBQztBQWVoQyxTQUFTLGVBQWUsQ0FBQyxLQUFjO0lBQ25DLElBQUksQ0FBQyxLQUFLO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDdEIsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUMvRCxDQUFDO0FBRUQsU0FBUyxpQkFBaUIsQ0FDdEIsTUFBYyxFQUNkLElBQW9CLEVBQ3BCLE9BQWU7SUFFZixNQUFNLFNBQVMsR0FBRztRQUNkLFlBQVksRUFBRTtZQUNWLHNCQUFzQixFQUFFLE9BQU87U0FDbEM7UUFDRCxVQUFVLEVBQUU7WUFDUiwyQkFBMkIsRUFBRTtnQkFDekIsZUFBZTtnQkFDZixjQUFjO2FBQ2pCO1NBQ0o7S0FDSixDQUFDO0lBRUYsTUFBTSxVQUFVLEdBQWEsRUFBRSxDQUFDO0lBRWhDLElBQUksSUFBSSxLQUFLLFlBQVksSUFBSSxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7UUFDaEQsVUFBVSxDQUFDLElBQUksQ0FBQztZQUNaLEdBQUcsRUFBRSxnQkFBZ0I7WUFDckIsTUFBTSxFQUFFLE9BQU87WUFDZixTQUFTLEVBQUUsR0FBRztZQUNkLE1BQU0sRUFBRSxlQUFlO1lBQ3ZCLFFBQVEsRUFBRSxnQkFBZ0IsTUFBTSxFQUFFO1lBQ2xDLFNBQVMsRUFB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SyxVQUFVLGVBQWUsQ0FDMUIsR0FBa0UsRUFDbEUsU0FBaUI7SUFFakIsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLDZDQUFxQixDQUFDLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN2RixPQUFPLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sSUFBSSxFQUFFLENBQUM7QUFDdEMsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLE9BQXNCO0lBQ3pDLE1BQU0sUUFBUSxHQUFHO1FBQ2IsRUFBRSxHQUFHLEVBQUUscUJBQXFCLEVBQUUsS0FBSyxFQUFFLHNCQUFzQixFQUFFO1FBQzdELEVBQUUsR0FBRyxFQUFFLG1CQUFtQixFQUFFLEtBQUssRUFBRSxvQkFBb0IsRUFBRTtLQUM1RCxDQUFDO0lBRUYsS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUM3QixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsS0FBSyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUQsSUFBSSxNQUFNLEVBQUUsV0FBVyxFQUFFLENBQUM7WUFDdEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLE9BQU8sQ0FBQyxLQUFLLEtBQUssTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDN0QsQ0FBQztJQUNMLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVhZEZpbGVTeW5jIH0gZnJvbSAnZnMnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQge1xuICAgIENyZWF0ZVN0YWNrQ29tbWFuZCxcbiAgICBVcGRhdGVTdGFja0NvbW1hbmQsXG4gICAgRGVzY3JpYmVTdGFja3NDb21tYW5kLFxufSBmcm9tICdAYXdzLXNkay9jbGllbnQtY2xvdWRmb3JtYXRpb24nO1xuaW1wb3J0IHsgR2V0Um9sZUNvbW1hbmQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtaWFtJztcbmltcG9ydCB7XG4gICAgR2V0QnVja2V0VGFnZ2luZ0NvbW1hbmQsXG4gICAgUHV0QnVja2V0VGFnZ2luZ0NvbW1hbmQsXG4gICAgUHV0QnVja2V0UG9saWN5Q29tbWFuZCxcbn0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXMzJztcbmltcG9ydCB7IGNyZWF0ZUNsaWVudHMsIGdldENhbGxlcklkZW50aXR5LCBwYXJzZUF3c1VyaSB9IGZyb20gJy4uLy4uL2F3cy9jbGllbnRzJztcbmltcG9ydCB7IENsaUVycm9yIH0gZnJvbSAnLi4vLi4vZXJyb3JzJztcblxuY29uc3QgU1RBQ0tfTkFNRSA9ICdnZW5pLXNldHVwJztcblxudHlwZSBQZXJtaXNzaW9uTW9kZSA9ICdyZWFkLXdyaXRlJyB8ICdyZWFkLW9ubHknIHwgJ3dyaXRlLW9ubHknO1xuXG5pbnRlcmZhY2UgQ3JlYXRlT3B0aW9ucyB7XG4gICAgZ2VuaUFjY291bnQ6IHN0cmluZztcbiAgICB0cnVzdD86IHN0cmluZztcbiAgICByZWFkV3JpdGVCdWNrZXRzPzogc3RyaW5nO1xuICAgIHJlYWRPbmx5QnVja2V0cz86IHN0cmluZztcbiAgICB3cml0ZU9ubHlCdWNrZXRzPzogc3RyaW5nO1xuICAgIHByb2ZpbGU/OiBzdHJpbmc7XG59XG5cbnR5cGUgU3RhY2tPdXRwdXQgPSB7IE91dHB1dEtleT86IHN0cmluZzsgT3V0cHV0VmFsdWU/OiBzdHJpbmcgfTtcblxuZnVuY3Rpb24gcGFyc2VCdWNrZXRMaXN0KHZhbHVlPzogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIGlmICghdmFsdWUpIHJldHVybiBbXTtcbiAgICByZXR1cm4gdmFsdWUuc3BsaXQoJywnKS5tYXAoYiA9PiBiLnRyaW0oKSkuZmlsdGVyKEJvb2xlYW4pO1xufVxuXG5mdW5jdGlvbiBidWlsZEJ1Y2tldFBvbGljeShcbiAgICBidWNrZXQ6IHN0cmluZyxcbiAgICBtb2RlOiBQZXJtaXNzaW9uTW9kZSxcbiAgICBhY2NvdW50OiBzdHJpbmcsXG4pOiBzdHJpbmcge1xuICAgIGNvbnN0IGNvbmRpdGlvbiA9IHtcbiAgICAgICAgU3RyaW5nRXF1YWxzOiB7XG4gICAgICAgICAgICAnYXdzOlByaW5jaXBhbEFjY291bnQnOiBhY2NvdW50LFxuICAgICAgICB9LFxuICAgICAgICBTdHJpbmdMaWtlOiB7XG4gICAgICAgICAgICAnYXdzOlByaW5jaXBhbFRhZy9HZW5pTmFtZSc6IFtcbiAgICAgICAgICAgICAgICAnZ2VuaS1lbmdpbmUtKicsXG4gICAgICAgICAgICAgICAgJ2dlbmktYmF0Y2gtKicsXG4gICAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgIH07XG5cbiAgICBjb25zdCBzdGF0ZW1lbnRzOiBvYmplY3RbXSA9IFtdO1xuXG4gICAgaWYgKG1vZGUgPT09ICdyZWFkLXdyaXRlJyB8fCBtb2RlID09PSAncmVhZC1vbmx5Jykge1xuICAgICAgICBzdGF0ZW1lbnRzLnB1c2goe1xuICAgICAgICAgICAgU2lkOiAnR2VuaUxpc3RCdWNrZXQnLFxuICAgICAgICAgICAgRWZmZWN0OiAnQWxsb3cnLFxuICAgICAgICAgICAgUHJpbmNpcGFsOiAnKicsXG4gICAgICAgICAgICBBY3Rpb246ICdzMzpMaXN0QnVja2V0JyxcbiAgICAgICAgICAgIFJlc291cmNlOiBgYXJuOmF3czpzMzo6OiR7YnVja2V0fWAsXG4gICAgICAgICAgICBDb25kaXRpb246IGNvbmRpdGlvbixcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgYWN0aW9uczogc3RyaW5nW10gPSBbXTtcbiAgICBpZiAobW9kZSA9PT0gJ3JlYWQtd3JpdGUnKSB7XG4gICAgICAgIGFjdGlvbnMucHVzaCgnczM6R2V0T2JqZWN0JywgJ3MzOlB1dE9iamVjdCcsICdzMzpEZWxldGVPYmplY3QnKTtcbiAgICB9IGVsc2UgaWYgKG1vZGUgPT09ICdyZWFkLW9ubHknKSB7XG4gICAgICAgIGFjdGlvbnMucHVzaCgnczM6R2V0T2JqZWN0Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgYWN0aW9ucy5wdXNoKCdzMzpQdXRPYmplY3QnLCAnczM6RGVsZXRlT2JqZWN0Jyk7XG4gICAgfVxuXG4gICAgc3RhdGVtZW50cy5wdXNoKHtcbiAgICAgICAgU2lkOiAnR2VuaU9iamVjdEFjY2VzcycsXG4gICAgICAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICAgICAgUHJpbmNpcGFsOiAnKicsXG4gICAgICAgIEFjdGlvbjogYWN0aW9ucyxcbiAgICAgICAgUmVzb3VyY2U6IGBhcm46YXdzOnMzOjo6JHtidWNrZXR9LypgLFxuICAgICAgICBDb25kaXRpb246IGNvbmRpdGlvbixcbiAgICB9KTtcblxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7IFZlcnNpb246ICcyMDEyLTEwLTE3JywgU3RhdGVtZW50OiBzdGF0ZW1lbnRzIH0pO1xufVxuXG5leHBvcnQgY29uc3QgY3JlYXRlQ29tbWFuZCA9IG5ldyBDb21tYW5kKCdjcmVhdGUnKVxuICAgIC5hbGlhcygnYWN0aXZhdGUnKVxuICAgIC5kZXNjcmlwdGlvbignQ3JlYXRlIElBTSByb2xlcyBhbmQgcG9saWNpZXMgZm9yIEdlbmkgY3Jvc3MtYWNjb3VudCBhY2Nlc3MnKVxuICAgIC5hcmd1bWVudCgnPHVyaT4nLCAnVGFyZ2V0IEFXUyBhY2NvdW50IFVSSSAoYXdzOi8vPGFjY291bnQ+LzxyZWdpb24+KScpXG4gICAgLm9wdGlvbignLS1nZW5pLWFjY291bnQgPGFjY291bnQ+JywgJ0dlbmkgQVdTIGFjY291bnQgSUQgdG8gdHJ1c3QnLCAnODgwNDIwMDM4NDYwJylcbiAgICAub3B0aW9uKCctLXRydXN0IDxhY2NvdW50PicsICdBbGlhcyBmb3IgLS1nZW5pLWFjY291bnQnKVxuICAgIC5vcHRpb24oJy0tcmVhZC13cml0ZS1idWNrZXRzIDxidWNrZXRzPicsICdDb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBleGlzdGluZyBTMyBidWNrZXRzIHRvIGdyYW50IHJlYWQtd3JpdGUgYWNjZXNzJylcbiAgICAub3B0aW9uKCctLXJlYWQtb25seS1idWNrZXRzIDxidWNrZXRzPicsICdDb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBleGlzdGluZyBTMyBidWNrZXRzIHRvIGdyYW50IHJlYWQtb25seSBhY2Nlc3MnKVxuICAgIC5vcHRpb24oJy0td3JpdGUtb25seS1idWNrZXRzIDxidWNrZXRzPicsICdDb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBleGlzdGluZyBTMyBidWNrZXRzIHRvIGdyYW50IHdyaXRlLW9ubHkgYWNjZXNzJylcbiAgICAub3B0aW9uKCctLXByb2ZpbGUgPHByb2ZpbGU+JywgJ0FXUyBwcm9maWxlIHRvIHVzZSBmb3IgY3JlZGVudGlhbHMnKVxuICAgIC5hY3Rpb24oYXN5bmMgKHVyaTogc3RyaW5nLCBvcHRpb25zOiBDcmVhdGVPcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgYWNjb3VudCwgcmVnaW9uIH0gPSBwYXJzZUF3c1VyaSh1cmkpO1xuICAgICAgICBjb25zdCB7IGNmbiwgaWFtLCBzMywgc3RzIH0gPSBjcmVhdGVDbGllbnRzKHJlZ2lvbiwgb3B0aW9ucy5wcm9maWxlKTtcbiAgICAgICAgY29uc3QgaWRlbnRpdHkgPSBhd2FpdCBnZXRDYWxsZXJJZGVudGl0eShzdHMpO1xuICAgICAgICBjb25zb2xlLmxvZyhgQXV0aGVudGljYXRlZCBhcyAke2lkZW50aXR5LmFybn0gKGFjY291bnQgJHtpZGVudGl0eS5hY2NvdW50fSlgKTtcblxuICAgICAgICBpZiAoaWRlbnRpdHkuYWNjb3VudCAhPT0gYWNjb3VudCkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgIGBXYXJuaW5nOiBDdXJyZW50IGFjY291bnQgKCR7aWRlbnRpdHkuYWNjb3VudH0pIGRvZXMgbm90IG1hdGNoIHRhcmdldCAoJHthY2NvdW50fSkuIGAgK1xuICAgICAgICAgICAgICAgIGBFbnN1cmUgeW91IGhhdmUgY3JlZGVudGlhbHMgZm9yIHRoZSB0YXJnZXQgYWNjb3VudC5gXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGVtcGxhdGVCb2R5ID0gcmVhZEZpbGVTeW5jKGpvaW4oX19kaXJuYW1lLCAnLi4vLi4vdGVtcGxhdGVzL3NldHVwLnlhbWwnKSwgJ3V0Zi04Jyk7XG4gICAgICAgIGNvbnN0IHRydXN0ZWRBY2NvdW50ID0gb3B0aW9ucy50cnVzdCA/PyBvcHRpb25zLmdlbmlBY2NvdW50O1xuICAgICAgICBjb25zdCBwYXJhbWV0ZXJzID0gW1xuICAgICAgICAgICAgeyBQYXJhbWV0ZXJLZXk6ICdHZW5pQWNjb3VudCcsIFBhcmFtZXRlclZhbHVlOiB0cnVzdGVkQWNjb3VudCB9LFxuICAgICAgICBdO1xuICAgICAgICBjb25zdCB0YWdzID0gW3sgS2V5OiAnQ3JlYXRlZEJ5JywgVmFsdWU6ICdHRU5JJyB9XTtcblxuICAgICAgICBsZXQgbmVlZHNQb2xsOiAnQ1JFQVRFJyB8ICdVUERBVEUnIHwgbnVsbCA9IG51bGw7XG4gICAgICAgIGxldCBzdGFja0FscmVhZHlVcFRvRGF0ZSA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgY2ZuLnNlbmQobmV3IENyZWF0ZVN0YWNrQ29tbWFuZCh7XG4gICAgICAgICAgICAgICAgU3RhY2tOYW1lOiBTVEFDS19OQU1FLFxuICAgICAgICAgICAgICAgIFRlbXBsYXRlQm9keTogdGVtcGxhdGVCb2R5LFxuICAgICAgICAgICAgICAgIENhcGFiaWxpdGllczogWydDQVBBQklMSVRZX05BTUVEX0lBTSddLFxuICAgICAgICAgICAgICAgIFBhcmFtZXRlcnM6IHBhcmFtZXRlcnMsXG4gICAgICAgICAgICAgICAgVGFnczogdGFncyxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBDcmVhdGluZyBzdGFjayAke1NUQUNLX05BTUV9Li4uYCk7XG4gICAgICAgICAgICBuZWVkc1BvbGwgPSAnQ1JFQVRFJztcbiAgICAgICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICAgICAgICBpZiAoKGVyciBhcyB7IG5hbWU/OiBzdHJpbmcgfSkubmFtZSA9PT0gJ0FscmVhZHlFeGlzdHNFeGNlcHRpb24nKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgY2ZuLnNlbmQobmV3IFVwZGF0ZVN0YWNrQ29tbWFuZCh7XG4gICAgICAgICAgICAgICAgICAgICAgICBTdGFja05hbWU6IFNUQUNLX05BTUUsXG4gICAgICAgICAgICAgICAgICAgICAgICBUZW1wbGF0ZUJvZHk6IHRlbXBsYXRlQm9keSxcbiAgICAgICAgICAgICAgICAgICAgICAgIENhcGFiaWxpdGllczogWydDQVBBQklMSVRZX05BTUVEX0lBTSddLFxuICAgICAgICAgICAgICAgICAgICAgICAgUGFyYW1ldGVyczogcGFyYW1ldGVycyxcbiAgICAgICAgICAgICAgICAgICAgICAgIFRhZ3M6IHRhZ3MsXG4gICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFVwZGF0aW5nIHN0YWNrICR7U1RBQ0tfTkFNRX0uLi5gKTtcbiAgICAgICAgICAgICAgICAgICAgbmVlZHNQb2xsID0gJ1VQREFURSc7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAodXBkYXRlRXJyOiB1bmtub3duKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSB1cGRhdGVFcnIgaW5zdGFuY2VvZiBFcnJvciA/IHVwZGF0ZUVyci5tZXNzYWdlIDogJyc7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKCdObyB1cGRhdGVzIGFyZSB0byBiZSBwZXJmb3JtZWQnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFN0YWNrICR7U1RBQ0tfTkFNRX0gaXMgYWxyZWFkeSB1cCB0byBkYXRlLmApO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RhY2tBbHJlYWR5VXBUb0RhdGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgdXBkYXRlRXJyO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTdGFjayBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIHJlZ2lvbi4gSUFNIHJvbGVzIGFyZSBnbG9iYWwg4oCUIGlmIHRoZXkgYWxyZWFkeVxuICAgICAgICAgICAgICAgIC8vIGV4aXN0IHRoZXkgd2VyZSBjcmVhdGVkIHZpYSBhIHN0YWNrIGluIGFub3RoZXIgcmVnaW9uOyBza2lwIHNpbGVudGx5LlxuICAgICAgICAgICAgICAgIGNvbnN0IGlhbVJvbGVzRXhpc3QgPSBhd2FpdCBjaGVja0lBTVJvbGVzRXhpc3QoaWFtKTtcbiAgICAgICAgICAgICAgICBpZiAoaWFtUm9sZXNFeGlzdCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgICAgICAgICAgICdcXG5JQU0gcm9sZXMgYWxyZWFkeSBleGlzdCBpbiB0aGlzIGFjY291bnQgKEdlbmlDcm9zc0FjY291bnRSb2xlLCBHZW5pQ2ZuU2VydmljZVJvbGUpLlxcbicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJ1NraXBwaW5nIENsb3VkRm9ybWF0aW9uIHN0YWNrIOKAlCBJQU0gcm9sZXMgYXJlIGdsb2JhbCBhbmQgc2hhcmVkIGFjcm9zcyBhbGwgcmVnaW9ucy5cXG4nICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdUbyB1cGRhdGUgcm9sZSBwZXJtaXNzaW9ucywgcnVuIHRoaXMgY29tbWFuZCBhZ2FpbnN0IHRoZSByZWdpb24gd2hlcmUgdGhlIHN0YWNrIHdhcyBmaXJzdCBjcmVhdGVkLidcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFxcbiAgR2VuaUNyb3NzQWNjb3VudFJvbGU6IGFybjphd3M6aWFtOjoke2FjY291bnR9OnJvbGUvR2VuaUNyb3NzQWNjb3VudFJvbGVgKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYCAgR2VuaUNmblNlcnZpY2VSb2xlOiAgIGFybjphd3M6aWFtOjoke2FjY291bnR9OnJvbGUvR2VuaUNmblNlcnZpY2VSb2xlYCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChuZWVkc1BvbGwpIHtcbiAgICAgICAgICAgIGNvbnN0IG91dHB1dHMgPSBhd2FpdCBwb2xsU3RhY2soY2ZuLCBTVEFDS19OQU1FLCBuZWVkc1BvbGwpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ1xcblNldHVwIGNvbXBsZXRlOicpO1xuICAgICAgICAgICAgcHJpbnRSb2xlQXJucyhvdXRwdXRzKTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qgb3V0cHV0IG9mIG91dHB1dHMpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgICAke291dHB1dC5PdXRwdXRLZXl9OiAke291dHB1dC5PdXRwdXRWYWx1ZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzdGFja0FscmVhZHlVcFRvRGF0ZSkge1xuICAgICAgICAgICAgY29uc3Qgb3V0cHV0cyA9IGF3YWl0IGdldFN0YWNrT3V0cHV0cyhjZm4sIFNUQUNLX05BTUUpO1xuICAgICAgICAgICAgaWYgKG91dHB1dHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdcXG5FeGlzdGluZyByb2xlIEFSTnM6Jyk7XG4gICAgICAgICAgICAgICAgcHJpbnRSb2xlQXJucyhvdXRwdXRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGJ1Y2tldENvbmZpZ3M6IEFycmF5PHsgYnVja2V0OiBzdHJpbmc7IG1vZGU6IFBlcm1pc3Npb25Nb2RlIH0+ID0gW1xuICAgICAgICAgICAgLi4ucGFyc2VCdWNrZXRMaXN0KG9wdGlvbnMucmVhZFdyaXRlQnVja2V0cykubWFwKGIgPT4gKHsgYnVja2V0OiBiLCBtb2RlOiAncmVhZC13cml0ZScgYXMgY29uc3QgfSkpLFxuICAgICAgICAgICAgLi4ucGFyc2VCdWNrZXRMaXN0KG9wdGlvbnMucmVhZE9ubHlCdWNrZXRzKS5tYXAoYiA9PiAoeyBidWNrZXQ6IGIsIG1vZGU6ICdyZWFkLW9ubHknIGFzIGNvbnN0IH0pKSxcbiAgICAgICAgICAgIC4uLnBhcnNlQnVja2V0TGlzdChvcHRpb25zLndyaXRlT25seUJ1Y2tldHMpLm1hcChiID0+ICh7IGJ1Y2tldDogYiwgbW9kZTogJ3dyaXRlLW9ubHknIGFzIGNvbnN0IH0pKSxcbiAgICAgICAgXTtcblxuICAgICAgICBpZiAoYnVja2V0Q29uZmlncy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnXFxuQ29uZmlndXJpbmcgYnVja2V0IHBlcm1pc3Npb25zLi4uJyk7XG4gICAgICAgICAgICBjb25zdCBidWNrZXRGYWlsdXJlczogQXJyYXk8eyBidWNrZXQ6IHN0cmluZzsgbW9kZTogUGVybWlzc2lvbk1vZGU7IG1lc3NhZ2U6IHN0cmluZyB9PiA9IFtdO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHsgYnVja2V0LCBtb2RlIH0gb2YgYnVja2V0Q29uZmlncykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBleGlzdGluZ1RhZ3M6IEFycmF5PHsgS2V5Pzogc3RyaW5nOyBWYWx1ZT86IHN0cmluZyB9PiA9IFtdO1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFnZ2luZyA9IGF3YWl0IHMzLnNlbmQobmV3IEdldEJ1Y2tldFRhZ2dpbmdDb21tYW5kKHsgQnVja2V0OiBidWNrZXQgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdUYWdzID0gdGFnZ2luZy5UYWdTZXQgPz8gW107XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChlcnIgYXMgeyBuYW1lPzogc3RyaW5nIH0pLm5hbWUgIT09ICdOb1N1Y2hUYWdTZXQnKSB0aHJvdyBlcnI7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZFRhZ3MgPSBleGlzdGluZ1RhZ3MuZmlsdGVyKFxuICAgICAgICAgICAgICAgICAgICAgICAgdCA9PiB0LktleSAhPT0gJ0NyZWF0ZWRCeScgJiYgdC5LZXkgIT09ICdHZW5pUGVybWlzc2lvbicsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGZpbHRlcmVkVGFncy5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBLZXk6ICdDcmVhdGVkQnknLCBWYWx1ZTogJ0dFTkknIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7IEtleTogJ0dlbmlQZXJtaXNzaW9uJywgVmFsdWU6IG1vZGUgfSxcbiAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBzMy5zZW5kKG5ldyBQdXRCdWNrZXRUYWdnaW5nQ29tbWFuZCh7XG4gICAgICAgICAgICAgICAgICAgICAgICBCdWNrZXQ6IGJ1Y2tldCxcbiAgICAgICAgICAgICAgICAgICAgICAgIFRhZ2dpbmc6IHsgVGFnU2V0OiBmaWx0ZXJlZFRhZ3MgYXMgQXJyYXk8eyBLZXk6IHN0cmluZzsgVmFsdWU6IHN0cmluZyB9PiB9LFxuICAgICAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9saWN5ID0gYnVpbGRCdWNrZXRQb2xpY3koYnVja2V0LCBtb2RlLCBhY2NvdW50KTtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgczMuc2VuZChuZXcgUHV0QnVja2V0UG9saWN5Q29tbWFuZCh7IEJ1Y2tldDogYnVja2V0LCBQb2xpY3k6IHBvbGljeSB9KSk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYCAgJHtidWNrZXR9OiAke21vZGV9YCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYCAgJHtidWNrZXR9OiBGQUlMRUQgLSAke21lc3NhZ2V9YCk7XG4gICAgICAgICAgICAgICAgICAgIGJ1Y2tldEZhaWx1cmVzLnB1c2goeyBidWNrZXQsIG1vZGUsIG1lc3NhZ2UgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoYnVja2V0RmFpbHVyZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGlFcnJvcih7XG4gICAgICAgICAgICAgICAgICAgIGNvZGU6ICdVUFNUUkVBTScsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBGYWlsZWQgdG8gY29uZmlndXJlICR7YnVja2V0RmFpbHVyZXMubGVuZ3RofSBidWNrZXQgcGVybWlzc2lvbiB1cGRhdGUocykuYCxcbiAgICAgICAgICAgICAgICAgICAgaGludDogJ0ZpeCBmYWlsZWQgYnVja2V0IHBlcm1pc3Npb25zIGFuZCByZXJ1biBgZ2VuaSBzZXR1cCBjcmVhdGVgLicsXG4gICAgICAgICAgICAgICAgICAgIGV4aXRDb2RlOiA1LFxuICAgICAgICAgICAgICAgICAgICBkZXRhaWxzOiB7IGZhaWx1cmVzOiBidWNrZXRGYWlsdXJlcyB9LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG5cbmFzeW5jIGZ1bmN0aW9uIGNoZWNrSUFNUm9sZXNFeGlzdChcbiAgICBpYW06IGltcG9ydCgnQGF3cy1zZGsvY2xpZW50LWlhbScpLklBTUNsaWVudCxcbik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGlhbS5zZW5kKG5ldyBHZXRSb2xlQ29tbWFuZCh7IFJvbGVOYW1lOiAnR2VuaUNyb3NzQWNjb3VudFJvbGUnIH0pKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICAgIGlmICgoZXJyIGFzIHsgbmFtZT86IHN0cmluZyB9KS5uYW1lID09PSAnTm9TdWNoRW50aXR5RXhjZXB0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycjtcbiAgICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHBvbGxTdGFjayhcbiAgICBjZm46IGltcG9ydCgnQGF3cy1zZGsvY2xpZW50LWNsb3VkZm9ybWF0aW9uJykuQ2xvdWRGb3JtYXRpb25DbGllbnQsXG4gICAgc3RhY2tOYW1lOiBzdHJpbmcsXG4gICAgb3BlcmF0aW9uOiAnQ1JFQVRFJyB8ICdVUERBVEUnLFxuKTogUHJvbWlzZTxTdGFja091dHB1dFtdPiB7XG4gICAgY29uc3Qgc3VjY2Vzc1N0YXRlID0gYCR7b3BlcmF0aW9ufV9DT01QTEVURWA7XG4gICAgY29uc3QgZmFpbHVyZVN0YXRlcyA9IFtcbiAgICAgICAgYCR7b3BlcmF0aW9ufV9GQUlMRURgLFxuICAgICAgICAnUk9MTEJBQ0tfQ09NUExFVEUnLFxuICAgICAgICAnUk9MTEJBQ0tfRkFJTEVEJyxcbiAgICAgICAgJ1VQREFURV9ST0xMQkFDS19DT01QTEVURScsXG4gICAgICAgICdVUERBVEVfUk9MTEJBQ0tfRkFJTEVEJyxcbiAgICBdO1xuXG4gICAgZm9yICg7IDspIHtcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgNTAwMCkpO1xuXG4gICAgICAgIGNvbnN0IHsgU3RhY2tzIH0gPSBhd2FpdCBjZm4uc2VuZChuZXcgRGVzY3JpYmVTdGFja3NDb21tYW5kKHsgU3RhY2tOYW1lOiBzdGFja05hbWUgfSkpO1xuICAgICAgICBjb25zdCBzdGFjayA9IFN0YWNrcz8uWzBdO1xuICAgICAgICBpZiAoIXN0YWNrKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFN0YWNrICR7c3RhY2tOYW1lfSBub3QgZm91bmRgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IHN0YWNrLlN0YWNrU3RhdHVzID8/ICcnO1xuICAgICAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShgICBTdGF0dXM6ICR7c3RhdHVzfVxcbmApO1xuXG4gICAgICAgIGlmIChzdGF0dXMgPT09IHN1Y2Nlc3NTdGF0ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHN0YWNrLk91dHB1dHMgPz8gW107XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmFpbHVyZVN0YXRlcy5pbmNsdWRlcyhzdGF0dXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFN0YWNrICR7c3RhY2tOYW1lfSByZWFjaGVkIGZhaWx1cmUgc3RhdGU6ICR7c3RhdHVzfWApO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRTdGFja091dHB1dHMoXG4gICAgY2ZuOiBpbXBvcnQoJ0Bhd3Mtc2RrL2NsaWVudC1jbG91ZGZvcm1hdGlvbicpLkNsb3VkRm9ybWF0aW9uQ2xpZW50LFxuICAgIHN0YWNrTmFtZTogc3RyaW5nLFxuKTogUHJvbWlzZTxTdGFja091dHB1dFtdPiB7XG4gICAgY29uc3QgeyBTdGFja3MgfSA9IGF3YWl0IGNmbi5zZW5kKG5ldyBEZXNjcmliZVN0YWNrc0NvbW1hbmQoeyBTdGFja05hbWU6IHN0YWNrTmFtZSB9KSk7XG4gICAgcmV0dXJuIFN0YWNrcz8uWzBdPy5PdXRwdXRzID8/IFtdO1xufVxuXG5mdW5jdGlvbiBwcmludFJvbGVBcm5zKG91dHB1dHM6IFN0YWNrT3V0cHV0W10pOiB2b2lkIHtcbiAgICBjb25zdCByb2xlQXJucyA9IFtcbiAgICAgICAgeyBrZXk6ICdDcm9zc0FjY291bnRSb2xlQXJuJywgbGFiZWw6ICdHZW5pQ3Jvc3NBY2NvdW50Um9sZScgfSxcbiAgICAgICAgeyBrZXk6ICdDZm5TZXJ2aWNlUm9sZUFybicsIGxhYmVsOiAnR2VuaUNmblNlcnZpY2VSb2xlJyB9LFxuICAgIF07XG5cbiAgICBmb3IgKGNvbnN0IHJvbGVBcm4gb2Ygcm9sZUFybnMpIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0cy5maW5kKG8gPT4gby5PdXRwdXRLZXkgPT09IHJvbGVBcm4ua2V5KTtcbiAgICAgICAgaWYgKG91dHB1dD8uT3V0cHV0VmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGAgICR7cm9sZUFybi5sYWJlbH06ICR7b3V0cHV0Lk91dHB1dFZhbHVlfWApO1xuICAgICAgICB9XG4gICAgfVxufVxuIl19
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.deleteCommand = void 0;
|
|
37
|
+
const readline = __importStar(require("readline"));
|
|
38
|
+
const commander_1 = require("commander");
|
|
39
|
+
const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
|
|
40
|
+
const clients_1 = require("../../aws/clients");
|
|
41
|
+
const STACK_NAME = 'geni-setup';
|
|
42
|
+
exports.deleteCommand = new commander_1.Command('destroy')
|
|
43
|
+
.description('Remove Geni cross-account roles and policies')
|
|
44
|
+
.argument('<uri>', 'Target AWS account URI (aws://<account>/<region>)')
|
|
45
|
+
.option('--force', 'Skip confirmation prompt')
|
|
46
|
+
.option('--profile <profile>', 'AWS profile to use for credentials')
|
|
47
|
+
.action(async (uri, options) => {
|
|
48
|
+
const { account, region } = (0, clients_1.parseAwsUri)(uri);
|
|
49
|
+
const { cfn } = (0, clients_1.createClients)(region, options.profile);
|
|
50
|
+
if (!options.force) {
|
|
51
|
+
const confirmed = await confirm(`This will delete the Geni roles and policies from account ${account}. Continue? (y/N) `);
|
|
52
|
+
if (!confirmed) {
|
|
53
|
+
console.log('Aborted.');
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
await cfn.send(new client_cloudformation_1.DeleteStackCommand({ StackName: STACK_NAME }));
|
|
58
|
+
console.log(`Deleting stack ${STACK_NAME}...`);
|
|
59
|
+
await pollDelete(cfn, STACK_NAME);
|
|
60
|
+
console.log('\nGeni setup removed.');
|
|
61
|
+
});
|
|
62
|
+
async function pollDelete(cfn, stackName) {
|
|
63
|
+
for (;;) {
|
|
64
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
65
|
+
try {
|
|
66
|
+
const { Stacks } = await cfn.send(new client_cloudformation_1.DescribeStacksCommand({ StackName: stackName }));
|
|
67
|
+
const status = Stacks?.[0]?.StackStatus ?? '';
|
|
68
|
+
process.stdout.write(` Status: ${status}\n`);
|
|
69
|
+
if (status === 'DELETE_COMPLETE') {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (status === 'DELETE_FAILED') {
|
|
73
|
+
throw new Error(`Stack ${stackName} delete failed`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const message = err.message ?? '';
|
|
78
|
+
if (message.includes('does not exist')) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
throw err;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function confirm(message) {
|
|
86
|
+
const rl = readline.createInterface({
|
|
87
|
+
input: process.stdin,
|
|
88
|
+
output: process.stdout,
|
|
89
|
+
});
|
|
90
|
+
return new Promise((resolve) => {
|
|
91
|
+
rl.question(message, (answer) => {
|
|
92
|
+
rl.close();
|
|
93
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVsZXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL3NldHVwL2RlbGV0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxtREFBcUM7QUFDckMseUNBQW9DO0FBQ3BDLDBFQUd3QztBQUN4QywrQ0FBK0Q7QUFFL0QsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDO0FBRW5CLFFBQUEsYUFBYSxHQUFHLElBQUksbUJBQU8sQ0FBQyxTQUFTLENBQUM7S0FDOUMsV0FBVyxDQUFDLDhDQUE4QyxDQUFDO0tBQzNELFFBQVEsQ0FBQyxPQUFPLEVBQUUsbURBQW1ELENBQUM7S0FDdEUsTUFBTSxDQUFDLFNBQVMsRUFBRSwwQkFBMEIsQ0FBQztLQUM3QyxNQUFNLENBQUMscUJBQXFCLEVBQUUsb0NBQW9DLENBQUM7S0FDbkUsTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFXLEVBQUUsT0FBOEMsRUFBRSxFQUFFO0lBQzFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBQSxxQkFBVyxFQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFBLHVCQUFhLEVBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUV2RCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2pCLE1BQU0sU0FBUyxHQUFHLE1BQU0sT0FBTyxDQUMzQiw2REFBNkQsT0FBTyxvQkFBb0IsQ0FDM0YsQ0FBQztRQUNGLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNiLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEIsT0FBTztRQUNYLENBQUM7SUFDTCxDQUFDO0lBRUQsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksMENBQWtCLENBQUMsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2xFLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLFVBQVUsS0FBSyxDQUFDLENBQUM7SUFFL0MsTUFBTSxVQUFVLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBRWxDLE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLENBQUMsQ0FBQztBQUN6QyxDQUFDLENBQUMsQ0FBQztBQUVQLEtBQUssVUFBVSxVQUFVLENBQ3JCLEdBQWtFLEVBQ2xFLFNBQWlCO0lBRWpCLFNBQVUsQ0FBQztRQUNQLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUUxRCxJQUFJLENBQUM7WUFDRCxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksNkNBQXFCLENBQUMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3ZGLE1BQU0sTUFBTSxHQUFHLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsSUFBSSxFQUFFLENBQUM7WUFDOUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxNQUFNLElBQUksQ0FBQyxDQUFDO1lBRTlDLElBQUksTUFBTSxLQUFLLGlCQUFpQixFQUFFLENBQUM7Z0JBQy9CLE9BQU87WUFDWCxDQUFDO1lBRUQsSUFBSSxNQUFNLEtBQUssZUFBZSxFQUFFLENBQUM7Z0JBQzdCLE1BQU0sSUFBSSxLQUFLLENBQUMsU0FBUyxTQUFTLGdCQUFnQixDQUFDLENBQUM7WUFDeEQsQ0FBQztRQUNMLENBQUM7UUFBQyxPQUFPLEdBQVksRUFBRSxDQUFDO1lBQ3BCLE1BQU0sT0FBTyxHQUFJLEdBQTRCLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQztZQUM1RCxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUFDO2dCQUNyQyxPQUFPO1lBQ1gsQ0FBQztZQUNELE1BQU0sR0FBRyxDQUFDO1FBQ2QsQ0FBQztJQUNMLENBQUM7QUFDTCxDQUFDO0FBRUQsU0FBUyxPQUFPLENBQUMsT0FBZTtJQUM1QixNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsZUFBZSxDQUFDO1FBQ2hDLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSztRQUNwQixNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07S0FDekIsQ0FBQyxDQUFDO0lBRUgsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1FBQzNCLEVBQUUsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDNUIsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsS0FBSyxHQUFHLElBQUksTUFBTSxDQUFDLFdBQVcsRUFBRSxLQUFLLEtBQUssQ0FBQyxDQUFDO1FBQzVFLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcmVhZGxpbmUgZnJvbSAncmVhZGxpbmUnO1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQge1xuICAgIERlbGV0ZVN0YWNrQ29tbWFuZCxcbiAgICBEZXNjcmliZVN0YWNrc0NvbW1hbmQsXG59IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1jbG91ZGZvcm1hdGlvbic7XG5pbXBvcnQgeyBjcmVhdGVDbGllbnRzLCBwYXJzZUF3c1VyaSB9IGZyb20gJy4uLy4uL2F3cy9jbGllbnRzJztcblxuY29uc3QgU1RBQ0tfTkFNRSA9ICdnZW5pLXNldHVwJztcblxuZXhwb3J0IGNvbnN0IGRlbGV0ZUNvbW1hbmQgPSBuZXcgQ29tbWFuZCgnZGVzdHJveScpXG4gICAgLmRlc2NyaXB0aW9uKCdSZW1vdmUgR2VuaSBjcm9zcy1hY2NvdW50IHJvbGVzIGFuZCBwb2xpY2llcycpXG4gICAgLmFyZ3VtZW50KCc8dXJpPicsICdUYXJnZXQgQVdTIGFjY291bnQgVVJJIChhd3M6Ly88YWNjb3VudD4vPHJlZ2lvbj4pJylcbiAgICAub3B0aW9uKCctLWZvcmNlJywgJ1NraXAgY29uZmlybWF0aW9uIHByb21wdCcpXG4gICAgLm9wdGlvbignLS1wcm9maWxlIDxwcm9maWxlPicsICdBV1MgcHJvZmlsZSB0byB1c2UgZm9yIGNyZWRlbnRpYWxzJylcbiAgICAuYWN0aW9uKGFzeW5jICh1cmk6IHN0cmluZywgb3B0aW9uczogeyBmb3JjZT86IGJvb2xlYW47IHByb2ZpbGU/OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICBjb25zdCB7IGFjY291bnQsIHJlZ2lvbiB9ID0gcGFyc2VBd3NVcmkodXJpKTtcbiAgICAgICAgY29uc3QgeyBjZm4gfSA9IGNyZWF0ZUNsaWVudHMocmVnaW9uLCBvcHRpb25zLnByb2ZpbGUpO1xuXG4gICAgICAgIGlmICghb3B0aW9ucy5mb3JjZSkge1xuICAgICAgICAgICAgY29uc3QgY29uZmlybWVkID0gYXdhaXQgY29uZmlybShcbiAgICAgICAgICAgICAgICBgVGhpcyB3aWxsIGRlbGV0ZSB0aGUgR2VuaSByb2xlcyBhbmQgcG9saWNpZXMgZnJvbSBhY2NvdW50ICR7YWNjb3VudH0uIENvbnRpbnVlPyAoeS9OKSBgXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKCFjb25maXJtZWQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnQWJvcnRlZC4nKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCBjZm4uc2VuZChuZXcgRGVsZXRlU3RhY2tDb21tYW5kKHsgU3RhY2tOYW1lOiBTVEFDS19OQU1FIH0pKTtcbiAgICAgICAgY29uc29sZS5sb2coYERlbGV0aW5nIHN0YWNrICR7U1RBQ0tfTkFNRX0uLi5gKTtcblxuICAgICAgICBhd2FpdCBwb2xsRGVsZXRlKGNmbiwgU1RBQ0tfTkFNRSk7XG5cbiAgICAgICAgY29uc29sZS5sb2coJ1xcbkdlbmkgc2V0dXAgcmVtb3ZlZC4nKTtcbiAgICB9KTtcblxuYXN5bmMgZnVuY3Rpb24gcG9sbERlbGV0ZShcbiAgICBjZm46IGltcG9ydCgnQGF3cy1zZGsvY2xpZW50LWNsb3VkZm9ybWF0aW9uJykuQ2xvdWRGb3JtYXRpb25DbGllbnQsXG4gICAgc3RhY2tOYW1lOiBzdHJpbmcsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKDsgOykge1xuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCA1MDAwKSk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHsgU3RhY2tzIH0gPSBhd2FpdCBjZm4uc2VuZChuZXcgRGVzY3JpYmVTdGFja3NDb21tYW5kKHsgU3RhY2tOYW1lOiBzdGFja05hbWUgfSkpO1xuICAgICAgICAgICAgY29uc3Qgc3RhdHVzID0gU3RhY2tzPy5bMF0/LlN0YWNrU3RhdHVzID8/ICcnO1xuICAgICAgICAgICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoYCAgU3RhdHVzOiAke3N0YXR1c31cXG5gKTtcblxuICAgICAgICAgICAgaWYgKHN0YXR1cyA9PT0gJ0RFTEVURV9DT01QTEVURScpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdERUxFVEVfRkFJTEVEJykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU3RhY2sgJHtzdGFja05hbWV9IGRlbGV0ZSBmYWlsZWRgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gKGVyciBhcyB7IG1lc3NhZ2U/OiBzdHJpbmcgfSkubWVzc2FnZSA/PyAnJztcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKCdkb2VzIG5vdCBleGlzdCcpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBjb25maXJtKG1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHJsID0gcmVhZGxpbmUuY3JlYXRlSW50ZXJmYWNlKHtcbiAgICAgICAgaW5wdXQ6IHByb2Nlc3Muc3RkaW4sXG4gICAgICAgIG91dHB1dDogcHJvY2Vzcy5zdGRvdXQsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgcmwucXVlc3Rpb24obWVzc2FnZSwgKGFuc3dlcikgPT4ge1xuICAgICAgICAgICAgcmwuY2xvc2UoKTtcbiAgICAgICAgICAgIHJlc29sdmUoYW5zd2VyLnRvTG93ZXJDYXNlKCkgPT09ICd5JyB8fCBhbnN3ZXIudG9Mb3dlckNhc2UoKSA9PT0gJ3llcycpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.statusCommand = void 0;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
|
|
6
|
+
const clients_1 = require("../../aws/clients");
|
|
7
|
+
const STACK_NAME = 'geni-setup';
|
|
8
|
+
exports.statusCommand = new commander_1.Command('status')
|
|
9
|
+
.description('Check the status of Geni cross-account setup')
|
|
10
|
+
.argument('<uri>', 'Target AWS account URI (aws://<account>/<region>)')
|
|
11
|
+
.option('--profile <profile>', 'AWS profile to use for credentials')
|
|
12
|
+
.action(async (uri, options) => {
|
|
13
|
+
const { account, region } = (0, clients_1.parseAwsUri)(uri);
|
|
14
|
+
const { cfn } = (0, clients_1.createClients)(region, options.profile);
|
|
15
|
+
console.log(`Checking Geni setup in account ${account} (${region})...\n`);
|
|
16
|
+
try {
|
|
17
|
+
const { Stacks } = await cfn.send(new client_cloudformation_1.DescribeStacksCommand({ StackName: STACK_NAME }));
|
|
18
|
+
const stack = Stacks?.[0];
|
|
19
|
+
if (!stack) {
|
|
20
|
+
console.log('Geni setup not found. Run `geni setup create` to set up.');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
console.log(`Stack: ${stack.StackName}`);
|
|
24
|
+
console.log(`Status: ${stack.StackStatus}`);
|
|
25
|
+
console.log(`Created: ${stack.CreationTime?.toISOString()}`);
|
|
26
|
+
if (stack.LastUpdatedTime) {
|
|
27
|
+
console.log(`Updated: ${stack.LastUpdatedTime.toISOString()}`);
|
|
28
|
+
}
|
|
29
|
+
if (stack.Outputs && stack.Outputs.length > 0) {
|
|
30
|
+
console.log('\nOutputs:');
|
|
31
|
+
for (const output of stack.Outputs) {
|
|
32
|
+
console.log(` ${output.OutputKey}: ${output.OutputValue}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
const message = err.message ?? '';
|
|
38
|
+
if (message.includes('does not exist')) {
|
|
39
|
+
console.log('Geni setup not found. Run `geni setup create` to set up.');
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
throw err;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdHVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL3NldHVwL3N0YXR1cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5Q0FBb0M7QUFDcEMsMEVBQXVFO0FBQ3ZFLCtDQUErRDtBQUUvRCxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUM7QUFFbkIsUUFBQSxhQUFhLEdBQUcsSUFBSSxtQkFBTyxDQUFDLFFBQVEsQ0FBQztLQUM3QyxXQUFXLENBQUMsOENBQThDLENBQUM7S0FDM0QsUUFBUSxDQUFDLE9BQU8sRUFBRSxtREFBbUQsQ0FBQztLQUN0RSxNQUFNLENBQUMscUJBQXFCLEVBQUUsb0NBQW9DLENBQUM7S0FDbkUsTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFXLEVBQUUsT0FBNkIsRUFBRSxFQUFFO0lBQ3pELE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBQSxxQkFBVyxFQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFBLHVCQUFhLEVBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUV2RCxPQUFPLENBQUMsR0FBRyxDQUFDLGtDQUFrQyxPQUFPLEtBQUssTUFBTSxRQUFRLENBQUMsQ0FBQztJQUUxRSxJQUFJLENBQUM7UUFDRCxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksNkNBQXFCLENBQUMsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3hGLE1BQU0sS0FBSyxHQUFHLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzFCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNULE9BQU8sQ0FBQyxHQUFHLENBQUMsMERBQTBELENBQUMsQ0FBQztZQUN4RSxPQUFPO1FBQ1gsQ0FBQztRQUVELE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxLQUFLLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUMzQyxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDN0MsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLEtBQUssQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzdELElBQUksS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxLQUFLLENBQUMsZUFBZSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNuRSxDQUFDO1FBRUQsSUFBSSxLQUFLLENBQUMsT0FBTyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzVDLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDMUIsS0FBSyxNQUFNLE1BQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2pDLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxNQUFNLENBQUMsU0FBUyxLQUFLLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1lBQ2hFLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQztJQUFDLE9BQU8sR0FBWSxFQUFFLENBQUM7UUFDcEIsTUFBTSxPQUFPLEdBQUksR0FBNEIsQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDO1FBQzVELElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7WUFDckMsT0FBTyxDQUFDLEdBQUcsQ0FBQywwREFBMEQsQ0FBQyxDQUFDO1FBQzVFLENBQUM7YUFBTSxDQUFDO1lBQ0osTUFBTSxHQUFHLENBQUM7UUFDZCxDQUFDO0lBQ0wsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgeyBEZXNjcmliZVN0YWNrc0NvbW1hbmQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtY2xvdWRmb3JtYXRpb24nO1xuaW1wb3J0IHsgY3JlYXRlQ2xpZW50cywgcGFyc2VBd3NVcmkgfSBmcm9tICcuLi8uLi9hd3MvY2xpZW50cyc7XG5cbmNvbnN0IFNUQUNLX05BTUUgPSAnZ2VuaS1zZXR1cCc7XG5cbmV4cG9ydCBjb25zdCBzdGF0dXNDb21tYW5kID0gbmV3IENvbW1hbmQoJ3N0YXR1cycpXG4gICAgLmRlc2NyaXB0aW9uKCdDaGVjayB0aGUgc3RhdHVzIG9mIEdlbmkgY3Jvc3MtYWNjb3VudCBzZXR1cCcpXG4gICAgLmFyZ3VtZW50KCc8dXJpPicsICdUYXJnZXQgQVdTIGFjY291bnQgVVJJIChhd3M6Ly88YWNjb3VudD4vPHJlZ2lvbj4pJylcbiAgICAub3B0aW9uKCctLXByb2ZpbGUgPHByb2ZpbGU+JywgJ0FXUyBwcm9maWxlIHRvIHVzZSBmb3IgY3JlZGVudGlhbHMnKVxuICAgIC5hY3Rpb24oYXN5bmMgKHVyaTogc3RyaW5nLCBvcHRpb25zOiB7IHByb2ZpbGU/OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICBjb25zdCB7IGFjY291bnQsIHJlZ2lvbiB9ID0gcGFyc2VBd3NVcmkodXJpKTtcbiAgICAgICAgY29uc3QgeyBjZm4gfSA9IGNyZWF0ZUNsaWVudHMocmVnaW9uLCBvcHRpb25zLnByb2ZpbGUpO1xuXG4gICAgICAgIGNvbnNvbGUubG9nKGBDaGVja2luZyBHZW5pIHNldHVwIGluIGFjY291bnQgJHthY2NvdW50fSAoJHtyZWdpb259KS4uLlxcbmApO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB7IFN0YWNrcyB9ID0gYXdhaXQgY2ZuLnNlbmQobmV3IERlc2NyaWJlU3RhY2tzQ29tbWFuZCh7IFN0YWNrTmFtZTogU1RBQ0tfTkFNRSB9KSk7XG4gICAgICAgICAgICBjb25zdCBzdGFjayA9IFN0YWNrcz8uWzBdO1xuICAgICAgICAgICAgaWYgKCFzdGFjaykge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdHZW5pIHNldHVwIG5vdCBmb3VuZC4gUnVuIGBnZW5pIHNldHVwIGNyZWF0ZWAgdG8gc2V0IHVwLicpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc29sZS5sb2coYFN0YWNrOiAgICR7c3RhY2suU3RhY2tOYW1lfWApO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFN0YXR1czogICR7c3RhY2suU3RhY2tTdGF0dXN9YCk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgQ3JlYXRlZDogJHtzdGFjay5DcmVhdGlvblRpbWU/LnRvSVNPU3RyaW5nKCl9YCk7XG4gICAgICAgICAgICBpZiAoc3RhY2suTGFzdFVwZGF0ZWRUaW1lKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFVwZGF0ZWQ6ICR7c3RhY2suTGFzdFVwZGF0ZWRUaW1lLnRvSVNPU3RyaW5nKCl9YCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdGFjay5PdXRwdXRzICYmIHN0YWNrLk91dHB1dHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdcXG5PdXRwdXRzOicpO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgb3V0cHV0IG9mIHN0YWNrLk91dHB1dHMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYCAgJHtvdXRwdXQuT3V0cHV0S2V5fTogJHtvdXRwdXQuT3V0cHV0VmFsdWV9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnI6IHVua25vd24pIHtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSAoZXJyIGFzIHsgbWVzc2FnZT86IHN0cmluZyB9KS5tZXNzYWdlID8/ICcnO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoJ2RvZXMgbm90IGV4aXN0JykpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnR2VuaSBzZXR1cCBub3QgZm91bmQuIFJ1biBgZ2VuaSBzZXR1cCBjcmVhdGVgIHRvIHNldCB1cC4nKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG4iXX0=
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupCommand = void 0;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const create_1 = require("./setup/create");
|
|
6
|
+
const status_1 = require("./setup/status");
|
|
7
|
+
const delete_1 = require("./setup/delete");
|
|
8
|
+
exports.setupCommand = new commander_1.Command('setup')
|
|
9
|
+
.description('Manage AWS cross-account setup for Geni')
|
|
10
|
+
.addCommand(create_1.createCommand)
|
|
11
|
+
.addCommand(status_1.statusCommand)
|
|
12
|
+
.addCommand(delete_1.deleteCommand);
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dXAuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvc2V0dXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUNBQW9DO0FBQ3BDLDJDQUErQztBQUMvQywyQ0FBK0M7QUFDL0MsMkNBQStDO0FBRWxDLFFBQUEsWUFBWSxHQUFHLElBQUksbUJBQU8sQ0FBQyxPQUFPLENBQUM7S0FDM0MsV0FBVyxDQUFDLHlDQUF5QyxDQUFDO0tBQ3RELFVBQVUsQ0FBQyxzQkFBYSxDQUFDO0tBQ3pCLFVBQVUsQ0FBQyxzQkFBYSxDQUFDO0tBQ3pCLFVBQVUsQ0FBQyxzQkFBYSxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tYW5kIH0gZnJvbSAnY29tbWFuZGVyJztcbmltcG9ydCB7IGNyZWF0ZUNvbW1hbmQgfSBmcm9tICcuL3NldHVwL2NyZWF0ZSc7XG5pbXBvcnQgeyBzdGF0dXNDb21tYW5kIH0gZnJvbSAnLi9zZXR1cC9zdGF0dXMnO1xuaW1wb3J0IHsgZGVsZXRlQ29tbWFuZCB9IGZyb20gJy4vc2V0dXAvZGVsZXRlJztcblxuZXhwb3J0IGNvbnN0IHNldHVwQ29tbWFuZCA9IG5ldyBDb21tYW5kKCdzZXR1cCcpXG4gICAgLmRlc2NyaXB0aW9uKCdNYW5hZ2UgQVdTIGNyb3NzLWFjY291bnQgc2V0dXAgZm9yIEdlbmknKVxuICAgIC5hZGRDb21tYW5kKGNyZWF0ZUNvbW1hbmQpXG4gICAgLmFkZENvbW1hbmQoc3RhdHVzQ29tbWFuZClcbiAgICAuYWRkQ29tbWFuZChkZWxldGVDb21tYW5kKTtcbiJdfQ==
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.storageCommand = void 0;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const auth_1 = require("../auth");
|
|
6
|
+
const format_js_1 = require("../format.js");
|
|
7
|
+
exports.storageCommand = new commander_1.Command('storage')
|
|
8
|
+
.description('Manage storages');
|
|
9
|
+
exports.storageCommand
|
|
10
|
+
.command('list')
|
|
11
|
+
.description('List storages')
|
|
12
|
+
.option('--status <status>', 'Filter by status (e.g. ACTIVE, PENDING, FAILED, DELETED)')
|
|
13
|
+
.option('--environment-id <id>', 'Filter by environment ID')
|
|
14
|
+
.addOption(new commander_1.Option('--format <format>', 'Output format').choices(['table', 'json', 'csv']).default('table'))
|
|
15
|
+
.action(async (opts) => {
|
|
16
|
+
const params = new URLSearchParams();
|
|
17
|
+
if (opts.status)
|
|
18
|
+
params.set('status', opts.status);
|
|
19
|
+
if (opts.environmentId)
|
|
20
|
+
params.set('environmentId', opts.environmentId);
|
|
21
|
+
if (process.env.GENI_TENANT_ID)
|
|
22
|
+
params.set('tenantId', process.env.GENI_TENANT_ID);
|
|
23
|
+
const query = params.size ? `?${params}` : '';
|
|
24
|
+
const data = await (0, auth_1.fetchJson)((0, auth_1.apiUrl)(`/admin/storages${query}`));
|
|
25
|
+
(0, format_js_1.formatOutput)(opts.format === 'json' ? data : data.items, opts.format, format_js_1.storageColumns);
|
|
26
|
+
});
|
|
27
|
+
exports.storageCommand
|
|
28
|
+
.command('get <id>')
|
|
29
|
+
.description('Get a storage by ID')
|
|
30
|
+
.addOption(new commander_1.Option('--format <format>', 'Output format').choices(['table', 'json', 'csv']).default('table'))
|
|
31
|
+
.action(async (id, opts) => {
|
|
32
|
+
const query = process.env.GENI_TENANT_ID ? `?tenantId=${process.env.GENI_TENANT_ID}` : '';
|
|
33
|
+
const data = await (0, auth_1.fetchJson)((0, auth_1.apiUrl)(`/admin/storages/${id}${query}`));
|
|
34
|
+
(0, format_js_1.formatOutput)(data, opts.format, format_js_1.storageColumns);
|
|
35
|
+
});
|
|
36
|
+
exports.storageCommand
|
|
37
|
+
.command('delete <id>')
|
|
38
|
+
.description('Delete a storage')
|
|
39
|
+
.addOption(new commander_1.Option('--format <format>', 'Output format').choices(['table', 'json', 'csv']).default('table'))
|
|
40
|
+
.action(async (id, opts) => {
|
|
41
|
+
const query = process.env.GENI_TENANT_ID ? `?tenantId=${process.env.GENI_TENANT_ID}` : '';
|
|
42
|
+
const data = await (0, auth_1.fetchJson)((0, auth_1.apiUrl)(`/admin/storages/${id}${query}`), {
|
|
43
|
+
method: 'DELETE',
|
|
44
|
+
});
|
|
45
|
+
(0, format_js_1.formatOutput)(data, opts.format, format_js_1.storageColumns);
|
|
46
|
+
});
|
|
47
|
+
exports.storageCommand
|
|
48
|
+
.command('create')
|
|
49
|
+
.description('Create a storage')
|
|
50
|
+
.requiredOption('--name <name>', 'Storage name')
|
|
51
|
+
.requiredOption('--environment-id <id>', 'Environment ID')
|
|
52
|
+
.option('--permission-mode <mode>', 'Permission mode (read-write, read-only, write-only)', 'read-write')
|
|
53
|
+
.addOption(new commander_1.Option('--format <format>', 'Output format').choices(['table', 'json', 'csv']).default('table'))
|
|
54
|
+
.action(async (opts) => {
|
|
55
|
+
const data = await (0, auth_1.fetchJson)((0, auth_1.apiUrl)('/admin/storages'), {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
headers: { 'Content-Type': 'application/json' },
|
|
58
|
+
body: JSON.stringify({
|
|
59
|
+
name: opts.name,
|
|
60
|
+
environmentId: opts.environmentId,
|
|
61
|
+
permissionMode: opts.permissionMode,
|
|
62
|
+
...(process.env.GENI_TENANT_ID ? { tenantId: process.env.GENI_TENANT_ID } : {}),
|
|
63
|
+
}),
|
|
64
|
+
});
|
|
65
|
+
(0, format_js_1.formatOutput)(data, opts.format, format_js_1.storageColumns);
|
|
66
|
+
});
|
|
67
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy9zdG9yYWdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlDQUEyQztBQUMzQyxrQ0FBMkM7QUFDM0MsNENBQThFO0FBRWpFLFFBQUEsY0FBYyxHQUFHLElBQUksbUJBQU8sQ0FBQyxTQUFTLENBQUM7S0FDakQsV0FBVyxDQUFDLGlCQUFpQixDQUFDLENBQUE7QUFFakMsc0JBQWM7S0FDWCxPQUFPLENBQUMsTUFBTSxDQUFDO0tBQ2YsV0FBVyxDQUFDLGVBQWUsQ0FBQztLQUM1QixNQUFNLENBQUMsbUJBQW1CLEVBQUUsMERBQTBELENBQUM7S0FDdkYsTUFBTSxDQUFDLHVCQUF1QixFQUFFLDBCQUEwQixDQUFDO0tBQzNELFNBQVMsQ0FBQyxJQUFJLGtCQUFNLENBQUMsbUJBQW1CLEVBQUUsZUFBZSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztLQUM5RyxNQUFNLENBQUMsS0FBSyxFQUFFLElBQXVFLEVBQUUsRUFBRTtJQUN4RixNQUFNLE1BQU0sR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFBO0lBQ3BDLElBQUksSUFBSSxDQUFDLE1BQU07UUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDbEQsSUFBSSxJQUFJLENBQUMsYUFBYTtRQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQTtJQUN2RSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYztRQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUE7SUFDbEYsTUFBTSxLQUFLLEdBQUcs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QyxDQUFDO0tBQzlHLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFLZCxFQUFFLEVBQUU7SUFDSCxNQUFNLElBQUksR0FBRyxNQUFNLElBQUEsZ0JBQVMsRUFBQyxJQUFBLGFBQU0sRUFBQyxpQkFBaUIsQ0FBQyxFQUFFO1FBQ3RELE1BQU0sRUFBRSxNQUFNO1FBQ2QsT0FBTyxFQUFFLEVBQUUsY0FBYyxFQUFFLGtCQUFrQixFQUFFO1FBQy9DLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ25CLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTtZQUNmLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYTtZQUNqQyxjQUFjLEVBQUUsSUFBSSxDQUFDLGNBQWM7WUFDbkMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7U0FDaEYsQ0FBQztLQUNILENBQUMsQ0FBQTtJQUNGLElBQUEsd0JBQVksRUFBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSwwQkFBYyxDQUFDLENBQUE7QUFDakQsQ0FBQyxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tYW5kLCBPcHRpb24gfSBmcm9tICdjb21tYW5kZXInXG5pbXBvcnQgeyBhcGlVcmwsIGZldGNoSnNvbiB9IGZyb20gJy4uL2F1dGgnXG5pbXBvcnQgeyBmb3JtYXRPdXRwdXQsIHN0b3JhZ2VDb2x1bW5zLCB0eXBlIE91dHB1dEZvcm1hdCB9IGZyb20gJy4uL2Zvcm1hdC5qcydcblxuZXhwb3J0IGNvbnN0IHN0b3JhZ2VDb21tYW5kID0gbmV3IENvbW1hbmQoJ3N0b3JhZ2UnKVxuICAuZGVzY3JpcHRpb24oJ01hbmFnZSBzdG9yYWdlcycpXG5cbnN0b3JhZ2VDb21tYW5kXG4gIC5jb21tYW5kKCdsaXN0JylcbiAgLmRlc2NyaXB0aW9uKCdMaXN0IHN0b3JhZ2VzJylcbiAgLm9wdGlvbignLS1zdGF0dXMgPHN0YXR1cz4nLCAnRmlsdGVyIGJ5IHN0YXR1cyAoZS5nLiBBQ1RJVkUsIFBFTkRJTkcsIEZBSUxFRCwgREVMRVRFRCknKVxuICAub3B0aW9uKCctLWVudmlyb25tZW50LWlkIDxpZD4nLCAnRmlsdGVyIGJ5IGVudmlyb25tZW50IElEJylcbiAgLmFkZE9wdGlvbihuZXcgT3B0aW9uKCctLWZvcm1hdCA8Zm9ybWF0PicsICdPdXRwdXQgZm9ybWF0JykuY2hvaWNlcyhbJ3RhYmxlJywgJ2pzb24nLCAnY3N2J10pLmRlZmF1bHQoJ3RhYmxlJykpXG4gIC5hY3Rpb24oYXN5bmMgKG9wdHM6IHsgc3RhdHVzPzogc3RyaW5nOyBlbnZpcm9ubWVudElkPzogc3RyaW5nOyBmb3JtYXQ6IE91dHB1dEZvcm1hdCB9KSA9PiB7XG4gICAgY29uc3QgcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpXG4gICAgaWYgKG9wdHMuc3RhdHVzKSBwYXJhbXMuc2V0KCdzdGF0dXMnLCBvcHRzLnN0YXR1cylcbiAgICBpZiAob3B0cy5lbnZpcm9ubWVudElkKSBwYXJhbXMuc2V0KCdlbnZpcm9ubWVudElkJywgb3B0cy5lbnZpcm9ubWVudElkKVxuICAgIGlmIChwcm9jZXNzLmVudi5HRU5JX1RFTkFOVF9JRCkgcGFyYW1zLnNldCgndGVuYW50SWQnLCBwcm9jZXNzLmVudi5HRU5JX1RFTkFOVF9JRClcbiAgICBjb25zdCBxdWVyeSA9IHBhcmFtcy5zaXplID8gYD8ke3BhcmFtc31gIDogJydcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgZmV0Y2hKc29uKGFwaVVybChgL2FkbWluL3N0b3JhZ2VzJHtxdWVyeX1gKSkgYXMgeyBpdGVtczogdW5rbm93bltdIH1cbiAgICBmb3JtYXRPdXRwdXQob3B0cy5mb3JtYXQgPT09ICdqc29uJyA/IGRhdGEgOiBkYXRhLml0ZW1zLCBvcHRzLmZvcm1hdCwgc3RvcmFnZUNvbHVtbnMpXG4gIH0pXG5cbnN0b3JhZ2VDb21tYW5kXG4gIC5jb21tYW5kKCdnZXQgPGlkPicpXG4gIC5kZXNjcmlwdGlvbignR2V0IGEgc3RvcmFnZSBieSBJRCcpXG4gIC5hZGRPcHRpb24obmV3IE9wdGlvbignLS1mb3JtYXQgPGZvcm1hdD4nLCAnT3V0cHV0IGZvcm1hdCcpLmNob2ljZXMoWyd0YWJsZScsICdqc29uJywgJ2NzdiddKS5kZWZhdWx0KCd0YWJsZScpKVxuICAuYWN0aW9uKGFzeW5jIChpZDogc3RyaW5nLCBvcHRzOiB7IGZvcm1hdDogT3V0cHV0Rm9ybWF0IH0pID0+IHtcbiAgICBjb25zdCBxdWVyeSA9IHByb2Nlc3MuZW52LkdFTklfVEVOQU5UX0lEID8gYD90ZW5hbnRJZD0ke3Byb2Nlc3MuZW52LkdFTklfVEVOQU5UX0lEfWAgOiAnJ1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBmZXRjaEpzb24oYXBpVXJsKGAvYWRtaW4vc3RvcmFnZXMvJHtpZH0ke3F1ZXJ5fWApKVxuICAgIGZvcm1hdE91dHB1dChkYXRhLCBvcHRzLmZvcm1hdCwgc3RvcmFnZUNvbHVtbnMpXG4gIH0pXG5cbnN0b3JhZ2VDb21tYW5kXG4gIC5jb21tYW5kKCdkZWxldGUgPGlkPicpXG4gIC5kZXNjcmlwdGlvbignRGVsZXRlIGEgc3RvcmFnZScpXG4gIC5hZGRPcHRpb24obmV3IE9wdGlvbignLS1mb3JtYXQgPGZvcm1hdD4nLCAnT3V0cHV0IGZvcm1hdCcpLmNob2ljZXMoWyd0YWJsZScsICdqc29uJywgJ2NzdiddKS5kZWZhdWx0KCd0YWJsZScpKVxuICAuYWN0aW9uKGFzeW5jIChpZDogc3RyaW5nLCBvcHRzOiB7IGZvcm1hdDogT3V0cHV0Rm9ybWF0IH0pID0+IHtcbiAgICBjb25zdCBxdWVyeSA9IHByb2Nlc3MuZW52LkdFTklfVEVOQU5UX0lEID8gYD90ZW5hbnRJZD0ke3Byb2Nlc3MuZW52LkdFTklfVEVOQU5UX0lEfWAgOiAnJ1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBmZXRjaEpzb24oYXBpVXJsKGAvYWRtaW4vc3RvcmFnZXMvJHtpZH0ke3F1ZXJ5fWApLCB7XG4gICAgICBtZXRob2Q6ICdERUxFVEUnLFxuICAgIH0pXG4gICAgZm9ybWF0T3V0cHV0KGRhdGEsIG9wdHMuZm9ybWF0LCBzdG9yYWdlQ29sdW1ucylcbiAgfSlcblxuc3RvcmFnZUNvbW1hbmRcbiAgLmNvbW1hbmQoJ2NyZWF0ZScpXG4gIC5kZXNjcmlwdGlvbignQ3JlYXRlIGEgc3RvcmFnZScpXG4gIC5yZXF1aXJlZE9wdGlvbignLS1uYW1lIDxuYW1lPicsICdTdG9yYWdlIG5hbWUnKVxuICAucmVxdWlyZWRPcHRpb24oJy0tZW52aXJvbm1lbnQtaWQgPGlkPicsICdFbnZpcm9ubWVudCBJRCcpXG4gIC5vcHRpb24oJy0tcGVybWlzc2lvbi1tb2RlIDxtb2RlPicsICdQZXJtaXNzaW9uIG1vZGUgKHJlYWQtd3JpdGUsIHJlYWQtb25seSwgd3JpdGUtb25seSknLCAncmVhZC13cml0ZScpXG4gIC5hZGRPcHRpb24obmV3IE9wdGlvbignLS1mb3JtYXQgPGZvcm1hdD4nLCAnT3V0cHV0IGZvcm1hdCcpLmNob2ljZXMoWyd0YWJsZScsICdqc29uJywgJ2NzdiddKS5kZWZhdWx0KCd0YWJsZScpKVxuICAuYWN0aW9uKGFzeW5jIChvcHRzOiB7XG4gICAgbmFtZTogc3RyaW5nXG4gICAgZW52aXJvbm1lbnRJZDogc3RyaW5nXG4gICAgcGVybWlzc2lvbk1vZGU6IHN0cmluZ1xuICAgIGZvcm1hdDogT3V0cHV0Rm9ybWF0XG4gIH0pID0+IHtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgZmV0Y2hKc29uKGFwaVVybCgnL2FkbWluL3N0b3JhZ2VzJyksIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIG5hbWU6IG9wdHMubmFtZSxcbiAgICAgICAgZW52aXJvbm1lbnRJZDogb3B0cy5lbnZpcm9ubWVudElkLFxuICAgICAgICBwZXJtaXNzaW9uTW9kZTogb3B0cy5wZXJtaXNzaW9uTW9kZSxcbiAgICAgICAgLi4uKHByb2Nlc3MuZW52LkdFTklfVEVOQU5UX0lEID8geyB0ZW5hbnRJZDogcHJvY2Vzcy5lbnYuR0VOSV9URU5BTlRfSUQgfSA6IHt9KSxcbiAgICAgIH0pLFxuICAgIH0pXG4gICAgZm9ybWF0T3V0cHV0KGRhdGEsIG9wdHMuZm9ybWF0LCBzdG9yYWdlQ29sdW1ucylcbiAgfSlcbiJdfQ==
|