clever-tools 3.14.0 → 4.0.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/README.md +130 -37
- package/bin/clever.js +1427 -718
- package/package.json +61 -77
- package/src/clever-client/auth-bridge.js +9 -12
- package/src/clever-client/ng.js +1 -1
- package/src/clever-client/operators.js +7 -7
- package/src/command-options.js +6 -6
- package/src/command-promise-handler.js +6 -6
- package/src/commands/accesslogs.js +38 -29
- package/src/commands/activity.js +62 -40
- package/src/commands/addon.js +65 -69
- package/src/commands/applications.js +33 -31
- package/src/commands/cancel-deploy.js +7 -7
- package/src/commands/config.js +9 -7
- package/src/commands/console.js +3 -3
- package/src/commands/create.js +32 -31
- package/src/commands/curl.js +14 -36
- package/src/commands/database.js +10 -30
- package/src/commands/delete.js +8 -8
- package/src/commands/deploy.js +60 -46
- package/src/commands/diag.js +27 -25
- package/src/commands/domain.js +89 -91
- package/src/commands/drain.js +26 -14
- package/src/commands/emails.js +24 -28
- package/src/commands/env.js +18 -18
- package/src/commands/features.js +12 -18
- package/src/commands/keycloak.js +11 -11
- package/src/commands/kv.js +13 -13
- package/src/commands/link.js +9 -8
- package/src/commands/login.js +19 -27
- package/src/commands/logout.js +1 -1
- package/src/commands/logs.js +20 -12
- package/src/commands/makeDefault.js +5 -5
- package/src/commands/matomo.js +7 -7
- package/src/commands/metabase.js +9 -9
- package/src/commands/ng.js +32 -32
- package/src/commands/notify-email.js +11 -15
- package/src/commands/open.js +1 -1
- package/src/commands/otoroshi.js +11 -11
- package/src/commands/profile.js +8 -8
- package/src/commands/published-config.js +11 -11
- package/src/commands/restart.js +15 -8
- package/src/commands/scale.js +25 -16
- package/src/commands/service.js +18 -9
- package/src/commands/ssh-keys.js +25 -29
- package/src/commands/ssh.js +1 -2
- package/src/commands/status.js +31 -22
- package/src/commands/stop.js +3 -3
- package/src/commands/tcp-redirs.js +27 -26
- package/src/commands/tokens.js +44 -43
- package/src/commands/unlink.js +7 -5
- package/src/commands/version.js +2 -4
- package/src/commands/webhooks.js +8 -10
- package/src/experimental-features.js +7 -5
- package/src/format-table.js +46 -15
- package/src/initial-setup.js +2 -32
- package/src/initial-update-notifier.js +18 -0
- package/src/lib/has-param.js +16 -0
- package/src/lib/ng-print.js +21 -24
- package/src/lib/operator-commands.js +58 -53
- package/src/lib/prompts.js +5 -5
- package/src/lib/slugify.js +1 -1
- package/src/logger.js +24 -22
- package/src/models/activity.js +3 -3
- package/src/models/addon.js +52 -53
- package/src/models/app_configuration.js +34 -32
- package/src/models/application.js +90 -77
- package/src/models/application_configuration.js +19 -27
- package/src/models/configuration.js +30 -32
- package/src/models/deployments.js +9 -19
- package/src/models/domain.js +10 -9
- package/src/models/drain.js +16 -15
- package/src/models/exit-strategy-option.js +15 -5
- package/src/models/fs-utils.js +4 -3
- package/src/models/git.js +26 -32
- package/src/models/ids-resolver.js +37 -41
- package/src/models/isomorphic-http-with-agent.js +3 -3
- package/src/models/json-array.js +5 -6
- package/src/models/log-v4.js +44 -52
- package/src/models/log.js +40 -45
- package/src/models/namespaces.js +4 -4
- package/src/models/ng-resources.js +49 -39
- package/src/models/ng.js +41 -40
- package/src/models/node-dns-resolver.js +3 -3
- package/src/models/notification.js +7 -10
- package/src/models/operator.js +8 -10
- package/src/models/organisation.js +5 -8
- package/src/models/send-to-api.js +18 -11
- package/src/models/user.js +6 -5
- package/src/models/utils.js +5 -8
- package/src/models/variables.js +18 -20
- package/src/parsers.js +34 -34
- package/src/load-package-json.cjs +0 -5
package/src/parsers.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import cliparse from 'cliparse';
|
|
2
|
-
|
|
3
|
-
import * as Application from './models/application.js';
|
|
4
2
|
import ISO8601 from 'iso8601-duration';
|
|
3
|
+
import * as Application from './models/application.js';
|
|
5
4
|
|
|
6
5
|
const addonOptionsRegex = /^[\w-]+=.+$/;
|
|
7
6
|
|
|
8
|
-
export function addonOptions
|
|
7
|
+
export function addonOptions(options) {
|
|
9
8
|
const optionsArray = typeof options === 'string' ? [options] : options;
|
|
10
9
|
for (const option of optionsArray) {
|
|
11
10
|
if (!option.match(addonOptionsRegex)) {
|
|
@@ -15,7 +14,7 @@ export function addonOptions (options) {
|
|
|
15
14
|
return cliparse.parsers.success(optionsArray.join(','));
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
export function flavor
|
|
17
|
+
export function flavor(flavor) {
|
|
19
18
|
const flavors = Application.listAvailableFlavors();
|
|
20
19
|
if (flavors.includes(flavor)) {
|
|
21
20
|
return cliparse.parsers.success(flavor);
|
|
@@ -23,14 +22,14 @@ export function flavor (flavor) {
|
|
|
23
22
|
return cliparse.parsers.error('Invalid value: ' + flavor);
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
export function buildFlavor
|
|
25
|
+
export function buildFlavor(flavorOrDisabled) {
|
|
27
26
|
if (flavorOrDisabled === 'disabled') {
|
|
28
27
|
return cliparse.parsers.success(flavorOrDisabled);
|
|
29
28
|
}
|
|
30
29
|
return flavor(flavorOrDisabled);
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
export function instances
|
|
32
|
+
export function instances(instances) {
|
|
34
33
|
const parsedInstances = parseInt(instances, 10);
|
|
35
34
|
if (isNaN(parsedInstances)) {
|
|
36
35
|
return cliparse.parsers.error('Invalid number: ' + instances);
|
|
@@ -41,7 +40,7 @@ export function instances (instances) {
|
|
|
41
40
|
return cliparse.parsers.success(parsedInstances);
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
export function date
|
|
43
|
+
export function date(dateString) {
|
|
45
44
|
const date = new Date(dateString);
|
|
46
45
|
if (isNaN(dateString) && !isNaN(date.getTime())) {
|
|
47
46
|
return cliparse.parsers.success(date);
|
|
@@ -49,13 +48,13 @@ export function date (dateString) {
|
|
|
49
48
|
|
|
50
49
|
const duration = durationInSeconds(dateString);
|
|
51
50
|
if (duration.success) {
|
|
52
|
-
return cliparse.parsers.success(new Date(Date.now() -
|
|
51
|
+
return cliparse.parsers.success(new Date(Date.now() - duration.success * 1000));
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
return duration;
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
export function futureDateOrDuration
|
|
57
|
+
export function futureDateOrDuration(dateString) {
|
|
59
58
|
const date = new Date(dateString);
|
|
60
59
|
if (isNaN(dateString) && !isNaN(date.getTime())) {
|
|
61
60
|
return cliparse.parsers.success(date);
|
|
@@ -63,7 +62,7 @@ export function futureDateOrDuration (dateString) {
|
|
|
63
62
|
|
|
64
63
|
const duration = durationInSeconds(dateString);
|
|
65
64
|
if (duration.success) {
|
|
66
|
-
return cliparse.parsers.success(new Date(Date.now() +
|
|
65
|
+
return cliparse.parsers.success(new Date(Date.now() + duration.success * 1000));
|
|
67
66
|
}
|
|
68
67
|
|
|
69
68
|
return duration;
|
|
@@ -72,7 +71,7 @@ export function futureDateOrDuration (dateString) {
|
|
|
72
71
|
// This simple regex is enough for our use cases
|
|
73
72
|
const emailRegex = /^\S+@\S+\.\S+$/g;
|
|
74
73
|
|
|
75
|
-
export function email
|
|
74
|
+
export function email(string) {
|
|
76
75
|
if (string.match(emailRegex)) {
|
|
77
76
|
return cliparse.parsers.success(string);
|
|
78
77
|
}
|
|
@@ -81,7 +80,7 @@ export function email (string) {
|
|
|
81
80
|
|
|
82
81
|
const appIdRegex = /^app_[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
83
82
|
|
|
84
|
-
export function appIdOrName
|
|
83
|
+
export function appIdOrName(string) {
|
|
85
84
|
if (string.match(appIdRegex)) {
|
|
86
85
|
return cliparse.parsers.success({ app_id: string });
|
|
87
86
|
}
|
|
@@ -90,7 +89,7 @@ export function appIdOrName (string) {
|
|
|
90
89
|
|
|
91
90
|
const orgaIdRegex = /^(user_|orga_)[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
92
91
|
|
|
93
|
-
export function orgaIdOrName
|
|
92
|
+
export function orgaIdOrName(string) {
|
|
94
93
|
if (string.match(orgaIdRegex)) {
|
|
95
94
|
return cliparse.parsers.success({ orga_id: string });
|
|
96
95
|
}
|
|
@@ -98,9 +97,10 @@ export function orgaIdOrName (string) {
|
|
|
98
97
|
}
|
|
99
98
|
|
|
100
99
|
const addonIdRegex = /^addon_[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
101
|
-
const operatorIdRegex =
|
|
100
|
+
const operatorIdRegex =
|
|
101
|
+
/^(keycloak|otoroshi|matomo|metabase)_[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
102
102
|
|
|
103
|
-
export function addonIdOrName
|
|
103
|
+
export function addonIdOrName(string) {
|
|
104
104
|
if (string.match(addonIdRegex)) {
|
|
105
105
|
return cliparse.parsers.success({ addon_id: string });
|
|
106
106
|
}
|
|
@@ -110,11 +110,11 @@ export function addonIdOrName (string) {
|
|
|
110
110
|
return cliparse.parsers.success({ addon_name: string });
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
export function commaSeparated
|
|
113
|
+
export function commaSeparated(string) {
|
|
114
114
|
return cliparse.parsers.success(string.split(','));
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
export function integer
|
|
117
|
+
export function integer(string) {
|
|
118
118
|
const integer = parseInt(string);
|
|
119
119
|
if (isNaN(integer)) {
|
|
120
120
|
return cliparse.parsers.error('Invalid number: ' + string);
|
|
@@ -122,7 +122,7 @@ export function integer (string) {
|
|
|
122
122
|
return cliparse.parsers.success(integer);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
export function nonEmptyString
|
|
125
|
+
export function nonEmptyString(string) {
|
|
126
126
|
if (typeof string !== 'string' || string === '') {
|
|
127
127
|
return cliparse.parsers.error('Invalid string, it should not be empty');
|
|
128
128
|
}
|
|
@@ -132,14 +132,14 @@ export function nonEmptyString (string) {
|
|
|
132
132
|
// /^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?$/i;
|
|
133
133
|
const tagRegex = /^[^,\s]+$/;
|
|
134
134
|
|
|
135
|
-
export function tag
|
|
135
|
+
export function tag(string) {
|
|
136
136
|
if (string.match(tagRegex)) {
|
|
137
137
|
return cliparse.parsers.success(string);
|
|
138
138
|
}
|
|
139
139
|
return cliparse.parsers.error(`Invalid tag '${string}'. Should match ${tagRegex}`);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
export function tags
|
|
142
|
+
export function tags(string) {
|
|
143
143
|
if (String(string).length === 0) {
|
|
144
144
|
return cliparse.parsers.success([]);
|
|
145
145
|
}
|
|
@@ -152,9 +152,10 @@ export function tags (string) {
|
|
|
152
152
|
return cliparse.parsers.success(tags);
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
export const ipAddressRegex =
|
|
155
|
+
export const ipAddressRegex =
|
|
156
|
+
/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$/;
|
|
156
157
|
|
|
157
|
-
export function ipAddress
|
|
158
|
+
export function ipAddress(string) {
|
|
158
159
|
if (string.match(ipAddressRegex)) {
|
|
159
160
|
return cliparse.parsers.success(string);
|
|
160
161
|
}
|
|
@@ -163,7 +164,7 @@ export function ipAddress (string) {
|
|
|
163
164
|
|
|
164
165
|
export const portNumberRegex = /^\d{1,5}$/;
|
|
165
166
|
|
|
166
|
-
export function portNumber
|
|
167
|
+
export function portNumber(number) {
|
|
167
168
|
if (String(number).match(portNumberRegex)) {
|
|
168
169
|
return cliparse.parsers.success(number);
|
|
169
170
|
}
|
|
@@ -176,15 +177,16 @@ export function portNumber (number) {
|
|
|
176
177
|
* @param {string} durationStr an ISO8601, 1h or a positive number
|
|
177
178
|
* @returns {number} number of seconds
|
|
178
179
|
*/
|
|
179
|
-
export function durationInSeconds
|
|
180
|
-
const failed = cliparse.parsers.error(
|
|
180
|
+
export function durationInSeconds(durationStr = '') {
|
|
181
|
+
const failed = cliparse.parsers.error(
|
|
182
|
+
`Invalid duration: "${durationStr}", expect (IS0 8601 duration / a "1h, 1m, 30s" like duration / a positive number in seconds)`,
|
|
183
|
+
);
|
|
181
184
|
|
|
182
185
|
if (durationStr.startsWith('P')) {
|
|
183
186
|
try {
|
|
184
187
|
const d = ISO8601.parse(durationStr);
|
|
185
188
|
return cliparse.parsers.success(ISO8601.toSeconds(d));
|
|
186
|
-
}
|
|
187
|
-
catch (err) {
|
|
189
|
+
} catch {
|
|
188
190
|
return failed;
|
|
189
191
|
}
|
|
190
192
|
}
|
|
@@ -192,8 +194,7 @@ export function durationInSeconds (durationStr = '') {
|
|
|
192
194
|
try {
|
|
193
195
|
const durationInSeconds = parseSimpleDuration(durationStr);
|
|
194
196
|
return cliparse.parsers.success(durationInSeconds);
|
|
195
|
-
}
|
|
196
|
-
catch (err) {
|
|
197
|
+
} catch {
|
|
197
198
|
const n = Number.parseInt(durationStr);
|
|
198
199
|
if (isNaN(n) || n < 0) {
|
|
199
200
|
return failed;
|
|
@@ -214,7 +215,7 @@ const SHORT_UNITS_TO_ISO = {
|
|
|
214
215
|
y: (v) => `P${v}Y`,
|
|
215
216
|
};
|
|
216
217
|
|
|
217
|
-
function parseSimpleDuration
|
|
218
|
+
function parseSimpleDuration(durationStr) {
|
|
218
219
|
const { rawValue, unit } = durationStr.match(/^(?<rawValue>\d+)(?<unit>.*)$/)?.groups ?? {};
|
|
219
220
|
if (unit in SHORT_UNITS_TO_ISO) {
|
|
220
221
|
const value = Number(rawValue);
|
|
@@ -225,7 +226,7 @@ function parseSimpleDuration (durationStr) {
|
|
|
225
226
|
}
|
|
226
227
|
|
|
227
228
|
// Network groups parsers
|
|
228
|
-
export function ngResourceType
|
|
229
|
+
export function ngResourceType(string) {
|
|
229
230
|
if (string.startsWith('ng_')) {
|
|
230
231
|
return cliparse.parsers.success({ ngId: string });
|
|
231
232
|
}
|
|
@@ -235,11 +236,10 @@ export function ngResourceType (string) {
|
|
|
235
236
|
return cliparse.parsers.success({ ngResourceLabel: string });
|
|
236
237
|
}
|
|
237
238
|
|
|
238
|
-
export function ngValidType
|
|
239
|
+
export function ngValidType(string) {
|
|
239
240
|
if (string === 'NetworkGroup' || string === 'Member' || string === 'CleverPeer' || string === 'ExternalPeer') {
|
|
240
241
|
return cliparse.parsers.success(string);
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
242
|
+
} else {
|
|
243
243
|
return cliparse.parsers.error(`Invalid Network Group resource type: ${string}`);
|
|
244
244
|
}
|
|
245
245
|
}
|