clever-tools 3.12.0 → 3.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/clever.js +280 -6
- package/package.json +1 -1
- package/src/clever-client/auth-bridge.js +1 -1
- package/src/clever-client/operators.js +121 -0
- package/src/commands/addon.js +12 -7
- package/src/commands/cancel-deploy.js +3 -4
- package/src/commands/config.js +16 -20
- package/src/commands/console.js +4 -10
- package/src/commands/create.js +76 -9
- package/src/commands/delete.js +11 -10
- package/src/commands/deploy.js +35 -21
- package/src/commands/emails.js +174 -0
- package/src/commands/keycloak.js +138 -0
- package/src/commands/link.js +3 -1
- package/src/commands/makeDefault.js +2 -1
- package/src/commands/matomo.js +85 -0
- package/src/commands/metabase.js +112 -0
- package/src/commands/open.js +2 -5
- package/src/commands/otoroshi.js +138 -0
- package/src/commands/profile.js +2 -4
- package/src/commands/restart.js +1 -1
- package/src/commands/ssh-keys.js +159 -0
- package/src/commands/stop.js +1 -1
- package/src/commands/tcp-redirs.js +3 -3
- package/src/commands/tokens.js +16 -7
- package/src/commands/unlink.js +2 -1
- package/src/experimental-features.js +16 -15
- package/src/lib/operator-commands.js +281 -0
- package/src/lib/prompts.js +30 -0
- package/src/lib/slugify.js +10 -0
- package/src/models/addon.js +5 -2
- package/src/models/app_configuration.js +12 -9
- package/src/models/application.js +24 -12
- package/src/models/application_configuration.js +72 -72
- package/src/models/git.js +29 -1
- package/src/models/ids-resolver.js +37 -1
- package/src/models/interact.js +0 -24
- package/src/models/log-v4.js +13 -4
- package/src/models/operator.js +48 -0
- package/src/models/utils.js +21 -0
- package/src/parsers.js +14 -0
- package/src/prompt-password.js +0 -10
package/bin/clever.js
CHANGED
|
@@ -36,24 +36,30 @@ import * as deploy from '../src/commands/deploy.js';
|
|
|
36
36
|
import * as diag from '../src/commands/diag.js';
|
|
37
37
|
import * as domain from '../src/commands/domain.js';
|
|
38
38
|
import * as drain from '../src/commands/drain.js';
|
|
39
|
+
import * as emails from '../src/commands/emails.js';
|
|
39
40
|
import * as env from '../src/commands/env.js';
|
|
40
41
|
import * as features from '../src/commands/features.js';
|
|
42
|
+
import * as keycloak from '../src/commands/keycloak.js';
|
|
41
43
|
import * as kv from '../src/commands/kv.js';
|
|
42
44
|
import * as link from '../src/commands/link.js';
|
|
43
45
|
import * as login from '../src/commands/login.js';
|
|
44
46
|
import * as logout from '../src/commands/logout.js';
|
|
45
47
|
import * as logs from '../src/commands/logs.js';
|
|
48
|
+
import * as matomo from '../src/commands/matomo.js';
|
|
49
|
+
import * as metabase from '../src/commands/metabase.js';
|
|
46
50
|
import * as makeDefault from '../src/commands/makeDefault.js';
|
|
47
51
|
import * as ng from '../src/commands/ng.js';
|
|
48
52
|
import * as notifyEmail from '../src/commands/notify-email.js';
|
|
49
53
|
import * as open from '../src/commands/open.js';
|
|
50
54
|
import * as consoleModule from '../src/commands/console.js';
|
|
55
|
+
import * as otoroshi from '../src/commands/otoroshi.js';
|
|
51
56
|
import * as profile from '../src/commands/profile.js';
|
|
52
57
|
import * as publishedConfig from '../src/commands/published-config.js';
|
|
53
58
|
import * as restart from '../src/commands/restart.js';
|
|
54
59
|
import * as scale from '../src/commands/scale.js';
|
|
55
60
|
import * as service from '../src/commands/service.js';
|
|
56
61
|
import * as ssh from '../src/commands/ssh.js';
|
|
62
|
+
import * as sshKeys from '../src/commands/ssh-keys.js';
|
|
57
63
|
import * as status from '../src/commands/status.js';
|
|
58
64
|
import * as stop from '../src/commands/stop.js';
|
|
59
65
|
import * as tcpRedirs from '../src/commands/tcp-redirs.js';
|
|
@@ -129,6 +135,12 @@ async function run () {
|
|
|
129
135
|
metavar: 'public_key',
|
|
130
136
|
description: 'Wireguard public key of the external peer to link to a Network Group',
|
|
131
137
|
}),
|
|
138
|
+
email: cliparse.argument('email', {
|
|
139
|
+
description: 'Email address',
|
|
140
|
+
parser: Parsers.email,
|
|
141
|
+
}),
|
|
142
|
+
sshKeyName: cliparse.argument('ssh-key-name', { description: 'SSH key name' }),
|
|
143
|
+
sshKeyPath: cliparse.argument('ssh-key-path', { description: 'SSH public key path (.pub)' }),
|
|
132
144
|
addonIdOrName: cliparse.argument('addon-id', {
|
|
133
145
|
description: 'Add-on ID (or name, if unambiguous)',
|
|
134
146
|
parser: Parsers.addonIdOrName,
|
|
@@ -172,7 +184,7 @@ async function run () {
|
|
|
172
184
|
parser: Parsers.integer,
|
|
173
185
|
}),
|
|
174
186
|
configurationName: cliparse.argument('configuration-name', {
|
|
175
|
-
description:
|
|
187
|
+
description: `Configuration to manage: ${ApplicationConfiguration.listAvailableIds(true)}`,
|
|
176
188
|
complete () {
|
|
177
189
|
return cliparse.autocomplete.words(ApplicationConfiguration.listAvailableIds());
|
|
178
190
|
},
|
|
@@ -182,6 +194,10 @@ async function run () {
|
|
|
182
194
|
|
|
183
195
|
// OPTIONS
|
|
184
196
|
const opts = {
|
|
197
|
+
targetVersion: cliparse.option('target', {
|
|
198
|
+
metavar: 'version',
|
|
199
|
+
description: 'Target version to upgrade to (e.g.: 24, 2.4, 2.4.1)',
|
|
200
|
+
}),
|
|
185
201
|
apiTokenExpiration: cliparse.option('expiration', {
|
|
186
202
|
aliases: ['e'],
|
|
187
203
|
metavar: 'expiration',
|
|
@@ -508,10 +524,18 @@ async function run () {
|
|
|
508
524
|
aliases: ['y'],
|
|
509
525
|
description: 'Skip confirmation and delete the application directly',
|
|
510
526
|
}),
|
|
527
|
+
confirmSshKeyClean: cliparse.flag('yes', {
|
|
528
|
+
aliases: ['y'],
|
|
529
|
+
description: 'Skip confirmation and remove all SSH keys directly',
|
|
530
|
+
}),
|
|
511
531
|
confirmTcpRedirCreation: cliparse.flag('yes', {
|
|
512
532
|
aliases: ['y'],
|
|
513
533
|
description: 'Skip confirmation even if the TCP redirection is not free',
|
|
514
534
|
}),
|
|
535
|
+
yes: cliparse.flag('yes', {
|
|
536
|
+
aliases: ['y'],
|
|
537
|
+
description: 'Skip confirmation',
|
|
538
|
+
}),
|
|
515
539
|
jsonFormat: cliparse.flag('json', { aliases: ['j'], description: 'Show result in JSON format' }),
|
|
516
540
|
humanJsonOutputFormat: getOutputFormatOption(),
|
|
517
541
|
tag: cliparse.option('tag', {
|
|
@@ -632,7 +656,7 @@ async function run () {
|
|
|
632
656
|
description: 'Display or edit the configuration of your application',
|
|
633
657
|
options: [opts.alias, opts.appIdOrName],
|
|
634
658
|
commands: [configGetCommand, configSetCommand, configUpdateCommand],
|
|
635
|
-
}, config.
|
|
659
|
+
}, config.list);
|
|
636
660
|
|
|
637
661
|
// CREATE COMMAND
|
|
638
662
|
const appCreateCommand = cliparse.command('create', {
|
|
@@ -728,6 +752,32 @@ async function run () {
|
|
|
728
752
|
commands: [drainCreateCommand, drainRemoveCommand, drainEnableCommand, drainDisableCommand],
|
|
729
753
|
}, drain.list);
|
|
730
754
|
|
|
755
|
+
// EMAILS COMMANDS
|
|
756
|
+
const emailsAddCommand = cliparse.command('add', {
|
|
757
|
+
description: 'Add a new secondary email address to the current user',
|
|
758
|
+
args: [args.email],
|
|
759
|
+
}, emails.addSecondary);
|
|
760
|
+
const emailsPrimaryCommand = cliparse.command('primary', {
|
|
761
|
+
description: 'Set the primary email address of the current user',
|
|
762
|
+
args: [args.email],
|
|
763
|
+
}, emails.setPrimary);
|
|
764
|
+
const emailsRemoveCommand = cliparse.command('remove', {
|
|
765
|
+
description: 'Remove a secondary email address from the current user',
|
|
766
|
+
args: [args.email],
|
|
767
|
+
}, emails.removeSecondary);
|
|
768
|
+
const emailsClearCommand = cliparse.command('remove-all', {
|
|
769
|
+
description: 'Remove all secondary email addresses from the current user',
|
|
770
|
+
options: [opts.yes],
|
|
771
|
+
}, emails.removeAllSecondary);
|
|
772
|
+
const emailsOpenConsoleCommand = cliparse.command('open', {
|
|
773
|
+
description: 'Open the email addresses management page in the Console',
|
|
774
|
+
}, emails.openConsole);
|
|
775
|
+
const emailsCommands = cliparse.command('emails', {
|
|
776
|
+
description: 'Manage email addresses of the current user',
|
|
777
|
+
privateOptions: [opts.humanJsonOutputFormat],
|
|
778
|
+
commands: [emailsAddCommand, emailsPrimaryCommand, emailsRemoveCommand, emailsClearCommand, emailsOpenConsoleCommand],
|
|
779
|
+
}, emails.list);
|
|
780
|
+
|
|
731
781
|
// ENV COMMANDS
|
|
732
782
|
const envSetCommand = cliparse.command('set', {
|
|
733
783
|
description: 'Add or update an environment variable named <variable-name> with the value <variable-value>',
|
|
@@ -774,6 +824,63 @@ async function run () {
|
|
|
774
824
|
commands: [enableFeatureCommand, disableFeatureCommand, listFeaturesCommand, infoFeaturesCommand],
|
|
775
825
|
}, features.list);
|
|
776
826
|
|
|
827
|
+
// KEYCLOAK COMMAND
|
|
828
|
+
const keycloakGetCommand = cliparse.command('get', {
|
|
829
|
+
description: 'Get information about a deployed Keycloak',
|
|
830
|
+
args: [args.addonIdOrName],
|
|
831
|
+
options: [opts.humanJsonOutputFormat],
|
|
832
|
+
}, keycloak.get);
|
|
833
|
+
const keycloakEnableNgCommand = cliparse.command('enable-ng', {
|
|
834
|
+
description: 'Link Keycloak to a Network Group, used for multi-instances secure communication',
|
|
835
|
+
args: [args.addonIdOrName],
|
|
836
|
+
}, keycloak.ngEnable);
|
|
837
|
+
const keycloakDisableNgCommand = cliparse.command('disable-ng', {
|
|
838
|
+
description: 'Unlink Keycloak from its Network Group',
|
|
839
|
+
args: [args.addonIdOrName],
|
|
840
|
+
}, keycloak.ngDisable);
|
|
841
|
+
const keycloakOpenLogsCommand = cliparse.command('logs', {
|
|
842
|
+
description: 'Open the Keycloak application logs in Clever Cloud Console',
|
|
843
|
+
args: [args.addonIdOrName],
|
|
844
|
+
}, keycloak.openLogs);
|
|
845
|
+
const keycloakOpenWebUiCommand = cliparse.command('webui', {
|
|
846
|
+
description: 'Open the Keycloak admin console in your browser',
|
|
847
|
+
args: [args.addonIdOrName],
|
|
848
|
+
}, keycloak.openWebUi);
|
|
849
|
+
const keycloakOpenCommand = cliparse.command('open', {
|
|
850
|
+
description: 'Open the Keycloak dashboard in Clever Cloud Console',
|
|
851
|
+
args: [args.addonIdOrName],
|
|
852
|
+
commands: [keycloakOpenLogsCommand, keycloakOpenWebUiCommand],
|
|
853
|
+
}, keycloak.open);
|
|
854
|
+
const keycloakRestartCommand = cliparse.command('restart', {
|
|
855
|
+
description: 'Restart Keycloak',
|
|
856
|
+
args: [args.addonIdOrName],
|
|
857
|
+
}, keycloak.reboot);
|
|
858
|
+
const keycloakRebuildCommand = cliparse.command('rebuild', {
|
|
859
|
+
description: 'Rebuild Keycloak',
|
|
860
|
+
args: [args.addonIdOrName],
|
|
861
|
+
}, keycloak.rebuild);
|
|
862
|
+
const keycloakVersionCheckCommand = cliparse.command('check', {
|
|
863
|
+
description: 'Check Keycloak deployed version',
|
|
864
|
+
args: [args.addonIdOrName],
|
|
865
|
+
options: [opts.humanJsonOutputFormat],
|
|
866
|
+
}, keycloak.checkVersion);
|
|
867
|
+
const keycloakVersionUpdateCommand = cliparse.command('update', {
|
|
868
|
+
description: 'Update Keycloak deployed version',
|
|
869
|
+
args: [args.addonIdOrName],
|
|
870
|
+
options: [opts.targetVersion],
|
|
871
|
+
}, keycloak.updateVersion);
|
|
872
|
+
const keycloakVersionsCommands = cliparse.command('version', {
|
|
873
|
+
description: 'Check Keycloak deployed version',
|
|
874
|
+
args: [args.addonIdOrName],
|
|
875
|
+
options: [opts.humanJsonOutputFormat],
|
|
876
|
+
commands: [keycloakVersionCheckCommand, keycloakVersionUpdateCommand],
|
|
877
|
+
}, keycloak.checkVersion);
|
|
878
|
+
const keycloakCommand = cliparse.command('keycloak', {
|
|
879
|
+
description: 'Manage Clever Cloud Keycloak services',
|
|
880
|
+
privateOptions: [opts.humanJsonOutputFormat],
|
|
881
|
+
commands: [keycloakGetCommand, keycloakEnableNgCommand, keycloakDisableNgCommand, keycloakOpenCommand, keycloakRestartCommand, keycloakRebuildCommand, keycloakVersionsCommands],
|
|
882
|
+
}, keycloak.list);
|
|
883
|
+
|
|
777
884
|
// KV COMMAND
|
|
778
885
|
const kvRawCommand = cliparse.command('kv', {
|
|
779
886
|
description: 'Send a raw command to a Materia KV or Redis® add-on',
|
|
@@ -811,6 +918,88 @@ async function run () {
|
|
|
811
918
|
args: [args.alias],
|
|
812
919
|
}, makeDefault.makeDefault);
|
|
813
920
|
|
|
921
|
+
// MATOMO COMMAND
|
|
922
|
+
const matomoGetCommand = cliparse.command('get', {
|
|
923
|
+
description: 'Get information about a deployed Matomo',
|
|
924
|
+
args: [args.addonIdOrName],
|
|
925
|
+
options: [opts.humanJsonOutputFormat],
|
|
926
|
+
}, matomo.get);
|
|
927
|
+
const matomoOpenLogsCommand = cliparse.command('logs', {
|
|
928
|
+
description: 'Open the Matomo application logs in Clever Cloud Console',
|
|
929
|
+
args: [args.addonIdOrName],
|
|
930
|
+
}, matomo.openLogs);
|
|
931
|
+
const matomoOpenWebUiCommand = cliparse.command('webui', {
|
|
932
|
+
description: 'Open the Matomo admin console in your browser',
|
|
933
|
+
args: [args.addonIdOrName],
|
|
934
|
+
}, matomo.openWebUi);
|
|
935
|
+
const matomoOpenCommand = cliparse.command('open', {
|
|
936
|
+
description: 'Open the Matomo dashboard in Clever Cloud Console',
|
|
937
|
+
args: [args.addonIdOrName],
|
|
938
|
+
commands: [matomoOpenLogsCommand, matomoOpenWebUiCommand],
|
|
939
|
+
}, matomo.open);
|
|
940
|
+
const matomoRestartCommand = cliparse.command('restart', {
|
|
941
|
+
description: 'Restart Matomo',
|
|
942
|
+
args: [args.addonIdOrName],
|
|
943
|
+
}, matomo.reboot);
|
|
944
|
+
const matomoRebuildCommand = cliparse.command('rebuild', {
|
|
945
|
+
description: 'Rebuild Matomo',
|
|
946
|
+
args: [args.addonIdOrName],
|
|
947
|
+
}, matomo.rebuild);
|
|
948
|
+
const matomoCommand = cliparse.command('matomo', {
|
|
949
|
+
description: 'Manage Clever Cloud Matomo services',
|
|
950
|
+
privateOptions: [opts.humanJsonOutputFormat],
|
|
951
|
+
commands: [matomoGetCommand, matomoOpenCommand, matomoRestartCommand, matomoRebuildCommand],
|
|
952
|
+
}, matomo.list);
|
|
953
|
+
|
|
954
|
+
// METABASE COMMAND
|
|
955
|
+
const metabaseGetCommand = cliparse.command('get', {
|
|
956
|
+
description: 'Get information about a deployed Metabase',
|
|
957
|
+
args: [args.addonIdOrName],
|
|
958
|
+
options: [opts.humanJsonOutputFormat],
|
|
959
|
+
}, metabase.get);
|
|
960
|
+
const metabaseOpenLogsCommand = cliparse.command('logs', {
|
|
961
|
+
description: 'Open the Metabase application logs in Clever Cloud Console',
|
|
962
|
+
args: [args.addonIdOrName],
|
|
963
|
+
}, metabase.openLogs);
|
|
964
|
+
const metabaseOpenWebUiCommand = cliparse.command('webui', {
|
|
965
|
+
description: 'Open the Metabase admin console in your browser',
|
|
966
|
+
args: [args.addonIdOrName],
|
|
967
|
+
}, metabase.openWebUi);
|
|
968
|
+
const metabaseOpenCommand = cliparse.command('open', {
|
|
969
|
+
description: 'Open the Metabase dashboard in Clever Cloud Console',
|
|
970
|
+
args: [args.addonIdOrName],
|
|
971
|
+
commands: [metabaseOpenLogsCommand, metabaseOpenWebUiCommand],
|
|
972
|
+
}, metabase.open);
|
|
973
|
+
const metabaseRestartCommand = cliparse.command('restart', {
|
|
974
|
+
description: 'Restart Metabase',
|
|
975
|
+
args: [args.addonIdOrName],
|
|
976
|
+
}, metabase.reboot);
|
|
977
|
+
const metabaseRebuildCommand = cliparse.command('rebuild', {
|
|
978
|
+
description: 'Rebuild Metabase',
|
|
979
|
+
args: [args.addonIdOrName],
|
|
980
|
+
}, metabase.rebuild);
|
|
981
|
+
const metabaseVersionCheckCommand = cliparse.command('check', {
|
|
982
|
+
description: 'Check Metabase deployed version',
|
|
983
|
+
args: [args.addonIdOrName],
|
|
984
|
+
options: [opts.humanJsonOutputFormat],
|
|
985
|
+
}, metabase.checkVersion);
|
|
986
|
+
const metabaseVersionUpdateCommand = cliparse.command('update', {
|
|
987
|
+
description: 'Update Metabase deployed version',
|
|
988
|
+
args: [args.addonIdOrName],
|
|
989
|
+
options: [opts.targetVersion],
|
|
990
|
+
}, metabase.updateVersion);
|
|
991
|
+
const metabaseVersionsCommands = cliparse.command('version', {
|
|
992
|
+
description: 'Manage Metabase deployed version',
|
|
993
|
+
args: [args.addonIdOrName],
|
|
994
|
+
options: [opts.humanJsonOutputFormat],
|
|
995
|
+
commands: [metabaseVersionCheckCommand, metabaseVersionUpdateCommand],
|
|
996
|
+
}, metabase.checkVersion);
|
|
997
|
+
const metabaseCommand = cliparse.command('metabase', {
|
|
998
|
+
description: 'Manage Clever Cloud Metabase services',
|
|
999
|
+
privateOptions: [opts.humanJsonOutputFormat],
|
|
1000
|
+
commands: [metabaseGetCommand, metabaseOpenCommand, metabaseRestartCommand, metabaseRebuildCommand, metabaseVersionsCommands],
|
|
1001
|
+
}, metabase.list);
|
|
1002
|
+
|
|
814
1003
|
// NETWORK GROUP COMMANDS
|
|
815
1004
|
const ngCreateExternalPeerCommand = cliparse.command('external', {
|
|
816
1005
|
description: 'Create an external peer in a Network Group',
|
|
@@ -884,6 +1073,63 @@ async function run () {
|
|
|
884
1073
|
options: [opts.alias, opts.appIdOrName],
|
|
885
1074
|
}, open.open);
|
|
886
1075
|
|
|
1076
|
+
// OTOROSHI COMMAND
|
|
1077
|
+
const otoroshiGetCommand = cliparse.command('get', {
|
|
1078
|
+
description: 'Get information about a deployed Otoroshi',
|
|
1079
|
+
args: [args.addonIdOrName],
|
|
1080
|
+
options: [opts.humanJsonOutputFormat],
|
|
1081
|
+
}, otoroshi.get);
|
|
1082
|
+
const otoroshiEnableNgCommand = cliparse.command('enable-ng', {
|
|
1083
|
+
description: 'Link Otoroshi to a Network Group',
|
|
1084
|
+
args: [args.addonIdOrName],
|
|
1085
|
+
}, otoroshi.ngEnable);
|
|
1086
|
+
const otoroshiDisableNgCommand = cliparse.command('disable-ng', {
|
|
1087
|
+
description: 'Unlink Otoroshi from its Network Group',
|
|
1088
|
+
args: [args.addonIdOrName],
|
|
1089
|
+
}, otoroshi.ngDisable);
|
|
1090
|
+
const otoroshiOpenLogsCommand = cliparse.command('logs', {
|
|
1091
|
+
description: 'Open the Otoroshi application logs in Clever Cloud Console',
|
|
1092
|
+
args: [args.addonIdOrName],
|
|
1093
|
+
}, otoroshi.openLogs);
|
|
1094
|
+
const otoroshiOpenWebUiCommand = cliparse.command('webui', {
|
|
1095
|
+
description: 'Open the Otoroshi admin console in your browser',
|
|
1096
|
+
args: [args.addonIdOrName],
|
|
1097
|
+
}, otoroshi.openWebUi);
|
|
1098
|
+
const otoroshiOpenCommand = cliparse.command('open', {
|
|
1099
|
+
description: 'Open the Otoroshi dashboard in Clever Cloud Console',
|
|
1100
|
+
args: [args.addonIdOrName],
|
|
1101
|
+
commands: [otoroshiOpenLogsCommand, otoroshiOpenWebUiCommand],
|
|
1102
|
+
}, otoroshi.open);
|
|
1103
|
+
const otoroshiRestartCommand = cliparse.command('restart', {
|
|
1104
|
+
description: 'Restart Otoroshi',
|
|
1105
|
+
args: [args.addonIdOrName],
|
|
1106
|
+
}, otoroshi.reboot);
|
|
1107
|
+
const otoroshiRebuildCommand = cliparse.command('rebuild', {
|
|
1108
|
+
description: 'Rebuild Otoroshi',
|
|
1109
|
+
args: [args.addonIdOrName],
|
|
1110
|
+
}, otoroshi.rebuild);
|
|
1111
|
+
const otoroshiVersionCheckCommand = cliparse.command('check', {
|
|
1112
|
+
description: 'Check Otoroshi deployed version',
|
|
1113
|
+
args: [args.addonIdOrName],
|
|
1114
|
+
options: [opts.humanJsonOutputFormat],
|
|
1115
|
+
}, otoroshi.checkVersion);
|
|
1116
|
+
const otoroshiVersionUpdateCommand = cliparse.command('update', {
|
|
1117
|
+
description: 'Update Otoroshi deployed version',
|
|
1118
|
+
args: [args.addonIdOrName],
|
|
1119
|
+
options: [opts.targetVersion],
|
|
1120
|
+
}, otoroshi.updateVersion);
|
|
1121
|
+
const otoroshiVersionsCommands = cliparse.command('version', {
|
|
1122
|
+
description: 'Manage Otoroshi deployed version',
|
|
1123
|
+
args: [args.addonIdOrName],
|
|
1124
|
+
options: [opts.humanJsonOutputFormat],
|
|
1125
|
+
commands: [otoroshiVersionCheckCommand, otoroshiVersionUpdateCommand],
|
|
1126
|
+
}, otoroshi.checkVersion);
|
|
1127
|
+
const otoroshiCommand = cliparse.command('otoroshi', {
|
|
1128
|
+
description: 'Manage Clever Cloud Otoroshi services',
|
|
1129
|
+
privateOptions: [opts.humanJsonOutputFormat],
|
|
1130
|
+
commands: [otoroshiGetCommand, otoroshiEnableNgCommand, otoroshiDisableNgCommand, otoroshiOpenCommand, otoroshiRestartCommand, otoroshiRebuildCommand, otoroshiVersionsCommands],
|
|
1131
|
+
}, otoroshi.list);
|
|
1132
|
+
|
|
887
1133
|
// CONSOLE COMMAND
|
|
888
1134
|
const consoleCommand = cliparse.command('console', {
|
|
889
1135
|
description: 'Open an application in the Console',
|
|
@@ -962,6 +1208,28 @@ async function run () {
|
|
|
962
1208
|
options: [opts.alias, opts.appIdOrName, opts.sshIdentityFile],
|
|
963
1209
|
}, ssh.ssh);
|
|
964
1210
|
|
|
1211
|
+
// SSH KEYS COMMANDS
|
|
1212
|
+
const sshKeysAddCommand = cliparse.command('add', {
|
|
1213
|
+
description: 'Add a new SSH key to the current user',
|
|
1214
|
+
args: [args.sshKeyName, args.sshKeyPath],
|
|
1215
|
+
}, sshKeys.add);
|
|
1216
|
+
const sshKeysRemoveCommand = cliparse.command('remove', {
|
|
1217
|
+
description: 'Remove a SSH key from the current user',
|
|
1218
|
+
args: [args.sshKeyName],
|
|
1219
|
+
}, sshKeys.remove);
|
|
1220
|
+
const sshKeysRemoveAllCommand = cliparse.command('remove-all', {
|
|
1221
|
+
description: 'Remove all SSH keys from the current user',
|
|
1222
|
+
options: [opts.confirmSshKeyClean],
|
|
1223
|
+
}, sshKeys.removeAll);
|
|
1224
|
+
const sshKeysOpenConsoleCommand = cliparse.command('open', {
|
|
1225
|
+
description: 'Open the SSH keys management page in the Console',
|
|
1226
|
+
}, sshKeys.openConsole);
|
|
1227
|
+
const sshKeysCommands = cliparse.command('ssh-keys', {
|
|
1228
|
+
description: 'Manage SSH keys of the current user',
|
|
1229
|
+
privateOptions: [opts.humanJsonOutputFormat],
|
|
1230
|
+
commands: [sshKeysAddCommand, sshKeysRemoveCommand, sshKeysRemoveAllCommand, sshKeysOpenConsoleCommand],
|
|
1231
|
+
}, sshKeys.list);
|
|
1232
|
+
|
|
965
1233
|
// STATUS COMMAND
|
|
966
1234
|
const statusCommand = cliparse.command('status', {
|
|
967
1235
|
description: 'See the status of an application',
|
|
@@ -1084,6 +1352,7 @@ async function run () {
|
|
|
1084
1352
|
domainCommands,
|
|
1085
1353
|
drainCommands,
|
|
1086
1354
|
emailNotificationsCommand,
|
|
1355
|
+
emailsCommands,
|
|
1087
1356
|
envCommands,
|
|
1088
1357
|
featuresCommands,
|
|
1089
1358
|
cliparseCommands.helpCommand,
|
|
@@ -1099,9 +1368,11 @@ async function run () {
|
|
|
1099
1368
|
scaleCommand,
|
|
1100
1369
|
serviceCommands,
|
|
1101
1370
|
sshCommand,
|
|
1371
|
+
sshKeysCommands,
|
|
1102
1372
|
statusCommand,
|
|
1103
1373
|
stopCommand,
|
|
1104
1374
|
tcpRedirsCommands,
|
|
1375
|
+
tokensCommands,
|
|
1105
1376
|
versionCommand,
|
|
1106
1377
|
webhooksCommand,
|
|
1107
1378
|
];
|
|
@@ -1109,12 +1380,15 @@ async function run () {
|
|
|
1109
1380
|
// Add experimental features only if they are enabled through the configuration file
|
|
1110
1381
|
const featuresFromConf = await getFeatures();
|
|
1111
1382
|
|
|
1112
|
-
if (featuresFromConf.
|
|
1113
|
-
commands.push(colorizeExperimentalCommand(
|
|
1383
|
+
if (featuresFromConf.operators) {
|
|
1384
|
+
commands.push(colorizeExperimentalCommand(keycloakCommand, 'operators'));
|
|
1385
|
+
commands.push(colorizeExperimentalCommand(matomoCommand, 'operators'));
|
|
1386
|
+
commands.push(colorizeExperimentalCommand(metabaseCommand, 'operators'));
|
|
1387
|
+
commands.push(colorizeExperimentalCommand(otoroshiCommand, 'operators'));
|
|
1114
1388
|
}
|
|
1115
1389
|
|
|
1116
|
-
if (featuresFromConf.
|
|
1117
|
-
commands.push(colorizeExperimentalCommand(
|
|
1390
|
+
if (featuresFromConf.kv) {
|
|
1391
|
+
commands.push(colorizeExperimentalCommand(kvRawCommand, 'kv'));
|
|
1118
1392
|
}
|
|
1119
1393
|
|
|
1120
1394
|
if (featuresFromConf.ng) {
|
package/package.json
CHANGED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// TODO: Move this to the Clever Cloud JS Client
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* GET /v4/addon-providers/addon-{provider}/addons/{realId}
|
|
5
|
+
* @param {Object} params
|
|
6
|
+
* @param {String} params.provider
|
|
7
|
+
* @param {String} params.realId
|
|
8
|
+
*/
|
|
9
|
+
export function getOperator (params) {
|
|
10
|
+
// no multipath for /self or /organisations/{id}
|
|
11
|
+
return Promise.resolve({
|
|
12
|
+
method: 'get',
|
|
13
|
+
url: `/v4/addon-providers/addon-${params.provider}/addons/${params.realId}`,
|
|
14
|
+
headers: { Accept: 'application/json' },
|
|
15
|
+
// no queryParams
|
|
16
|
+
// no body
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* POST /v4/addon-providers/addon-{provider}/addons/{realId}/reboot
|
|
22
|
+
* @param {Object} params
|
|
23
|
+
* @param {String} params.provider
|
|
24
|
+
* @param {String} params.realId
|
|
25
|
+
*/
|
|
26
|
+
export function rebootOperator (params) {
|
|
27
|
+
// no multipath for /self or /organisations/{id}
|
|
28
|
+
return Promise.resolve({
|
|
29
|
+
method: 'post',
|
|
30
|
+
url: `/v4/addon-providers/addon-${params.provider}/addons/${params.realId}/reboot`,
|
|
31
|
+
headers: { Accept: 'application/json' },
|
|
32
|
+
// no queryParams
|
|
33
|
+
// no body
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* POST /v4/addon-providers/addon-{provider}/addons/{realId}/rebuild
|
|
39
|
+
* @param {Object} params
|
|
40
|
+
* @param {String} params.provider
|
|
41
|
+
* @param {String} params.realId
|
|
42
|
+
*/
|
|
43
|
+
export function rebuildOperator (params) {
|
|
44
|
+
// no multipath for /self or /organisations/{id}
|
|
45
|
+
return Promise.resolve({
|
|
46
|
+
method: 'post',
|
|
47
|
+
url: `/v4/addon-providers/addon-${params.provider}/addons/${params.realId}/rebuild`,
|
|
48
|
+
headers: { Accept: 'application/json' },
|
|
49
|
+
// no queryParams
|
|
50
|
+
// no body
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* POST /v4/addon-providers/addon-{provider}/addons/{realId}/networkgroup
|
|
56
|
+
* @param {Object} params
|
|
57
|
+
* @param {String} params.provider
|
|
58
|
+
* @param {String} params.realId
|
|
59
|
+
*/
|
|
60
|
+
export function ngEnableOperator (params) {
|
|
61
|
+
// no multipath for /self or /organisations/{id}
|
|
62
|
+
return Promise.resolve({
|
|
63
|
+
method: 'post',
|
|
64
|
+
url: `/v4/addon-providers/addon-${params.provider}/addons/${params.realId}/networkgroup`,
|
|
65
|
+
headers: { Accept: 'application/json' },
|
|
66
|
+
// no queryParams
|
|
67
|
+
// no body
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* POST /v4/addon-providers/addon-{provider}/addons/{realId}/networkgroup
|
|
73
|
+
* @param {Object} params
|
|
74
|
+
* @param {String} params.provider
|
|
75
|
+
* @param {String} params.realId
|
|
76
|
+
*/
|
|
77
|
+
export function ngDisableOperator (params) {
|
|
78
|
+
// no multipath for /self or /organisations/{id}
|
|
79
|
+
return Promise.resolve({
|
|
80
|
+
method: 'delete',
|
|
81
|
+
url: `/v4/addon-providers/addon-${params.provider}/addons/${params.realId}/networkgroup`,
|
|
82
|
+
headers: { Accept: 'application/json' },
|
|
83
|
+
// no queryParams
|
|
84
|
+
// no body
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* GET /v4/addon-providers/addon-{provider}/addons/{realId}/version/check
|
|
90
|
+
* @param {Object} params
|
|
91
|
+
* @param {String} params.provider
|
|
92
|
+
* @param {String} params.realId
|
|
93
|
+
*/
|
|
94
|
+
export function versionCheck (params) {
|
|
95
|
+
// no multipath for /self or /organisations/{id}
|
|
96
|
+
return Promise.resolve({
|
|
97
|
+
method: 'get',
|
|
98
|
+
url: `/v4/addon-providers/addon-${params.provider}/addons/${params.realId}/version/check`,
|
|
99
|
+
headers: { Accept: 'application/json' },
|
|
100
|
+
// no queryParams
|
|
101
|
+
// no body
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* POST /v4/addon-providers/addon-{provider}/addons/{realId}/version/update
|
|
107
|
+
* @param {Object} params
|
|
108
|
+
* @param {String} params.provider
|
|
109
|
+
* @param {String} params.realId
|
|
110
|
+
* @param {Object} body
|
|
111
|
+
*/
|
|
112
|
+
export function versionUpdate (params, body) {
|
|
113
|
+
// no multipath for /self or /organisations/{id}
|
|
114
|
+
return Promise.resolve({
|
|
115
|
+
method: 'post',
|
|
116
|
+
url: `/v4/addon-providers/addon-${params.provider}/addons/${params.realId}/version/update`,
|
|
117
|
+
headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
|
|
118
|
+
// no queryParams
|
|
119
|
+
body,
|
|
120
|
+
});
|
|
121
|
+
}
|
package/src/commands/addon.js
CHANGED
|
@@ -124,7 +124,7 @@ function displayAddon (format, addon, providerName, message) {
|
|
|
124
124
|
|
|
125
125
|
const WIP_PROVIDERS = {
|
|
126
126
|
keycloak: {
|
|
127
|
-
status: '
|
|
127
|
+
status: '',
|
|
128
128
|
postCreateInstructions: dedent`
|
|
129
129
|
Learn more about Keycloak on Clever Cloud: ${conf.DOC_URL}/addons/keycloak/,
|
|
130
130
|
`,
|
|
@@ -139,19 +139,19 @@ function displayAddon (format, addon, providerName, message) {
|
|
|
139
139
|
`,
|
|
140
140
|
},
|
|
141
141
|
'addon-matomo': {
|
|
142
|
-
status: '
|
|
142
|
+
status: '',
|
|
143
143
|
postCreateInstructions: dedent`
|
|
144
144
|
Learn more about Matomo on Clever Cloud: ${conf.DOC_URL}/addons/matomo/
|
|
145
145
|
`,
|
|
146
146
|
},
|
|
147
147
|
metabase: {
|
|
148
|
-
status: '
|
|
148
|
+
status: '',
|
|
149
149
|
postCreateInstructions: dedent`
|
|
150
150
|
Learn more about Metabase on Clever Cloud: ${conf.DOC_URL}/addons/metabase/
|
|
151
151
|
`,
|
|
152
152
|
},
|
|
153
153
|
otoroshi: {
|
|
154
|
-
status: '
|
|
154
|
+
status: '',
|
|
155
155
|
postCreateInstructions: dedent`
|
|
156
156
|
Learn more about Otoroshi with LLM on Clever Cloud: ${conf.DOC_URL}/addons/otoroshi/
|
|
157
157
|
`,
|
|
@@ -166,7 +166,7 @@ function displayAddon (format, addon, providerName, message) {
|
|
|
166
166
|
|
|
167
167
|
let providerNameToShow = '';
|
|
168
168
|
let statusMessage = '';
|
|
169
|
-
if (providerName in WIP_PROVIDERS) {
|
|
169
|
+
if (providerName in WIP_PROVIDERS && WIP_PROVIDERS[providerName].status !== '') {
|
|
170
170
|
|
|
171
171
|
providerNameToShow = providerName === 'kv'
|
|
172
172
|
? 'Materia KV'
|
|
@@ -207,11 +207,12 @@ function displayAddon (format, addon, providerName, message) {
|
|
|
207
207
|
const provider = PROVIDERS_WITH_URL[providerName];
|
|
208
208
|
const urlEnv = addon.env.find((entry) => entry.name === provider.urlEnv);
|
|
209
209
|
const urlToShow = urlEnv.value;
|
|
210
|
+
const urlToShowWithHttps = urlToShow.startsWith('http') ? urlToShow : `https://${urlToShow}`;
|
|
210
211
|
|
|
211
212
|
if (urlEnv) {
|
|
212
213
|
Logger.println();
|
|
213
214
|
Logger.println(`Your ${provider.name} is starting:`);
|
|
214
|
-
Logger.println(` - Access it: ${
|
|
215
|
+
Logger.println(` - Access it: ${urlToShowWithHttps}`);
|
|
215
216
|
Logger.println(` - Manage it: ${conf.GOTO_URL}/${addon.id}`);
|
|
216
217
|
}
|
|
217
218
|
|
|
@@ -233,7 +234,11 @@ function displayAddon (format, addon, providerName, message) {
|
|
|
233
234
|
if (providerName in WIP_PROVIDERS) {
|
|
234
235
|
|
|
235
236
|
Logger.println();
|
|
236
|
-
|
|
237
|
+
|
|
238
|
+
if (statusMessage !== '') {
|
|
239
|
+
Logger.println(colors.yellow(`/!\\ ${statusMessage}`));
|
|
240
|
+
}
|
|
241
|
+
|
|
237
242
|
Logger.println(WIP_PROVIDERS[providerName].postCreateInstructions);
|
|
238
243
|
}
|
|
239
244
|
}
|
|
@@ -2,6 +2,7 @@ import * as Application from '../models/application.js';
|
|
|
2
2
|
import { Logger } from '../logger.js';
|
|
3
3
|
import { getAllDeployments, cancelDeployment } from '@clevercloud/client/esm/api/v2/application.js';
|
|
4
4
|
import { sendToApi } from '../models/send-to-api.js';
|
|
5
|
+
import colors from 'colors/safe.js';
|
|
5
6
|
|
|
6
7
|
export async function cancelDeploy (params) {
|
|
7
8
|
const { alias, app: appIdOrName } = params.options;
|
|
@@ -13,8 +14,6 @@ export async function cancelDeploy (params) {
|
|
|
13
14
|
throw new Error('There is no ongoing deployment for this application');
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Logger.println('Deployment cancelled!');
|
|
17
|
+
await cancelDeployment({ id: ownerId, appId, deploymentId: deployments[0].id }).then(sendToApi);
|
|
18
|
+
Logger.printSuccess(`Deployment ${colors.bold.green(deployments[0].uuid)} successfully cancelled!`);
|
|
20
19
|
};
|