clever-tools 3.6.0 → 3.7.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 +0 -6
- package/package.json +3 -4
- package/src/command-options.js +3 -3
- package/src/commands/activity.js +7 -5
- package/src/commands/addon.js +3 -20
- package/src/commands/curl.js +13 -16
- package/src/models/addon.js +21 -12
package/README.md
CHANGED
|
@@ -70,9 +70,3 @@ If you want to know more or if you need to release a new version, please read [R
|
|
|
70
70
|
## License
|
|
71
71
|
|
|
72
72
|
This project is licensed under the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html).
|
|
73
|
-
|
|
74
|
-
We're using a CJS bundled version of a file from [curlconverter](https://github.com/curlconverter/curlconverter):
|
|
75
|
-
|
|
76
|
-
* The project is licensed with [MIT](https://github.com/curlconverter/curlconverter/blob/master/LICENSE)
|
|
77
|
-
* The copyright is at the top the file `vendors/curlconverter-parse`
|
|
78
|
-
* The details are explained in [README_VENDORS.md](vendors/README_VENDORS.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clever-tools",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"description": "Command Line Interface for Clever Cloud.",
|
|
5
5
|
"main": "bin/clever.js",
|
|
6
6
|
"keywords": [
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@clevercloud/client": "^8.1.2",
|
|
29
29
|
"clf-date": "^0.2.0",
|
|
30
|
-
"cliparse": "
|
|
30
|
+
"cliparse": "0.3.5",
|
|
31
31
|
"colors": "1.4.0",
|
|
32
32
|
"common-env": "^6.4.0",
|
|
33
|
-
"curlconverter": "^
|
|
33
|
+
"curlconverter": "^3.21.0",
|
|
34
34
|
"duration-js": "^4.0.0",
|
|
35
35
|
"eventsource": "^1.1.0",
|
|
36
36
|
"iso8601-duration": "^2.1.2",
|
|
@@ -78,7 +78,6 @@
|
|
|
78
78
|
"pkg-fetch": "3.5.2"
|
|
79
79
|
},
|
|
80
80
|
"scripts": {
|
|
81
|
-
"bundle-curlconverter": "rollup -c rollup-curlconverter.config.js",
|
|
82
81
|
"pretest": "npm run lint",
|
|
83
82
|
"test": "grunt test",
|
|
84
83
|
"lint": "eslint bin src scripts",
|
package/src/command-options.js
CHANGED
|
@@ -22,14 +22,14 @@ function getSameCommitPolicyOption () {
|
|
|
22
22
|
const availablePolicies = ['error', 'ignore', 'restart', 'rebuild'];
|
|
23
23
|
return cliparse.option('same-commit-policy', {
|
|
24
24
|
aliases: ['p'],
|
|
25
|
-
metavar: '
|
|
25
|
+
metavar: 'policy',
|
|
26
26
|
parser: (policy) => {
|
|
27
27
|
return availablePolicies.includes(policy)
|
|
28
28
|
? cliparse.parsers.success(policy)
|
|
29
|
-
: cliparse.parsers.error(`
|
|
29
|
+
: cliparse.parsers.error(`the policy must be one of ${availablePolicies.join(', ')}`);
|
|
30
30
|
},
|
|
31
31
|
default: 'error',
|
|
32
|
-
description: `
|
|
32
|
+
description: `What to do when local and remote commit are identical (${availablePolicies.join(', ')})`,
|
|
33
33
|
complete () {
|
|
34
34
|
return cliparse.autocomplete.words(availablePolicies);
|
|
35
35
|
},
|
package/src/commands/activity.js
CHANGED
|
@@ -31,10 +31,11 @@ function getColoredState (state, isLast) {
|
|
|
31
31
|
// We use examples of maximum width text to have a clean display
|
|
32
32
|
const formatActivityTable = formatTable([
|
|
33
33
|
moment().format(),
|
|
34
|
+
47,
|
|
34
35
|
'IN PROGRESS',
|
|
35
36
|
'downscale',
|
|
36
|
-
// a git commit id is
|
|
37
|
-
|
|
37
|
+
// a git commit id is 8 chars long
|
|
38
|
+
8,
|
|
38
39
|
0,
|
|
39
40
|
]);
|
|
40
41
|
|
|
@@ -42,9 +43,10 @@ function formatActivityLine (event) {
|
|
|
42
43
|
return formatActivityTable([
|
|
43
44
|
[
|
|
44
45
|
moment(event.date).format(),
|
|
46
|
+
event.uuid,
|
|
45
47
|
getColoredState(event.state, event.isLast),
|
|
46
48
|
event.action,
|
|
47
|
-
event
|
|
49
|
+
event?.commit?.substring(0, 8) ?? 'N/A',
|
|
48
50
|
event.cause,
|
|
49
51
|
],
|
|
50
52
|
]);
|
|
@@ -77,11 +79,11 @@ function handleEvent (previousEvent, event) {
|
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
function onEvent (previousEvent, newEvent) {
|
|
80
|
-
const { event, date, data: { state, action, commit, cause } } = newEvent;
|
|
82
|
+
const { event, date, data: { uuid, state, action, commit, cause } } = newEvent;
|
|
81
83
|
if (event !== 'DEPLOYMENT_ACTION_BEGIN' && event !== 'DEPLOYMENT_ACTION_END') {
|
|
82
84
|
return previousEvent;
|
|
83
85
|
}
|
|
84
|
-
return handleEvent(previousEvent, { date, state, action, commit, cause, isLast: true });
|
|
86
|
+
return handleEvent(previousEvent, { date, uuid, state, action, commit, cause, isLast: true });
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
async function activity (params) {
|
package/src/commands/addon.js
CHANGED
|
@@ -15,22 +15,6 @@ const { sendToApi } = require('../models/send-to-api.js');
|
|
|
15
15
|
const { toNameEqualsValueString } = require('@clevercloud/client/cjs/utils/env-vars.js');
|
|
16
16
|
const { resolveAddonId } = require('../models/ids-resolver.js');
|
|
17
17
|
|
|
18
|
-
function getPlan (inputPlan, providerName) {
|
|
19
|
-
|
|
20
|
-
// Return user plan
|
|
21
|
-
if (inputPlan !== '') {
|
|
22
|
-
return inputPlan;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Choose a default plan based on the add-on provider
|
|
26
|
-
switch (providerName) {
|
|
27
|
-
case 'kv':
|
|
28
|
-
return 'alpha';
|
|
29
|
-
default:
|
|
30
|
-
return 'dev';
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
18
|
async function list (params) {
|
|
35
19
|
const { org: orgaIdOrName, format } = params.options;
|
|
36
20
|
|
|
@@ -74,7 +58,7 @@ async function create (params) {
|
|
|
74
58
|
const [providerName, name] = params.args;
|
|
75
59
|
const {
|
|
76
60
|
link: linkedAppAlias,
|
|
77
|
-
plan:
|
|
61
|
+
plan: planName,
|
|
78
62
|
region,
|
|
79
63
|
yes: skipConfirmation,
|
|
80
64
|
org: orgaIdOrName,
|
|
@@ -82,7 +66,6 @@ async function create (params) {
|
|
|
82
66
|
} = params.options;
|
|
83
67
|
const version = params.options['addon-version'];
|
|
84
68
|
const addonOptions = parseAddonOptions(params.options.option);
|
|
85
|
-
const planName = getPlan(inputPlan, providerName);
|
|
86
69
|
|
|
87
70
|
const ownerId = (orgaIdOrName != null)
|
|
88
71
|
? await Organisation.getId(orgaIdOrName)
|
|
@@ -143,8 +126,8 @@ function displayAddon (format, addon, providerName, message) {
|
|
|
143
126
|
if (providerName === 'kv') {
|
|
144
127
|
const materiaMessage = [
|
|
145
128
|
'',
|
|
146
|
-
colors.yellow(`/!\\ The
|
|
147
|
-
'You can easily use
|
|
129
|
+
colors.yellow(`/!\\ The Materia ${providerName.toUpperCase()} provider is in Alpha testing phase, don't store sensitive or production grade data`),
|
|
130
|
+
'You can easily use Materia KV with \'redis-cli\', with such commands:',
|
|
148
131
|
colors.blue(`source <(clever addon env ${addon.id} -F shell)`),
|
|
149
132
|
colors.blue('redis-cli -h $KV_HOST -p $KV_PORT --tls'),
|
|
150
133
|
].join('\n');
|
package/src/commands/curl.js
CHANGED
|
@@ -5,7 +5,7 @@ const { loadOAuthConf, conf } = require('../models/configuration.js');
|
|
|
5
5
|
const { addOauthHeader } = require('@clevercloud/client/cjs/oauth.js');
|
|
6
6
|
const Logger = require('../logger.js');
|
|
7
7
|
const colors = require('colors/safe');
|
|
8
|
-
const
|
|
8
|
+
const curlconverter = require('curlconverter');
|
|
9
9
|
|
|
10
10
|
async function loadTokens () {
|
|
11
11
|
const tokens = await loadOAuthConf();
|
|
@@ -49,7 +49,12 @@ async function curl () {
|
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
// WARNING: Version 3.x of curlconverter uses a fork of yargs.
|
|
53
|
+
// For "reasons", when the command has a help param, it stops the parsing and triggers a very short and localized version of some help (WAT?).
|
|
54
|
+
// That's why we remove the help param before parsing and "reinstate" it before execution.
|
|
55
|
+
const curlArgsNoHelp = curlArgs.filter((arg) => arg !== '--help' && arg !== '-h');
|
|
56
|
+
const curlCommand = ['curl', ...curlArgsNoHelp].join(' ');
|
|
57
|
+
const requestParams = await parseCurlCommand(curlCommand);
|
|
53
58
|
|
|
54
59
|
// We only allow request to the respective API_HOST
|
|
55
60
|
if (!requestParams.url.startsWith(conf.API_HOST)) {
|
|
@@ -78,23 +83,15 @@ async function curl () {
|
|
|
78
83
|
|
|
79
84
|
async function parseCurlCommand (curlCommand) {
|
|
80
85
|
|
|
81
|
-
const
|
|
82
|
-
const
|
|
86
|
+
const jsonString = curlconverter.toJsonString(curlCommand);
|
|
87
|
+
const curlRequestParams = JSON.parse(jsonString);
|
|
83
88
|
|
|
84
89
|
return {
|
|
85
|
-
method:
|
|
86
|
-
url: url
|
|
87
|
-
headers:
|
|
88
|
-
queryParams:
|
|
90
|
+
method: curlRequestParams.method,
|
|
91
|
+
url: curlRequestParams.url,
|
|
92
|
+
headers: curlRequestParams.headers,
|
|
93
|
+
queryParams: curlRequestParams.queries,
|
|
89
94
|
};
|
|
90
95
|
}
|
|
91
96
|
|
|
92
|
-
function transformCurlConverterWordsToObject (words = []) {
|
|
93
|
-
return Object.fromEntries(
|
|
94
|
-
words.map(([key, value]) => {
|
|
95
|
-
return [key.toString(), value.toString()];
|
|
96
|
-
}),
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
97
|
module.exports = { curl };
|
package/src/models/addon.js
CHANGED
|
@@ -26,7 +26,7 @@ async function getProvider (providerName) {
|
|
|
26
26
|
const providers = await listProviders();
|
|
27
27
|
const provider = providers.find((p) => p.id === providerName);
|
|
28
28
|
if (provider == null) {
|
|
29
|
-
throw new Error(
|
|
29
|
+
throw new Error(`Invalid provider name. Available providers: ${providers.map((p) => p.id).join(', ')}`);
|
|
30
30
|
}
|
|
31
31
|
return provider;
|
|
32
32
|
}
|
|
@@ -136,22 +136,17 @@ function validateAddonVersionAndOptions (region, version, addonOptions, provider
|
|
|
136
136
|
async function create ({ ownerId, name, providerName, planName, region, skipConfirmation, version, addonOptions }) {
|
|
137
137
|
|
|
138
138
|
// TODO: We should be able to use it without {}
|
|
139
|
-
const
|
|
139
|
+
const provider = await getProvider(providerName);
|
|
140
140
|
|
|
141
|
-
const provider = providers.find((p) => p.id === providerName);
|
|
142
|
-
if (provider == null) {
|
|
143
|
-
throw new Error('invalid provider name');
|
|
144
|
-
}
|
|
145
141
|
if (!provider.regions.includes(region)) {
|
|
146
|
-
throw new Error(`
|
|
142
|
+
throw new Error(`Invalid region name. Available regions: ${provider.regions.join(', ')}`);
|
|
147
143
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if (plan == null) {
|
|
151
|
-
const availablePlans = provider.plans.map((p) => p.slug);
|
|
152
|
-
throw new Error(`invalid plan name. Available plans: ${availablePlans.join(', ')}`);
|
|
144
|
+
if (provider.plans.length === 0) {
|
|
145
|
+
throw new Error(`No plans available for provider ${providerName}`);
|
|
153
146
|
}
|
|
154
147
|
|
|
148
|
+
const plan = getPlan(planName, provider.plans);
|
|
149
|
+
|
|
155
150
|
const providerInfos = await getProviderInfos(provider.id);
|
|
156
151
|
const planType = plan.features.find(({ name }) => name.toLowerCase() === 'type');
|
|
157
152
|
|
|
@@ -289,6 +284,20 @@ function parseAddonOptions (options) {
|
|
|
289
284
|
}, {});
|
|
290
285
|
}
|
|
291
286
|
|
|
287
|
+
function getPlan (planName, plans) {
|
|
288
|
+
// if no plan specified, pick the cheapest one
|
|
289
|
+
if (planName == null || planName === '') {
|
|
290
|
+
return plans.sort((p1, p2) => p1.price - p2.price)[0];
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const plan = plans.find((p) => p.slug.toLowerCase() === planName.toLowerCase());
|
|
294
|
+
if (plan == null) {
|
|
295
|
+
const availablePlans = plans.map((p) => p.slug);
|
|
296
|
+
throw new Error(`Invalid plan name. Available plans: ${availablePlans.join(', ')}`);
|
|
297
|
+
}
|
|
298
|
+
return plan;
|
|
299
|
+
}
|
|
300
|
+
|
|
292
301
|
module.exports = {
|
|
293
302
|
completePlan,
|
|
294
303
|
completeRegion,
|