opal-security 2.0.12 → 2.0.15
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 +59 -35
- package/lib/commands/iam-roles/start.d.ts +1 -0
- package/lib/commands/iam-roles/start.js +22 -3
- package/lib/commands/kube-roles/start.d.ts +1 -0
- package/lib/commands/kube-roles/start.js +22 -3
- package/lib/commands/login.d.ts +1 -0
- package/lib/commands/login.js +3 -2
- package/lib/commands/postgres-instances/start.d.ts +1 -0
- package/lib/commands/postgres-instances/start.js +22 -2
- package/lib/commands/set-token.d.ts +10 -0
- package/lib/commands/set-token.js +58 -0
- package/lib/commands/set-url.js +2 -0
- package/lib/commands/ssh/copyFrom.d.ts +1 -0
- package/lib/commands/ssh/copyFrom.js +22 -3
- package/lib/commands/ssh/copyTo.d.ts +1 -0
- package/lib/commands/ssh/copyTo.js +22 -3
- package/lib/commands/ssh/start.d.ts +1 -0
- package/lib/commands/ssh/start.js +28 -3
- package/lib/lib/common.d.ts +2 -0
- package/lib/lib/common.js +13 -0
- package/lib/lib/config.js +1 -0
- package/oclif.manifest.json +1 -1
- package/package.json +12 -8
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.15 darwin-x64 node-v14.16.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-token`](#opal-set-token)
|
|
46
47
|
* [`opal set-url`](#opal-set-url)
|
|
47
48
|
* [`opal ssh:copyFrom`](#opal-sshcopyfrom)
|
|
48
49
|
* [`opal ssh:copyTo`](#opal-sshcopyto)
|
|
@@ -86,7 +87,7 @@ EXAMPLE
|
|
|
86
87
|
opal aws:identity
|
|
87
88
|
```
|
|
88
89
|
|
|
89
|
-
_See code: [src/commands/aws/identity.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
90
|
+
_See code: [src/commands/aws/identity.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.15/src/commands/aws/identity.ts)_
|
|
90
91
|
|
|
91
92
|
## `opal curl-example`
|
|
92
93
|
|
|
@@ -100,24 +101,24 @@ OPTIONS
|
|
|
100
101
|
-h, --help show CLI help
|
|
101
102
|
```
|
|
102
103
|
|
|
103
|
-
_See code: [src/commands/curl-example.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
104
|
+
_See code: [src/commands/curl-example.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.15/src/commands/curl-example.ts)_
|
|
104
105
|
|
|
105
106
|
## `opal help [COMMAND]`
|
|
106
107
|
|
|
107
|
-
|
|
108
|
+
Display help for opal.
|
|
108
109
|
|
|
109
110
|
```
|
|
110
111
|
USAGE
|
|
111
112
|
$ opal help [COMMAND]
|
|
112
113
|
|
|
113
114
|
ARGUMENTS
|
|
114
|
-
COMMAND
|
|
115
|
+
COMMAND Command to show help for.
|
|
115
116
|
|
|
116
117
|
OPTIONS
|
|
117
|
-
--
|
|
118
|
+
-n, --nested-commands Include all nested commands in the output.
|
|
118
119
|
```
|
|
119
120
|
|
|
120
|
-
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/
|
|
121
|
+
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.1.12/src/commands/help.ts)_
|
|
121
122
|
|
|
122
123
|
## `opal iam-roles:start`
|
|
123
124
|
|
|
@@ -128,15 +129,16 @@ USAGE
|
|
|
128
129
|
$ opal iam-roles:start
|
|
129
130
|
|
|
130
131
|
OPTIONS
|
|
131
|
-
-h, --help
|
|
132
|
-
--id=id
|
|
132
|
+
-h, --help show CLI help
|
|
133
|
+
--id=id The ID of the Opal role resource.
|
|
134
|
+
--sessionId=sessionId SessionId of a session that has already been created via the web flow.
|
|
133
135
|
|
|
134
136
|
EXAMPLES
|
|
135
137
|
opal iam-roles:start
|
|
136
138
|
opal iam-roles:start --id 51f7176b-0464-4a6f-8369-e951e187b398
|
|
137
139
|
```
|
|
138
140
|
|
|
139
|
-
_See code: [src/commands/iam-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
141
|
+
_See code: [src/commands/iam-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.15/src/commands/iam-roles/start.ts)_
|
|
140
142
|
|
|
141
143
|
## `opal kube-roles:start`
|
|
142
144
|
|
|
@@ -150,6 +152,7 @@ OPTIONS
|
|
|
150
152
|
-h, --help show CLI help
|
|
151
153
|
--accessLevelRemoteId=accessLevelRemoteId The remote ID of the access level with which to access the cluster.
|
|
152
154
|
--id=id The ID of the Opal role resource.
|
|
155
|
+
--sessionId=sessionId SessionId of a session that has already been created via the web flow.
|
|
153
156
|
|
|
154
157
|
EXAMPLES
|
|
155
158
|
opal kube-roles:start
|
|
@@ -158,7 +161,7 @@ EXAMPLES
|
|
|
158
161
|
"arn:aws:iam::712234975475:role/acme-eks-cluster-admin-role"
|
|
159
162
|
```
|
|
160
163
|
|
|
161
|
-
_See code: [src/commands/kube-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
164
|
+
_See code: [src/commands/kube-roles/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.15/src/commands/kube-roles/start.ts)_
|
|
162
165
|
|
|
163
166
|
## `opal login`
|
|
164
167
|
|
|
@@ -175,7 +178,7 @@ EXAMPLE
|
|
|
175
178
|
$ opal login
|
|
176
179
|
```
|
|
177
180
|
|
|
178
|
-
_See code: [src/commands/login.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
181
|
+
_See code: [src/commands/login.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.15/src/commands/login.ts)_
|
|
179
182
|
|
|
180
183
|
## `opal logout`
|
|
181
184
|
|
|
@@ -192,7 +195,7 @@ EXAMPLE
|
|
|
192
195
|
$ opal logout
|
|
193
196
|
```
|
|
194
197
|
|
|
195
|
-
_See code: [src/commands/logout.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
198
|
+
_See code: [src/commands/logout.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.15/src/commands/logout.ts)_
|
|
196
199
|
|
|
197
200
|
## `opal postgres-instances:start`
|
|
198
201
|
|
|
@@ -206,6 +209,7 @@ OPTIONS
|
|
|
206
209
|
-h, --help show CLI help
|
|
207
210
|
--accessLevelRemoteId=accessLevelRemoteId The remote ID of the access level with which to access the database.
|
|
208
211
|
--id=id The ID of the Opal instance resource.
|
|
212
|
+
--sessionId=sessionId SessionId of a session that has already been created via the web flow.
|
|
209
213
|
|
|
210
214
|
EXAMPLES
|
|
211
215
|
opal postgres-instances:start
|
|
@@ -213,7 +217,7 @@ EXAMPLES
|
|
|
213
217
|
opal postgres-instances:start --id 51f7176b-0464-4a6f-8369-e951e187b398 --accessLevelRemoteId "fullaccess"
|
|
214
218
|
```
|
|
215
219
|
|
|
216
|
-
_See code: [src/commands/postgres-instances/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
220
|
+
_See code: [src/commands/postgres-instances/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.15/src/commands/postgres-instances/start.ts)_
|
|
217
221
|
|
|
218
222
|
## `opal resources:get`
|
|
219
223
|
|
|
@@ -231,7 +235,24 @@ EXAMPLE
|
|
|
231
235
|
opal resources:get --id 54052a3e-5375-4392-aeaf-0c6c44c131d4
|
|
232
236
|
```
|
|
233
237
|
|
|
234
|
-
_See code: [src/commands/resources/get.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
238
|
+
_See code: [src/commands/resources/get.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.15/src/commands/resources/get.ts)_
|
|
239
|
+
|
|
240
|
+
## `opal set-token`
|
|
241
|
+
|
|
242
|
+
Sets an API token to authenticate with the Opal server - alternative auth flow for headless environments.
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
USAGE
|
|
246
|
+
$ opal set-token
|
|
247
|
+
|
|
248
|
+
OPTIONS
|
|
249
|
+
-h, --help show CLI help
|
|
250
|
+
|
|
251
|
+
EXAMPLE
|
|
252
|
+
$ opal set-token
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
_See code: [src/commands/set-token.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.15/src/commands/set-token.ts)_
|
|
235
256
|
|
|
236
257
|
## `opal set-url`
|
|
237
258
|
|
|
@@ -255,7 +276,7 @@ EXAMPLE
|
|
|
255
276
|
$ opal set-host
|
|
256
277
|
```
|
|
257
278
|
|
|
258
|
-
_See code: [src/commands/set-url.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
279
|
+
_See code: [src/commands/set-url.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.15/src/commands/set-url.ts)_
|
|
259
280
|
|
|
260
281
|
## `opal ssh:copyFrom`
|
|
261
282
|
|
|
@@ -266,22 +287,23 @@ USAGE
|
|
|
266
287
|
$ opal ssh:copyFrom
|
|
267
288
|
|
|
268
289
|
OPTIONS
|
|
269
|
-
-h, --help
|
|
270
|
-
--dest=dest
|
|
271
|
-
--id=id
|
|
290
|
+
-h, --help show CLI help
|
|
291
|
+
--dest=dest [default: .] Pick which directory you want your files to be copied to.
|
|
292
|
+
--id=id The ID of the Opal instance resource.
|
|
293
|
+
--sessionId=sessionId SessionId of a session that has already been created via the web flow.
|
|
272
294
|
|
|
273
|
-
--src=src
|
|
274
|
-
|
|
295
|
+
--src=src (required) The path of the directory or file you would like to copy over SCP. Note we only
|
|
296
|
+
support one file or directory at a time.
|
|
275
297
|
|
|
276
|
-
--user=user
|
|
277
|
-
|
|
298
|
+
--user=user [default: ssm-user] Pick which user you want to run SCP over. Keep in mind not all users will
|
|
299
|
+
have access to each other's home directory.
|
|
278
300
|
|
|
279
301
|
EXAMPLES
|
|
280
302
|
opal ssh:copyFrom --src instance/dir --dest my/dir
|
|
281
303
|
opal ssh:copyFrom --src instance/dir --dest my/dir --id 51f7176b-0464-4a6f-8369-e951e187b398
|
|
282
304
|
```
|
|
283
305
|
|
|
284
|
-
_See code: [src/commands/ssh/copyFrom.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
306
|
+
_See code: [src/commands/ssh/copyFrom.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.15/src/commands/ssh/copyFrom.ts)_
|
|
285
307
|
|
|
286
308
|
## `opal ssh:copyTo`
|
|
287
309
|
|
|
@@ -292,22 +314,23 @@ USAGE
|
|
|
292
314
|
$ opal ssh:copyTo
|
|
293
315
|
|
|
294
316
|
OPTIONS
|
|
295
|
-
-h, --help
|
|
296
|
-
--dest=dest
|
|
297
|
-
--id=id
|
|
317
|
+
-h, --help show CLI help
|
|
318
|
+
--dest=dest [default: .] Pick which directory you want your files to be copied to.
|
|
319
|
+
--id=id The ID of the Opal instance resource.
|
|
320
|
+
--sessionId=sessionId SessionId of a session that has already been created via the web flow.
|
|
298
321
|
|
|
299
|
-
--src=src
|
|
300
|
-
|
|
322
|
+
--src=src (required) The path of the directory or file you would like to copy over SCP. Note we only
|
|
323
|
+
support one file or directory at a time.
|
|
301
324
|
|
|
302
|
-
--user=user
|
|
303
|
-
|
|
325
|
+
--user=user [default: ssm-user] Pick which user you want to run SCP over. Keep in mind not all users will
|
|
326
|
+
have access to each other's home directory.
|
|
304
327
|
|
|
305
328
|
EXAMPLES
|
|
306
329
|
opal ssh:copyTo --src my/dir --dest instance/dir
|
|
307
330
|
opal ssh:copyTo --src my/dir --dest instance/dir --id 51f7176b-0464-4a6f-8369-e951e187b398
|
|
308
331
|
```
|
|
309
332
|
|
|
310
|
-
_See code: [src/commands/ssh/copyTo.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
333
|
+
_See code: [src/commands/ssh/copyTo.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.15/src/commands/ssh/copyTo.ts)_
|
|
311
334
|
|
|
312
335
|
## `opal ssh:start`
|
|
313
336
|
|
|
@@ -318,13 +341,14 @@ USAGE
|
|
|
318
341
|
$ opal ssh:start
|
|
319
342
|
|
|
320
343
|
OPTIONS
|
|
321
|
-
-h, --help
|
|
322
|
-
--id=id
|
|
344
|
+
-h, --help show CLI help
|
|
345
|
+
--id=id The ID of the Opal instance resource.
|
|
346
|
+
--sessionId=sessionId SessionId of a session that has already been created via the web flow.
|
|
323
347
|
|
|
324
348
|
EXAMPLES
|
|
325
349
|
opal ssh:start
|
|
326
350
|
opal ssh:start --id 51f7176b-0464-4a6f-8369-e951e187b398
|
|
327
351
|
```
|
|
328
352
|
|
|
329
|
-
_See code: [src/commands/ssh/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.
|
|
353
|
+
_See code: [src/commands/ssh/start.ts](https://github.com/opalsecurity/opal-cli/blob/v2.0.15/src/commands/ssh/start.ts)_
|
|
330
354
|
<!-- commandsstop -->
|
|
@@ -5,6 +5,7 @@ export default class StartIAMRoleSession extends Command {
|
|
|
5
5
|
static flags: {
|
|
6
6
|
help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
|
|
7
7
|
id: flags.IOptionFlag<string | undefined>;
|
|
8
|
+
sessionId: flags.IOptionFlag<string | undefined>;
|
|
8
9
|
};
|
|
9
10
|
run(): Promise<void>;
|
|
10
11
|
}
|
|
@@ -8,9 +8,10 @@ const inquirer = require("inquirer");
|
|
|
8
8
|
const aws_1 = require("../../lib/aws");
|
|
9
9
|
const resources_1 = require("../../lib/resources");
|
|
10
10
|
const get_1 = require("../../commands/resources/get");
|
|
11
|
+
const common_1 = require("../../lib/common");
|
|
11
12
|
const StartIAMRoleSessionDocument = `
|
|
12
|
-
mutation StartIAMRoleSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInput
|
|
13
|
-
createSession(input: {resourceId: $id, accessLevel: $accessLevel}) {
|
|
13
|
+
mutation StartIAMRoleSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInput!, $sessionId: SessionId) {
|
|
14
|
+
createSession(input: {resourceId: $id, accessLevel: $accessLevel, sessionId: $sessionId}) {
|
|
14
15
|
__typename
|
|
15
16
|
... on CreateSessionResult {
|
|
16
17
|
session {
|
|
@@ -27,9 +28,18 @@ mutation StartIAMRoleSession($id: ResourceId!, $accessLevel: ResourceAccessLevel
|
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
}
|
|
31
|
+
... on SessionNotFoundError {
|
|
32
|
+
message
|
|
33
|
+
}
|
|
34
|
+
... on MfaInvalidError {
|
|
35
|
+
message
|
|
36
|
+
}
|
|
30
37
|
... on ResourceNotFoundError {
|
|
31
38
|
message
|
|
32
39
|
}
|
|
40
|
+
... on EndSystemAuthorizationError {
|
|
41
|
+
message
|
|
42
|
+
}
|
|
33
43
|
}
|
|
34
44
|
}`;
|
|
35
45
|
const ListIamRolesDocument = `
|
|
@@ -51,6 +61,7 @@ class StartIAMRoleSession extends command_1.Command {
|
|
|
51
61
|
const { flags } = this.parse(StartIAMRoleSession);
|
|
52
62
|
let roleId = flags.id;
|
|
53
63
|
let roleName = null;
|
|
64
|
+
const sessionId = flags.sessionId;
|
|
54
65
|
if (!roleId) {
|
|
55
66
|
const { resp: iamRolesResp, error } = await handler_1.runQuery({
|
|
56
67
|
command: this,
|
|
@@ -106,7 +117,7 @@ class StartIAMRoleSession extends command_1.Command {
|
|
|
106
117
|
const { resp, error } = await handler_1.runMutation({
|
|
107
118
|
command: this,
|
|
108
119
|
query: StartIAMRoleSessionDocument,
|
|
109
|
-
variables: { id: roleId, accessLevel: cmd_1.DEFAULT_ACCESS_LEVEL },
|
|
120
|
+
variables: { id: roleId, accessLevel: cmd_1.DEFAULT_ACCESS_LEVEL, sessionId: sessionId },
|
|
110
121
|
});
|
|
111
122
|
switch (resp === null || resp === void 0 ? void 0 : resp.data.createSession.__typename) {
|
|
112
123
|
case 'CreateSessionResult': {
|
|
@@ -125,6 +136,10 @@ class StartIAMRoleSession extends command_1.Command {
|
|
|
125
136
|
}
|
|
126
137
|
break;
|
|
127
138
|
}
|
|
139
|
+
case 'MfaInvalidError': {
|
|
140
|
+
common_1.handleMfaRedirect(this, roleId);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
128
143
|
default:
|
|
129
144
|
apollo_1.printRequestOutput(this, resp, error);
|
|
130
145
|
}
|
|
@@ -142,4 +157,8 @@ StartIAMRoleSession.flags = {
|
|
|
142
157
|
multiple: false,
|
|
143
158
|
description: 'The ID of the Opal role resource.',
|
|
144
159
|
}),
|
|
160
|
+
sessionId: command_1.flags.string({
|
|
161
|
+
multiple: false,
|
|
162
|
+
description: 'SessionId of a session that has already been created via the web flow.',
|
|
163
|
+
}),
|
|
145
164
|
};
|
|
@@ -6,6 +6,7 @@ export default class StartKubeIAMRoleSession extends Command {
|
|
|
6
6
|
help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
|
|
7
7
|
id: flags.IOptionFlag<string | undefined>;
|
|
8
8
|
accessLevelRemoteId: flags.IOptionFlag<string | undefined>;
|
|
9
|
+
sessionId: flags.IOptionFlag<string | undefined>;
|
|
9
10
|
};
|
|
10
11
|
run(): Promise<void>;
|
|
11
12
|
}
|
|
@@ -8,9 +8,10 @@ const inquirer = require("inquirer");
|
|
|
8
8
|
const types_1 = require("../../types");
|
|
9
9
|
const aws_1 = require("../../lib/aws");
|
|
10
10
|
const resources_1 = require("../../lib/resources");
|
|
11
|
+
const common_1 = require("../../lib/common");
|
|
11
12
|
const StartKubeIAMRoleSessionDocument = `
|
|
12
|
-
mutation StartKubeIAMRoleSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInput
|
|
13
|
-
createSession(input: {resourceId: $id, accessLevel: $accessLevel}) {
|
|
13
|
+
mutation StartKubeIAMRoleSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInput!, $sessionId: SessionId) {
|
|
14
|
+
createSession(input: {resourceId: $id, accessLevel: $accessLevel, sessionId: $sessionId}) {
|
|
14
15
|
__typename
|
|
15
16
|
... on CreateSessionResult {
|
|
16
17
|
session {
|
|
@@ -27,9 +28,18 @@ mutation StartKubeIAMRoleSession($id: ResourceId!, $accessLevel: ResourceAccessL
|
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
}
|
|
31
|
+
... on SessionNotFoundError {
|
|
32
|
+
message
|
|
33
|
+
}
|
|
34
|
+
... on MfaInvalidError {
|
|
35
|
+
message
|
|
36
|
+
}
|
|
30
37
|
... on ResourceNotFoundError {
|
|
31
38
|
message
|
|
32
39
|
}
|
|
40
|
+
... on EndSystemAuthorizationError {
|
|
41
|
+
message
|
|
42
|
+
}
|
|
33
43
|
}
|
|
34
44
|
}`;
|
|
35
45
|
const ListKubeIamRolesDocument = `
|
|
@@ -54,6 +64,7 @@ class StartKubeIAMRoleSession extends command_1.Command {
|
|
|
54
64
|
const { flags } = this.parse(StartKubeIAMRoleSession);
|
|
55
65
|
// TODO: RESOURCES-1: How do we grant access to a perm using ID
|
|
56
66
|
let clusterId = flags.id;
|
|
67
|
+
const sessionId = flags.sessionId;
|
|
57
68
|
if (!clusterId) {
|
|
58
69
|
const { resp: kubeIamRolesResp, error } = await handler_1.runQuery({
|
|
59
70
|
command: this,
|
|
@@ -101,7 +112,7 @@ class StartKubeIAMRoleSession extends command_1.Command {
|
|
|
101
112
|
const { resp, error } = await handler_1.runMutation({
|
|
102
113
|
command: this,
|
|
103
114
|
query: StartKubeIAMRoleSessionDocument,
|
|
104
|
-
variables: { id: clusterId, accessLevel },
|
|
115
|
+
variables: { id: clusterId, accessLevel, sessionId },
|
|
105
116
|
});
|
|
106
117
|
switch (resp === null || resp === void 0 ? void 0 : resp.data.createSession.__typename) {
|
|
107
118
|
case 'CreateSessionResult': {
|
|
@@ -120,6 +131,10 @@ class StartKubeIAMRoleSession extends command_1.Command {
|
|
|
120
131
|
}
|
|
121
132
|
break;
|
|
122
133
|
}
|
|
134
|
+
case 'MfaInvalidError': {
|
|
135
|
+
common_1.handleMfaRedirect(this, clusterId);
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
123
138
|
default:
|
|
124
139
|
apollo_1.printRequestOutput(this, resp, error);
|
|
125
140
|
}
|
|
@@ -142,4 +157,8 @@ StartKubeIAMRoleSession.flags = {
|
|
|
142
157
|
multiple: false,
|
|
143
158
|
description: 'The remote ID of the access level with which to access the cluster.',
|
|
144
159
|
}),
|
|
160
|
+
sessionId: command_1.flags.string({
|
|
161
|
+
multiple: false,
|
|
162
|
+
description: 'SessionId of a session that has already been created via the web flow.',
|
|
163
|
+
}),
|
|
145
164
|
};
|
package/lib/commands/login.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Command } from '@oclif/command';
|
|
2
|
+
export declare const CLIAuthSessionCheckDocument = "\nquery CLIAuthSessionCheck {\n organizationSettings {\n ... on OrganizationSettingsResult {\n settings {\n id\n }\n }\n }\n}\n";
|
|
2
3
|
export default class Login extends Command {
|
|
3
4
|
static description: string;
|
|
4
5
|
static examples: string[];
|
package/lib/commands/login.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CLIAuthSessionCheckDocument = void 0;
|
|
3
4
|
const command_1 = require("@oclif/command");
|
|
4
5
|
const keytar = require("keytar");
|
|
5
6
|
const open = require("open");
|
|
@@ -27,7 +28,7 @@ query CLISignInMethod($input: SignInMethodInput!) {
|
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
}`;
|
|
30
|
-
|
|
31
|
+
exports.CLIAuthSessionCheckDocument = `
|
|
31
32
|
query CLIAuthSessionCheck {
|
|
32
33
|
organizationSettings {
|
|
33
34
|
... on OrganizationSettingsResult {
|
|
@@ -131,7 +132,7 @@ class Login extends command_1.Command {
|
|
|
131
132
|
// "Representative" authenticated call to check the log-in worked as expected.
|
|
132
133
|
const { resp: authCheckResp, error: authCheckErr } = await handler_1.runQuery({
|
|
133
134
|
command: this,
|
|
134
|
-
query: CLIAuthSessionCheckDocument,
|
|
135
|
+
query: exports.CLIAuthSessionCheckDocument,
|
|
135
136
|
variables: {},
|
|
136
137
|
});
|
|
137
138
|
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)) {
|
|
@@ -6,6 +6,7 @@ export default class StartPostgresInstanceSession extends Command {
|
|
|
6
6
|
help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
|
|
7
7
|
id: flags.IOptionFlag<string | undefined>;
|
|
8
8
|
accessLevelRemoteId: flags.IOptionFlag<string | undefined>;
|
|
9
|
+
sessionId: flags.IOptionFlag<string | undefined>;
|
|
9
10
|
};
|
|
10
11
|
run(): Promise<void>;
|
|
11
12
|
}
|
|
@@ -6,6 +6,7 @@ const cmd_1 = require("../../lib/cmd");
|
|
|
6
6
|
const apollo_1 = require("../../lib/apollo");
|
|
7
7
|
const inquirer = require("inquirer");
|
|
8
8
|
const resources_1 = require("../../lib/resources");
|
|
9
|
+
const common_1 = require("../../lib/common");
|
|
9
10
|
const ListPostgresInstancesDocument = `
|
|
10
11
|
query ListPostgresInstances {
|
|
11
12
|
resources(input: {serviceType: POSTGRES, onlyMine: true, maxNumEntries: 1000}) {
|
|
@@ -20,8 +21,8 @@ query ListPostgresInstances {
|
|
|
20
21
|
}
|
|
21
22
|
}`;
|
|
22
23
|
const StartPostgresInstanceSessionDocument = `
|
|
23
|
-
mutation StartPostgresInstanceSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInput
|
|
24
|
-
createSession(input: {resourceId: $id, accessLevel: $accessLevel}) {
|
|
24
|
+
mutation StartPostgresInstanceSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInput!, $sessionId: SessionId) {
|
|
25
|
+
createSession(input: {resourceId: $id, accessLevel: $accessLevel, sessionId: $sessionId}) {
|
|
25
26
|
__typename
|
|
26
27
|
... on CreateSessionResult {
|
|
27
28
|
session {
|
|
@@ -38,9 +39,18 @@ mutation StartPostgresInstanceSession($id: ResourceId!, $accessLevel: ResourceAc
|
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
}
|
|
42
|
+
... on SessionNotFoundError {
|
|
43
|
+
message
|
|
44
|
+
}
|
|
45
|
+
... on MfaInvalidError {
|
|
46
|
+
message
|
|
47
|
+
}
|
|
41
48
|
... on ResourceNotFoundError {
|
|
42
49
|
message
|
|
43
50
|
}
|
|
51
|
+
... on EndSystemAuthorizationError {
|
|
52
|
+
message
|
|
53
|
+
}
|
|
44
54
|
}
|
|
45
55
|
}`;
|
|
46
56
|
class StartPostgresInstanceSession extends command_1.Command {
|
|
@@ -49,6 +59,7 @@ class StartPostgresInstanceSession extends command_1.Command {
|
|
|
49
59
|
const { flags } = this.parse(StartPostgresInstanceSession);
|
|
50
60
|
let instanceId = flags.id;
|
|
51
61
|
let instanceName = null;
|
|
62
|
+
const sessionId = flags.sessionId;
|
|
52
63
|
// TODO: RESOURCES-1: How do we grant access to a perm using ID
|
|
53
64
|
if (!instanceId) {
|
|
54
65
|
const { resp: postgresInstancesResp, error } = await handler_1.runQuery({
|
|
@@ -100,6 +111,7 @@ class StartPostgresInstanceSession extends command_1.Command {
|
|
|
100
111
|
variables: {
|
|
101
112
|
id: instanceId,
|
|
102
113
|
accessLevel,
|
|
114
|
+
sessionId,
|
|
103
115
|
},
|
|
104
116
|
});
|
|
105
117
|
switch (resp === null || resp === void 0 ? void 0 : resp.data.createSession.__typename) {
|
|
@@ -138,6 +150,10 @@ class StartPostgresInstanceSession extends command_1.Command {
|
|
|
138
150
|
}
|
|
139
151
|
break;
|
|
140
152
|
}
|
|
153
|
+
case 'MfaInvalidError': {
|
|
154
|
+
common_1.handleMfaRedirect(this, instanceId);
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
141
157
|
default:
|
|
142
158
|
apollo_1.printRequestOutput(this, resp, error);
|
|
143
159
|
}
|
|
@@ -160,4 +176,8 @@ StartPostgresInstanceSession.flags = {
|
|
|
160
176
|
multiple: false,
|
|
161
177
|
description: 'The remote ID of the access level with which to access the database.',
|
|
162
178
|
}),
|
|
179
|
+
sessionId: command_1.flags.string({
|
|
180
|
+
multiple: false,
|
|
181
|
+
description: 'SessionId of a session that has already been created via the web flow.',
|
|
182
|
+
}),
|
|
163
183
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from '@oclif/command';
|
|
2
|
+
export default class SetToken extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
|
|
7
|
+
};
|
|
8
|
+
static args: never[];
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const command_1 = require("@oclif/command");
|
|
4
|
+
const keytar = require("keytar");
|
|
5
|
+
const inquirer = require("inquirer");
|
|
6
|
+
const apollo_1 = require("../lib/apollo");
|
|
7
|
+
const credentials_1 = require("../lib/credentials");
|
|
8
|
+
const handler_1 = require("../handler");
|
|
9
|
+
const credentials_2 = require("../lib/credentials");
|
|
10
|
+
const login_1 = require("./login");
|
|
11
|
+
class SetToken extends command_1.Command {
|
|
12
|
+
async run() {
|
|
13
|
+
var _a, _b, _c;
|
|
14
|
+
try {
|
|
15
|
+
await apollo_1.initClient(this);
|
|
16
|
+
const { apiToken } = await inquirer.prompt([
|
|
17
|
+
{
|
|
18
|
+
name: 'apiToken',
|
|
19
|
+
message: 'Enter your API Key:',
|
|
20
|
+
type: 'password',
|
|
21
|
+
validate: key => Boolean(key),
|
|
22
|
+
},
|
|
23
|
+
]);
|
|
24
|
+
// Clear previously-stored credentials from keychain if they exist
|
|
25
|
+
let email;
|
|
26
|
+
let organizationID;
|
|
27
|
+
if (await credentials_1.cred.accessToken) {
|
|
28
|
+
email = await credentials_1.cred.email;
|
|
29
|
+
organizationID = await credentials_1.cred.organizationID;
|
|
30
|
+
await credentials_1.cred.removeCredentials(-1);
|
|
31
|
+
}
|
|
32
|
+
// Store API token in keychain - mimics login command
|
|
33
|
+
await keytar.setPassword(credentials_2.OPAL_CREDS_KEY, (email || 'unset-email') + '|' + organizationID, apiToken || '');
|
|
34
|
+
// "Representative" authenticated call to check the log-in worked as expected.
|
|
35
|
+
const { resp: authCheckResp, error: authCheckErr } = await handler_1.runQuery({
|
|
36
|
+
command: this,
|
|
37
|
+
query: login_1.CLIAuthSessionCheckDocument,
|
|
38
|
+
variables: {},
|
|
39
|
+
});
|
|
40
|
+
if (authCheckErr ||
|
|
41
|
+
!((_c = (_b = (_a = authCheckResp === null || authCheckResp === void 0 ? void 0 : authCheckResp.data) === null || _a === void 0 ? void 0 : _a.organizationSettings) === null || _b === void 0 ? void 0 : _b.settings) === null || _c === void 0 ? void 0 : _c.id)) {
|
|
42
|
+
this.log('Error verifying log in. Authenticated commands may fail. Please double check your API token and use `opal logout; opal set-token` to try again.\n');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.log('🎉 You have successfully authenticated with Opal! You can now run authenticated commands.\n');
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
this.error(error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.default = SetToken;
|
|
53
|
+
SetToken.description = 'Sets an API token to authenticate with the Opal server - alternative auth flow for headless environments.';
|
|
54
|
+
SetToken.examples = ['$ opal set-token'];
|
|
55
|
+
SetToken.flags = {
|
|
56
|
+
help: command_1.flags.help({ char: 'h' }),
|
|
57
|
+
};
|
|
58
|
+
SetToken.args = [];
|
package/lib/commands/set-url.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const command_1 = require("@oclif/command");
|
|
4
4
|
const apollo_1 = require("../lib/apollo");
|
|
5
5
|
const config_1 = require("../lib/config");
|
|
6
|
+
const credentials_1 = require("../lib/credentials");
|
|
6
7
|
class SetUrl extends command_1.Command {
|
|
7
8
|
async run() {
|
|
8
9
|
try {
|
|
@@ -31,6 +32,7 @@ class SetUrl extends command_1.Command {
|
|
|
31
32
|
configData[config_1.allowSelfSignedCertsKey] = flags.allowSelfSignedCerts !== undefined;
|
|
32
33
|
config_1.writeConfigData(this.config.configDir, configData);
|
|
33
34
|
const updatedConfigData = config_1.getOrCreateConfigData(this.config.configDir);
|
|
35
|
+
await credentials_1.cred.removeCredentials(-1);
|
|
34
36
|
await apollo_1.initClient(this);
|
|
35
37
|
this.log(`Opal CLI will now make requests to the server at ${updatedConfigData[config_1.urlKey]}`);
|
|
36
38
|
}
|
|
@@ -5,9 +5,10 @@ const handler_1 = require("../../handler");
|
|
|
5
5
|
const apollo_1 = require("../../lib/apollo");
|
|
6
6
|
const cmd_1 = require("../../lib/cmd");
|
|
7
7
|
const ssh_1 = require("../../lib/ssh");
|
|
8
|
+
const common_1 = require("../../lib/common");
|
|
8
9
|
const StartSSHSessionDocument = `
|
|
9
|
-
mutation StartSSHSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInput
|
|
10
|
-
createSession(input: {resourceId: $id, accessLevel: $accessLevel}) {
|
|
10
|
+
mutation StartSSHSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInput!, $sessionId: SessionId) {
|
|
11
|
+
createSession(input: {resourceId: $id, accessLevel: $accessLevel, sessionId: $sessionId}) {
|
|
11
12
|
__typename
|
|
12
13
|
... on CreateSessionResult {
|
|
13
14
|
session {
|
|
@@ -26,9 +27,18 @@ mutation StartSSHSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInpu
|
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
}
|
|
30
|
+
... on SessionNotFoundError {
|
|
31
|
+
message
|
|
32
|
+
}
|
|
33
|
+
... on MfaInvalidError {
|
|
34
|
+
message
|
|
35
|
+
}
|
|
29
36
|
... on ResourceNotFoundError {
|
|
30
37
|
message
|
|
31
38
|
}
|
|
39
|
+
... on EndSystemAuthorizationError {
|
|
40
|
+
message
|
|
41
|
+
}
|
|
32
42
|
}
|
|
33
43
|
}`;
|
|
34
44
|
class StartSCPSession extends command_1.Command {
|
|
@@ -41,6 +51,7 @@ class StartSCPSession extends command_1.Command {
|
|
|
41
51
|
}
|
|
42
52
|
let instanceId = flags.id;
|
|
43
53
|
let instanceName = null;
|
|
54
|
+
const sessionId = flags.sessionId;
|
|
44
55
|
if (!instanceId) {
|
|
45
56
|
const selectedInstance = await ssh_1.selectComputeInstance(this, 'SCP into');
|
|
46
57
|
if (!selectedInstance) {
|
|
@@ -52,7 +63,7 @@ class StartSCPSession extends command_1.Command {
|
|
|
52
63
|
const { resp, error } = await handler_1.runMutation({
|
|
53
64
|
command: this,
|
|
54
65
|
query: StartSSHSessionDocument,
|
|
55
|
-
variables: { id: instanceId, accessLevel: cmd_1.DEFAULT_ACCESS_LEVEL },
|
|
66
|
+
variables: { id: instanceId, accessLevel: cmd_1.DEFAULT_ACCESS_LEVEL, sessionId },
|
|
56
67
|
});
|
|
57
68
|
switch (resp === null || resp === void 0 ? void 0 : resp.data.createSession.__typename) {
|
|
58
69
|
case 'CreateSessionResult': {
|
|
@@ -75,6 +86,10 @@ class StartSCPSession extends command_1.Command {
|
|
|
75
86
|
}
|
|
76
87
|
break;
|
|
77
88
|
}
|
|
89
|
+
case 'MfaInvalidError': {
|
|
90
|
+
common_1.handleMfaRedirect(this, instanceId);
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
78
93
|
default:
|
|
79
94
|
apollo_1.printRequestOutput(this, resp, error);
|
|
80
95
|
}
|
|
@@ -109,4 +124,8 @@ StartSCPSession.flags = {
|
|
|
109
124
|
multiple: false,
|
|
110
125
|
description: 'The ID of the Opal instance resource.',
|
|
111
126
|
}),
|
|
127
|
+
sessionId: command_1.flags.string({
|
|
128
|
+
multiple: false,
|
|
129
|
+
description: 'SessionId of a session that has already been created via the web flow.',
|
|
130
|
+
}),
|
|
112
131
|
};
|
|
@@ -5,9 +5,10 @@ const handler_1 = require("../../handler");
|
|
|
5
5
|
const apollo_1 = require("../../lib/apollo");
|
|
6
6
|
const cmd_1 = require("../../lib/cmd");
|
|
7
7
|
const ssh_1 = require("../../lib/ssh");
|
|
8
|
+
const common_1 = require("../../lib/common");
|
|
8
9
|
const StartSSHSessionDocument = `
|
|
9
|
-
mutation StartSSHSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInput
|
|
10
|
-
createSession(input: {resourceId: $id, accessLevel: $accessLevel}) {
|
|
10
|
+
mutation StartSSHSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInput!, $sessionId: SessionId) {
|
|
11
|
+
createSession(input: {resourceId: $id, accessLevel: $accessLevel, sessionId: $sessionId}) {
|
|
11
12
|
__typename
|
|
12
13
|
... on CreateSessionResult {
|
|
13
14
|
session {
|
|
@@ -26,9 +27,18 @@ mutation StartSSHSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInpu
|
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
}
|
|
30
|
+
... on SessionNotFoundError {
|
|
31
|
+
message
|
|
32
|
+
}
|
|
33
|
+
... on MfaInvalidError {
|
|
34
|
+
message
|
|
35
|
+
}
|
|
29
36
|
... on ResourceNotFoundError {
|
|
30
37
|
message
|
|
31
38
|
}
|
|
39
|
+
... on EndSystemAuthorizationError {
|
|
40
|
+
message
|
|
41
|
+
}
|
|
32
42
|
}
|
|
33
43
|
}`;
|
|
34
44
|
class StartSCPSession extends command_1.Command {
|
|
@@ -41,6 +51,7 @@ class StartSCPSession extends command_1.Command {
|
|
|
41
51
|
}
|
|
42
52
|
let instanceId = flags.id;
|
|
43
53
|
let instanceName = null;
|
|
54
|
+
const sessionId = flags.sessionId;
|
|
44
55
|
if (!instanceId) {
|
|
45
56
|
const selectedInstance = await ssh_1.selectComputeInstance(this, 'SCP into');
|
|
46
57
|
if (!selectedInstance) {
|
|
@@ -52,7 +63,7 @@ class StartSCPSession extends command_1.Command {
|
|
|
52
63
|
const { resp, error } = await handler_1.runMutation({
|
|
53
64
|
command: this,
|
|
54
65
|
query: StartSSHSessionDocument,
|
|
55
|
-
variables: { id: instanceId, accessLevel: cmd_1.DEFAULT_ACCESS_LEVEL },
|
|
66
|
+
variables: { id: instanceId, accessLevel: cmd_1.DEFAULT_ACCESS_LEVEL, sessionId },
|
|
56
67
|
});
|
|
57
68
|
switch (resp === null || resp === void 0 ? void 0 : resp.data.createSession.__typename) {
|
|
58
69
|
case 'CreateSessionResult': {
|
|
@@ -75,6 +86,10 @@ class StartSCPSession extends command_1.Command {
|
|
|
75
86
|
}
|
|
76
87
|
break;
|
|
77
88
|
}
|
|
89
|
+
case 'MfaInvalidError': {
|
|
90
|
+
common_1.handleMfaRedirect(this, instanceId);
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
78
93
|
default:
|
|
79
94
|
apollo_1.printRequestOutput(this, resp, error);
|
|
80
95
|
}
|
|
@@ -109,4 +124,8 @@ StartSCPSession.flags = {
|
|
|
109
124
|
multiple: false,
|
|
110
125
|
description: 'The ID of the Opal instance resource.',
|
|
111
126
|
}),
|
|
127
|
+
sessionId: command_1.flags.string({
|
|
128
|
+
multiple: false,
|
|
129
|
+
description: 'SessionId of a session that has already been created via the web flow.',
|
|
130
|
+
}),
|
|
112
131
|
};
|
|
@@ -7,9 +7,10 @@ const apollo_1 = require("../../lib/apollo");
|
|
|
7
7
|
const ssh_1 = require("../../lib/ssh");
|
|
8
8
|
const get_1 = require("../../commands/resources/get");
|
|
9
9
|
const aws_1 = require("../../lib/aws");
|
|
10
|
+
const common_1 = require("../../lib/common");
|
|
10
11
|
const StartSSHSessionDocument = `
|
|
11
|
-
mutation StartSSHSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInput
|
|
12
|
-
createSession(input: {resourceId: $id, accessLevel: $accessLevel}) {
|
|
12
|
+
mutation StartSSHSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInput!, $sessionId: SessionId) {
|
|
13
|
+
createSession(input: {resourceId: $id, accessLevel: $accessLevel, sessionId: $sessionId}) {
|
|
13
14
|
__typename
|
|
14
15
|
... on CreateSessionResult {
|
|
15
16
|
session {
|
|
@@ -28,9 +29,18 @@ mutation StartSSHSession($id: ResourceId!, $accessLevel: ResourceAccessLevelInpu
|
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
}
|
|
32
|
+
... on SessionNotFoundError {
|
|
33
|
+
message
|
|
34
|
+
}
|
|
35
|
+
... on MfaInvalidError {
|
|
36
|
+
message
|
|
37
|
+
}
|
|
31
38
|
... on ResourceNotFoundError {
|
|
32
39
|
message
|
|
33
40
|
}
|
|
41
|
+
... on EndSystemAuthorizationError {
|
|
42
|
+
message
|
|
43
|
+
}
|
|
34
44
|
}
|
|
35
45
|
}`;
|
|
36
46
|
class StartSSHSession extends command_1.Command {
|
|
@@ -43,6 +53,7 @@ class StartSSHSession extends command_1.Command {
|
|
|
43
53
|
}
|
|
44
54
|
let instanceId = flags.id;
|
|
45
55
|
let instanceName = null;
|
|
56
|
+
const sessionId = flags.sessionId;
|
|
46
57
|
// TODO: RESOURCES-1: How do we grant access to a perm using ID
|
|
47
58
|
if (!instanceId) {
|
|
48
59
|
const selectedInstance = await ssh_1.selectComputeInstance(this, 'SSH into');
|
|
@@ -69,7 +80,7 @@ class StartSSHSession extends command_1.Command {
|
|
|
69
80
|
const { resp, error } = await handler_1.runMutation({
|
|
70
81
|
command: this,
|
|
71
82
|
query: StartSSHSessionDocument,
|
|
72
|
-
variables: { id: instanceId, accessLevel: cmd_1.DEFAULT_ACCESS_LEVEL },
|
|
83
|
+
variables: { id: instanceId, accessLevel: cmd_1.DEFAULT_ACCESS_LEVEL, sessionId },
|
|
73
84
|
});
|
|
74
85
|
switch (resp === null || resp === void 0 ? void 0 : resp.data.createSession.__typename) {
|
|
75
86
|
case 'CreateSessionResult': {
|
|
@@ -90,6 +101,10 @@ class StartSSHSession extends command_1.Command {
|
|
|
90
101
|
}
|
|
91
102
|
break;
|
|
92
103
|
}
|
|
104
|
+
case 'MfaInvalidError': {
|
|
105
|
+
common_1.handleMfaRedirect(this, instanceId);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
93
108
|
default:
|
|
94
109
|
apollo_1.printRequestOutput(this, resp, error);
|
|
95
110
|
}
|
|
@@ -107,4 +122,14 @@ StartSSHSession.flags = {
|
|
|
107
122
|
multiple: false,
|
|
108
123
|
description: 'The ID of the Opal instance resource.',
|
|
109
124
|
}),
|
|
125
|
+
// TODO: Unfortunately allowing SSM over SSH disables logging
|
|
126
|
+
// user: flags.string({
|
|
127
|
+
// multiple: false,
|
|
128
|
+
// required: false,
|
|
129
|
+
// default: "ssm-user",
|
|
130
|
+
// }),
|
|
131
|
+
sessionId: command_1.flags.string({
|
|
132
|
+
multiple: false,
|
|
133
|
+
description: 'SessionId of a session that has already been created via the web flow.',
|
|
134
|
+
}),
|
|
110
135
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleMfaRedirect = void 0;
|
|
4
|
+
const config_1 = require("./config");
|
|
5
|
+
const open = require("open");
|
|
6
|
+
exports.handleMfaRedirect = (command, resourceId) => {
|
|
7
|
+
command.log('❗ MFA validation needed. Please connect via browser. Redirecting...');
|
|
8
|
+
const configData = config_1.getOrCreateConfigData(command.config.configDir);
|
|
9
|
+
const url = configData[config_1.urlKey];
|
|
10
|
+
setTimeout(() => {
|
|
11
|
+
open(url + `/resources/${resourceId}?showModal=true`);
|
|
12
|
+
}, 2000);
|
|
13
|
+
};
|
package/lib/lib/config.js
CHANGED
|
@@ -55,6 +55,7 @@ exports.isProduction = (configDir) => {
|
|
|
55
55
|
// Custom URLs are considered production since it includes on-prem
|
|
56
56
|
return configData[exports.urlKey] !== 'https://dev.opal.dev' &&
|
|
57
57
|
configData[exports.urlKey] !== 'http://localhost:3000' &&
|
|
58
|
+
configData[exports.urlKey] !== 'http://localhost:4000' &&
|
|
58
59
|
configData[exports.urlKey] !== 'https://demo.opal.dev' &&
|
|
59
60
|
configData[exports.urlKey] !== 'https://staging.opal.dev';
|
|
60
61
|
};
|
package/oclif.manifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"2.0.
|
|
1
|
+
{"version":"2.0.15","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-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-host"],"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"],"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."}},"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.15",
|
|
5
5
|
"author": "Stephen Cobbe",
|
|
6
6
|
"bin": {
|
|
7
7
|
"opal": "./bin/run"
|
|
@@ -9,22 +9,24 @@
|
|
|
9
9
|
"bugs": "https://github.com/opalsecurity/opal-cli/issues",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@apollo/client": "^3.3.13",
|
|
12
|
-
"@graphql-codegen/cli": "^
|
|
12
|
+
"@graphql-codegen/cli": "^2.6.2",
|
|
13
13
|
"@graphql-codegen/near-operation-file-preset": "^1.17.13",
|
|
14
14
|
"@graphql-codegen/typescript": "^1.21.1",
|
|
15
15
|
"@graphql-codegen/typescript-oclif": "^1.17.9",
|
|
16
|
-
"@oclif/command": "^1.8.
|
|
16
|
+
"@oclif/command": "^1.8.16",
|
|
17
17
|
"@oclif/config": "^1.17.0",
|
|
18
|
+
"@oclif/errors": "^1.3.5",
|
|
18
19
|
"@oclif/plugin-autocomplete": "^0.3.0",
|
|
19
|
-
"@oclif/plugin-help": "^
|
|
20
|
+
"@oclif/plugin-help": "^5.1.12",
|
|
20
21
|
"@types/inquirer": "^7.3.1",
|
|
21
22
|
"@types/prettyjson": "0.0.29",
|
|
22
23
|
"chalk": "^2.4.2",
|
|
23
24
|
"graphql": "^15.5.0",
|
|
25
|
+
"inquirer": "^8.2.4",
|
|
24
26
|
"inquirer-autocomplete-prompt": "^1.4.0",
|
|
25
27
|
"keytar": "^7.7.0",
|
|
26
28
|
"lodash": "^4.17.21",
|
|
27
|
-
"node-fetch": "^2.6.
|
|
29
|
+
"node-fetch": "^2.6.7",
|
|
28
30
|
"open": "^8.0.4",
|
|
29
31
|
"openid-client": "^4.6.0",
|
|
30
32
|
"prettyjson": "^1.2.1",
|
|
@@ -35,17 +37,16 @@
|
|
|
35
37
|
"@oclif/dev-cli": "^1.26.0",
|
|
36
38
|
"@oclif/test": "^1.2.8",
|
|
37
39
|
"@types/chai": "^4.2.16",
|
|
38
|
-
"@types/chalk": "^2.2.0",
|
|
39
40
|
"@types/lodash": "^4.14.169",
|
|
40
41
|
"@types/mocha": "^5.2.7",
|
|
41
42
|
"@types/node": "^14.14.37",
|
|
42
43
|
"@types/semver": "^7.3.8",
|
|
43
44
|
"chai": "^4.3.4",
|
|
44
|
-
"eslint": "^
|
|
45
|
+
"eslint": "^8.17.0",
|
|
45
46
|
"eslint-config-oclif": "^3.1.0",
|
|
46
47
|
"eslint-config-oclif-typescript": "^0.1.0",
|
|
47
48
|
"globby": "^10.0.2",
|
|
48
|
-
"mocha": "^
|
|
49
|
+
"mocha": "^10.0.0",
|
|
49
50
|
"nyc": "^14.1.1",
|
|
50
51
|
"ts-node": "^8.10.2",
|
|
51
52
|
"typescript": "^3.9.9"
|
|
@@ -78,6 +79,9 @@
|
|
|
78
79
|
"type": "git",
|
|
79
80
|
"url": "https://github.com/opalsecurity/opal-cli.git"
|
|
80
81
|
},
|
|
82
|
+
"resolutions": {
|
|
83
|
+
"ansi-regex": "5.0.1"
|
|
84
|
+
},
|
|
81
85
|
"scripts": {
|
|
82
86
|
"postpack": "rm -f oclif.manifest.json",
|
|
83
87
|
"posttest": "eslint . --ext .ts --config .eslintrc",
|