Skip to content

Commit 6468999

Browse files
Initial commit
0 parents  commit 6468999

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+4457
-0
lines changed

.gitignore

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
8+
# Runtime data
9+
pids
10+
*.pid
11+
*.seed
12+
*.pid.lock
13+
14+
# Directory for instrumented libs generated by jscoverage/JSCover
15+
lib-cov
16+
17+
# Coverage directory used by tools like istanbul
18+
coverage
19+
20+
# nyc test coverage
21+
.nyc_output
22+
23+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24+
.grunt
25+
26+
# Bower dependency directory (https://bower.io/)
27+
bower_components
28+
29+
# node-waf configuration
30+
.lock-wscript
31+
32+
# Compiled binary addons (http://nodejs.org/api/addons.html)
33+
build/Release
34+
35+
# Dependency directories
36+
node_modules/
37+
jspm_packages/
38+
39+
# Typescript v1 declaration files
40+
typings/
41+
42+
# Optional npm cache directory
43+
.npm
44+
45+
# Optional eslint cache
46+
.eslintcache
47+
48+
# Optional REPL history
49+
.node_repl_history
50+
51+
# Output of 'npm pack'
52+
*.tgz
53+
54+
# Yarn Integrity file
55+
.yarn-integrity
56+
57+
# dotenv environment variables file
58+
.env
59+

CHANGELOG.md

Whitespace-only changes.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2017 Warsaw Data Center
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# h1 cli client

bin/_plugins/api.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict';
2+
3+
const api = require('lib/api');
4+
5+
module.exports = {
6+
onBeforeConfigure: context => {
7+
const node = context.node;
8+
9+
node.addOption('verbose', {
10+
alias: 'v'
11+
, description: 'verbose'
12+
, defaultValue: !!process.env.H1_DEFAULT_VERBOSE
13+
, type: 'boolean'
14+
});
15+
16+
// websocks depends on no-wait existing and being false
17+
node.addOption('no-wait', {
18+
description: 'in case of queued event do not wait for completion'
19+
, type: 'boolean'
20+
});
21+
22+
node.addOption('dry-run', {
23+
description: 'dry run for the request'
24+
, type: 'boolean'
25+
});
26+
}
27+
, onBeforeHandler: context => {
28+
api.setVerbose(context.args.verbose);
29+
api.setArgs(context.args);
30+
31+
context.args.helpers = context.args.helpers || {};
32+
context.args.helpers.api = api;
33+
}
34+
};

bin/_plugins/confirmYes.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
'use strict';
2+
3+
module.exports = {
4+
onBeforeConfigure: context => {
5+
const node = context.node;
6+
7+
node.addOption('yes',
8+
{
9+
description: 'confirm yes',
10+
type: 'boolean'
11+
});
12+
}
13+
};

bin/_plugins/interactiveOptions.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
'use strict';
2+
3+
module.exports = {
4+
onBeforeHandler: context => {
5+
let p = Promise.resolve();
6+
7+
Object
8+
.keys(context.args)
9+
.filter(arg => /^[^\$]/.test(arg))
10+
.filter(arg => context.args[arg] && !!context.args[arg].interactive)
11+
.forEach(arg => {
12+
p = p
13+
.then(() => context.args[arg].interactive(context))
14+
.then(prompt => context.args[arg] = prompt.value);
15+
});
16+
17+
return p;
18+
}
19+
};

bin/_plugins/loginRequired.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict';
2+
3+
const config = require('lib/config');
4+
const logger = require('lib/logger');
5+
6+
const login = require('bin/login');
7+
8+
const api = require('./api');
9+
10+
module.exports = {
11+
onBeforeHandler: context => {
12+
const profile = config.get('profile', {});
13+
14+
if (profile.apiKey && profile.expires && new Date(profile.expires) > Date.now()) {
15+
context.args.profile = profile;
16+
context.args.apiKey = profile.apiKey;
17+
return;
18+
}
19+
20+
// Hack to reuse login handler
21+
api.onBeforeHandler(context);
22+
23+
const username = context.args.username;
24+
25+
if (profile.user) {
26+
logger('info', `Your authtoken expired, trying to login using ssh "${profile.user}"`);
27+
context.args.username = profile.user;
28+
} else {
29+
return logger('info', 'Please login first');
30+
}
31+
32+
return login
33+
.handler(context.args)
34+
.then(() => context.args.username = username)
35+
;
36+
}
37+
};

bin/_plugins/outputFormat.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
'use strict';
2+
3+
const jmespath = require('jmespath');
4+
const tabula = require('tabula');
5+
const _ = require('lodash');
6+
7+
const queryFilter = (args, result) => {
8+
9+
const config = args.$node.parent.config;
10+
if (config.transform) {
11+
result = config.transform(result);
12+
}
13+
14+
if (args.transform) {
15+
result = eval(args.transform)(result);
16+
}
17+
18+
const query = args.query || config.defaultQuery || "[].['_id']";
19+
result = Array.isArray(result) ? result : [ result ];
20+
result = jmespath.search(result, query);
21+
return result;
22+
};
23+
24+
const outputFormat = {
25+
table: (args, result) => {
26+
result = queryFilter(args, result);
27+
return tabula.format(result);
28+
},
29+
tsv: (args, result) => {
30+
result = queryFilter(args, result);
31+
return result.map(item =>
32+
Object.values(item).map(value => {
33+
if (typeof value === 'number' || typeof value === 'boolean') {
34+
return value;
35+
}
36+
if (typeof value === 'string') {
37+
return value.match(/\t/) ? `"${value}"` : value;
38+
}
39+
return '-';
40+
41+
}).join('\t')
42+
).join('\n');
43+
},
44+
list: (args, result) => {
45+
result = queryFilter(args, result);
46+
const maxKeyLength = result[0] ? Math.max(...Object.keys(result[0]).map(i=>i.length)) : 0;
47+
return result
48+
.map(item => Object
49+
.entries(item)
50+
.map(([i, value]) => `${i}${' '.repeat(maxKeyLength-i.length)} : ${value}`)
51+
.concat('')
52+
.join('\n')
53+
).join('\n')
54+
;
55+
},
56+
json: (args, result) => args.query ? queryFilter(args, result) : result
57+
};
58+
59+
module.exports = {
60+
onBeforeConfigure: context => {
61+
const node = context.node;
62+
const options = {
63+
output: {
64+
alias: 'o',
65+
description: 'output format',
66+
type: 'string',
67+
defaultValue: process.env.H1_DEFAULT_OUTPUT || 'table',
68+
choices: Object.keys(outputFormat),
69+
dest: 'output'
70+
},
71+
query: {
72+
description: 'query selector',
73+
type: 'string'
74+
},
75+
transform: {
76+
description: 'transform results',
77+
type: 'string'
78+
}
79+
};
80+
81+
node.addOptionGroup('Output options', _.omit(options, _.get(context.node.config, 'outputOptions.hide', [])));
82+
},
83+
84+
onBeforeHandler: context => {
85+
context.args.helpers = context.args.helpers || {};
86+
context.args.helpers.sendOutput = (args, result) => outputFormat[args.output](args, result);
87+
}
88+
};

bin/_plugins/tenantRequired.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
3+
const config = require('lib/config');
4+
5+
const logger = require('lib/logger');
6+
7+
module.exports = {
8+
onBeforeConfigure: context => {
9+
const node = context.node;
10+
11+
node.addOption('tenant-select',
12+
{
13+
description: 'Override current tenant on the request',
14+
type: 'string'
15+
});
16+
},
17+
onBeforeHandler: context => {
18+
const profile = config.get('profile', {});
19+
20+
if (!profile.tenant || !profile.tenant._id) {
21+
logger('info', 'You need to select tenant before you can manage your resources');
22+
return process.exit(-1); //TODO find a better way
23+
}
24+
25+
context.args.profile = Object.assign({}, profile);
26+
27+
if (context.args['tenant-select']) {
28+
context.args.profile.tenant.name = '';
29+
context.args.profile.tenant._id = context.args['tenant-select'];
30+
}
31+
}
32+
};

0 commit comments

Comments
 (0)