Skip to content

Commit e43df1a

Browse files
committed
Add update traefik command, closes #49
1 parent 61b19f2 commit e43df1a

File tree

4 files changed

+187
-1
lines changed

4 files changed

+187
-1
lines changed

src/commands/update.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// npm packages
2+
const _ = require('lodash');
3+
const got = require('got');
4+
const chalk = require('chalk');
5+
6+
// our packages
7+
const {userConfig, isLoggedIn, logout} = require('../config');
8+
9+
// valid targets list
10+
const validTargets = ['traefik'];
11+
12+
exports.command = ['update [target]'];
13+
exports.describe = 'update given target';
14+
exports.builder = {
15+
target: {
16+
alias: 't',
17+
description: `Target for update (${validTargets.join(', ')})`,
18+
},
19+
};
20+
exports.handler = async ({target} = {target: 'self'}) => {
21+
if (!isLoggedIn()) {
22+
return;
23+
}
24+
25+
if (!validTargets.includes(target)) {
26+
console.log(
27+
chalk.red('Error!'),
28+
'Invalid target! Should be one of:',
29+
validTargets.map(it => chalk.green(it)).join(', ')
30+
);
31+
return;
32+
}
33+
34+
console.log(chalk.bold(`Updating ${target} on:`), userConfig.endpoint);
35+
36+
// services request url
37+
const remoteUrl = `${userConfig.endpoint}/update/${target}`;
38+
// construct shared request params
39+
const options = {
40+
headers: {
41+
Authorization: `Bearer ${userConfig.token}`,
42+
},
43+
json: true,
44+
};
45+
// try sending request
46+
try {
47+
const {body, statusCode} = await got.post(remoteUrl, options);
48+
if (statusCode !== 200 || body.error) {
49+
throw new Error(body.error || 'Oops. Something went wrong! Try again please.');
50+
}
51+
52+
if (body.updated) {
53+
console.log(chalk.green(`Successfully updated ${target}!`));
54+
return;
55+
}
56+
57+
console.log(chalk.green(`${_.capitalize(target)} is already up to date!`));
58+
} catch (e) {
59+
// if authorization is expired/broken/etc
60+
if (e.statusCode === 401) {
61+
logout(userConfig);
62+
console.log(chalk.red('Error: authorization expired!'), 'Please, relogin and try again.');
63+
return;
64+
}
65+
66+
const reason = e.response.body ? e.response.body.error : e.toString();
67+
console.log(chalk.red(`Error updating ${target}:`), reason);
68+
console.log('Update log:\n');
69+
e.response.body.log
70+
.split('\n')
71+
.map(l => {
72+
try {
73+
return JSON.parse(l);
74+
} catch (e) {
75+
return l;
76+
}
77+
})
78+
.filter(l => l !== undefined)
79+
.map(l => l.trim())
80+
.filter(l => l && l.length > 0)
81+
.forEach(line => console.log(line));
82+
}
83+
};

src/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const remove = require('./commands/remove');
1313
const endpoint = require('./commands/endpoint');
1414
const config = require('./commands/config');
1515
const token = require('./commands/token');
16+
const update = require('./commands/update');
1617

1718
// init program
1819
yargs
@@ -27,4 +28,5 @@ yargs
2728
.command(logs)
2829
.command(remove)
2930
.command(token)
30-
.command(config).argv;
31+
.command(config)
32+
.command(update).argv;

test/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const list = require('./list');
77
const config = require('./config');
88
const token = require('./token');
99
const endpoint = require('./endpoint');
10+
const update = require('./update');
1011

1112
// run tests
1213
login();
@@ -17,3 +18,4 @@ list();
1718
config();
1819
token();
1920
endpoint();
21+
update();

test/update.js

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// npm packages
2+
const tap = require('tap');
3+
const nock = require('nock');
4+
const sinon = require('sinon');
5+
6+
// our packages
7+
const {handler: update} = require('../src/commands/update');
8+
const {userConfig, updateConfig} = require('../src/config');
9+
10+
module.exports = () => {
11+
// test update
12+
tap.test('Should update traefik', t => {
13+
// handle correct request
14+
const updateServer = nock('http://localhost:8080').post('/update/traefik').reply(200, {updated: true});
15+
// spy on console
16+
const consoleSpy = sinon.spy(console, 'log');
17+
// execute login
18+
update({target: 'traefik'}).then(() => {
19+
// make sure log in was successful
20+
// check that server was called
21+
t.ok(updateServer.isDone());
22+
// first check console output
23+
t.deepEqual(
24+
consoleSpy.args,
25+
[['Updating traefik on:', 'http://localhost:8080'], ['Successfully updated traefik!']],
26+
'Correct log output'
27+
);
28+
// restore console
29+
console.log.restore();
30+
updateServer.done();
31+
t.end();
32+
});
33+
});
34+
35+
// test update error
36+
tap.test('Should display update error', t => {
37+
// handle correct request
38+
const response = {updated: false, error: 'Test error', log: 'log'};
39+
const updateServer = nock('http://localhost:8080').post('/update/traefik').reply(500, response);
40+
// spy on console
41+
const consoleSpy = sinon.spy(console, 'log');
42+
// execute login
43+
update({target: 'traefik'}).then(() => {
44+
// make sure log in was successful
45+
// check that server was called
46+
t.ok(updateServer.isDone());
47+
// first check console output
48+
t.deepEqual(
49+
consoleSpy.args,
50+
[
51+
['Updating traefik on:', 'http://localhost:8080'],
52+
['Error updating traefik:', 'Test error'],
53+
['Update log:\n'],
54+
['log'],
55+
],
56+
'Correct log output'
57+
);
58+
// restore console
59+
console.log.restore();
60+
updateServer.done();
61+
t.end();
62+
});
63+
});
64+
65+
// test deauth
66+
tap.test('Should deauth on 401', t => {
67+
// copy original config for restoration
68+
const originalConfig = Object.assign({}, userConfig);
69+
// handle correct request
70+
const updateServer = nock('http://localhost:8080').post(`/update/traefik`).reply(401);
71+
// spy on console
72+
const consoleSpy = sinon.spy(console, 'log');
73+
// execute login
74+
update({target: 'traefik'}).then(() => {
75+
// make sure log in was successful
76+
// check that server was called
77+
t.ok(updateServer.isDone());
78+
// first check console output
79+
t.deepEqual(
80+
consoleSpy.args,
81+
[
82+
['Updating traefik on:', 'http://localhost:8080'],
83+
['Error: authorization expired!', 'Please, relogin and try again.'],
84+
],
85+
'Correct log output'
86+
);
87+
// check config
88+
t.notOk(userConfig.user, 'Should not have user');
89+
t.notOk(userConfig.token, 'Should not have token');
90+
// restore console
91+
console.log.restore();
92+
// tear down nock
93+
updateServer.done();
94+
// restore original config
95+
updateConfig(originalConfig);
96+
t.end();
97+
});
98+
});
99+
};

0 commit comments

Comments
 (0)