opal-security 2.0.15 → 2.0.17
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 +39 -18
- package/lib/commands/iam-roles/start.d.ts +1 -0
- package/lib/commands/iam-roles/start.js +8 -0
- package/lib/commands/kube-roles/start.js +1 -1
- package/lib/commands/login.js +3 -0
- package/lib/commands/resources/get.d.ts +1 -1
- package/lib/commands/resources/get.js +3 -7
- package/lib/commands/set-custom-header.d.ts +11 -0
- package/lib/commands/set-custom-header.js +34 -0
- package/lib/commands/set-url.js +1 -1
- package/lib/lib/apollo.js +8 -1
- package/lib/lib/config.d.ts +1 -0
- package/lib/lib/config.js +9 -18
- package/lib/lib/credentials.js +28 -53
- package/oclif.manifest.json +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ $ npm install -g opal-security
|
|
|
22
22
|
$ opal COMMAND
|
|
23
23
|
running command...
|
|
24
24
|
$ opal (-v|--version|version)
|
|
25
|
-
opal-security/2.0.
|
|
25
|
+
opal-security/2.0.17 darwin-x64 node-v16.17.1
|
|
26
26
|
$ opal --help [COMMAND]
|
|
27
27
|
USAGE
|
|
28
28
|
$ opal COMMAND
|
|
@@ -43,6 +43,7 @@ USAGE
|
|
|
43
43
|
* [`opal logout`](#opal-logout)
|
|
44
44
|
* [`opal postgres-instances:start`](#opal-postgres-instancesstart)
|
|
45
45
|
* [`opal resources:get`](#opal-resourcesget)
|
|
46
|
+
* [`opal set-custom-header`](#opal-set-custom-header)
|
|
46
47
|
* [`opal set-token`](#opal-set-token)
|
|
47
48
|
* [`opal set-url`](#opal-set-url)
|
|
48
49
|
* [`opal ssh:copyFrom`](#opal-sshcopyfrom)
|
|
@@ -87,7 +88,7 @@ EXAMPLE
|
|
|
87
88
|
opal aws:identity
|
|
88
89
|
```
|
|
89
90
|
|
|
90
|
-
_See code: [src/commands/aws/identity.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
91
|
+
_See code: [src/commands/aws/identity.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/aws/identity.ts)_
|
|
91
92
|
|
|
92
93
|
## `opal curl-example`
|
|
93
94
|
|
|
@@ -101,7 +102,7 @@ OPTIONS
|
|
|
101
102
|
-h, --help show CLI help
|
|
102
103
|
```
|
|
103
104
|
|
|
104
|
-
_See code: [src/commands/curl-example.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
105
|
+
_See code: [src/commands/curl-example.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/curl-example.ts)_
|
|
105
106
|
|
|
106
107
|
## `opal help [COMMAND]`
|
|
107
108
|
|
|
@@ -129,16 +130,18 @@ USAGE
|
|
|
129
130
|
$ opal iam-roles:start
|
|
130
131
|
|
|
131
132
|
OPTIONS
|
|
132
|
-
-h, --help
|
|
133
|
-
--id=id
|
|
134
|
-
--
|
|
133
|
+
-h, --help show CLI help
|
|
134
|
+
--id=id The ID of the Opal role resource.
|
|
135
|
+
--profileName=profileName Uses a custom AWS profile name for the IAM role. Default value is the role's name.
|
|
136
|
+
--sessionId=sessionId SessionId of a session that has already been created via the web flow.
|
|
135
137
|
|
|
136
138
|
EXAMPLES
|
|
137
139
|
opal iam-roles:start
|
|
138
140
|
opal iam-roles:start --id 51f7176b-0464-4a6f-8369-e951e187b398
|
|
141
|
+
opal iam-roles:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --profileName "custom-profile"
|
|
139
142
|
```
|
|
140
143
|
|
|
141
|
-
_See code: [src/commands/iam-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
144
|
+
_See code: [src/commands/iam-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/iam-roles/start.ts)_
|
|
142
145
|
|
|
143
146
|
## `opal kube-roles:start`
|
|
144
147
|
|
|
@@ -161,7 +164,7 @@ EXAMPLES
|
|
|
161
164
|
"arn:aws:iam::712234975475:role/acme-eks-cluster-admin-role"
|
|
162
165
|
```
|
|
163
166
|
|
|
164
|
-
_See code: [src/commands/kube-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
167
|
+
_See code: [src/commands/kube-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/kube-roles/start.ts)_
|
|
165
168
|
|
|
166
169
|
## `opal login`
|
|
167
170
|
|
|
@@ -178,7 +181,7 @@ EXAMPLE
|
|
|
178
181
|
$ opal login
|
|
179
182
|
```
|
|
180
183
|
|
|
181
|
-
_See code: [src/commands/login.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
184
|
+
_See code: [src/commands/login.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/login.ts)_
|
|
182
185
|
|
|
183
186
|
## `opal logout`
|
|
184
187
|
|
|
@@ -195,7 +198,7 @@ EXAMPLE
|
|
|
195
198
|
$ opal logout
|
|
196
199
|
```
|
|
197
200
|
|
|
198
|
-
_See code: [src/commands/logout.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
201
|
+
_See code: [src/commands/logout.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/logout.ts)_
|
|
199
202
|
|
|
200
203
|
## `opal postgres-instances:start`
|
|
201
204
|
|
|
@@ -217,7 +220,7 @@ EXAMPLES
|
|
|
217
220
|
opal postgres-instances:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --accessLevelRemoteId "fullaccess"
|
|
218
221
|
```
|
|
219
222
|
|
|
220
|
-
_See code: [src/commands/postgres-instances/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
223
|
+
_See code: [src/commands/postgres-instances/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/postgres-instances/start.ts)_
|
|
221
224
|
|
|
222
225
|
## `opal resources:get`
|
|
223
226
|
|
|
@@ -235,7 +238,25 @@ EXAMPLE
|
|
|
235
238
|
opal resources:get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4
|
|
236
239
|
```
|
|
237
240
|
|
|
238
|
-
_See code: [src/commands/resources/get.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
241
|
+
_See code: [src/commands/resources/get.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/resources/get.ts)_
|
|
242
|
+
|
|
243
|
+
## `opal set-custom-header`
|
|
244
|
+
|
|
245
|
+
Sets a custom HTTP header to connect to the Opal server.
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
USAGE
|
|
249
|
+
$ opal set-custom-header
|
|
250
|
+
|
|
251
|
+
OPTIONS
|
|
252
|
+
-h, --help show CLI help
|
|
253
|
+
--header=header
|
|
254
|
+
|
|
255
|
+
EXAMPLE
|
|
256
|
+
$ opal set-custom-header --header 'cf-access-token: $TOKEN'
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
_See code: [src/commands/set-custom-header.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/set-custom-header.ts)_
|
|
239
260
|
|
|
240
261
|
## `opal set-token`
|
|
241
262
|
|
|
@@ -252,7 +273,7 @@ EXAMPLE
|
|
|
252
273
|
$ opal set-token
|
|
253
274
|
```
|
|
254
275
|
|
|
255
|
-
_See code: [src/commands/set-token.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
276
|
+
_See code: [src/commands/set-token.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/set-token.ts)_
|
|
256
277
|
|
|
257
278
|
## `opal set-url`
|
|
258
279
|
|
|
@@ -273,10 +294,10 @@ OPTIONS
|
|
|
273
294
|
--staging
|
|
274
295
|
|
|
275
296
|
EXAMPLE
|
|
276
|
-
$ opal set-
|
|
297
|
+
$ opal set-url
|
|
277
298
|
```
|
|
278
299
|
|
|
279
|
-
_See code: [src/commands/set-url.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
300
|
+
_See code: [src/commands/set-url.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/set-url.ts)_
|
|
280
301
|
|
|
281
302
|
## `opal ssh:copyFrom`
|
|
282
303
|
|
|
@@ -303,7 +324,7 @@ EXAMPLES
|
|
|
303
324
|
opal ssh:copyFrom --src instance/dir --dest my/dir --id 51f7176b-0464-4a6f-8369-e951e187b398
|
|
304
325
|
```
|
|
305
326
|
|
|
306
|
-
_See code: [src/commands/ssh/copyFrom.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
327
|
+
_See code: [src/commands/ssh/copyFrom.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/ssh/copyFrom.ts)_
|
|
307
328
|
|
|
308
329
|
## `opal ssh:copyTo`
|
|
309
330
|
|
|
@@ -330,7 +351,7 @@ EXAMPLES
|
|
|
330
351
|
opal ssh:copyTo --src my/dir --dest instance/dir --id 51f7176b-0464-4a6f-8369-e951e187b398
|
|
331
352
|
```
|
|
332
353
|
|
|
333
|
-
_See code: [src/commands/ssh/copyTo.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
354
|
+
_See code: [src/commands/ssh/copyTo.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/ssh/copyTo.ts)_
|
|
334
355
|
|
|
335
356
|
## `opal ssh:start`
|
|
336
357
|
|
|
@@ -350,5 +371,5 @@ EXAMPLES
|
|
|
350
371
|
opal ssh:start --id 51f7176b-0464-4a6f-8369-e951e187b398
|
|
351
372
|
```
|
|
352
373
|
|
|
353
|
-
_See code: [src/commands/ssh/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
374
|
+
_See code: [src/commands/ssh/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.17/src/commands/ssh/start.ts)_
|
|
354
375
|
<!-- commandsstop -->
|
|
@@ -6,6 +6,7 @@ export default class StartIAMRoleSession extends Command {
|
|
|
6
6
|
help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
|
|
7
7
|
id: flags.IOptionFlag<string | undefined>;
|
|
8
8
|
sessionId: flags.IOptionFlag<string | undefined>;
|
|
9
|
+
profileName: flags.IOptionFlag<string | undefined>;
|
|
9
10
|
};
|
|
10
11
|
run(): Promise<void>;
|
|
11
12
|
}
|
|
@@ -114,6 +114,9 @@ class StartIAMRoleSession extends command_1.Command {
|
|
|
114
114
|
}
|
|
115
115
|
roleName = (sshInstanceResp === null || sshInstanceResp === void 0 ? void 0 : sshInstanceResp.data.resource.resource.name) || 'iam-role';
|
|
116
116
|
}
|
|
117
|
+
if (flags.profileName && flags.profileName !== "") {
|
|
118
|
+
roleName = flags.profileName;
|
|
119
|
+
}
|
|
117
120
|
const { resp, error } = await handler_1.runMutation({
|
|
118
121
|
command: this,
|
|
119
122
|
query: StartIAMRoleSessionDocument,
|
|
@@ -150,6 +153,7 @@ StartIAMRoleSession.description = 'Starts a session to assume an IAM role.';
|
|
|
150
153
|
StartIAMRoleSession.examples = [
|
|
151
154
|
'opal iam-roles:start',
|
|
152
155
|
'opal iam-roles:start --id 51f7176b-0464-4a6f-8369-e951e187b398',
|
|
156
|
+
'opal iam-roles:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --profileName "custom-profile"',
|
|
153
157
|
];
|
|
154
158
|
StartIAMRoleSession.flags = {
|
|
155
159
|
help: command_1.flags.help({ char: 'h' }),
|
|
@@ -161,4 +165,8 @@ StartIAMRoleSession.flags = {
|
|
|
161
165
|
multiple: false,
|
|
162
166
|
description: 'SessionId of a session that has already been created via the web flow.',
|
|
163
167
|
}),
|
|
168
|
+
profileName: command_1.flags.string({
|
|
169
|
+
multiple: false,
|
|
170
|
+
description: 'Uses a custom AWS profile name for the IAM role. Default value is the role\'s name.'
|
|
171
|
+
})
|
|
164
172
|
};
|
|
@@ -120,7 +120,7 @@ class StartKubeIAMRoleSession extends command_1.Command {
|
|
|
120
120
|
switch (metadata === null || metadata === void 0 ? void 0 : metadata.__typename) {
|
|
121
121
|
case 'AwsIamFederatedEksSession': {
|
|
122
122
|
const updateAwsConfigCommand = aws_1.getAwsConfigUpdateCmd(roleName, metadata.awsAccessKeyId, metadata.awsSecretAccessKey, metadata.awsSessionToken);
|
|
123
|
-
const updateKubeConfigCmd = `aws eks update-kubeconfig --name ${metadata.clusterName} --region ${metadata.clusterRegion} --profile opal`;
|
|
123
|
+
const updateKubeConfigCmd = `aws eks update-kubeconfig --name ${metadata.clusterName} --region ${metadata.clusterRegion} --alias ${metadata.clusterName} --profile opal`;
|
|
124
124
|
const startSessionCmd = `${updateAwsConfigCommand} && ${updateKubeConfigCmd}`;
|
|
125
125
|
const awsEnvVarMessage = aws_1.getAwsEnvVarMessage();
|
|
126
126
|
cmd_1.runCommandExec(startSessionCmd, `Now set to use ${roleName ? `"${roleName}" role` : 'role'} with updated Kube config pointing to "${metadata.clusterName}" cluster.${awsEnvVarMessage}`, `Failed to assume ${roleName ? `"${roleName}" role` : 'role'} and update Kube config.`);
|
package/lib/commands/login.js
CHANGED
|
@@ -104,6 +104,7 @@ class Login extends command_1.Command {
|
|
|
104
104
|
issuer = await openid_client_1.Issuer.discover(ISSUER_DEV);
|
|
105
105
|
clientId = CLIENT_ID_DEV;
|
|
106
106
|
}
|
|
107
|
+
/* eslint-disable camelcase */
|
|
107
108
|
const client = new issuer.Client({
|
|
108
109
|
grant_types: [GRANT_TYPE],
|
|
109
110
|
client_id: clientId,
|
|
@@ -112,6 +113,7 @@ class Login extends command_1.Command {
|
|
|
112
113
|
token_endpoint_auth_method: 'none',
|
|
113
114
|
application_type: 'native',
|
|
114
115
|
});
|
|
116
|
+
/* eslint-enable camelcase */
|
|
115
117
|
const handle = await client.deviceAuthorization({
|
|
116
118
|
audience: 'https://opal.dev',
|
|
117
119
|
scope: 'openid email profile',
|
|
@@ -137,6 +139,7 @@ class Login extends command_1.Command {
|
|
|
137
139
|
});
|
|
138
140
|
if (authCheckErr || !((_e = (_d = (_c = authCheckResp === null || authCheckResp === void 0 ? void 0 : authCheckResp.data) === null || _c === void 0 ? void 0 : _c.organizationSettings) === null || _d === void 0 ? void 0 : _d.settings) === null || _e === void 0 ? void 0 : _e.id)) {
|
|
139
141
|
this.log('Error verifying log in. Authenticated commands may fail. Please double check your URL and use `opal logout; opal login` to try again.\n');
|
|
142
|
+
this.log(authCheckErr + '\n');
|
|
140
143
|
return;
|
|
141
144
|
}
|
|
142
145
|
this.log('🎉 You have successfully authenticated with Opal! You can now run authenticated commands.\n');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command, flags } from '@oclif/command';
|
|
2
|
-
export declare const GetResourceDocument = "\nquery GetResource($id: ResourceId!) {\n resource(input: {id: $id}) {\n __typename\n ... on ResourceResult {\n resource {\n name\n id\n description\n
|
|
2
|
+
export declare const GetResourceDocument = "\nquery GetResource($id: ResourceId!) {\n resource(input: {id: $id}) {\n __typename\n ... on ResourceResult {\n resource {\n name\n id\n description\n connection {\n name\n id\n }\n resourceUsers {\n user {\n email\n }\n }\n }\n }\n ... on ResourceNotFoundError {\n message\n }\n }\n}";
|
|
3
3
|
export default class GetResource extends Command {
|
|
4
4
|
static description: string;
|
|
5
5
|
static examples: string[];
|
|
@@ -13,10 +13,6 @@ query GetResource($id: ResourceId!) {
|
|
|
13
13
|
name
|
|
14
14
|
id
|
|
15
15
|
description
|
|
16
|
-
ownerTeam {
|
|
17
|
-
name
|
|
18
|
-
id
|
|
19
|
-
}
|
|
20
16
|
connection {
|
|
21
17
|
name
|
|
22
18
|
id
|
|
@@ -41,12 +37,12 @@ class GetResource extends command_1.Command {
|
|
|
41
37
|
}
|
|
42
38
|
}
|
|
43
39
|
exports.default = GetResource;
|
|
44
|
-
GetResource.description =
|
|
45
|
-
GetResource.examples = [
|
|
40
|
+
GetResource.description = 'Get resource info for a particular resource.';
|
|
41
|
+
GetResource.examples = ['opal resources:get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4'];
|
|
46
42
|
GetResource.flags = {
|
|
47
43
|
help: command_1.flags.help({ char: 'h' }),
|
|
48
44
|
id: command_1.flags.string({
|
|
49
45
|
multiple: false,
|
|
50
46
|
required: true,
|
|
51
|
-
})
|
|
47
|
+
}),
|
|
52
48
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command, flags } from '@oclif/command';
|
|
2
|
+
export default class SetCustomHeader extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
|
|
7
|
+
header: flags.IOptionFlag<string | undefined>;
|
|
8
|
+
};
|
|
9
|
+
static args: never[];
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const command_1 = require("@oclif/command");
|
|
4
|
+
const apollo_1 = require("../lib/apollo");
|
|
5
|
+
const config_1 = require("../lib/config");
|
|
6
|
+
class SetCustomHeader extends command_1.Command {
|
|
7
|
+
async run() {
|
|
8
|
+
try {
|
|
9
|
+
const { flags } = this.parse(SetCustomHeader);
|
|
10
|
+
let header;
|
|
11
|
+
if (flags.header) {
|
|
12
|
+
header = flags.header;
|
|
13
|
+
}
|
|
14
|
+
const configData = config_1.getOrCreateConfigData(this.config.configDir);
|
|
15
|
+
configData[config_1.customHttpHeaderKey] = header;
|
|
16
|
+
config_1.writeConfigData(this.config.configDir, configData);
|
|
17
|
+
await apollo_1.initClient(this);
|
|
18
|
+
this.log('Custom HTTP header updated');
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
this.error(error);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.default = SetCustomHeader;
|
|
26
|
+
SetCustomHeader.description = 'Sets a custom HTTP header to connect to the Opal server.';
|
|
27
|
+
SetCustomHeader.examples = ['$ opal set-custom-header --header \'cf-access-token: $TOKEN\''];
|
|
28
|
+
SetCustomHeader.flags = {
|
|
29
|
+
help: command_1.flags.help({ char: 'h' }),
|
|
30
|
+
header: command_1.flags.string({
|
|
31
|
+
multiple: false,
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
SetCustomHeader.args = [];
|
package/lib/commands/set-url.js
CHANGED
|
@@ -43,7 +43,7 @@ class SetUrl extends command_1.Command {
|
|
|
43
43
|
}
|
|
44
44
|
exports.default = SetUrl;
|
|
45
45
|
SetUrl.description = `Sets the url of the Opal server. Defaults to ${config_1.defaultUrl}.`;
|
|
46
|
-
SetUrl.examples = ['$ opal set-
|
|
46
|
+
SetUrl.examples = ['$ opal set-url'];
|
|
47
47
|
SetUrl.flags = {
|
|
48
48
|
help: command_1.flags.help({ char: 'h' }),
|
|
49
49
|
custom: command_1.flags.string({
|
package/lib/lib/apollo.js
CHANGED
|
@@ -27,6 +27,13 @@ exports.initClient = async (command) => {
|
|
|
27
27
|
});
|
|
28
28
|
const httpAgent = new http.Agent({});
|
|
29
29
|
const specifiedUrl = configData[config_1.urlKey];
|
|
30
|
+
const customHeader = configData[config_1.customHttpHeaderKey];
|
|
31
|
+
const customHeaderKey = customHeader === undefined ?
|
|
32
|
+
'' :
|
|
33
|
+
customHeader.split(':')[0];
|
|
34
|
+
const customHeaderValue = customHeader === undefined ?
|
|
35
|
+
'' :
|
|
36
|
+
customHeader.split(':')[1];
|
|
30
37
|
const agent = specifiedUrl.includes('https') ? httpsAgent : httpAgent;
|
|
31
38
|
const httpLink = core_1.createHttpLink({
|
|
32
39
|
uri: `${specifiedUrl}/query`,
|
|
@@ -37,7 +44,7 @@ exports.initClient = async (command) => {
|
|
|
37
44
|
});
|
|
38
45
|
const authLink = context_1.setContext((_, { headers }) => {
|
|
39
46
|
return {
|
|
40
|
-
headers: Object.assign(Object.assign({}, headers), { authorization: `Bearer ${accessToken}`, 'X-Opal-Organization-ID': organizationID }),
|
|
47
|
+
headers: Object.assign(Object.assign({}, headers), { authorization: `Bearer ${accessToken}`, 'X-Opal-Organization-ID': organizationID, customHeaderKey: customHeaderValue }),
|
|
41
48
|
};
|
|
42
49
|
});
|
|
43
50
|
const checkCLIVersion = (operation) => {
|
package/lib/lib/config.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export declare const urlKey = "url";
|
|
|
2
2
|
export declare const defaultUrl = "https://app.opal.dev";
|
|
3
3
|
export declare const allowSelfSignedCertsKey = "allowSelfSignedCerts";
|
|
4
4
|
export declare const defaultAllowSelfSignedCerts = false;
|
|
5
|
+
export declare const customHttpHeaderKey = "customHttpHeader";
|
|
5
6
|
export declare const getOrCreateConfigData: (configDir: string) => Record<string, any>;
|
|
6
7
|
export declare const writeConfigData: (configDir: string, newConfigData: Record<string, any>) => void;
|
|
7
8
|
export declare const isProduction: (configDir: string) => boolean;
|
package/lib/lib/config.js
CHANGED
|
@@ -1,32 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isProduction = exports.writeConfigData = exports.getOrCreateConfigData = exports.defaultAllowSelfSignedCerts = exports.allowSelfSignedCertsKey = exports.defaultUrl = exports.urlKey = void 0;
|
|
3
|
+
exports.isProduction = exports.writeConfigData = exports.getOrCreateConfigData = exports.customHttpHeaderKey = exports.defaultAllowSelfSignedCerts = exports.allowSelfSignedCertsKey = exports.defaultUrl = exports.urlKey = void 0;
|
|
4
4
|
const fs = require("fs");
|
|
5
5
|
const path = require("path");
|
|
6
6
|
exports.urlKey = 'url';
|
|
7
7
|
exports.defaultUrl = 'https://app.opal.dev';
|
|
8
8
|
exports.allowSelfSignedCertsKey = 'allowSelfSignedCerts';
|
|
9
9
|
exports.defaultAllowSelfSignedCerts = false;
|
|
10
|
+
exports.customHttpHeaderKey = 'customHttpHeader';
|
|
10
11
|
exports.getOrCreateConfigData = (configDir) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
catch (error) {
|
|
17
|
-
throw error;
|
|
12
|
+
if (!fs.existsSync(configDir)) {
|
|
13
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
18
14
|
}
|
|
19
15
|
const configFilePath = path.join(configDir, 'config.json');
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}));
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
throw error;
|
|
16
|
+
if (!fs.existsSync(configFilePath)) {
|
|
17
|
+
fs.writeFileSync(configFilePath, JSON.stringify({
|
|
18
|
+
[exports.urlKey]: exports.defaultUrl,
|
|
19
|
+
[exports.allowSelfSignedCertsKey]: exports.defaultAllowSelfSignedCerts,
|
|
20
|
+
}));
|
|
30
21
|
}
|
|
31
22
|
let configData = {};
|
|
32
23
|
try {
|
package/lib/lib/credentials.js
CHANGED
|
@@ -8,80 +8,55 @@ function removeAfter(credentials, lastIndex) {
|
|
|
8
8
|
}
|
|
9
9
|
exports.cred = {
|
|
10
10
|
async removeCredentials(after) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
removeAfter(keyContents, after);
|
|
14
|
-
}
|
|
15
|
-
catch (error) {
|
|
16
|
-
throw error;
|
|
17
|
-
}
|
|
11
|
+
const keyContents = await keytar.findCredentials(exports.OPAL_CREDS_KEY);
|
|
12
|
+
removeAfter(keyContents, after);
|
|
18
13
|
},
|
|
19
14
|
get accountId() {
|
|
20
15
|
return (async () => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return undefined;
|
|
25
|
-
}
|
|
26
|
-
const { account } = keyContents[0];
|
|
27
|
-
return account;
|
|
28
|
-
}
|
|
29
|
-
catch (error) {
|
|
30
|
-
throw error;
|
|
16
|
+
const keyContents = await keytar.findCredentials(exports.OPAL_CREDS_KEY);
|
|
17
|
+
if (!keyContents[0]) {
|
|
18
|
+
return undefined;
|
|
31
19
|
}
|
|
20
|
+
const { account } = keyContents[0];
|
|
21
|
+
return account;
|
|
32
22
|
})();
|
|
33
23
|
},
|
|
34
24
|
get organizationID() {
|
|
35
25
|
return (async () => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
const { account } = keyContents[0];
|
|
42
|
-
const parts = account.split('|');
|
|
43
|
-
if (!parts || parts.length <= 1) {
|
|
44
|
-
return undefined;
|
|
45
|
-
}
|
|
46
|
-
return parts.pop();
|
|
26
|
+
const keyContents = await keytar.findCredentials(exports.OPAL_CREDS_KEY);
|
|
27
|
+
if (!keyContents[0]) {
|
|
28
|
+
return undefined;
|
|
47
29
|
}
|
|
48
|
-
|
|
49
|
-
|
|
30
|
+
const { account } = keyContents[0];
|
|
31
|
+
const parts = account.split('|');
|
|
32
|
+
if (!parts || parts.length <= 1) {
|
|
33
|
+
return undefined;
|
|
50
34
|
}
|
|
35
|
+
return parts.pop();
|
|
51
36
|
})();
|
|
52
37
|
},
|
|
53
38
|
get email() {
|
|
54
39
|
return (async () => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return undefined;
|
|
59
|
-
}
|
|
60
|
-
const { account } = keyContents[0];
|
|
61
|
-
const parts = account.split('|');
|
|
62
|
-
if (!parts || parts.length <= 1) {
|
|
63
|
-
return undefined;
|
|
64
|
-
}
|
|
65
|
-
return parts[0];
|
|
40
|
+
const keyContents = await keytar.findCredentials(exports.OPAL_CREDS_KEY);
|
|
41
|
+
if (!keyContents[0]) {
|
|
42
|
+
return undefined;
|
|
66
43
|
}
|
|
67
|
-
|
|
68
|
-
|
|
44
|
+
const { account } = keyContents[0];
|
|
45
|
+
const parts = account.split('|');
|
|
46
|
+
if (!parts || parts.length <= 1) {
|
|
47
|
+
return undefined;
|
|
69
48
|
}
|
|
49
|
+
return parts[0];
|
|
70
50
|
})();
|
|
71
51
|
},
|
|
72
52
|
get accessToken() {
|
|
73
53
|
return (async () => {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return undefined;
|
|
78
|
-
}
|
|
79
|
-
const { password } = keyContents[0];
|
|
80
|
-
return password;
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
throw error;
|
|
54
|
+
const keyContents = await keytar.findCredentials(exports.OPAL_CREDS_KEY);
|
|
55
|
+
if (!keyContents[0]) {
|
|
56
|
+
return undefined;
|
|
84
57
|
}
|
|
58
|
+
const { password } = keyContents[0];
|
|
59
|
+
return password;
|
|
85
60
|
})();
|
|
86
61
|
},
|
|
87
62
|
};
|
package/oclif.manifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"2.0.
|
|
1
|
+
{"version":"2.0.17","commands":{"curl-example":{"id":"curl-example","description":"Prints out an example cURL command containing the parameters the CLI uses to query the Opal server.","pluginName":"opal-security","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"login":{"id":"login","description":"Authenticates you with the Opal server.","pluginName":"opal-security","pluginType":"core","aliases":[],"examples":["$ opal login"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"logout":{"id":"logout","description":"Clears locally stored Opal server authentication credentials.","pluginName":"opal-security","pluginType":"core","aliases":[],"examples":["$ opal logout"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"set-custom-header":{"id":"set-custom-header","description":"Sets a custom HTTP header to connect to the Opal server.","pluginName":"opal-security","pluginType":"core","aliases":[],"examples":["$ opal set-custom-header --header 'cf-access-token: $TOKEN'"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"header":{"name":"header","type":"option"}},"args":[]},"set-token":{"id":"set-token","description":"Sets an API token to authenticate with the Opal server - alternative auth flow for headless environments.","pluginName":"opal-security","pluginType":"core","aliases":[],"examples":["$ opal set-token"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"set-url":{"id":"set-url","description":"Sets the url of the Opal server. Defaults to https://app.opal.dev.","pluginName":"opal-security","pluginType":"core","aliases":[],"examples":["$ opal set-url"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"custom":{"name":"custom","type":"option"},"allowSelfSignedCerts":{"name":"allowSelfSignedCerts","type":"boolean","allowNo":false},"prod":{"name":"prod","type":"boolean","allowNo":false},"staging":{"name":"staging","type":"boolean","allowNo":false},"demo":{"name":"demo","type":"boolean","allowNo":false},"dev":{"name":"dev","type":"boolean","allowNo":false},"devLocal":{"name":"devLocal","type":"boolean","allowNo":false}},"args":[]},"aws:identity":{"id":"aws:identity","description":"Gets the current caller identity for the \"opal\" AWS profile.","pluginName":"opal-security","pluginType":"core","aliases":[],"examples":["opal aws:identity"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"iam-roles:start":{"id":"iam-roles:start","description":"Starts a session to assume an IAM role.","pluginName":"opal-security","pluginType":"core","aliases":[],"examples":["opal iam-roles:start","opal iam-roles:start --id 51f7176b-0464-4a6f-8369-e951e187b398","opal iam-roles:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --profileName \"custom-profile\""],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"id":{"name":"id","type":"option","description":"The ID of the Opal role resource."},"sessionId":{"name":"sessionId","type":"option","description":"SessionId of a session that has already been created via the web flow."},"profileName":{"name":"profileName","type":"option","description":"Uses a custom AWS profile name for the IAM role. Default value is the role's name."}},"args":[]},"kube-roles:start":{"id":"kube-roles:start","description":"Starts a session to assume a Kubernetes cluster IAM role.","pluginName":"opal-security","pluginType":"core","aliases":[],"examples":["opal kube-roles:start","opal kube-roles:start --id 51f7176b-0464-4a6f-8369-e951e187b398","opal kube-roles:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --accessLevelRemoteId \"arn:aws:iam::712234975475:role/acme-eks-cluster-admin-role\""],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"id":{"name":"id","type":"option","description":"The ID of the Opal role resource."},"accessLevelRemoteId":{"name":"accessLevelRemoteId","type":"option","description":"The remote ID of the access level with which to access the cluster."},"sessionId":{"name":"sessionId","type":"option","description":"SessionId of a session that has already been created via the web flow."}},"args":[]},"postgres-instances:start":{"id":"postgres-instances:start","description":"Starts a session to query a Postgres database.","pluginName":"opal-security","pluginType":"core","aliases":[],"examples":["opal postgres-instances:start","opal postgres-instances:start --id 51f7176b-0464-4a6f-8369-e951e187b398","opal postgres-instances:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --accessLevelRemoteId \"fullaccess\""],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"id":{"name":"id","type":"option","description":"The ID of the Opal instance resource."},"accessLevelRemoteId":{"name":"accessLevelRemoteId","type":"option","description":"The remote ID of the access level with which to access the database."},"sessionId":{"name":"sessionId","type":"option","description":"SessionId of a session that has already been created via the web flow."}},"args":[]},"resources:get":{"id":"resources:get","description":"Get resource info for a particular resource.","pluginName":"opal-security","pluginType":"core","aliases":[],"examples":["opal resources:get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"id":{"name":"id","type":"option","required":true}},"args":[]},"ssh:copyFrom":{"id":"ssh:copyFrom","description":"Use SCP to copy files from a compute instance.","pluginName":"opal-security","pluginType":"core","aliases":[],"examples":["opal ssh:copyFrom --src instance/dir --dest my/dir","opal ssh:copyFrom --src instance/dir --dest my/dir --id 51f7176b-0464-4a6f-8369-e951e187b398"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"src":{"name":"src","type":"option","description":"The path of the directory or file you would like to copy over SCP. Note we only support one file or directory at a time.","required":true},"dest":{"name":"dest","type":"option","description":"Pick which directory you want your files to be copied to.","required":false,"default":"."},"user":{"name":"user","type":"option","description":"Pick which user you want to run SCP over. Keep in mind not all users will have access to each other's home directory.","required":false,"default":"ssm-user"},"id":{"name":"id","type":"option","description":"The ID of the Opal instance resource."},"sessionId":{"name":"sessionId","type":"option","description":"SessionId of a session that has already been created via the web flow."}},"args":[]},"ssh:copyTo":{"id":"ssh:copyTo","description":"Use SCP to copy files to a compute instance.","pluginName":"opal-security","pluginType":"core","aliases":[],"examples":["opal ssh:copyTo --src my/dir --dest instance/dir","opal ssh:copyTo --src my/dir --dest instance/dir --id 51f7176b-0464-4a6f-8369-e951e187b398"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"src":{"name":"src","type":"option","description":"The path of the directory or file you would like to copy over SCP. Note we only support one file or directory at a time.","required":true},"dest":{"name":"dest","type":"option","description":"Pick which directory you want your files to be copied to.","required":false,"default":"."},"user":{"name":"user","type":"option","description":"Pick which user you want to run SCP over. Keep in mind not all users will have access to each other's home directory.","required":false,"default":"ssm-user"},"id":{"name":"id","type":"option","description":"The ID of the Opal instance resource."},"sessionId":{"name":"sessionId","type":"option","description":"SessionId of a session that has already been created via the web flow."}},"args":[]},"ssh:start":{"id":"ssh:start","description":"Start an SSH session to access a particular compute instance.","pluginName":"opal-security","pluginType":"core","aliases":[],"examples":["opal ssh:start","opal ssh:start --id 51f7176b-0464-4a6f-8369-e951e187b398"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"id":{"name":"id","type":"option","description":"The ID of the Opal instance resource."},"sessionId":{"name":"sessionId","type":"option","description":"SessionId of a session that has already been created via the web flow."}},"args":[]}}}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opal-security",
|
|
3
3
|
"description": "Opal allows you to centrally manage access to all of your sensitive systems.",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.17",
|
|
5
5
|
"author": "Stephen Cobbe",
|
|
6
6
|
"bin": {
|
|
7
7
|
"opal": "./bin/run"
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"@types/mocha": "^5.2.7",
|
|
42
42
|
"@types/node": "^14.14.37",
|
|
43
43
|
"@types/semver": "^7.3.8",
|
|
44
|
+
"@typescript-eslint/eslint-plugin": "^5.31.0",
|
|
44
45
|
"chai": "^4.3.4",
|
|
45
46
|
"eslint": "^8.17.0",
|
|
46
47
|
"eslint-config-oclif": "^3.1.0",
|