opal-security 3.0.0 → 3.0.1-beta.4f1a7ce
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 -44
- package/bin/run +1 -1
- package/lib/commands/aws/identity.d.ts +1 -1
- package/lib/commands/aws/identity.js +2 -2
- package/lib/commands/clear-auth-provider.d.ts +1 -1
- package/lib/commands/clear-auth-provider.js +3 -3
- package/lib/commands/curl-example.d.ts +1 -1
- package/lib/commands/curl-example.js +2 -2
- package/lib/commands/iam-roles/start.d.ts +1 -1
- package/lib/commands/iam-roles/start.js +14 -14
- package/lib/commands/kube-roles/start.d.ts +1 -1
- package/lib/commands/kube-roles/start.js +10 -10
- package/lib/commands/login.d.ts +1 -1
- package/lib/commands/login.js +71 -63
- package/lib/commands/logout.d.ts +1 -1
- package/lib/commands/logout.js +3 -3
- package/lib/commands/postgres-instances/start.d.ts +1 -1
- package/lib/commands/postgres-instances/start.js +35 -34
- package/lib/commands/request/create.d.ts +6 -0
- package/lib/commands/request/create.js +37 -0
- package/lib/commands/request/get.d.ts +6 -0
- package/lib/commands/request/get.js +13 -0
- package/lib/commands/request/list.d.ts +7 -0
- package/lib/commands/request/list.js +14 -0
- package/lib/commands/resources/get.d.ts +1 -1
- package/lib/commands/resources/get.js +11 -4
- package/lib/commands/set-auth-provider.d.ts +1 -1
- package/lib/commands/set-auth-provider.js +6 -4
- package/lib/commands/set-custom-header.d.ts +1 -1
- package/lib/commands/set-custom-header.js +5 -3
- package/lib/commands/set-token.d.ts +1 -1
- package/lib/commands/set-token.js +26 -19
- package/lib/commands/set-url.d.ts +1 -1
- package/lib/commands/set-url.js +13 -12
- package/lib/commands/ssh/copyFrom.d.ts +1 -1
- package/lib/commands/ssh/copyFrom.js +13 -13
- package/lib/commands/ssh/copyTo.d.ts +1 -1
- package/lib/commands/ssh/copyTo.js +13 -13
- package/lib/commands/ssh/start.d.ts +1 -1
- package/lib/commands/ssh/start.js +14 -15
- package/lib/graphql/fragment-masking.d.ts +19 -0
- package/lib/graphql/fragment-masking.js +21 -0
- package/lib/graphql/gql.d.ts +46 -0
- package/lib/graphql/gql.js +14 -0
- package/lib/graphql/graphql.d.ts +11476 -0
- package/lib/graphql/graphql.js +1819 -0
- package/lib/graphql/index.d.ts +2 -0
- package/lib/graphql/index.js +5 -0
- package/lib/handler.d.ts +5 -5
- package/lib/handler.js +7 -7
- package/lib/index.d.ts +1 -1
- package/lib/lib/apollo.d.ts +3 -2
- package/lib/lib/apollo.js +59 -46
- package/lib/lib/aws.js +15 -12
- package/lib/lib/cmd.d.ts +4 -6
- package/lib/lib/cmd.js +11 -11
- package/lib/lib/config.js +14 -14
- package/lib/lib/credentials/index.d.ts +1 -1
- package/lib/lib/credentials/index.js +6 -6
- package/lib/lib/credentials/keychain.js +5 -5
- package/lib/lib/credentials/localEncryption.d.ts +2 -2
- package/lib/lib/credentials/localEncryption.js +33 -24
- package/lib/lib/flags.js +9 -9
- package/lib/lib/requests.d.ts +22 -0
- package/lib/lib/requests.js +274 -0
- package/lib/lib/resources.d.ts +2 -2
- package/lib/lib/resources.js +29 -23
- package/lib/lib/sessions.d.ts +2 -2
- package/lib/lib/sessions.js +18 -17
- package/lib/lib/ssh.d.ts +1 -1
- package/lib/lib/ssh.js +8 -8
- package/lib/lib/util.d.ts +0 -1
- package/lib/lib/util.js +13 -13
- package/lib/types.d.ts +1787 -1787
- package/lib/utils/displays.d.ts +5 -0
- package/lib/utils/displays.js +65 -0
- package/lib/utils/utils.d.ts +1 -0
- package/lib/utils/utils.js +18 -0
- package/oclif.manifest.json +70 -3
- package/package.json +25 -29
|
@@ -13,7 +13,7 @@ class SetAuthProvider extends core_1.Command {
|
|
|
13
13
|
configData.clientID = flags.clientID;
|
|
14
14
|
(0, config_1.writeConfigData)(this.config.configDir, configData);
|
|
15
15
|
await (0, credentials_1.removeOpalCredentials)(this);
|
|
16
|
-
this.log(
|
|
16
|
+
this.log("Client ID and Issuer URL updated");
|
|
17
17
|
}
|
|
18
18
|
catch (error) {
|
|
19
19
|
this.error(error);
|
|
@@ -25,18 +25,20 @@ SetAuthProvider.description = `Sets the Issuer URL and Client ID of the Auth Pro
|
|
|
25
25
|
|
|
26
26
|
Note - you will need an OIDC provider that supports the device_code grant.
|
|
27
27
|
`;
|
|
28
|
-
SetAuthProvider.examples = [
|
|
28
|
+
SetAuthProvider.examples = [
|
|
29
|
+
"$ opal set-auth-provider --clientID 1234asdf --issuerUrl https://auth.example.com",
|
|
30
|
+
];
|
|
29
31
|
SetAuthProvider.flags = {
|
|
30
32
|
help: flags_1.SHARED_FLAGS.help,
|
|
31
33
|
clientID: core_1.Flags.string({
|
|
32
34
|
multiple: false,
|
|
33
35
|
description: "Client ID of your Auth Provider",
|
|
34
|
-
required: true
|
|
36
|
+
required: true,
|
|
35
37
|
}),
|
|
36
38
|
issuerUrl: core_1.Flags.string({
|
|
37
39
|
multiple: false,
|
|
38
40
|
description: "Issuer URL of your Auth Provider",
|
|
39
|
-
required: true
|
|
41
|
+
required: true,
|
|
40
42
|
}),
|
|
41
43
|
};
|
|
42
44
|
exports.default = SetAuthProvider;
|
|
@@ -16,15 +16,17 @@ class SetCustomHeader extends core_1.Command {
|
|
|
16
16
|
configData[config_1.customHttpHeaderKey] = header;
|
|
17
17
|
(0, config_1.writeConfigData)(this.config.configDir, configData);
|
|
18
18
|
await (0, apollo_1.initClient)(this);
|
|
19
|
-
this.log(
|
|
19
|
+
this.log("Custom HTTP header updated");
|
|
20
20
|
}
|
|
21
21
|
catch (error) {
|
|
22
22
|
this.error(error);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
SetCustomHeader.description =
|
|
27
|
-
SetCustomHeader.examples = [
|
|
26
|
+
SetCustomHeader.description = "Sets a custom HTTP header to connect to the Opal server.";
|
|
27
|
+
SetCustomHeader.examples = [
|
|
28
|
+
"$ opal set-custom-header --header 'cf-access-token: $TOKEN'",
|
|
29
|
+
];
|
|
28
30
|
SetCustomHeader.flags = {
|
|
29
31
|
help: flags_1.SHARED_FLAGS.help,
|
|
30
32
|
header: core_1.Flags.string({
|
|
@@ -2,49 +2,56 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
4
|
const inquirer = require("inquirer");
|
|
5
|
+
const graphql_1 = require("../graphql");
|
|
5
6
|
const apollo_1 = require("../lib/apollo");
|
|
6
7
|
const credentials_1 = require("../lib/credentials");
|
|
7
|
-
const handler_1 = require("../handler");
|
|
8
|
-
const login_1 = require("./login");
|
|
9
8
|
const flags_1 = require("../lib/flags");
|
|
9
|
+
const CHECK_AUTH_SESSION_QUERY = (0, graphql_1.graphql)(`
|
|
10
|
+
query CheckAuthSessionQuery {
|
|
11
|
+
organizationSettings {
|
|
12
|
+
... on OrganizationSettingsResult {
|
|
13
|
+
settings {
|
|
14
|
+
id
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
`);
|
|
10
20
|
class SetToken extends core_1.Command {
|
|
11
21
|
async run() {
|
|
12
|
-
var _a, _b
|
|
22
|
+
var _a, _b;
|
|
13
23
|
try {
|
|
14
24
|
await (0, apollo_1.initClient)(this, false);
|
|
15
25
|
const { apiToken } = await inquirer.prompt([
|
|
16
26
|
{
|
|
17
|
-
name:
|
|
18
|
-
message:
|
|
19
|
-
type:
|
|
27
|
+
name: "apiToken",
|
|
28
|
+
message: "Enter your API Key:",
|
|
29
|
+
type: "password",
|
|
20
30
|
validate: (key) => Boolean(key),
|
|
21
31
|
},
|
|
22
32
|
]);
|
|
23
33
|
// Overwrite previously-stored credentials from keychain if they exist
|
|
24
|
-
let email;
|
|
25
|
-
let organizationID;
|
|
26
34
|
const existingCreds = await (0, credentials_1.getOpalCredentials)(this, false);
|
|
27
|
-
await (0, credentials_1.setOpalCredentials)(this, existingCreds === null || existingCreds === void 0 ? void 0 : existingCreds.email, (existingCreds === null || existingCreds === void 0 ? void 0 : existingCreds.organizationID) ||
|
|
35
|
+
await (0, credentials_1.setOpalCredentials)(this, existingCreds === null || existingCreds === void 0 ? void 0 : existingCreds.email, (existingCreds === null || existingCreds === void 0 ? void 0 : existingCreds.organizationID) || "unset-org-id", existingCreds === null || existingCreds === void 0 ? void 0 : existingCreds.clientIDCandidate, apiToken || "", credentials_1.SecretType.ApiToken);
|
|
28
36
|
// "Representative" authenticated call to check the log-in worked as expected.
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
query:
|
|
32
|
-
variables: {},
|
|
37
|
+
const client = await (0, apollo_1.getClient)(this, true);
|
|
38
|
+
const resp = await client.query({
|
|
39
|
+
query: CHECK_AUTH_SESSION_QUERY,
|
|
33
40
|
});
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
this.log(
|
|
41
|
+
if (((_b = (_a = resp === null || resp === void 0 ? void 0 : resp.data) === null || _a === void 0 ? void 0 : _a.organizationSettings) === null || _b === void 0 ? void 0 : _b.__typename) ===
|
|
42
|
+
"OrganizationSettingsNotFoundError") {
|
|
43
|
+
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");
|
|
37
44
|
return;
|
|
38
45
|
}
|
|
39
|
-
this.log(
|
|
46
|
+
this.log("🎉 You have successfully authenticated with Opal! You can now run authenticated commands.\n");
|
|
40
47
|
}
|
|
41
48
|
catch (error) {
|
|
42
49
|
this.error(error);
|
|
43
50
|
}
|
|
44
51
|
}
|
|
45
52
|
}
|
|
46
|
-
SetToken.description =
|
|
47
|
-
SetToken.examples = [
|
|
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"];
|
|
48
55
|
SetToken.flags = {
|
|
49
56
|
help: flags_1.SHARED_FLAGS.help,
|
|
50
57
|
};
|
package/lib/commands/set-url.js
CHANGED
|
@@ -17,24 +17,24 @@ class SetUrl extends core_1.Command {
|
|
|
17
17
|
url = flags.custom;
|
|
18
18
|
}
|
|
19
19
|
else if (flags.prod) {
|
|
20
|
-
url =
|
|
20
|
+
url = "https://app.opal.dev";
|
|
21
21
|
}
|
|
22
22
|
else if (flags.demo) {
|
|
23
|
-
url =
|
|
23
|
+
url = "https://demo.opal.dev";
|
|
24
24
|
}
|
|
25
25
|
else if (flags.dev) {
|
|
26
|
-
url =
|
|
26
|
+
url = "https://dev.opal.dev";
|
|
27
27
|
}
|
|
28
28
|
else if (flags.devLocal) {
|
|
29
|
-
url =
|
|
29
|
+
url = "http://localhost:3000";
|
|
30
30
|
}
|
|
31
|
-
if (!url.startsWith(
|
|
31
|
+
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
|
32
32
|
// Add protocol if not specified
|
|
33
|
-
if (url.startsWith(
|
|
34
|
-
url =
|
|
33
|
+
if (url.startsWith("localhost")) {
|
|
34
|
+
url = `http://${url}`;
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
|
-
url =
|
|
37
|
+
url = `https://${url}`;
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
if (url.match(/^https?:\/\/[^/]+\/$/)) {
|
|
@@ -43,11 +43,12 @@ class SetUrl extends core_1.Command {
|
|
|
43
43
|
}
|
|
44
44
|
else if (!url.match(/^https?:\/\/[^/]+$/)) {
|
|
45
45
|
// Error if URL doesn't match `https://x.y.z` or `http://x.y.z`
|
|
46
|
-
throw new Error(
|
|
46
|
+
throw new Error("Invalid URL. Please provide only the protocol and domain (e.g. https://app.opal.dev).");
|
|
47
47
|
}
|
|
48
48
|
const configData = (0, config_1.getOrCreateConfigData)(this.config.configDir);
|
|
49
49
|
configData[config_1.urlKey] = url;
|
|
50
|
-
configData[config_1.allowSelfSignedCertsKey] =
|
|
50
|
+
configData[config_1.allowSelfSignedCertsKey] =
|
|
51
|
+
flags.allowSelfSignedCerts !== undefined;
|
|
51
52
|
(0, config_1.writeConfigData)(this.config.configDir, configData);
|
|
52
53
|
const updatedConfigData = (0, config_1.getOrCreateConfigData)(this.config.configDir);
|
|
53
54
|
await (0, credentials_1.removeOpalCredentials)(this);
|
|
@@ -60,7 +61,7 @@ class SetUrl extends core_1.Command {
|
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
63
|
SetUrl.description = `Sets the url of the Opal server. Defaults to ${config_1.defaultUrl}.`;
|
|
63
|
-
SetUrl.examples = [
|
|
64
|
+
SetUrl.examples = ["$ opal set-url"];
|
|
64
65
|
SetUrl.flags = {
|
|
65
66
|
help: flags_1.SHARED_FLAGS.help,
|
|
66
67
|
allowSelfSignedCerts: core_1.Flags.boolean(),
|
|
@@ -77,7 +78,7 @@ SetUrl.flags = {
|
|
|
77
78
|
};
|
|
78
79
|
SetUrl.args = {
|
|
79
80
|
url: core_1.Args.string({
|
|
80
|
-
description:
|
|
81
|
+
description: "URL of the Opal server to use. If unspecified, defaults to https://app.opal.dev",
|
|
81
82
|
required: false,
|
|
82
83
|
}),
|
|
83
84
|
};
|
|
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
4
|
const apollo_1 = require("../../lib/apollo");
|
|
5
5
|
const cmd_1 = require("../../lib/cmd");
|
|
6
|
-
const
|
|
6
|
+
const flags_1 = require("../../lib/flags");
|
|
7
7
|
const resources_1 = require("../../lib/resources");
|
|
8
8
|
const sessions_1 = require("../../lib/sessions");
|
|
9
|
+
const ssh_1 = require("../../lib/ssh");
|
|
9
10
|
const start_1 = require("./start");
|
|
10
|
-
const flags_1 = require("../../lib/flags");
|
|
11
11
|
class StartSCPSession extends core_1.Command {
|
|
12
12
|
async run() {
|
|
13
13
|
(0, cmd_1.setMostRecentCommand)(this);
|
|
@@ -20,7 +20,7 @@ class StartSCPSession extends core_1.Command {
|
|
|
20
20
|
let instanceName = null;
|
|
21
21
|
const sessionId = flags.sessionId;
|
|
22
22
|
if (!instanceId) {
|
|
23
|
-
const selectedInstance = await (0, ssh_1.selectComputeInstance)(this,
|
|
23
|
+
const selectedInstance = await (0, ssh_1.selectComputeInstance)(this, "SCP into");
|
|
24
24
|
if (!selectedInstance) {
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
@@ -33,7 +33,7 @@ class StartSCPSession extends core_1.Command {
|
|
|
33
33
|
}
|
|
34
34
|
const metadata = session.metadata;
|
|
35
35
|
switch (metadata === null || metadata === void 0 ? void 0 : metadata.__typename) {
|
|
36
|
-
case
|
|
36
|
+
case "AwsIamFederatedSSMSession": {
|
|
37
37
|
const envVars = {
|
|
38
38
|
AWS_ACCESS_KEY_ID: metadata.awsAccessKeyId,
|
|
39
39
|
AWS_SECRET_ACCESS_KEY: metadata.awsSecretAccessKey,
|
|
@@ -41,7 +41,7 @@ class StartSCPSession extends core_1.Command {
|
|
|
41
41
|
};
|
|
42
42
|
// Run SCP script
|
|
43
43
|
const scpCmd = `$SCRIPT_PATH/../../scripts/ssh_ssm_scp_from_server.sh ${metadata.ec2InstanceId} ${flags.user} ${flags.src} ${metadata.ec2Region} ${flags.dest}`;
|
|
44
|
-
const outputMessage = `from "${flags.src}" on ${instanceName ? `"${instanceName}" instance` :
|
|
44
|
+
const outputMessage = `from "${flags.src}" on ${instanceName ? `"${instanceName}" instance` : "instance"} to "${flags.dest}" locally.`;
|
|
45
45
|
(0, cmd_1.runCommandSpawn)(scpCmd, `Copied ${outputMessage}`, `Failed to copy ${outputMessage}`, envVars);
|
|
46
46
|
break;
|
|
47
47
|
}
|
|
@@ -50,29 +50,29 @@ class StartSCPSession extends core_1.Command {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
StartSCPSession.description =
|
|
53
|
+
StartSCPSession.description = "Use SCP to copy files from a compute instance.";
|
|
54
54
|
StartSCPSession.examples = [
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
"opal ssh:copyFrom --src instance/dir --dest my/dir",
|
|
56
|
+
"opal ssh:copyFrom --src instance/dir --dest my/dir --id 51f7176b-0464-4a6f-8369-e951e187b398",
|
|
57
57
|
];
|
|
58
58
|
StartSCPSession.flags = {
|
|
59
59
|
help: flags_1.SHARED_FLAGS.help,
|
|
60
60
|
src: core_1.Flags.string({
|
|
61
61
|
multiple: false,
|
|
62
62
|
required: true,
|
|
63
|
-
description:
|
|
63
|
+
description: "The directory or file you would like to copy over SCP. Note we only support one file or directory at a time.",
|
|
64
64
|
}),
|
|
65
65
|
dest: core_1.Flags.string({
|
|
66
66
|
multiple: false,
|
|
67
67
|
required: false,
|
|
68
|
-
default:
|
|
69
|
-
description:
|
|
68
|
+
default: ".",
|
|
69
|
+
description: "The directory you want your files to be copied to.",
|
|
70
70
|
}),
|
|
71
71
|
user: core_1.Flags.string({
|
|
72
72
|
multiple: false,
|
|
73
73
|
required: false,
|
|
74
|
-
default:
|
|
75
|
-
description:
|
|
74
|
+
default: "ssm-user",
|
|
75
|
+
description: "The user you want to run SCP over. Keep in mind not all users will have access to each other's home directory.",
|
|
76
76
|
}),
|
|
77
77
|
id: flags_1.SHARED_FLAGS.id,
|
|
78
78
|
sessionId: flags_1.SHARED_FLAGS.sessionId,
|
|
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
4
|
const apollo_1 = require("../../lib/apollo");
|
|
5
5
|
const cmd_1 = require("../../lib/cmd");
|
|
6
|
-
const
|
|
6
|
+
const flags_1 = require("../../lib/flags");
|
|
7
7
|
const resources_1 = require("../../lib/resources");
|
|
8
8
|
const sessions_1 = require("../../lib/sessions");
|
|
9
|
+
const ssh_1 = require("../../lib/ssh");
|
|
9
10
|
const start_1 = require("./start");
|
|
10
|
-
const flags_1 = require("../../lib/flags");
|
|
11
11
|
class StartSCPSession extends core_1.Command {
|
|
12
12
|
async run() {
|
|
13
13
|
(0, cmd_1.setMostRecentCommand)(this);
|
|
@@ -20,7 +20,7 @@ class StartSCPSession extends core_1.Command {
|
|
|
20
20
|
let instanceName = null;
|
|
21
21
|
const sessionId = flags.sessionId;
|
|
22
22
|
if (!instanceId) {
|
|
23
|
-
const selectedInstance = await (0, ssh_1.selectComputeInstance)(this,
|
|
23
|
+
const selectedInstance = await (0, ssh_1.selectComputeInstance)(this, "SCP into");
|
|
24
24
|
if (!selectedInstance) {
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
@@ -33,7 +33,7 @@ class StartSCPSession extends core_1.Command {
|
|
|
33
33
|
}
|
|
34
34
|
const metadata = session.metadata;
|
|
35
35
|
switch (metadata === null || metadata === void 0 ? void 0 : metadata.__typename) {
|
|
36
|
-
case
|
|
36
|
+
case "AwsIamFederatedSSMSession": {
|
|
37
37
|
const envVars = {
|
|
38
38
|
AWS_ACCESS_KEY_ID: metadata.awsAccessKeyId,
|
|
39
39
|
AWS_SECRET_ACCESS_KEY: metadata.awsSecretAccessKey,
|
|
@@ -41,7 +41,7 @@ class StartSCPSession extends core_1.Command {
|
|
|
41
41
|
};
|
|
42
42
|
// Run SCP script
|
|
43
43
|
const scpCmd = `$SCRIPT_PATH/../../scripts/ssh_ssm_scp_to_server.sh ${metadata.ec2InstanceId} ${flags.user} ${flags.src} ${metadata.ec2Region} ${flags.dest}`;
|
|
44
|
-
const outputMessage = `from "${flags.src}" locally to "${flags.dest}" on ${instanceName ? `"${instanceName}" instance` :
|
|
44
|
+
const outputMessage = `from "${flags.src}" locally to "${flags.dest}" on ${instanceName ? `"${instanceName}" instance` : "instance"}.`;
|
|
45
45
|
(0, cmd_1.runCommandSpawn)(scpCmd, `Copied ${outputMessage}`, `Failed to copy ${outputMessage}.`, envVars);
|
|
46
46
|
break;
|
|
47
47
|
}
|
|
@@ -50,29 +50,29 @@ class StartSCPSession extends core_1.Command {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
StartSCPSession.description =
|
|
53
|
+
StartSCPSession.description = "Use SCP to copy files to a compute instance.";
|
|
54
54
|
StartSCPSession.examples = [
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
"opal ssh:copyTo --src my/dir --dest instance/dir",
|
|
56
|
+
"opal ssh:copyTo --src my/dir --dest instance/dir --id 51f7176b-0464-4a6f-8369-e951e187b398",
|
|
57
57
|
];
|
|
58
58
|
StartSCPSession.flags = {
|
|
59
59
|
help: flags_1.SHARED_FLAGS.help,
|
|
60
60
|
src: core_1.Flags.string({
|
|
61
61
|
multiple: false,
|
|
62
62
|
required: true,
|
|
63
|
-
description:
|
|
63
|
+
description: "The directory or file you would like to copy over SCP. Note we only support one file or directory at a time.",
|
|
64
64
|
}),
|
|
65
65
|
dest: core_1.Flags.string({
|
|
66
66
|
multiple: false,
|
|
67
67
|
required: false,
|
|
68
|
-
default:
|
|
69
|
-
description:
|
|
68
|
+
default: ".",
|
|
69
|
+
description: "The directory you want your files to be copied to.",
|
|
70
70
|
}),
|
|
71
71
|
user: core_1.Flags.string({
|
|
72
72
|
multiple: false,
|
|
73
73
|
required: false,
|
|
74
|
-
default:
|
|
75
|
-
description:
|
|
74
|
+
default: "ssm-user",
|
|
75
|
+
description: "The user you want to run SCP over. Keep in mind not all users will have access to each other's home directory.",
|
|
76
76
|
}),
|
|
77
77
|
id: flags_1.SHARED_FLAGS.id,
|
|
78
78
|
sessionId: flags_1.SHARED_FLAGS.sessionId,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Command } from
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
2
|
export declare const Ec2SessionMetadataFragment = "\n... on AwsIamFederatedSSMSession {\n awsAccessKeyId\n awsSecretAccessKey\n awsSessionToken\n awsLoginUrl\n federatedArn\n ec2InstanceId\n ec2Region\n}";
|
|
3
3
|
export default class StartSSHSession extends Command {
|
|
4
4
|
static description: string;
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Ec2SessionMetadataFragment = void 0;
|
|
4
4
|
const core_1 = require("@oclif/core");
|
|
5
|
+
const get_1 = require("../../commands/resources/get");
|
|
5
6
|
const handler_1 = require("../../handler");
|
|
6
|
-
const cmd_1 = require("../../lib/cmd");
|
|
7
7
|
const apollo_1 = require("../../lib/apollo");
|
|
8
|
-
const ssh_1 = require("../../lib/ssh");
|
|
9
|
-
const get_1 = require("../../commands/resources/get");
|
|
10
8
|
const aws_1 = require("../../lib/aws");
|
|
9
|
+
const cmd_1 = require("../../lib/cmd");
|
|
10
|
+
const flags_1 = require("../../lib/flags");
|
|
11
11
|
const resources_1 = require("../../lib/resources");
|
|
12
12
|
const sessions_1 = require("../../lib/sessions");
|
|
13
|
-
const
|
|
13
|
+
const ssh_1 = require("../../lib/ssh");
|
|
14
14
|
exports.Ec2SessionMetadataFragment = `
|
|
15
15
|
... on AwsIamFederatedSSMSession {
|
|
16
16
|
awsAccessKeyId
|
|
@@ -26,7 +26,7 @@ class StartSSHSession extends core_1.Command {
|
|
|
26
26
|
(0, cmd_1.setMostRecentCommand)(this);
|
|
27
27
|
const { flags } = await this.parse(StartSSHSession);
|
|
28
28
|
if (flags.sessionId && flags.refresh) {
|
|
29
|
-
return (0, apollo_1.handleError)(this,
|
|
29
|
+
return (0, apollo_1.handleError)(this, "Cannot use both --sessionId and --refresh");
|
|
30
30
|
}
|
|
31
31
|
const pluginExists = await (0, ssh_1.assertSessionManagerPluginExists)();
|
|
32
32
|
if (!pluginExists) {
|
|
@@ -36,7 +36,7 @@ class StartSSHSession extends core_1.Command {
|
|
|
36
36
|
let instanceName = null;
|
|
37
37
|
const sessionId = flags.sessionId;
|
|
38
38
|
if (!instanceId) {
|
|
39
|
-
const selectedInstance = await (0, ssh_1.selectComputeInstance)(this,
|
|
39
|
+
const selectedInstance = await (0, ssh_1.selectComputeInstance)(this, "SSH into");
|
|
40
40
|
if (!selectedInstance) {
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
@@ -44,7 +44,7 @@ class StartSSHSession extends core_1.Command {
|
|
|
44
44
|
instanceName = selectedInstance.name;
|
|
45
45
|
}
|
|
46
46
|
else {
|
|
47
|
-
const { resp, error } = await (0, handler_1.
|
|
47
|
+
const { resp, error } = await (0, handler_1.runQueryDeprecated)({
|
|
48
48
|
command: this,
|
|
49
49
|
query: get_1.GetResourceDocument,
|
|
50
50
|
variables: {
|
|
@@ -57,8 +57,7 @@ class StartSSHSession extends core_1.Command {
|
|
|
57
57
|
if (!(resp === null || resp === void 0 ? void 0 : resp.data.resource.resource)) {
|
|
58
58
|
return (0, apollo_1.handleError)(this, `Resource not found for ID: ${instanceId}`);
|
|
59
59
|
}
|
|
60
|
-
instanceName =
|
|
61
|
-
(resp === null || resp === void 0 ? void 0 : resp.data.resource.resource.name) || 'ssh-instance';
|
|
60
|
+
instanceName = (resp === null || resp === void 0 ? void 0 : resp.data.resource.resource.name) || "ssh-instance";
|
|
62
61
|
}
|
|
63
62
|
const session = await (0, sessions_1.getOrCreateSession)(this, instanceId, resources_1.DEFAULT_ACCESS_LEVEL, sessionId, exports.Ec2SessionMetadataFragment, flags.refresh);
|
|
64
63
|
if (!session) {
|
|
@@ -66,15 +65,15 @@ class StartSSHSession extends core_1.Command {
|
|
|
66
65
|
}
|
|
67
66
|
const metadata = session.metadata;
|
|
68
67
|
switch (metadata === null || metadata === void 0 ? void 0 : metadata.__typename) {
|
|
69
|
-
case
|
|
70
|
-
this.log(`\n
|
|
68
|
+
case "AwsIamFederatedSSMSession": {
|
|
69
|
+
this.log(`\n🕰 Connecting to a session that expires in ${(0, sessions_1.getSessionExpirationMessage)(session)}.`);
|
|
71
70
|
const updateAwsConfigCommand = (0, aws_1.getAwsConfigUpdateCmd)(instanceName, metadata.awsAccessKeyId, metadata.awsSecretAccessKey, metadata.awsSessionToken);
|
|
72
71
|
const sessionCmd = `aws ssm start-session --target ${metadata.ec2InstanceId} --region ${metadata.ec2Region} --profile opal`;
|
|
73
72
|
// TODO: Unfortunately allowing SSH over SSM disables logging
|
|
74
73
|
// Run SSH script
|
|
75
74
|
// const sessionCmd = `../../scripts/ssh_ssm.sh ${metadata.ec2InstanceId} ${flags.user} ${metadata.ec2Region}`
|
|
76
75
|
const startSessionCmd = `${updateAwsConfigCommand} && ${sessionCmd}`;
|
|
77
|
-
(0, cmd_1.startInteractiveShell)(startSessionCmd, `shell into ${instanceName ? `"${instanceName}" instance` :
|
|
76
|
+
(0, cmd_1.startInteractiveShell)(startSessionCmd, `shell into ${instanceName ? `"${instanceName}" instance` : "instance"}`);
|
|
78
77
|
break;
|
|
79
78
|
}
|
|
80
79
|
default:
|
|
@@ -82,10 +81,10 @@ class StartSSHSession extends core_1.Command {
|
|
|
82
81
|
}
|
|
83
82
|
}
|
|
84
83
|
}
|
|
85
|
-
StartSSHSession.description =
|
|
84
|
+
StartSSHSession.description = "Starts an SSH session to access a compute instance.";
|
|
86
85
|
StartSSHSession.examples = [
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
"opal ssh:start",
|
|
87
|
+
"opal ssh:start --id 51f7176b-0464-4a6f-8369-e951e187b398",
|
|
89
88
|
];
|
|
90
89
|
StartSSHSession.flags = {
|
|
91
90
|
help: flags_1.SHARED_FLAGS.help,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DocumentTypeDecoration, ResultOf, TypedDocumentNode } from "@graphql-typed-document-node/core";
|
|
2
|
+
import type { Incremental } from "./graphql";
|
|
3
|
+
export type FragmentType<TDocumentType extends DocumentTypeDecoration<any, any>> = TDocumentType extends DocumentTypeDecoration<infer TType, any> ? [TType] extends [{
|
|
4
|
+
" $fragmentName"?: infer TKey;
|
|
5
|
+
}] ? TKey extends string ? {
|
|
6
|
+
" $fragmentRefs"?: {
|
|
7
|
+
[key in TKey]: TType;
|
|
8
|
+
};
|
|
9
|
+
} : never : never : never;
|
|
10
|
+
export declare function useFragment<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>): TType;
|
|
11
|
+
export declare function useFragment<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined): TType | undefined;
|
|
12
|
+
export declare function useFragment<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null): TType | null;
|
|
13
|
+
export declare function useFragment<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined): TType | null | undefined;
|
|
14
|
+
export declare function useFragment<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: Array<FragmentType<DocumentTypeDecoration<TType, any>>>): Array<TType>;
|
|
15
|
+
export declare function useFragment<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: Array<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined): Array<TType> | null | undefined;
|
|
16
|
+
export declare function useFragment<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>): ReadonlyArray<TType>;
|
|
17
|
+
export declare function useFragment<TType>(_documentNode: DocumentTypeDecoration<TType, any>, fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined): ReadonlyArray<TType> | null | undefined;
|
|
18
|
+
export declare function makeFragmentData<F extends DocumentTypeDecoration<any, any>, FT extends ResultOf<F>>(data: FT, _fragment: F): FragmentType<F>;
|
|
19
|
+
export declare function isFragmentReady<TQuery, TFrag>(queryNode: DocumentTypeDecoration<TQuery, any>, fragmentNode: TypedDocumentNode<TFrag>, data: FragmentType<TypedDocumentNode<Incremental<TFrag>, any>> | null | undefined): data is FragmentType<typeof fragmentNode>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useFragment = useFragment;
|
|
4
|
+
exports.makeFragmentData = makeFragmentData;
|
|
5
|
+
exports.isFragmentReady = isFragmentReady;
|
|
6
|
+
function useFragment(_documentNode, fragmentType) {
|
|
7
|
+
return fragmentType;
|
|
8
|
+
}
|
|
9
|
+
function makeFragmentData(data, _fragment) {
|
|
10
|
+
return data;
|
|
11
|
+
}
|
|
12
|
+
function isFragmentReady(queryNode, fragmentNode, data) {
|
|
13
|
+
var _a, _b;
|
|
14
|
+
const deferredFields = (_a = queryNode.__meta__) === null || _a === void 0 ? void 0 : _a.deferredFields;
|
|
15
|
+
if (!deferredFields)
|
|
16
|
+
return true;
|
|
17
|
+
const fragDef = fragmentNode.definitions[0];
|
|
18
|
+
const fragName = (_b = fragDef === null || fragDef === void 0 ? void 0 : fragDef.name) === null || _b === void 0 ? void 0 : _b.value;
|
|
19
|
+
const fields = (fragName && deferredFields[fragName]) || [];
|
|
20
|
+
return fields.length > 0 && fields.every((field) => data && field in data);
|
|
21
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { TypedDocumentNode as DocumentNode } from "@graphql-typed-document-node/core";
|
|
2
|
+
import * as types from "./graphql";
|
|
3
|
+
/**
|
|
4
|
+
* Map of all GraphQL operations in the project.
|
|
5
|
+
*
|
|
6
|
+
* This map has several performance disadvantages:
|
|
7
|
+
* 1. It is not tree-shakeable, so it will include all operations in the project.
|
|
8
|
+
* 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle.
|
|
9
|
+
* 3. It does not support dead code elimination, so it will add unused operations.
|
|
10
|
+
*
|
|
11
|
+
* Therefore it is highly recommended to use the babel or swc plugin for production.
|
|
12
|
+
* Learn more about it here: https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#reducing-bundle-size
|
|
13
|
+
*/
|
|
14
|
+
type Documents = {
|
|
15
|
+
"\nquery CheckAuthSessionQuery {\n organizationSettings {\n ... on OrganizationSettingsResult {\n settings {\n id\n }\n }\n }\n}\n": typeof types.CheckAuthSessionQueryDocument;
|
|
16
|
+
'\n query GetRequestableAppsQuery($searchQuery: String) {\n appsV2(\n filters: {\n access: REQUESTABLE\n searchQuery: $searchQuery\n }\n ) @connection(key: "paginated-app-dropdown") {\n edges {\n node {\n id\n displayName\n ... on Connection {\n connectionType\n }\n ... on Resource {\n resourceType\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n ': typeof types.GetRequestableAppsQueryDocument;
|
|
17
|
+
"\n query PaginatedEntityDropdown(\n $id: UUID!\n $searchQuery: String\n) {\n app(id: $id) {\n __typename\n ... on App {\n id\n items(\n input: {\n access: REQUESTABLE\n searchQuery: $searchQuery\n includeOnlyRequestable: true\n }\n ) {\n items {\n key\n resource {\n id\n name\n }\n group {\n id\n name\n }\n }\n cursor\n }\n }\n }\n}\n": typeof types.PaginatedEntityDropdownDocument;
|
|
18
|
+
};
|
|
19
|
+
declare const documents: Documents;
|
|
20
|
+
/**
|
|
21
|
+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
22
|
+
*
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* const query = graphql(`query GetUser($id: ID!) { user(id: $id) { name } }`);
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* The query argument is unknown!
|
|
30
|
+
* Please regenerate the types.
|
|
31
|
+
*/
|
|
32
|
+
export declare function graphql(source: string): unknown;
|
|
33
|
+
/**
|
|
34
|
+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
35
|
+
*/
|
|
36
|
+
export declare function graphql(source: "\nquery CheckAuthSessionQuery {\n organizationSettings {\n ... on OrganizationSettingsResult {\n settings {\n id\n }\n }\n }\n}\n"): (typeof documents)["\nquery CheckAuthSessionQuery {\n organizationSettings {\n ... on OrganizationSettingsResult {\n settings {\n id\n }\n }\n }\n}\n"];
|
|
37
|
+
/**
|
|
38
|
+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
39
|
+
*/
|
|
40
|
+
export declare function graphql(source: '\n query GetRequestableAppsQuery($searchQuery: String) {\n appsV2(\n filters: {\n access: REQUESTABLE\n searchQuery: $searchQuery\n }\n ) @connection(key: "paginated-app-dropdown") {\n edges {\n node {\n id\n displayName\n ... on Connection {\n connectionType\n }\n ... on Resource {\n resourceType\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n '): (typeof documents)['\n query GetRequestableAppsQuery($searchQuery: String) {\n appsV2(\n filters: {\n access: REQUESTABLE\n searchQuery: $searchQuery\n }\n ) @connection(key: "paginated-app-dropdown") {\n edges {\n node {\n id\n displayName\n ... on Connection {\n connectionType\n }\n ... on Resource {\n resourceType\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n '];
|
|
41
|
+
/**
|
|
42
|
+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
|
43
|
+
*/
|
|
44
|
+
export declare function graphql(source: "\n query PaginatedEntityDropdown(\n $id: UUID!\n $searchQuery: String\n) {\n app(id: $id) {\n __typename\n ... on App {\n id\n items(\n input: {\n access: REQUESTABLE\n searchQuery: $searchQuery\n includeOnlyRequestable: true\n }\n ) {\n items {\n key\n resource {\n id\n name\n }\n group {\n id\n name\n }\n }\n cursor\n }\n }\n }\n}\n"): (typeof documents)["\n query PaginatedEntityDropdown(\n $id: UUID!\n $searchQuery: String\n) {\n app(id: $id) {\n __typename\n ... on App {\n id\n items(\n input: {\n access: REQUESTABLE\n searchQuery: $searchQuery\n includeOnlyRequestable: true\n }\n ) {\n items {\n key\n resource {\n id\n name\n }\n group {\n id\n name\n }\n }\n cursor\n }\n }\n }\n}\n"];
|
|
45
|
+
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode<infer TType, any> ? TType : never;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.graphql = graphql;
|
|
4
|
+
/* eslint-disable */
|
|
5
|
+
const types = require("./graphql");
|
|
6
|
+
const documents = {
|
|
7
|
+
"\nquery CheckAuthSessionQuery {\n organizationSettings {\n ... on OrganizationSettingsResult {\n settings {\n id\n }\n }\n }\n}\n": types.CheckAuthSessionQueryDocument,
|
|
8
|
+
'\n query GetRequestableAppsQuery($searchQuery: String) {\n appsV2(\n filters: {\n access: REQUESTABLE\n searchQuery: $searchQuery\n }\n ) @connection(key: "paginated-app-dropdown") {\n edges {\n node {\n id\n displayName\n ... on Connection {\n connectionType\n }\n ... on Resource {\n resourceType\n }\n }\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n ': types.GetRequestableAppsQueryDocument,
|
|
9
|
+
"\n query PaginatedEntityDropdown(\n $id: UUID!\n $searchQuery: String\n) {\n app(id: $id) {\n __typename\n ... on App {\n id\n items(\n input: {\n access: REQUESTABLE\n searchQuery: $searchQuery\n includeOnlyRequestable: true\n }\n ) {\n items {\n key\n resource {\n id\n name\n }\n group {\n id\n name\n }\n }\n cursor\n }\n }\n }\n}\n": types.PaginatedEntityDropdownDocument,
|
|
10
|
+
};
|
|
11
|
+
function graphql(source) {
|
|
12
|
+
var _a;
|
|
13
|
+
return (_a = documents[source]) !== null && _a !== void 0 ? _a : {};
|
|
14
|
+
}
|