clever-tools 2.7.1 → 2.8.1
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/CHANGELOG.md +18 -0
- package/README.md +34 -2
- package/bin/clever.js +10 -2
- package/package.json +32 -28
- package/src/commands/accesslogs.js +1 -1
- package/src/commands/addon.js +34 -3
- package/src/commands/cancel-deploy.js +1 -1
- package/src/commands/config.js +1 -1
- package/src/commands/deploy.js +1 -1
- package/src/commands/domain.js +1 -1
- package/src/commands/drain.js +1 -1
- package/src/commands/env.js +1 -1
- package/src/commands/notify-email.js +2 -1
- package/src/commands/published-config.js +1 -1
- package/src/commands/status.js +1 -1
- package/src/commands/stop.js +1 -1
- package/src/commands/tcp-redirs.js +1 -1
- package/src/commands/webhooks.js +1 -1
- package/src/models/accesslogs.js +12 -2
- package/src/models/activity.js +1 -1
- package/src/models/addon.js +139 -8
- package/src/models/app_configuration.js +1 -1
- package/src/models/application.js +2 -2
- package/src/models/configuration.js +38 -10
- package/src/models/deployments.js +2 -1
- package/src/models/domain.js +1 -1
- package/src/models/fs-utils.js +2 -5
- package/src/models/git.js +2 -1
- package/src/models/log.js +4 -3
- package/src/models/organisation.js +2 -2
- package/src/models/user.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# clever-tools changelog
|
|
2
2
|
|
|
3
|
+
## 2.8.1 (2021-01-10)
|
|
4
|
+
|
|
5
|
+
* Fix `colors` to `1.4.0`
|
|
6
|
+
|
|
7
|
+
## 2.8.0 (2021-02-09)
|
|
8
|
+
|
|
9
|
+
* Add options support for `clever addon create` (options like encryption-at-rest)
|
|
10
|
+
* Display available versions in `clever addon providers show <provider>`
|
|
11
|
+
* Display available options in `clever addon providers show <provider>`
|
|
12
|
+
* Fix `clever deploy` which was displaying logs from runtime instances
|
|
13
|
+
* Fix `clever accesslogs` so it doesn't fail when source object is undefined
|
|
14
|
+
* Prevent race conditions on parallel CI configs with `clever deploy` and git add remote
|
|
15
|
+
* Format `.clever.json` (Mickael Chanrion)
|
|
16
|
+
|
|
17
|
+
## 2.7.2 (2020-10-09)
|
|
18
|
+
|
|
19
|
+
* addon: fix create relying on default region
|
|
20
|
+
|
|
3
21
|
## 2.7.1 (2020-08-21)
|
|
4
22
|
|
|
5
23
|
* Fix linux-release-info usage in `clever diag`
|
package/README.md
CHANGED
|
@@ -26,6 +26,14 @@ npm install -g clever-tools@beta
|
|
|
26
26
|
|
|
27
27
|
#### Debian/Ubuntu (.deb)
|
|
28
28
|
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
##### Warning
|
|
32
|
+
|
|
33
|
+
Bintray is ending on May 1st 2021, we will migrate hosting as soon as possible. Please refer to the dedicated [issue](https://github.com/CleverCloud/clever-tools/issues/454) to track the migration.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
29
37
|
If you are using a GNU/Linux distribution that uses `.deb` packages like Debian or Ubuntu, you can run:
|
|
30
38
|
|
|
31
39
|
```sh
|
|
@@ -46,6 +54,14 @@ echo "deb https://dl.bintray.com/clevercloud/deb unstable beta" | tee -a /etc/ap
|
|
|
46
54
|
|
|
47
55
|
#### CentOS/Fedora (.rpm)
|
|
48
56
|
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
##### Warning
|
|
60
|
+
|
|
61
|
+
Bintray is ending on May 1st 2021, we will migrate hosting as soon as possible. Please refer to the dedicated [issue](https://github.com/CleverCloud/clever-tools/issues/454) to track the migration.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
49
65
|
If you are using a GNU/Linux distribution that uses `.rpm` packages like CentOS or Fedora, you can run:
|
|
50
66
|
|
|
51
67
|
```sh
|
|
@@ -131,7 +147,15 @@ NOTES:
|
|
|
131
147
|
|
|
132
148
|
#### Using chocolatey
|
|
133
149
|
|
|
134
|
-
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
##### Warning
|
|
153
|
+
|
|
154
|
+
Bintray is ending on May 1st 2021, we will migrate hosting as soon as possible. Please refer to the dedicated [issue](https://github.com/CleverCloud/clever-tools/issues/454) to track the migration.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
If you are using Windows and you have [chocolatey](https://chocolatey.org) installed, you can run:
|
|
135
159
|
|
|
136
160
|
```bash
|
|
137
161
|
choco sources add -n=clevercloud -s='https://api.bintray.com/nuget/clevercloud/nupkg'
|
|
@@ -160,6 +184,14 @@ docker pull clevercloud/clever-tools
|
|
|
160
184
|
docker run --rm clever-tools <command>
|
|
161
185
|
```
|
|
162
186
|
|
|
187
|
+
#### Dockerfile
|
|
188
|
+
|
|
189
|
+
In your `Dockerfile` you can copy the clever-tools CLI from the image itself with a simple one liner:
|
|
190
|
+
|
|
191
|
+
```Dockerfile
|
|
192
|
+
COPY --from=clevercloud/clever-tools /bin/clever /usr/local/bin/clever
|
|
193
|
+
```
|
|
194
|
+
|
|
163
195
|
### Via Nix
|
|
164
196
|
|
|
165
197
|
If you are using Nix, you will find a Nix derivation on Fretlink's Github repository: https://github.com/fretlink/clever-tools-nix
|
|
@@ -168,7 +200,7 @@ If you are using Nix, you will find a Nix derivation on Fretlink's Github reposi
|
|
|
168
200
|
|
|
169
201
|
The clever-tools CLI comes with a comprehensive auto-completion system.
|
|
170
202
|
Some installation methods like `.deb` packages, `.rpm` packages or brew will try to enable it automatically.
|
|
171
|
-
If it does not work, try this for bash:
|
|
203
|
+
If it does not work, try this for bash:
|
|
172
204
|
|
|
173
205
|
```bash
|
|
174
206
|
clever --bash-autocomplete-script $(which clever) | sudo tee /usr/share/bash-completion/completions/clever
|
package/bin/clever.js
CHANGED
|
@@ -292,11 +292,19 @@ function run () {
|
|
|
292
292
|
}),
|
|
293
293
|
addonRegion: cliparse.option('region', {
|
|
294
294
|
aliases: ['r'],
|
|
295
|
-
default: '
|
|
295
|
+
default: 'par',
|
|
296
296
|
metavar: 'region',
|
|
297
297
|
description: 'Region to provision the addon in, depends on the provider',
|
|
298
298
|
complete: Addon('completeRegion'),
|
|
299
299
|
}),
|
|
300
|
+
addonVersion: cliparse.option('addon-version', {
|
|
301
|
+
metavar: 'addon-version',
|
|
302
|
+
description: 'The version to use for the add-on',
|
|
303
|
+
}),
|
|
304
|
+
addonOptions: cliparse.option('option', {
|
|
305
|
+
metavar: 'option',
|
|
306
|
+
description: 'Option to enable for the add-on. Multiple --option argument can be passed to enable multiple options',
|
|
307
|
+
}),
|
|
300
308
|
region: cliparse.option('region', {
|
|
301
309
|
aliases: ['r'],
|
|
302
310
|
default: 'par',
|
|
@@ -379,7 +387,7 @@ function run () {
|
|
|
379
387
|
const addonCreateCommand = cliparse.command('create', {
|
|
380
388
|
description: 'Create an addon',
|
|
381
389
|
args: [args.addonProvider, args.addonName],
|
|
382
|
-
options: [opts.linkAddon, opts.confirmAddonCreation, opts.addonPlan, opts.addonRegion],
|
|
390
|
+
options: [opts.linkAddon, opts.confirmAddonCreation, opts.addonPlan, opts.addonRegion, opts.addonVersion, opts.addonOptions],
|
|
383
391
|
}, addon('create'));
|
|
384
392
|
const addonDeleteCommand = cliparse.command('delete', {
|
|
385
393
|
description: 'Delete an addon',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clever-tools",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.1",
|
|
4
4
|
"description": "Command Line Interface for Clever Cloud.",
|
|
5
5
|
"main": "bin/clever.js",
|
|
6
6
|
"keywords": [
|
|
@@ -25,45 +25,45 @@
|
|
|
25
25
|
"scripts/*.sh"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@clevercloud/client": "^
|
|
28
|
+
"@clevercloud/client": "^7.4.0",
|
|
29
29
|
"clf-date": "^0.2.0",
|
|
30
|
-
"cliparse": "^0.3.
|
|
31
|
-
"colors": "
|
|
30
|
+
"cliparse": "^0.3.3",
|
|
31
|
+
"colors": "1.4.0",
|
|
32
32
|
"common-env": "^6.4.0",
|
|
33
|
-
"eventsource": "^1.0
|
|
34
|
-
"isomorphic-git": "1.
|
|
33
|
+
"eventsource": "^1.1.0",
|
|
34
|
+
"isomorphic-git": "^1.8.2",
|
|
35
35
|
"linux-release-info": "^3.0.0",
|
|
36
|
-
"lodash": "^4.17.
|
|
36
|
+
"lodash": "^4.17.21",
|
|
37
37
|
"mkdirp": "^1.0.4",
|
|
38
|
-
"moment": "^2.
|
|
38
|
+
"moment": "^2.29.1",
|
|
39
39
|
"opn": "^6.0.0",
|
|
40
|
-
"slugify": "^1.
|
|
41
|
-
"string-length": "^
|
|
42
|
-
"superagent": "^6.
|
|
40
|
+
"slugify": "^1.5.3",
|
|
41
|
+
"string-length": "^4.0.2",
|
|
42
|
+
"superagent": "^6.1.0",
|
|
43
43
|
"text-table": "^0.2.0",
|
|
44
|
-
"update-notifier": "^
|
|
45
|
-
"ws": "^7.
|
|
44
|
+
"update-notifier": "^5.1.0",
|
|
45
|
+
"ws": "^7.4.6",
|
|
46
46
|
"xdg": "^0.1.1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"aws-sdk": "^2.
|
|
50
|
-
"chai": "^4.
|
|
51
|
-
"del": "^
|
|
52
|
-
"eslint": "^7.
|
|
53
|
-
"eslint-config-standard": "^
|
|
54
|
-
"eslint-plugin-import": "^2.
|
|
49
|
+
"aws-sdk": "^2.919.0",
|
|
50
|
+
"chai": "^4.3.4",
|
|
51
|
+
"del": "^6.0.0",
|
|
52
|
+
"eslint": "^7.27.0",
|
|
53
|
+
"eslint-config-standard": "^16.0.3",
|
|
54
|
+
"eslint-plugin-import": "^2.23.4",
|
|
55
55
|
"eslint-plugin-node": "^11.1.0",
|
|
56
|
-
"eslint-plugin-promise": "^
|
|
57
|
-
"eslint-plugin-standard": "^
|
|
58
|
-
"fs-extra": "^
|
|
59
|
-
"glob": "^7.1.
|
|
60
|
-
"grunt": "^1.
|
|
61
|
-
"grunt-cli": "^1.3
|
|
56
|
+
"eslint-plugin-promise": "^5.1.0",
|
|
57
|
+
"eslint-plugin-standard": "^5.0.0",
|
|
58
|
+
"fs-extra": "^10.0.0",
|
|
59
|
+
"glob": "^7.1.7",
|
|
60
|
+
"grunt": "^1.4.1",
|
|
61
|
+
"grunt-cli": "^1.4.3",
|
|
62
62
|
"grunt-http": "^2.3.3",
|
|
63
63
|
"grunt-mocha-test": "^0.13.3",
|
|
64
|
-
"mocha": "^8.
|
|
65
|
-
"pkg": "^
|
|
66
|
-
"semver": "^7.3.
|
|
64
|
+
"mocha": "^8.4.0",
|
|
65
|
+
"pkg": "^5.2.1",
|
|
66
|
+
"semver": "^7.3.5"
|
|
67
67
|
},
|
|
68
68
|
"scripts": {
|
|
69
69
|
"pretest": "npm run lint",
|
|
@@ -83,5 +83,9 @@
|
|
|
83
83
|
"scripts": [
|
|
84
84
|
"src/**/*.js"
|
|
85
85
|
]
|
|
86
|
+
},
|
|
87
|
+
"volta": {
|
|
88
|
+
"node": "12.22.8",
|
|
89
|
+
"npm": "6.14.15"
|
|
86
90
|
}
|
|
87
91
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { getAccessLogsFromWarp10InBatches, getContinuousAccessLogsFromWarp10 } = require('@clevercloud/client/cjs/access-logs.js');
|
|
4
|
-
const { getWarp10AccessLogsToken } = require('@clevercloud/client/cjs/api/warp-10.js');
|
|
4
|
+
const { getWarp10AccessLogsToken } = require('@clevercloud/client/cjs/api/v2/warp-10.js');
|
|
5
5
|
const { ONE_HOUR_MICROS, ONE_SECOND_MICROS, toMicroTimestamp } = require('@clevercloud/client/cjs/utils/date.js');
|
|
6
6
|
|
|
7
7
|
const Addon = require('../models/addon.js');
|
package/src/commands/addon.js
CHANGED
|
@@ -9,6 +9,7 @@ const formatTable = require('../format-table')();
|
|
|
9
9
|
const Logger = require('../logger.js');
|
|
10
10
|
const Organisation = require('../models/organisation.js');
|
|
11
11
|
const User = require('../models/user.js');
|
|
12
|
+
const { parseAddonOptions } = require('../models/addon.js');
|
|
12
13
|
|
|
13
14
|
async function list (params) {
|
|
14
15
|
const { org: orgaIdOrName } = params.options;
|
|
@@ -30,6 +31,8 @@ async function list (params) {
|
|
|
30
31
|
async function create (params) {
|
|
31
32
|
const [providerName, name] = params.args;
|
|
32
33
|
const { link: linkedAppAlias, plan: planName, region, yes: skipConfirmation, org: orgaIdOrName } = params.options;
|
|
34
|
+
const version = params.options['addon-version'];
|
|
35
|
+
const addonOptions = parseAddonOptions(params.options.option);
|
|
33
36
|
|
|
34
37
|
const ownerId = (orgaIdOrName != null)
|
|
35
38
|
? await Organisation.getId(orgaIdOrName)
|
|
@@ -47,12 +50,14 @@ async function create (params) {
|
|
|
47
50
|
planName,
|
|
48
51
|
region,
|
|
49
52
|
skipConfirmation,
|
|
53
|
+
version,
|
|
54
|
+
addonOptions,
|
|
50
55
|
});
|
|
51
56
|
await Addon.link(linkedAppData.ownerId, linkedAppData.appId, { addon_id: newAddon.id });
|
|
52
57
|
Logger.println(`Addon ${name} (id: ${newAddon.id}) successfully created and linked to the application`);
|
|
53
58
|
}
|
|
54
59
|
else {
|
|
55
|
-
const newAddon = await Addon.create({ ownerId, name, providerName, planName, region, skipConfirmation });
|
|
60
|
+
const newAddon = await Addon.create({ ownerId, name, providerName, planName, region, skipConfirmation, version, addonOptions });
|
|
56
61
|
Logger.println(`Addon ${name} (id: ${newAddon.id}) successfully created`);
|
|
57
62
|
}
|
|
58
63
|
}
|
|
@@ -85,7 +90,7 @@ async function listProviders () {
|
|
|
85
90
|
return [
|
|
86
91
|
colors.bold(provider.id),
|
|
87
92
|
provider.name,
|
|
88
|
-
provider.shortDesc,
|
|
93
|
+
provider.shortDesc || '',
|
|
89
94
|
];
|
|
90
95
|
});
|
|
91
96
|
Logger.println(formatTable(formattedProviders));
|
|
@@ -95,6 +100,8 @@ async function showProvider (params) {
|
|
|
95
100
|
const [providerName] = params.args;
|
|
96
101
|
|
|
97
102
|
const provider = await Addon.getProvider(providerName);
|
|
103
|
+
const providerInfos = await Addon.getProviderInfos(providerName);
|
|
104
|
+
const providerPlans = provider.plans.sort((a, b) => a.price - b.price);
|
|
98
105
|
|
|
99
106
|
Logger.println(colors.bold(provider.id));
|
|
100
107
|
Logger.println(`${provider.name}: ${provider.shortDesc}`);
|
|
@@ -103,11 +110,35 @@ async function showProvider (params) {
|
|
|
103
110
|
Logger.println();
|
|
104
111
|
Logger.println('Available plans');
|
|
105
112
|
|
|
106
|
-
|
|
113
|
+
providerPlans.forEach((plan) => {
|
|
107
114
|
Logger.println(`Plan ${colors.bold(plan.slug)}`);
|
|
108
115
|
_(plan.features)
|
|
109
116
|
.sortBy('name')
|
|
110
117
|
.forEach(({ name, value }) => Logger.println(` ${name}: ${value}`));
|
|
118
|
+
|
|
119
|
+
if (providerInfos != null) {
|
|
120
|
+
const planType = plan.features.find(({ name }) => name.toLowerCase() === 'type');
|
|
121
|
+
if (planType != null && planType.value.toLowerCase() === 'dedicated') {
|
|
122
|
+
const planVersions = Object.keys(providerInfos.dedicated);
|
|
123
|
+
const versions = planVersions.map((version) => {
|
|
124
|
+
if (version === providerInfos.defaultDedicatedVersion) {
|
|
125
|
+
return `${version} (default)`;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
return version;
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
Logger.println(` Available versions: ${versions.join(', ')}`);
|
|
132
|
+
|
|
133
|
+
planVersions.forEach((version) => {
|
|
134
|
+
const features = providerInfos.dedicated[version].features;
|
|
135
|
+
Logger.println(` Options for version ${version}:`);
|
|
136
|
+
features.forEach(({ name, enabled }) => {
|
|
137
|
+
Logger.println(` ${name}: default=${enabled}`);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
111
142
|
});
|
|
112
143
|
}
|
|
113
144
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const AppConfig = require('../models/app_configuration.js');
|
|
4
4
|
const Logger = require('../logger.js');
|
|
5
|
-
const { getAllDeployments, cancelDeployment } = require('@clevercloud/client/cjs/api/application.js');
|
|
5
|
+
const { getAllDeployments, cancelDeployment } = require('@clevercloud/client/cjs/api/v2/application.js');
|
|
6
6
|
const { sendToApi } = require('../models/send-to-api.js');
|
|
7
7
|
|
|
8
8
|
async function cancelDeploy (params) {
|
package/src/commands/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const application = require('@clevercloud/client/cjs/api/application.js');
|
|
3
|
+
const application = require('@clevercloud/client/cjs/api/v2/application.js');
|
|
4
4
|
|
|
5
5
|
const AppConfig = require('../models/app_configuration.js');
|
|
6
6
|
const Application = require('../models/application.js');
|
package/src/commands/deploy.js
CHANGED
|
@@ -7,7 +7,7 @@ const Application = require('../models/application.js');
|
|
|
7
7
|
const git = require('../models/git.js');
|
|
8
8
|
const Log = require('../models/log.js');
|
|
9
9
|
const Logger = require('../logger.js');
|
|
10
|
-
const { getAllDeployments } = require('@clevercloud/client/cjs/api/application.js');
|
|
10
|
+
const { getAllDeployments } = require('@clevercloud/client/cjs/api/v2/application.js');
|
|
11
11
|
const { sendToApi } = require('../models/send-to-api.js');
|
|
12
12
|
|
|
13
13
|
// Once the API call to redeploy() has been triggered successfully,
|
package/src/commands/domain.js
CHANGED
|
@@ -9,7 +9,7 @@ const {
|
|
|
9
9
|
markFavouriteDomain,
|
|
10
10
|
unmarkFavouriteDomain,
|
|
11
11
|
removeDomain,
|
|
12
|
-
} = require('@clevercloud/client/cjs/api/application.js');
|
|
12
|
+
} = require('@clevercloud/client/cjs/api/v2/application.js');
|
|
13
13
|
const { sendToApi } = require('../models/send-to-api.js');
|
|
14
14
|
|
|
15
15
|
function getFavouriteDomain ({ ownerId, appId }) {
|
package/src/commands/drain.js
CHANGED
|
@@ -4,7 +4,7 @@ const AppConfig = require('../models/app_configuration.js');
|
|
|
4
4
|
const { createDrainBody } = require('../models/drain.js');
|
|
5
5
|
const Logger = require('../logger.js');
|
|
6
6
|
|
|
7
|
-
const { getDrains, createDrain, deleteDrain, updateDrainState } = require('@clevercloud/client/cjs/api/log.js');
|
|
7
|
+
const { getDrains, createDrain, deleteDrain, updateDrainState } = require('@clevercloud/client/cjs/api/v2/log.js');
|
|
8
8
|
const { sendToApi } = require('../models/send-to-api.js');
|
|
9
9
|
|
|
10
10
|
// TODO: This could be useful in other commands
|
package/src/commands/env.js
CHANGED
|
@@ -5,7 +5,7 @@ const Logger = require('../logger.js');
|
|
|
5
5
|
const variables = require('../models/variables.js');
|
|
6
6
|
const { sendToApi } = require('../models/send-to-api.js');
|
|
7
7
|
const { toNameEqualsValueString, validateName } = require('@clevercloud/client/cjs/utils/env-vars.js');
|
|
8
|
-
const application = require('@clevercloud/client/cjs/api/application.js');
|
|
8
|
+
const application = require('@clevercloud/client/cjs/api/v2/application.js');
|
|
9
9
|
|
|
10
10
|
async function list (params) {
|
|
11
11
|
const { alias, 'add-export': addExports } = params.options;
|
|
@@ -5,7 +5,7 @@ const colors = require('colors/safe');
|
|
|
5
5
|
const Logger = require('../logger.js');
|
|
6
6
|
const { getOwnerAndApp, getOrgaIdOrUserId } = require('../models/notification.js');
|
|
7
7
|
|
|
8
|
-
const { getEmailhooks, createEmailhook, deleteEmailhook } = require('@clevercloud/client/cjs/api/notification.js');
|
|
8
|
+
const { getEmailhooks, createEmailhook, deleteEmailhook } = require('@clevercloud/client/cjs/api/v2/notification.js');
|
|
9
9
|
const { sendToApi } = require('../models/send-to-api.js');
|
|
10
10
|
|
|
11
11
|
function displayEmailhook (hook) {
|
|
@@ -55,6 +55,7 @@ function getEmailNotificationTargets (notifTargets) {
|
|
|
55
55
|
if (el.toLowerCase() === 'organisation') {
|
|
56
56
|
return { type: 'organisation' };
|
|
57
57
|
}
|
|
58
|
+
return null;
|
|
58
59
|
})
|
|
59
60
|
.filter((e) => e != null);
|
|
60
61
|
}
|
|
@@ -5,7 +5,7 @@ const Logger = require('../logger.js');
|
|
|
5
5
|
const variables = require('../models/variables.js');
|
|
6
6
|
const { sendToApi } = require('../models/send-to-api.js');
|
|
7
7
|
const { toNameEqualsValueString, validateName } = require('@clevercloud/client/cjs/utils/env-vars.js');
|
|
8
|
-
const application = require('@clevercloud/client/cjs/api/application.js');
|
|
8
|
+
const application = require('@clevercloud/client/cjs/api/v2/application.js');
|
|
9
9
|
|
|
10
10
|
async function list (params) {
|
|
11
11
|
const { alias } = params.options;
|
package/src/commands/status.js
CHANGED
|
@@ -6,7 +6,7 @@ const colors = require('colors/safe');
|
|
|
6
6
|
const AppConfig = require('../models/app_configuration.js');
|
|
7
7
|
const Logger = require('../logger.js');
|
|
8
8
|
|
|
9
|
-
const { get: getApplication, getAllInstances } = require('@clevercloud/client/cjs/api/application.js');
|
|
9
|
+
const { get: getApplication, getAllInstances } = require('@clevercloud/client/cjs/api/v2/application.js');
|
|
10
10
|
const { sendToApi } = require('../models/send-to-api.js');
|
|
11
11
|
|
|
12
12
|
function displayGroupInfo (instances, commit) {
|
package/src/commands/stop.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const AppConfig = require('../models/app_configuration.js');
|
|
4
|
-
const application = require('@clevercloud/client/cjs/api/application.js');
|
|
4
|
+
const application = require('@clevercloud/client/cjs/api/v2/application.js');
|
|
5
5
|
const Logger = require('../logger.js');
|
|
6
6
|
const { sendToApi } = require('../models/send-to-api.js');
|
|
7
7
|
|
|
@@ -7,7 +7,7 @@ const Organisation = require('../models/organisation.js');
|
|
|
7
7
|
const { sendToApi } = require('../models/send-to-api.js');
|
|
8
8
|
const Interact = require('../models/interact.js');
|
|
9
9
|
const Logger = require('../logger.js');
|
|
10
|
-
const application = require('@clevercloud/client/cjs/api/application.js');
|
|
10
|
+
const application = require('@clevercloud/client/cjs/api/v2/application.js');
|
|
11
11
|
|
|
12
12
|
async function listNamespaces (params) {
|
|
13
13
|
const namespaces = await Organisation.getNamespaces(params);
|
package/src/commands/webhooks.js
CHANGED
|
@@ -5,7 +5,7 @@ const colors = require('colors/safe');
|
|
|
5
5
|
const Logger = require('../logger.js');
|
|
6
6
|
const { getOwnerAndApp, getOrgaIdOrUserId } = require('../models/notification.js');
|
|
7
7
|
|
|
8
|
-
const { getWebhooks, createWebhook, deleteWebhook } = require('@clevercloud/client/cjs/api/notification.js');
|
|
8
|
+
const { getWebhooks, createWebhook, deleteWebhook } = require('@clevercloud/client/cjs/api/v2/notification.js');
|
|
9
9
|
const { sendToApi } = require('../models/send-to-api.js');
|
|
10
10
|
|
|
11
11
|
function displayWebhook (hook) {
|
package/src/models/accesslogs.js
CHANGED
|
@@ -19,12 +19,22 @@ function getFormatter (format, isAddon) {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
function formatSource (l) {
|
|
23
|
+
if (l.s != null) {
|
|
24
|
+
const location = l.s.ct ? `${l.s.ct}, ${l.s.co}` : l.s.co;
|
|
25
|
+
return `${l.ipS} - ${location}`;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
return l.ipS;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
function formatSimple (l) {
|
|
23
33
|
return `${new Date(l.t).toISOString()} ${l.ipS} ${l.vb} ${l.path}`;
|
|
24
34
|
}
|
|
25
35
|
|
|
26
36
|
function formatExtended (l) {
|
|
27
|
-
return `${new Date(l.t).toISOString()} [ ${l
|
|
37
|
+
return `${new Date(l.t).toISOString()} [ ${formatSource(l)} ] ${l.vb} ${l.h} ${l.path} ${l.sC}`;
|
|
28
38
|
}
|
|
29
39
|
|
|
30
40
|
function formatCLF (l) {
|
|
@@ -36,7 +46,7 @@ function formatSimpleAddon (l) {
|
|
|
36
46
|
}
|
|
37
47
|
|
|
38
48
|
function formatExtendedAddon (l) {
|
|
39
|
-
return `${new Date(l.t).toISOString()} [ ${l
|
|
49
|
+
return `${new Date(l.t).toISOString()} [ ${formatSource(l)} ] duration(ms): ${l.sDuration}`;
|
|
40
50
|
}
|
|
41
51
|
|
|
42
52
|
function formatCLFAddon (l) {
|
package/src/models/activity.js
CHANGED
package/src/models/addon.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const application = require('@clevercloud/client/cjs/api/application.js');
|
|
3
|
+
const application = require('@clevercloud/client/cjs/api/v2/application.js');
|
|
4
4
|
const autocomplete = require('cliparse').autocomplete;
|
|
5
5
|
const colors = require('colors/safe');
|
|
6
|
-
const { get: getAddon, getAll: getAllAddons, remove: removeAddon, create: createAddon, preorder: preorderAddon, update: updateAddon } = require('@clevercloud/client/cjs/api/addon.js');
|
|
7
|
-
const { getAllAddonProviders } = require('@clevercloud/client/cjs/api/product.js');
|
|
8
|
-
const { getSummary } = require('@clevercloud/client/cjs/api/user.js');
|
|
6
|
+
const { get: getAddon, getAll: getAllAddons, remove: removeAddon, create: createAddon, preorder: preorderAddon, update: updateAddon } = require('@clevercloud/client/cjs/api/v2/addon.js');
|
|
7
|
+
const { getAllAddonProviders } = require('@clevercloud/client/cjs/api/v2/product.js');
|
|
8
|
+
const { getSummary } = require('@clevercloud/client/cjs/api/v2/user.js');
|
|
9
|
+
const { getAddonProvider } = require('@clevercloud/client/cjs/api/v4/addon-providers.js');
|
|
9
10
|
|
|
10
11
|
const Interact = require('./interact.js');
|
|
11
12
|
const Logger = require('../logger.js');
|
|
@@ -24,6 +25,16 @@ async function getProvider (providerName) {
|
|
|
24
25
|
return provider;
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
function getProviderInfos (providerName) {
|
|
29
|
+
return getAddonProvider({ providerId: providerName }).then(sendToApi)
|
|
30
|
+
.catch(() => {
|
|
31
|
+
// An error can occur because the add-on api doesn't implement this endpoint yet
|
|
32
|
+
// This is fine, just ignore it
|
|
33
|
+
Logger.debug(`${providerName} doesn't yet implement the provider info endpoint`);
|
|
34
|
+
return Promise.resolve(null);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
27
38
|
async function list (ownerId, appId, showAll) {
|
|
28
39
|
const allAddons = await getAllAddons({ id: ownerId }).then(sendToApi);
|
|
29
40
|
|
|
@@ -45,7 +56,78 @@ async function list (ownerId, appId, showAll) {
|
|
|
45
56
|
});
|
|
46
57
|
}
|
|
47
58
|
|
|
48
|
-
|
|
59
|
+
function validateAddonVersionAndOptions (region, version, addonOptions, providerInfos, planType) {
|
|
60
|
+
if (providerInfos != null) {
|
|
61
|
+
if (version != null) {
|
|
62
|
+
const type = planType.value.toLowerCase();
|
|
63
|
+
if (type === 'shared') {
|
|
64
|
+
const cluster = providerInfos.clusters.find(({ zone }) => zone === region);
|
|
65
|
+
if (cluster == null) {
|
|
66
|
+
throw new Error(`Can't find cluster for region ${region}`);
|
|
67
|
+
}
|
|
68
|
+
else if (cluster.version !== version) {
|
|
69
|
+
throw new Error(`Invalid version ${version}, selected shared cluster only supports version ${cluster.version}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else if (type === 'dedicated') {
|
|
73
|
+
const availableVersions = Object.keys(providerInfos.dedicated);
|
|
74
|
+
const hasVersion = availableVersions.find((availableVersion) => availableVersion === version);
|
|
75
|
+
if (hasVersion == null) {
|
|
76
|
+
throw new Error(`Invalid version ${addonOptions.version}, available versions are: ${availableVersions.join(', ')}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const chosenVersion = version != null ? version : providerInfos.defaultDedicatedVersion;
|
|
82
|
+
|
|
83
|
+
// Check the selected options to see if the chosen plan / region offers them
|
|
84
|
+
// If not, abort the creation
|
|
85
|
+
if (Object.keys(addonOptions).length > 0) {
|
|
86
|
+
const type = planType.value.toLowerCase();
|
|
87
|
+
let availableOptions = [];
|
|
88
|
+
if (type === 'shared') {
|
|
89
|
+
const cluster = providerInfos.clusters.find(({ zone }) => zone === region);
|
|
90
|
+
if (cluster == null) {
|
|
91
|
+
throw new Error(`Can't find cluster for region ${region}`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
availableOptions = cluster.features;
|
|
95
|
+
}
|
|
96
|
+
else if (type === 'dedicated') {
|
|
97
|
+
availableOptions = providerInfos.dedicated[chosenVersion].features;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
for (const selectedOption in addonOptions) {
|
|
101
|
+
const isAvailable = availableOptions.find(({ name }) => name === selectedOption);
|
|
102
|
+
if (isAvailable == null) {
|
|
103
|
+
const optionNames = availableOptions.map(({ name }) => name).join(',');
|
|
104
|
+
let availableOptionsError = null;
|
|
105
|
+
if (optionNames.length > 0) {
|
|
106
|
+
availableOptionsError = `Avalailble options are: ${optionNames}.`;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
availableOptionsError = 'No options are available for this plan.';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
throw new Error(`Option "${selectedOption}" is not available on this plan. ${availableOptionsError}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
version: chosenVersion,
|
|
119
|
+
...addonOptions,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
if (version != null) {
|
|
124
|
+
throw new Error('You provided a version for an add-on that doesn\'t support choosing the version.');
|
|
125
|
+
}
|
|
126
|
+
return {};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async function create ({ ownerId, name, providerName, planName, region, skipConfirmation, version, addonOptions }) {
|
|
49
131
|
|
|
50
132
|
// TODO: We should be able to use it without {}
|
|
51
133
|
const providers = await listProviders();
|
|
@@ -58,13 +140,33 @@ async function create ({ ownerId, name, providerName, planName, region, skipConf
|
|
|
58
140
|
throw new Error(`invalid region name. Available regions: ${provider.regions.join(', ')}`);
|
|
59
141
|
}
|
|
60
142
|
|
|
61
|
-
const plan = provider.plans.find((p) => p.slug === planName);
|
|
143
|
+
const plan = provider.plans.find((p) => p.slug.toLowerCase() === planName.toLowerCase());
|
|
62
144
|
if (plan == null) {
|
|
63
145
|
const availablePlans = provider.plans.map((p) => p.slug);
|
|
64
146
|
throw new Error(`invalid plan name. Available plans: ${availablePlans.join(', ')}`);
|
|
65
147
|
}
|
|
66
148
|
|
|
67
|
-
const
|
|
149
|
+
const providerInfos = await getProviderInfos(provider.id);
|
|
150
|
+
const planType = plan.features.find(({ name }) => name.toLowerCase() === 'type');
|
|
151
|
+
|
|
152
|
+
// If we have a providerInfos but we don't have a planType, we won't be able to go further
|
|
153
|
+
// The process should stop here to make sure users don't create something they don't intend to
|
|
154
|
+
// This missing feature should have been added during the add-on's development phase
|
|
155
|
+
// The console has a similar check so I believe we shouldn't hit this
|
|
156
|
+
if (providerInfos != null && planType == null) {
|
|
157
|
+
throw new Error('Internal error. The selected plan misses the TYPE feature. Please contact our support with the command line you used');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const createOptions = validateAddonVersionAndOptions(region, version, addonOptions, providerInfos, planType);
|
|
161
|
+
|
|
162
|
+
const addonToCreate = {
|
|
163
|
+
name,
|
|
164
|
+
plan: plan.id,
|
|
165
|
+
providerId: provider.id,
|
|
166
|
+
region,
|
|
167
|
+
options: createOptions,
|
|
168
|
+
};
|
|
169
|
+
|
|
68
170
|
const result = await preorderAddon({ id: ownerId }, addonToCreate).then(sendToApi);
|
|
69
171
|
|
|
70
172
|
if (result.totalTTC > 0 && !skipConfirmation) {
|
|
@@ -129,7 +231,7 @@ async function rename (ownerId, addon, name) {
|
|
|
129
231
|
}
|
|
130
232
|
|
|
131
233
|
function completeRegion () {
|
|
132
|
-
return autocomplete.words(['
|
|
234
|
+
return autocomplete.words(['par', 'mtl']);
|
|
133
235
|
}
|
|
134
236
|
|
|
135
237
|
// TODO: We need to fix this
|
|
@@ -153,6 +255,33 @@ async function findById (addonId) {
|
|
|
153
255
|
throw new Error(`Could not find add-on with ID: ${addonId}`);
|
|
154
256
|
}
|
|
155
257
|
|
|
258
|
+
function parseAddonOptions (options) {
|
|
259
|
+
if (options == null) {
|
|
260
|
+
return {};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return options.split(',').reduce((options, option) => {
|
|
264
|
+
const [key, value] = option.split('=');
|
|
265
|
+
if (value == null) {
|
|
266
|
+
throw new Error("Options are malformed. Usage is '--option name=enabled|disabled|true|false'");
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
let formattedValue = value;
|
|
270
|
+
if (value === 'true' || value === 'enabled') {
|
|
271
|
+
formattedValue = 'true';
|
|
272
|
+
}
|
|
273
|
+
else if (value === 'false' || value === 'disabled') {
|
|
274
|
+
formattedValue = 'false';
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
throw new Error(`Can't parse option value: ${value}. Accepted values are: enabled, disabled, true, false`);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
options[key] = formattedValue;
|
|
281
|
+
return options;
|
|
282
|
+
}, {});
|
|
283
|
+
}
|
|
284
|
+
|
|
156
285
|
module.exports = {
|
|
157
286
|
completePlan,
|
|
158
287
|
completeRegion,
|
|
@@ -160,9 +289,11 @@ module.exports = {
|
|
|
160
289
|
delete: deleteAddon,
|
|
161
290
|
findById,
|
|
162
291
|
getProvider,
|
|
292
|
+
getProviderInfos,
|
|
163
293
|
link,
|
|
164
294
|
list,
|
|
165
295
|
listProviders,
|
|
296
|
+
parseAddonOptions,
|
|
166
297
|
rename,
|
|
167
298
|
unlink,
|
|
168
299
|
};
|
|
@@ -111,7 +111,7 @@ async function getAppDetails ({ alias }) {
|
|
|
111
111
|
};
|
|
112
112
|
|
|
113
113
|
function persistConfig (modifiedConfig) {
|
|
114
|
-
const jsonContents = JSON.stringify(modifiedConfig);
|
|
114
|
+
const jsonContents = JSON.stringify(modifiedConfig, null, 2);
|
|
115
115
|
return fs.writeFile(conf.APP_CONFIGURATION_FILE, jsonContents);
|
|
116
116
|
};
|
|
117
117
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const _ = require('lodash');
|
|
4
|
-
const application = require('@clevercloud/client/cjs/api/application.js');
|
|
4
|
+
const application = require('@clevercloud/client/cjs/api/v2/application.js');
|
|
5
5
|
const autocomplete = require('cliparse').autocomplete;
|
|
6
|
-
const product = require('@clevercloud/client/cjs/api/product.js');
|
|
6
|
+
const product = require('@clevercloud/client/cjs/api/v2/product.js');
|
|
7
7
|
|
|
8
8
|
const AppConfiguration = require('./app_configuration.js');
|
|
9
9
|
const Interact = require('./interact.js');
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const fs = require('fs');
|
|
3
|
+
const { promises: fs } = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
|
-
const util = require('util');
|
|
6
|
-
|
|
7
|
-
const readFile = util.promisify(fs.readFile);
|
|
8
|
-
const writeFile = util.promisify(fs.writeFile);
|
|
9
5
|
|
|
10
6
|
const commonEnv = require('common-env');
|
|
11
7
|
const mkdirp = require('mkdirp');
|
|
@@ -14,7 +10,7 @@ const xdg = require('xdg');
|
|
|
14
10
|
const Logger = require('../logger.js');
|
|
15
11
|
const env = commonEnv(Logger);
|
|
16
12
|
|
|
17
|
-
function
|
|
13
|
+
function getConfigDir () {
|
|
18
14
|
if (process.platform === 'win32') {
|
|
19
15
|
return path.resolve(process.env.APPDATA, 'clever-cloud');
|
|
20
16
|
}
|
|
@@ -23,6 +19,37 @@ function getConfigPath () {
|
|
|
23
19
|
}
|
|
24
20
|
}
|
|
25
21
|
|
|
22
|
+
function getConfigPath () {
|
|
23
|
+
const configDir = getConfigDir();
|
|
24
|
+
return path.resolve(configDir, 'clever-tools.json');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function isFile (path) {
|
|
28
|
+
try {
|
|
29
|
+
const pathStat = await fs.stat(path);
|
|
30
|
+
return pathStat.isFile();
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function maybeMigrateFromLegacyConfigurationPath () {
|
|
38
|
+
// This used to be a file
|
|
39
|
+
const configDir = getConfigDir();
|
|
40
|
+
const legacyConfig = await isFile(configDir);
|
|
41
|
+
// If it is still a file, we replace it with a dir and move it inside
|
|
42
|
+
if (legacyConfig) {
|
|
43
|
+
const tmpConfigFile = `${configDir}.tmp`;
|
|
44
|
+
const configFile = getConfigPath();
|
|
45
|
+
|
|
46
|
+
// Rename so that we can create the directory
|
|
47
|
+
await fs.rename(configDir, tmpConfigFile);
|
|
48
|
+
await mkdirp(configDir, { mode: 0o700 });
|
|
49
|
+
await fs.rename(tmpConfigFile, configFile);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
26
53
|
async function loadOAuthConf () {
|
|
27
54
|
Logger.debug('Load configuration from environment variables');
|
|
28
55
|
if (process.env.CLEVER_TOKEN != null && process.env.CLEVER_SECRET != null) {
|
|
@@ -32,8 +59,9 @@ async function loadOAuthConf () {
|
|
|
32
59
|
};
|
|
33
60
|
}
|
|
34
61
|
Logger.debug('Load configuration from ' + conf.CONFIGURATION_FILE);
|
|
62
|
+
await maybeMigrateFromLegacyConfigurationPath();
|
|
35
63
|
try {
|
|
36
|
-
const rawFile = await readFile(conf.CONFIGURATION_FILE);
|
|
64
|
+
const rawFile = await fs.readFile(conf.CONFIGURATION_FILE);
|
|
37
65
|
return JSON.parse(rawFile);
|
|
38
66
|
}
|
|
39
67
|
catch (error) {
|
|
@@ -47,7 +75,7 @@ async function writeOAuthConf (oauthData) {
|
|
|
47
75
|
const configDir = path.dirname(conf.CONFIGURATION_FILE);
|
|
48
76
|
try {
|
|
49
77
|
await mkdirp(configDir, { mode: 0o700 });
|
|
50
|
-
await writeFile(conf.CONFIGURATION_FILE, JSON.stringify(oauthData));
|
|
78
|
+
await fs.writeFile(conf.CONFIGURATION_FILE, JSON.stringify(oauthData));
|
|
51
79
|
}
|
|
52
80
|
catch (error) {
|
|
53
81
|
throw new Error(`Cannot write configuration to ${conf.CONFIGURATION_FILE}\n${error.message}`);
|
|
@@ -55,8 +83,8 @@ async function writeOAuthConf (oauthData) {
|
|
|
55
83
|
}
|
|
56
84
|
|
|
57
85
|
const conf = env.getOrElseAll({
|
|
58
|
-
API_HOST: 'https://api.clever-cloud.com
|
|
59
|
-
// API_HOST: 'https://ccapi-preprod.cleverapps.io
|
|
86
|
+
API_HOST: 'https://api.clever-cloud.com',
|
|
87
|
+
// API_HOST: 'https://ccapi-preprod.cleverapps.io',
|
|
60
88
|
LOG_WS_URL: 'wss://api.clever-cloud.com/v2/logs/logs-socket/<%- appId %>?since=<%- timestamp %>',
|
|
61
89
|
LOG_HTTP_URL: 'https://api.clever-cloud.com/v2/logs/<%- appId %>',
|
|
62
90
|
EVENT_URL: 'wss://api.clever-cloud.com/v2/events/event-socket',
|
|
@@ -4,7 +4,7 @@ const { promisify } = require('util');
|
|
|
4
4
|
const delay = promisify(setTimeout);
|
|
5
5
|
|
|
6
6
|
const Logger = require('../logger.js');
|
|
7
|
-
const { getDeployment, getAllDeployments } = require('@clevercloud/client/cjs/api/application.js');
|
|
7
|
+
const { getDeployment, getAllDeployments } = require('@clevercloud/client/cjs/api/v2/application.js');
|
|
8
8
|
const { sendToApi } = require('./send-to-api.js');
|
|
9
9
|
|
|
10
10
|
const DEPLOYMENT_POLLING_DELAY = 5000;
|
|
@@ -30,6 +30,7 @@ async function waitForDeploymentStart ({ ownerId, appId, deploymentId, commitId,
|
|
|
30
30
|
const isNew = knownDeployments.every(({ uuid }) => uuid !== d.uuid);
|
|
31
31
|
return isNew && d.commit === commitId;
|
|
32
32
|
}
|
|
33
|
+
return false;
|
|
33
34
|
});
|
|
34
35
|
if (deployment != null) {
|
|
35
36
|
Logger.debug(`Deployment has started (state:${deployment.state})`);
|
package/src/models/domain.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const _ = require('lodash');
|
|
4
4
|
|
|
5
5
|
const Logger = require('../logger.js');
|
|
6
|
-
const { getAllDomains, getFavouriteDomain } = require('@clevercloud/client/cjs/api/application.js');
|
|
6
|
+
const { getAllDomains, getFavouriteDomain } = require('@clevercloud/client/cjs/api/v2/application.js');
|
|
7
7
|
const { sendToApi } = require('../models/send-to-api.js');
|
|
8
8
|
|
|
9
9
|
async function getBest (appId, orgaId) {
|
package/src/models/fs-utils.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { join } = require('path');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const { promisify } = require('util');
|
|
6
|
-
|
|
7
|
-
const fsStat = promisify(fs.stat);
|
|
4
|
+
const { promises: fs } = require('fs');
|
|
8
5
|
|
|
9
6
|
function findPath (dir, name) {
|
|
10
7
|
const fullPath = join(dir, name);
|
|
11
|
-
return
|
|
8
|
+
return fs.stat(fullPath)
|
|
12
9
|
.then(() => dir)
|
|
13
10
|
.catch((e) => {
|
|
14
11
|
if (e.code === 'ENOENT' && dir !== '/') {
|
package/src/models/git.js
CHANGED
|
@@ -36,7 +36,8 @@ async function addRemote (remoteName, url) {
|
|
|
36
36
|
const allRemotes = await git.listRemotes({ ...repo });
|
|
37
37
|
const existingRemote = _.find(allRemotes, { remote: safeRemoteName });
|
|
38
38
|
if (existingRemote == null) {
|
|
39
|
-
|
|
39
|
+
// In some situations, we may end up with race conditions so we force it
|
|
40
|
+
return git.addRemote({ ...repo, remote: safeRemoteName, url, force: true });
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
|
package/src/models/log.js
CHANGED
|
@@ -5,7 +5,7 @@ const colors = require('colors/safe');
|
|
|
5
5
|
|
|
6
6
|
const Logger = require('../logger.js');
|
|
7
7
|
const { Deferred } = require('./utils.js');
|
|
8
|
-
const { getOldLogs } = require('@clevercloud/client/cjs/api/log.js');
|
|
8
|
+
const { getOldLogs } = require('@clevercloud/client/cjs/api/v2/log.js');
|
|
9
9
|
const { LogsStream } = require('@clevercloud/client/cjs/streams/logs.node.js');
|
|
10
10
|
const { sendToApi, getHostAndTokens } = require('./send-to-api.js');
|
|
11
11
|
const { waitForDeploymentEnd, waitForDeploymentStart } = require('./deployments.js');
|
|
@@ -25,7 +25,8 @@ function isDeploymentFailedMessage (line) {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
function isBuildSucessMessage (line) {
|
|
28
|
-
return
|
|
28
|
+
return isCleverMessage(line)
|
|
29
|
+
&& _.startsWith(line._source['@message'].toLowerCase(), 'build succeeded in');
|
|
29
30
|
};
|
|
30
31
|
|
|
31
32
|
function formatLogLine (line) {
|
|
@@ -115,7 +116,7 @@ async function watchDeploymentAndDisplayLogs ({ ownerId, appId, deploymentId, co
|
|
|
115
116
|
// displayLiveLogs() defines callback listeners so if it catches error in those callbacks,
|
|
116
117
|
// it has no proper way to bubble up the error here.
|
|
117
118
|
// Using the deferred enables this.
|
|
118
|
-
logsStream = await displayLiveLogs({ appId, deploymentId }, deferred);
|
|
119
|
+
logsStream = await displayLiveLogs({ appId, deploymentId: deployment.uuid }, deferred);
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
Logger.println('Waiting for application logs…');
|
|
@@ -5,8 +5,8 @@ const autocomplete = require('cliparse').autocomplete;
|
|
|
5
5
|
|
|
6
6
|
const AppConfig = require('./app_configuration.js');
|
|
7
7
|
|
|
8
|
-
const organisation = require('@clevercloud/client/cjs/api/organisation.js');
|
|
9
|
-
const { getSummary } = require('@clevercloud/client/cjs/api/user.js');
|
|
8
|
+
const organisation = require('@clevercloud/client/cjs/api/v2/organisation.js');
|
|
9
|
+
const { getSummary } = require('@clevercloud/client/cjs/api/v2/user.js');
|
|
10
10
|
const { sendToApi } = require('../models/send-to-api.js');
|
|
11
11
|
|
|
12
12
|
async function getId (orgaIdOrName) {
|
package/src/models/user.js
CHANGED