joyent/node-triton#113 error help for usage errors
This builds on cmdln 4.x's "errHelp" facilities.
This commit is contained in:
parent
42d5382c7e
commit
fabe0a0841
26
CHANGES.md
26
CHANGES.md
@ -5,9 +5,31 @@ Known issues:
|
|||||||
- `triton ssh ...` disables ssh ControlMaster to avoid issue #52.
|
- `triton ssh ...` disables ssh ControlMaster to avoid issue #52.
|
||||||
|
|
||||||
|
|
||||||
## 4.12.1 (not yet released)
|
## 4.13.0 (not yet released)
|
||||||
|
|
||||||
(nothing yet)
|
- [#113] *Usage* errors now some "error help", including option or command
|
||||||
|
synopses. Some examples (the new thing is marked with `>`):
|
||||||
|
|
||||||
|
- Command synopses when argument errors:
|
||||||
|
|
||||||
|
$ triton create
|
||||||
|
triton instance create: error (Usage): incorrect number of args
|
||||||
|
> usage: triton instance create [OPTIONS] IMAGE PACKAGE
|
||||||
|
|
||||||
|
- Option synopsis with option errors:
|
||||||
|
|
||||||
|
$ triton image ls --bogus
|
||||||
|
triton image ls: error (Option): unknown option: "--bogus"
|
||||||
|
> usage: triton image ls [ --help | -h ] [ --all | -a ] [ -H ] [ -o field1,... ]
|
||||||
|
> [ --long | -l ] [ -s field1,... ] [ --json | -j ] ...
|
||||||
|
|
||||||
|
- Suggested command name misspellings:
|
||||||
|
|
||||||
|
$ triton in
|
||||||
|
triton: error (UnknownCommand): unknown command: "in"
|
||||||
|
> Did you mean this?
|
||||||
|
> info
|
||||||
|
> inst
|
||||||
|
|
||||||
|
|
||||||
## 4.12.0
|
## 4.12.0
|
||||||
|
30
lib/cli.js
30
lib/cli.js
@ -342,7 +342,7 @@ CLI.prototype.fini = function fini(subcmd, err, cb) {
|
|||||||
this._tritonapi.close();
|
this._tritonapi.close();
|
||||||
delete this._tritonapi;
|
delete this._tritonapi;
|
||||||
}
|
}
|
||||||
cb(err, subcmd);
|
cb();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -667,7 +667,7 @@ function main(argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var cli = new CLI();
|
var cli = new CLI();
|
||||||
cli.main(argv, function (err, subcmd) {
|
cli.main(argv, function (err) {
|
||||||
var exitStatus = (err ? err.exitStatus || 1 : 0);
|
var exitStatus = (err ? err.exitStatus || 1 : 0);
|
||||||
var showErr = (cli.showErr !== undefined ? cli.showErr : true);
|
var showErr = (cli.showErr !== undefined ? cli.showErr : true);
|
||||||
|
|
||||||
@ -677,7 +677,7 @@ function main(argv) {
|
|||||||
/* jsl:pass */
|
/* jsl:pass */
|
||||||
} else if (err.message !== undefined) {
|
} else if (err.message !== undefined) {
|
||||||
/*
|
/*
|
||||||
* If the err has `body.errors` (as some Triton/SDC APIs do per
|
* If the err has `body.errors`, as some Triton/SDC APIs do per
|
||||||
* // JSSTYLED
|
* // JSSTYLED
|
||||||
* https://github.com/joyent/eng/blob/master/docs/index.md#error-handling
|
* https://github.com/joyent/eng/blob/master/docs/index.md#error-handling
|
||||||
* then append a one-line summary for each error object.
|
* then append a one-line summary for each error object.
|
||||||
@ -692,27 +692,14 @@ function main(argv) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.error('%s%s: error%s: %s%s',
|
console.error('%s: error%s: %s%s',
|
||||||
cli.name,
|
cmdln.nameFromErr(err),
|
||||||
(subcmd ? ' ' + subcmd : ''),
|
|
||||||
(code ? format(' (%s)', code) : ''),
|
(code ? format(' (%s)', code) : ''),
|
||||||
(cli.showErrStack ? err.stack : err.message),
|
(cli.showErrStack ? err.stack : err.message),
|
||||||
bodyErrors);
|
bodyErrors);
|
||||||
|
var errHelp = cmdln.errHelpFromErr(err);
|
||||||
// If this is a usage error, attempt to show some usage info.
|
if (errHelp) {
|
||||||
if (['Usage', 'Option'].indexOf(code) !== -1 && subcmd) {
|
console.error(errHelp);
|
||||||
var help = cli.helpFromSubcmd(subcmd);
|
|
||||||
if (help && typeof (help) === 'string') {
|
|
||||||
// Would like a shorter synopsis. Attempt to
|
|
||||||
// parse it down, somewhat generally. Unfortunately this
|
|
||||||
// doesn't work for multi-level subcmds, like
|
|
||||||
// `triton rbac subcmd ...`.
|
|
||||||
var usageIdx = help.indexOf('\nUsage:');
|
|
||||||
if (usageIdx !== -1) {
|
|
||||||
help = help.slice(usageIdx);
|
|
||||||
}
|
|
||||||
console.error(help);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -728,6 +715,7 @@ function main(argv) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---- exports
|
//---- exports
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -129,6 +129,8 @@ function jsonStream(arr, stream) {
|
|||||||
*
|
*
|
||||||
* @param {Array} kvs - an array of key=value pairs
|
* @param {Array} kvs - an array of key=value pairs
|
||||||
* @param {Array} valid (optional) - an array to validate pairs
|
* @param {Array} valid (optional) - an array to validate pairs
|
||||||
|
*
|
||||||
|
* TODO: merge this with objFromKeyValueArgs !
|
||||||
*/
|
*/
|
||||||
function kvToObj(kvs, valid) {
|
function kvToObj(kvs, valid) {
|
||||||
assert.arrayOfString(kvs, 'kvs');
|
assert.arrayOfString(kvs, 'kvs');
|
||||||
|
@ -58,13 +58,15 @@ do_get.options = [
|
|||||||
help: 'JSON output.'
|
help: 'JSON output.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
do_get.help = (
|
|
||||||
'Show account information\n'
|
do_get.synopses = ['{{name}} {{cmd}}'];
|
||||||
+ '\n'
|
|
||||||
+ 'Usage:\n'
|
do_get.help = [
|
||||||
+ ' {{name}} get\n'
|
'Show account information',
|
||||||
+ '\n'
|
'',
|
||||||
+ '{{options}}'
|
'{{usage}}',
|
||||||
);
|
'',
|
||||||
|
'{{options}}'
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
module.exports = do_get;
|
module.exports = do_get;
|
||||||
|
@ -148,13 +148,17 @@ do_update.options = [
|
|||||||
'JSON from stdin.'
|
'JSON from stdin.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_update.synopses = [
|
||||||
|
'{{name}} {{cmd}} [FIELD=VALUE ...]',
|
||||||
|
'{{name}} {{cmd}} -f JSON-FILE'
|
||||||
|
];
|
||||||
|
|
||||||
do_update.help = [
|
do_update.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Update account information',
|
'Update account information',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} update [FIELD=VALUE ...]',
|
|
||||||
' {{name}} update -f JSON-FILE',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ function do_cloudapi(subcmd, opts, args, callback) {
|
|||||||
reqOpts.data = JSON.parse(opts.data);
|
reqOpts.data = JSON.parse(opts.data);
|
||||||
} catch (parseErr) {
|
} catch (parseErr) {
|
||||||
callback(new errors.TritonError(parseErr,
|
callback(new errors.TritonError(parseErr,
|
||||||
'given <data> is not valid JSON: ' + parseErr.message));
|
'given DATA is not valid JSON: ' + parseErr.message));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,13 +94,13 @@ do_cloudapi.options = [
|
|||||||
{
|
{
|
||||||
names: ['method', 'X'],
|
names: ['method', 'X'],
|
||||||
type: 'string',
|
type: 'string',
|
||||||
helpArg: '<method>',
|
helpArg: 'METHOD',
|
||||||
help: 'Request method to use. Default is "GET".'
|
help: 'Request method to use. Default is "GET".'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
names: ['header', 'H'],
|
names: ['header', 'H'],
|
||||||
type: 'arrayOfString',
|
type: 'arrayOfString',
|
||||||
helpArg: '<header>',
|
helpArg: 'HEADER',
|
||||||
help: 'Headers to send with request.'
|
help: 'Headers to send with request.'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -111,19 +111,25 @@ do_cloudapi.options = [
|
|||||||
{
|
{
|
||||||
names: ['data', 'd'],
|
names: ['data', 'd'],
|
||||||
type: 'string',
|
type: 'string',
|
||||||
helpArg: '<data>',
|
helpArg: 'DATA',
|
||||||
help: 'Add POST data. This must be valid JSON.'
|
help: 'Add POST data. This must be valid JSON.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
do_cloudapi.help = (
|
|
||||||
'Raw cloudapi request.\n'
|
do_cloudapi.synopses = [
|
||||||
+ '\n'
|
'{{name}} {{cmd}} [-X METHOD] [-H HEADER=VAL] [-d DATA] ENDPOINT'
|
||||||
+ 'Usage:\n'
|
];
|
||||||
+ ' {{name}} cloudapi [-X <method>] [-H <header=value>] \\\n'
|
|
||||||
+ ' [-d <data>] <endpoint>\n'
|
do_cloudapi.help = [
|
||||||
+ '\n'
|
'Raw cloudapi request.',
|
||||||
+ '{{options}}'
|
'',
|
||||||
);
|
'{{usage}}',
|
||||||
|
'',
|
||||||
|
'{{options}}',
|
||||||
|
'Examples:',
|
||||||
|
' {{name}} {{cmd}} /--ping',
|
||||||
|
' {{name}} {{cmd}} /my/machines'
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
do_cloudapi.hidden = true;
|
do_cloudapi.hidden = true;
|
||||||
|
|
||||||
|
@ -75,15 +75,16 @@ do_datacenters.options = [
|
|||||||
sortDefault: sortDefault
|
sortDefault: sortDefault
|
||||||
}));
|
}));
|
||||||
|
|
||||||
do_datacenters.help = (
|
do_datacenters.synopses = ['{{name}} {{cmd}}'];
|
||||||
'Show datacenters in this cloud.\n'
|
|
||||||
+ 'A "cloud" is a set of related datacenters that share account\n'
|
do_datacenters.help = [
|
||||||
+ 'information.\n'
|
'Show datacenters in this cloud.',
|
||||||
+ '\n'
|
'A "cloud" is a set of related datacenters that share account',
|
||||||
+ 'Usage:\n'
|
'information.',
|
||||||
+ ' {{name}} datacenters\n'
|
'',
|
||||||
+ '\n'
|
'{{usage}}',
|
||||||
+ '{{options}}'
|
'',
|
||||||
);
|
'{{options}}'
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
module.exports = do_datacenters;
|
module.exports = do_datacenters;
|
||||||
|
@ -198,7 +198,8 @@ do_env.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// TODO: support env for docker usage.
|
do_env.synopses = ['{{name}} {{cmd}} [PROFILE]'];
|
||||||
|
|
||||||
do_env.help = [
|
do_env.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Emit shell commands to setup environment.',
|
'Emit shell commands to setup environment.',
|
||||||
@ -207,8 +208,7 @@ do_env.help = [
|
|||||||
'and node-triton itself. By default this emits the environment for all',
|
'and node-triton itself. By default this emits the environment for all',
|
||||||
'supported tools. Use options to be specific.',
|
'supported tools. Use options to be specific.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} env [PROFILE]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'If no options are given, environment variables are emitted for all clients.',
|
'If no options are given, environment variables are emitted for all clients.',
|
||||||
|
@ -28,7 +28,7 @@ function do_create(subcmd, opts, args, cb) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
cb(new errors.UsageError('missing <fwrule> argument'));
|
cb(new errors.UsageError('missing FWRULE argument'));
|
||||||
return;
|
return;
|
||||||
} else if (args.length > 1) {
|
} else if (args.length > 1) {
|
||||||
cb(new errors.UsageError('incorrect number of arguments'));
|
cb(new errors.UsageError('incorrect number of arguments'));
|
||||||
@ -79,17 +79,31 @@ do_create.options = [
|
|||||||
{
|
{
|
||||||
names: ['description', 'D'],
|
names: ['description', 'D'],
|
||||||
type: 'string',
|
type: 'string',
|
||||||
helpArg: '<desc>',
|
helpArg: 'DESC',
|
||||||
help: 'Description of the firewall rule.'
|
help: 'Description of the firewall rule.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_create.synopses = ['{{name}} {{cmd}} [OPTIONS] RULE-TEXT'];
|
||||||
|
|
||||||
do_create.help = [
|
do_create.help = [
|
||||||
|
/* BEGIN JSSTYLED */
|
||||||
'Create a firewall rule.',
|
'Create a firewall rule.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} create [<options>] <fwrule>',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}',
|
||||||
|
'Examples:',
|
||||||
|
' # Allow SSH access from any IP to all instances in a datacenter.',
|
||||||
|
' triton fwrule create -D "ssh" "FROM any TO all vms ALLOW tcp PORT 22"',
|
||||||
|
'',
|
||||||
|
' # Allow SSH access to a specific instance.',
|
||||||
|
' triton fwrule create \\',
|
||||||
|
' "FROM any TO vm ba2c95e9-1cdf-4295-8253-3fee371374d9 ALLOW tcp PORT 22"'
|
||||||
|
// TODO: link to
|
||||||
|
// https://github.com/joyent/sdc-fwrule/blob/master/docs/examples.md
|
||||||
|
// or docs.jo Cloud Firewall examples? What link? Ditto in parent.
|
||||||
|
/* END JSSTYLED */
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_create.helpOpts = {
|
do_create.helpOpts = {
|
||||||
|
@ -27,7 +27,7 @@ function do_delete(subcmd, opts, args, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
cb(new errors.UsageError('missing <fwrule-id> argument(s)'));
|
cb(new errors.UsageError('missing FWRULE argument(s)'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,13 +96,16 @@ do_delete.options = [
|
|||||||
help: 'Skip confirmation of delete.'
|
help: 'Skip confirmation of delete.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_delete.synopses = ['{{name}} {{cmd}} FWRULE [FWRULE ...]'];
|
||||||
|
|
||||||
do_delete.help = [
|
do_delete.help = [
|
||||||
'Remove a firewall rule.',
|
'Remove a firewall rule.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} delete [<options>] <fwrule-id> [<fwrule-id>...]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}',
|
||||||
|
'Where FWRULE is a firewall rule id (full UUID) or short id.'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_delete.aliases = ['rm'];
|
do_delete.aliases = ['rm'];
|
||||||
|
@ -26,7 +26,7 @@ function do_disable(subcmd, opts, args, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
cb(new errors.UsageError('Missing <fwrule-id> argument(s)'));
|
cb(new errors.UsageError('missing FWRULE argument(s)'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,13 +56,16 @@ do_disable.options = [
|
|||||||
help: 'Show this help.'
|
help: 'Show this help.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_disable.synopses = ['{{name}} {{cmd}} FWRULE [FWRULE ...]'];
|
||||||
|
|
||||||
do_disable.help = [
|
do_disable.help = [
|
||||||
'Disable a specific firewall rule.',
|
'Disable a specific firewall rule.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} disable <fwrule-id> [<fwrule-id>...]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}',
|
||||||
|
'Where FWRULE is a firewall rule id (full UUID) or short id.'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_disable.completionArgtypes = ['tritonfwrule'];
|
do_disable.completionArgtypes = ['tritonfwrule'];
|
||||||
|
@ -26,7 +26,7 @@ function do_enable(subcmd, opts, args, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
cb(new errors.UsageError('Missing <fwrule-id> argument(s)'));
|
cb(new errors.UsageError('missing FWRULE argument(s)'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,13 +56,16 @@ do_enable.options = [
|
|||||||
help: 'Show this help.'
|
help: 'Show this help.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_enable.synopses = ['{{name}} {{cmd}} FWRULE [FWRULE ...]'];
|
||||||
|
|
||||||
do_enable.help = [
|
do_enable.help = [
|
||||||
'Enable a specific firewall rule.',
|
'Enable a specific firewall rule.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} enable <fwrule-id> [<fwrule-id>...]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}',
|
||||||
|
'Where FWRULE is a firewall rule id (full UUID) or short id.'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_enable.completionArgtypes = ['tritonfwrule'];
|
do_enable.completionArgtypes = ['tritonfwrule'];
|
||||||
|
@ -25,7 +25,7 @@ function do_get(subcmd, opts, args, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
cb(new errors.UsageError('missing <fwrule-id> argument'));
|
cb(new errors.UsageError('missing FWRULE argument'));
|
||||||
return;
|
return;
|
||||||
} else if (args.length > 1) {
|
} else if (args.length > 1) {
|
||||||
cb(new errors.UsageError('incorrect number of arguments'));
|
cb(new errors.UsageError('incorrect number of arguments'));
|
||||||
@ -64,13 +64,16 @@ do_get.options = [
|
|||||||
help: 'JSON stream output.'
|
help: 'JSON stream output.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_get.synopses = ['{{name}} {{cmd}} FWRULE'];
|
||||||
|
|
||||||
do_get.help = [
|
do_get.help = [
|
||||||
'Show a specific firewall rule.',
|
'Show a specific firewall rule.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} get <fwrule-id>',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}',
|
||||||
|
'Where FWRULE is a firewall rule id (full UUID) or short id.'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_get.completionArgtypes = ['tritonfwrule', 'none'];
|
do_get.completionArgtypes = ['tritonfwrule', 'none'];
|
||||||
|
@ -30,7 +30,7 @@ function do_instances(subcmd, opts, args, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
cb(new errors.UsageError('missing <fwrule-id> argument'));
|
cb(new errors.UsageError('missing FWRULE argument'));
|
||||||
return;
|
return;
|
||||||
} else if (args.length > 1) {
|
} else if (args.length > 1) {
|
||||||
cb(new errors.UsageError('incorrect number of arguments'));
|
cb(new errors.UsageError('incorrect number of arguments'));
|
||||||
@ -135,14 +135,16 @@ do_instances.options = [
|
|||||||
sortDefault: SORT_DEFAULT
|
sortDefault: SORT_DEFAULT
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
do_instances.synopses = ['{{name}} {{cmd}} [OPTIONS] FWRULE'];
|
||||||
|
|
||||||
do_instances.help = [
|
do_instances.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'List instances a firewall rule is applied to.',
|
'List instances to which a firewall rule applies',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} instances [<options>] <fwrule-id>',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
|
'Where FWRULE is a firewall rule id (full UUID) or short id.',
|
||||||
'',
|
'',
|
||||||
'Fields (most are self explanatory, "*" indicates a field added client-side',
|
'Fields (most are self explanatory, "*" indicates a field added client-side',
|
||||||
'for convenience):',
|
'for convenience):',
|
||||||
|
@ -84,11 +84,12 @@ do_list.options = [
|
|||||||
sortDefault: SORT_DEFAULT
|
sortDefault: SORT_DEFAULT
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
do_list.synopses = ['{{name}} {{cmd}} [OPTIONS]'];
|
||||||
|
|
||||||
do_list.help = [
|
do_list.help = [
|
||||||
'Show all firewall rules.',
|
'Show all firewall rules.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} list [<options>]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
@ -31,7 +31,7 @@ function do_update(subcmd, opts, args, cb) {
|
|||||||
var tritonapi = this.top.tritonapi;
|
var tritonapi = this.top.tritonapi;
|
||||||
|
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
cb(new errors.UsageError('missing <fwrule-id> argument'));
|
cb(new errors.UsageError('missing FWRULE argument'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,17 +164,20 @@ do_update.options = [
|
|||||||
{
|
{
|
||||||
names: ['file', 'f'],
|
names: ['file', 'f'],
|
||||||
type: 'string',
|
type: 'string',
|
||||||
helpArg: '<json-file>',
|
helpArg: 'JSON-FILE',
|
||||||
help: 'A file holding a JSON file of updates, or "-" to read ' +
|
help: 'A file holding a JSON file of updates, or "-" to read ' +
|
||||||
'JSON from stdin.'
|
'JSON from stdin.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_update.synopses = [
|
||||||
|
'{{name}} {{cmd}} FWRULE [FIELD=VALUE ...]',
|
||||||
|
'{{name}} {{cmd}} -f JSON-FILE FWRULE'
|
||||||
|
];
|
||||||
do_update.help = [
|
do_update.help = [
|
||||||
'Update a firewall rule',
|
'Update a firewall rule',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} update <fwrule-id> [FIELD=VALUE ...]',
|
|
||||||
' {{name}} update -f <json-file> <fwrule-id>',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
|
|
||||||
@ -182,7 +185,8 @@ do_update.help = [
|
|||||||
' ' + Object.keys(UPDATE_FWRULE_FIELDS).sort().map(function (f) {
|
' ' + Object.keys(UPDATE_FWRULE_FIELDS).sort().map(function (f) {
|
||||||
return f + ' (' + UPDATE_FWRULE_FIELDS[f] + ')';
|
return f + ' (' + UPDATE_FWRULE_FIELDS[f] + ')';
|
||||||
}).join('\n '),
|
}).join('\n '),
|
||||||
''
|
'',
|
||||||
|
'Where FWRULE is a firewall rule id (full UUID) or short id.'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_update.completionArgtypes = ['tritonfwrule', 'tritonupdatefwrulefield'];
|
do_update.completionArgtypes = ['tritonfwrule', 'tritonupdatefwrulefield'];
|
||||||
|
@ -250,16 +250,20 @@ do_create.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
do_create.help = (
|
do_create.synopses = [
|
||||||
|
'{{name}} {{cmd}} [OPTIONS] INST IMAGE-NAME IMAGE-VERSION'
|
||||||
|
];
|
||||||
|
|
||||||
|
do_create.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Create a new instance.\n' +
|
'Create a new instance.',
|
||||||
'\n' +
|
'',
|
||||||
'Usage:\n' +
|
'{{usage}}',
|
||||||
' {{name}} create [<options>] INSTANCE IMAGE-NAME IMAGE-VERSION\n' +
|
'',
|
||||||
'\n' +
|
'{{options}}',
|
||||||
'{{options}}'
|
'Where "INST" is an instance name, id, or short id.'
|
||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
);
|
].join('\n');
|
||||||
|
|
||||||
do_create.helpOpts = {
|
do_create.helpOpts = {
|
||||||
maxHelpCol: 20
|
maxHelpCol: 20
|
||||||
|
@ -125,19 +125,21 @@ function do_delete(subcmd, opts, args, cb) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_delete.synopses = ['{{name}} {{cmd}} [OPTIONS] IMAGE [IMAGE ...]'];
|
||||||
|
|
||||||
do_delete.help = [
|
do_delete.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Delete one or more images.',
|
'Delete one or more images.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} delete IMAGE [IMAGE...]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where "IMAGE" is an image ID (a full UUID), an image name (selects the',
|
'Where "IMAGE" is an image id (a full UUID), an image name (selects the',
|
||||||
'latest, by "published_at", image with that name), an image "name@version"',
|
'latest, by "published_at", image with that name), an image "name@version"',
|
||||||
'(selects latest match by "published_at"), or an image short ID (ID prefix).'
|
'(selects latest match by "published_at"), or an image short ID (ID prefix).'
|
||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_delete.options = [
|
do_delete.options = [
|
||||||
{
|
{
|
||||||
names: ['help', 'h'],
|
names: ['help', 'h'],
|
||||||
|
@ -50,22 +50,24 @@ do_get.options = [
|
|||||||
help: 'JSON stream output.'
|
help: 'JSON stream output.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
do_get.help = (
|
|
||||||
|
do_get.synopses = ['{{name}} {{cmd}} [OPTIONS] IMAGE'];
|
||||||
|
|
||||||
|
do_get.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Get an image.\n' +
|
'Get an image.',
|
||||||
'\n' +
|
'',
|
||||||
'Usage:\n' +
|
'{{usage}}',
|
||||||
' {{name}} get [<options>] ID|NAME\n' +
|
'',
|
||||||
'\n' +
|
'{{options}}',
|
||||||
'{{options}}' +
|
'Where "IMAGE" is an image id (a full UUID), an image name (selects the',
|
||||||
'\n' +
|
'latest, by "published_at", image with that name), an image "name@version"',
|
||||||
'If there is more than one image with the given "NAME", the latest\n' +
|
'(selects latest match by "published_at"), or an image short ID (ID prefix).',
|
||||||
'image (by "published_at") is returned.\n' +
|
'',
|
||||||
'\n' +
|
'Note: Currently this dumps prettified JSON by default. That might change',
|
||||||
'Note: Currently this dumps prettified JSON by default. That might change\n' +
|
'in the future. Use "-j" to explicitly get JSON output.'
|
||||||
'in the future. Use "-j" to explicitly get JSON output.\n'
|
|
||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
);
|
].join('\n');
|
||||||
|
|
||||||
do_get.completionArgtypes = ['tritonimage', 'none'];
|
do_get.completionArgtypes = ['tritonimage', 'none'];
|
||||||
|
|
||||||
|
@ -122,6 +122,8 @@ do_list.options = [
|
|||||||
sortDefault: sortDefault
|
sortDefault: sortDefault
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
do_list.synopses = ['{{name}} {{cmd}} [OPTIONS] [FILTERS]'];
|
||||||
|
|
||||||
do_list.help = [
|
do_list.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'List images.',
|
'List images.',
|
||||||
@ -130,8 +132,7 @@ do_list.help = [
|
|||||||
'You must use `docker images` against the Docker service for this data center.',
|
'You must use `docker images` against the Docker service for this data center.',
|
||||||
'See <https://apidocs.joyent.com/docker>.',
|
'See <https://apidocs.joyent.com/docker>.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} list [<options>] [<filters>]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Filters:',
|
'Filters:',
|
||||||
|
@ -112,11 +112,12 @@ function do_wait(subcmd, opts, args, cb) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_wait.synopses = ['{{name}} {{cmd}} [-s STATES] IMAGE [IMAGE ...]'];
|
||||||
|
|
||||||
do_wait.help = [
|
do_wait.help = [
|
||||||
'Wait for images to change to a particular state.',
|
'Wait for images to change to a particular state.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} wait [-s STATES] IMAGE [IMAGE ...]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where "states" is a comma-separated list of target instance states,',
|
'Where "states" is a comma-separated list of target instance states,',
|
||||||
|
@ -105,13 +105,15 @@ do_info.options = [
|
|||||||
help: 'JSON output.'
|
help: 'JSON output.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
do_info.help = (
|
|
||||||
'Print an account summary.\n'
|
do_info.synopses = ['{{name}} {{cmd}}'];
|
||||||
+ '\n'
|
|
||||||
+ 'Usage:\n'
|
do_info.help = [
|
||||||
+ ' {{name}} info\n'
|
'Print an account summary.',
|
||||||
+ '\n'
|
'',
|
||||||
+ '{{options}}'
|
'{{usage}}',
|
||||||
);
|
'',
|
||||||
|
'{{options}}'
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
module.exports = do_info;
|
module.exports = do_info;
|
||||||
|
@ -28,13 +28,15 @@ var sortDefault = 'id,time';
|
|||||||
|
|
||||||
function do_audit(subcmd, opts, args, cb) {
|
function do_audit(subcmd, opts, args, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (opts.help) {
|
if (opts.help) {
|
||||||
this.do_help('help', {}, [subcmd], cb);
|
this.do_help('help', {}, [subcmd], cb);
|
||||||
return;
|
return;
|
||||||
} else if (args.length !== 1) {
|
} else if (args.length === 0) {
|
||||||
//XXX Support multiple machines.
|
cb(new errors.UsageError('missing INST argument'));
|
||||||
return cb(new Error('incorrect args: ' + args));
|
return;
|
||||||
|
} else if (args.length > 1) {
|
||||||
|
cb(new errors.UsageError('too many arguments: ' + args));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var columns = columnsDefault;
|
var columns = columnsDefault;
|
||||||
@ -102,14 +104,15 @@ do_audit.options = [
|
|||||||
sortDefault: sortDefault
|
sortDefault: sortDefault
|
||||||
}));
|
}));
|
||||||
|
|
||||||
do_audit.help = (
|
do_audit.synopses = ['{{name}} {{cmd}} [OPTIONS] INST'];
|
||||||
'List instance actions.\n'
|
do_audit.help = [
|
||||||
+ '\n'
|
'List instance actions.',
|
||||||
+ 'Usage:\n'
|
'',
|
||||||
+ ' {{name}} audit <alias|id>\n'
|
'{{usage}}',
|
||||||
+ '\n'
|
'',
|
||||||
+ '{{options}}'
|
'{{options}}',
|
||||||
);
|
'Where "INST" is an instance name, id, or short id.'
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
do_audit.completionArgtypes = ['tritoninstance', 'none'];
|
do_audit.completionArgtypes = ['tritoninstance', 'none'];
|
||||||
|
|
||||||
|
@ -498,16 +498,20 @@ do_create.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
do_create.help = (
|
do_create.synopses = ['{{name}} {{cmd}} [OPTIONS] IMAGE PACKAGE'];
|
||||||
|
|
||||||
|
do_create.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Create a new instance.\n' +
|
'Create a new instance.',
|
||||||
'\n' +
|
'',
|
||||||
'Usage:\n' +
|
'{{usage}}',
|
||||||
' {{name}} create [<options>] IMAGE PACKAGE\n' +
|
'',
|
||||||
'\n' +
|
'{{options}}',
|
||||||
'{{options}}'
|
'Where IMAGE is an image name, name@version, id, or short id (from ',
|
||||||
|
'`triton image list`) and PACKAGE is a package name, id, or short id',
|
||||||
|
'(from `triton package list`).'
|
||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
);
|
].join('\n');
|
||||||
|
|
||||||
do_create.helpOpts = {
|
do_create.helpOpts = {
|
||||||
maxHelpCol: 16
|
maxHelpCol: 16
|
||||||
|
@ -26,7 +26,7 @@ function do_disable_firewall(subcmd, opts, args, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
cb(new errors.UsageError('Missing <inst> argument(s)'));
|
cb(new errors.UsageError('missing INST argument(s)'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,13 +88,16 @@ do_disable_firewall.options = [
|
|||||||
help: 'Wait for the firewall to be disabled.'
|
help: 'Wait for the firewall to be disabled.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
do_disable_firewall.synopses = [
|
||||||
|
'{{name}} disable-firewall [OPTIONS] INST [INST ...]'
|
||||||
|
];
|
||||||
do_disable_firewall.help = [
|
do_disable_firewall.help = [
|
||||||
'Disable the firewall of one or more instances.',
|
'Disable the firewall of one or more instances.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} disable-firewall [<options>] <inst> [<inst>...]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}',
|
||||||
|
'Where "INST" is an instance name, id, or short id.'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_disable_firewall.completionArgtypes = ['tritoninstance'];
|
do_disable_firewall.completionArgtypes = ['tritoninstance'];
|
||||||
|
@ -26,7 +26,7 @@ function do_enable_firewall(subcmd, opts, args, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
cb(new errors.UsageError('Missing <inst> argument(s)'));
|
cb(new errors.UsageError('missing INST argument(s)'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,13 +88,16 @@ do_enable_firewall.options = [
|
|||||||
help: 'Wait for the firewall to be enabled.'
|
help: 'Wait for the firewall to be enabled.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
do_enable_firewall.synopses = [
|
||||||
|
'{{name}} enable-firewall [OPTIONS] INST [INST ...]'
|
||||||
|
];
|
||||||
do_enable_firewall.help = [
|
do_enable_firewall.help = [
|
||||||
'Enable the firewall of one or more instances.',
|
'Enable the firewall of one or more instances.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} enable-firewall [<options>] <inst> [<inst>...]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}',
|
||||||
|
'Where "INST" is an instance name, id, or short id.'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_enable_firewall.completionArgtypes = ['tritoninstance'];
|
do_enable_firewall.completionArgtypes = ['tritoninstance'];
|
||||||
|
@ -31,10 +31,10 @@ function do_fwrules(subcmd, opts, args, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
cb(new errors.UsageError('missing <inst> argument'));
|
cb(new errors.UsageError('missing INST argument'));
|
||||||
return;
|
return;
|
||||||
} else if (args.length > 1) {
|
} else if (args.length > 1) {
|
||||||
cb(new errors.UsageError('incorrect number of arguments'));
|
cb(new errors.UsageError('too many arguments: ' + args.join(' ')));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,13 +91,15 @@ do_fwrules.options = [
|
|||||||
sortDefault: SORT_DEFAULT
|
sortDefault: SORT_DEFAULT
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
do_fwrules.synopses = ['{{name}} {{cmd}} [OPTIONS] INST'];
|
||||||
|
|
||||||
do_fwrules.help = [
|
do_fwrules.help = [
|
||||||
'Show firewall rules applied to an instance.',
|
'Show firewall rules applied to an instance.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} fwrules [<options>] <inst>',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}',
|
||||||
|
'Where "INST" is an instance name, id, or short id.'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_fwrules.completionArgtypes = ['tritoninstance', 'none'];
|
do_fwrules.completionArgtypes = ['tritoninstance', 'none'];
|
||||||
|
@ -43,22 +43,24 @@ do_get.options = [
|
|||||||
help: 'JSON output.'
|
help: 'JSON output.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
do_get.help = (
|
do_get.synopses = ['{{name}} {{cmd}} [OPTIONS] INST'];
|
||||||
|
do_get.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Get an instance.\n'
|
'Get an instance.',
|
||||||
+ '\n'
|
'',
|
||||||
+ 'Usage:\n'
|
'{{usage}}',
|
||||||
+ ' {{name}} get <alias|id>\n'
|
'',
|
||||||
+ '\n'
|
'{{options}}',
|
||||||
+ '{{options}}'
|
'',
|
||||||
+ '\n'
|
'Where "INST" is an instance name, id, or short id.',
|
||||||
+ 'A *deleted* instance may still respond with the instance object. In that\n'
|
'',
|
||||||
+ 'case a the instance will be print *and* an error will be raised.\n'
|
'A *deleted* instance may still respond with the instance object. In that',
|
||||||
+ '\n'
|
'case a the instance will be print *and* an error will be raised.',
|
||||||
+ 'Currently this dumps prettified JSON by default. That might change\n'
|
'',
|
||||||
+ 'in the future. Use "-j" to explicitly get JSON output.\n'
|
'Currently this dumps prettified JSON by default. That might change',
|
||||||
|
'in the future. Use "-j" to explicitly get JSON output.'
|
||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
);
|
].join('\n');
|
||||||
|
|
||||||
do_get.completionArgtypes = ['tritoninstance', 'none'];
|
do_get.completionArgtypes = ['tritoninstance', 'none'];
|
||||||
|
|
||||||
|
@ -20,10 +20,10 @@ function do_ip(subcmd, opts, args, cb) {
|
|||||||
this.do_help('help', {}, [subcmd], cb);
|
this.do_help('help', {}, [subcmd], cb);
|
||||||
return;
|
return;
|
||||||
} else if (args.length === 0) {
|
} else if (args.length === 0) {
|
||||||
cb(new errors.UsageError('missing <inst> argument'));
|
cb(new errors.UsageError('missing INST argument'));
|
||||||
return;
|
return;
|
||||||
} else if (args.length > 1) {
|
} else if (args.length > 1) {
|
||||||
cb(new errors.UsageError('too many arguments: ' + args));
|
cb(new errors.UsageError('too many arguments: ' + args.join(' ')));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,14 +54,16 @@ do_ip.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_ip.synopses = ['{{name}} {{cmd}} INST'];
|
||||||
|
|
||||||
do_ip.help = [
|
do_ip.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Print the primaryIp of the given instance.',
|
'Print the primary IP of the given instance.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} ip <inst>',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
|
'Where "INST" is an instance name, id, or short id.',
|
||||||
'For example: ssh root@$(triton ip my-instance)'
|
'For example: ssh root@$(triton ip my-instance)'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
|
@ -159,12 +159,13 @@ do_list.options = [
|
|||||||
sortDefault: sortDefault
|
sortDefault: sortDefault
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
do_list.synopses = ['{{name}} {{cmd}} [OPTIONS] [FILTERS...]'];
|
||||||
|
|
||||||
do_list.help = [
|
do_list.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'List instances.',
|
'List instances.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} list [<filters>...]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Filters:',
|
'Filters:',
|
||||||
|
@ -114,7 +114,7 @@ do_create.options = [
|
|||||||
{
|
{
|
||||||
names: ['name', 'n'],
|
names: ['name', 'n'],
|
||||||
type: 'string',
|
type: 'string',
|
||||||
helpArg: '<snapname>',
|
helpArg: 'SNAPNAME',
|
||||||
help: 'An optional name for a snapshot.'
|
help: 'An optional name for a snapshot.'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -123,11 +123,13 @@ do_create.options = [
|
|||||||
help: 'Wait for the creation to complete.'
|
help: 'Wait for the creation to complete.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_create.synopses = ['{{name}} {{cmd}} [OPTIONS] INST'];
|
||||||
|
|
||||||
do_create.help = [
|
do_create.help = [
|
||||||
'Create a snapshot of an instance.',
|
'Create a snapshot of an instance.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} create [<options>] <inst>',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Snapshot do not work for instances of type "kvm".'
|
'Snapshot do not work for instances of type "kvm".'
|
||||||
|
@ -27,7 +27,7 @@ function do_delete(subcmd, opts, args, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length < 2) {
|
if (args.length < 2) {
|
||||||
cb(new errors.UsageError('missing <inst> and <snapname> argument(s)'));
|
cb(new errors.UsageError('missing INST and SNAPNAME argument(s)'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,11 +139,13 @@ do_delete.options = [
|
|||||||
help: 'Wait for the deletion to complete.'
|
help: 'Wait for the deletion to complete.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_delete.synopses = ['{{name}} {{cmd}} [OPTIONS] INST SNAPNAME [SNAPNAME...]'];
|
||||||
|
|
||||||
do_delete.help = [
|
do_delete.help = [
|
||||||
'Remove a snapshot from an instance.',
|
'Remove a snapshot from an instance.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} delete [<options>] <inst> <snapname> [<snapname>...]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
@ -25,7 +25,7 @@ function do_get(subcmd, opts, args, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length < 2) {
|
if (args.length < 2) {
|
||||||
cb(new errors.UsageError('missing <inst> and/or <snapname> arguments'));
|
cb(new errors.UsageError('missing INST and/or SNAPNAME arguments'));
|
||||||
return;
|
return;
|
||||||
} else if (args.length > 2) {
|
} else if (args.length > 2) {
|
||||||
cb(new errors.UsageError('incorrect number of arguments'));
|
cb(new errors.UsageError('incorrect number of arguments'));
|
||||||
@ -55,7 +55,6 @@ function do_get(subcmd, opts, args, cb) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
do_get.options = [
|
do_get.options = [
|
||||||
{
|
{
|
||||||
names: ['help', 'h'],
|
names: ['help', 'h'],
|
||||||
@ -68,11 +67,13 @@ do_get.options = [
|
|||||||
help: 'JSON stream output.'
|
help: 'JSON stream output.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_get.synopses = ['{{name}} {{cmd}} [OPTIONS] INST SNAPNAME'];
|
||||||
|
|
||||||
do_get.help = [
|
do_get.help = [
|
||||||
'Show a specific snapshot of an instance.',
|
'Show a specific snapshot of an instance.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} get <inst> <snapname>',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
@ -30,7 +30,7 @@ function do_list(subcmd, opts, args, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
cb(new errors.UsageError('missing <inst> argument'));
|
cb(new errors.UsageError('missing INST argument'));
|
||||||
return;
|
return;
|
||||||
} else if (args.length > 1) {
|
} else if (args.length > 1) {
|
||||||
cb(new errors.UsageError('incorrect number of arguments'));
|
cb(new errors.UsageError('incorrect number of arguments'));
|
||||||
@ -84,11 +84,12 @@ do_list.options = [
|
|||||||
sortDefault: SORT_DEFAULT
|
sortDefault: SORT_DEFAULT
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
do_list.synopses = ['{{name}} {{cmd}} [OPTIONS] INST'];
|
||||||
|
|
||||||
do_list.help = [
|
do_list.help = [
|
||||||
'Show all of an instance\'s snapshots.',
|
'Show all of an instance\'s snapshots.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} list [<options>] <inst>',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
@ -31,7 +31,7 @@ function SnapshotCLI(top) {
|
|||||||
'delete'
|
'delete'
|
||||||
],
|
],
|
||||||
helpBody: 'Instances can be rolled back to a snapshot using\n' +
|
helpBody: 'Instances can be rolled back to a snapshot using\n' +
|
||||||
'`triton instance start --snapshot=<snapname>`.'
|
'`triton instance start --snapshot=SNAPNAME`.'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
util.inherits(SnapshotCLI, Cmdln);
|
util.inherits(SnapshotCLI, Cmdln);
|
||||||
|
@ -14,6 +14,7 @@ var path = require('path');
|
|||||||
var spawn = require('child_process').spawn;
|
var spawn = require('child_process').spawn;
|
||||||
|
|
||||||
var common = require('../common');
|
var common = require('../common');
|
||||||
|
var errors = require('../errors');
|
||||||
|
|
||||||
|
|
||||||
function do_ssh(subcmd, opts, args, callback) {
|
function do_ssh(subcmd, opts, args, callback) {
|
||||||
@ -23,7 +24,7 @@ function do_ssh(subcmd, opts, args, callback) {
|
|||||||
this.do_help('help', {}, [subcmd], callback);
|
this.do_help('help', {}, [subcmd], callback);
|
||||||
return;
|
return;
|
||||||
} else if (args.length === 0) {
|
} else if (args.length === 0) {
|
||||||
callback(new Error('invalid args: ' + args));
|
callback(new errors.UsageError('missing INST arg'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,23 +95,23 @@ do_ssh.options = [
|
|||||||
help: 'Show this help.'
|
help: 'Show this help.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
do_ssh.synopses = ['{{name}} ssh [-h] INST [SSH-ARGUMENTS]'];
|
||||||
do_ssh.help = [
|
do_ssh.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'SSH to the primary IP of an instance',
|
'SSH to the primary IP of an instance',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} ssh [-h] [-M] <inst> [<ssh-arguments>]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where <inst> is the name, short ID or ID of a given instance. Note that',
|
'Where INST is the name, id, or short id of an instance. Note that',
|
||||||
'the <inst> argument must come before any `ssh` options or arguments.',
|
'the INST argument must come before any `ssh` options or arguments.',
|
||||||
'',
|
'',
|
||||||
'There is a known issue with SSH connection multiplexing (a.k.a. ',
|
'There is a known issue with SSH connection multiplexing (a.k.a. ',
|
||||||
'ControlMaster, mux) where stdout/stderr is lost. As a workaround, `ssh`',
|
'ControlMaster, mux) where stdout/stderr is lost. As a workaround, `ssh`',
|
||||||
'is spawned with options disabling ControlMaster. See ',
|
'is spawned with options disabling ControlMaster. See ',
|
||||||
'<https://github.com/joyent/node-triton/issues/52> for details. If you ',
|
'<https://github.com/joyent/node-triton/issues/52> for details. If you ',
|
||||||
'want to use ControlMaster, an alternative is:',
|
'want to use ControlMaster, an alternative is:',
|
||||||
' ssh root@$(triton ip <inst>)'
|
' ssh root@$(triton ip INST)'
|
||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
|
@ -91,20 +91,21 @@ do_delete.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_delete.synopses = [
|
||||||
|
'{{name}} {{cmd}} INST [NAME ...]',
|
||||||
|
'{{name}} {{cmd}} --all INST # delete all tags'
|
||||||
|
];
|
||||||
|
|
||||||
do_delete.help = [
|
do_delete.help = [
|
||||||
/* BEGIN JSSTYLED */
|
|
||||||
'Delete one or more instance tags.',
|
'Delete one or more instance tags.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} delete <inst> [<name> ...]',
|
|
||||||
' {{name}} delete --all <inst> # delete all tags',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where <inst> is an instance id, name, or shortid and <name> is a tag name.',
|
'Where INST is an instance id, name, or shortid and NAME is a tag name.',
|
||||||
'',
|
'',
|
||||||
'Changing instance tags is asynchronous. Use "--wait" to not return until',
|
'Changing instance tags is asynchronous. Use "--wait" to not return until',
|
||||||
'the changes are completed.'
|
'the changes are completed.'
|
||||||
/* END JSSTYLED */
|
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_delete.aliases = ['rm'];
|
do_delete.aliases = ['rm'];
|
||||||
|
@ -53,16 +53,15 @@ do_get.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_get.synopses = ['{{name}} {{cmd}} INST NAME'];
|
||||||
|
|
||||||
do_get.help = [
|
do_get.help = [
|
||||||
/* BEGIN JSSTYLED */
|
|
||||||
'Get an instance tag.',
|
'Get an instance tag.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} get <inst> <name>',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where <inst> is an instance id, name, or shortid and <name> is a tag name.'
|
'Where INST is an instance id, name, or shortid and NAME is a tag name.'
|
||||||
/* END JSSTYLED */
|
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
// TODO: When have 'tritoninstancetag' completion, add that in.
|
// TODO: When have 'tritoninstancetag' completion, add that in.
|
||||||
|
@ -49,19 +49,18 @@ do_list.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_list.synopses = ['{{name}} {{cmd}} INST'];
|
||||||
|
|
||||||
do_list.help = [
|
do_list.help = [
|
||||||
/* BEGIN JSSTYLED */
|
|
||||||
'List instance tags.',
|
'List instance tags.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} list <inst>',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where <inst> is an instance id, name, or shortid.',
|
'Where INST is an instance id, name, or shortid.',
|
||||||
'',
|
'',
|
||||||
'Note: Currently this dumps prettified JSON by default. That might change',
|
'Note: Currently this dumps prettified JSON by default. That might change',
|
||||||
'in the future. Use "-j" to explicitly get JSON output.'
|
'in the future. Use "-j" to explicitly get JSON output.'
|
||||||
/* END JSSTYLED */
|
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_list.aliases = ['ls'];
|
do_list.aliases = ['ls'];
|
||||||
|
@ -108,17 +108,19 @@ do_replace_all.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_replace_all.synopses = [
|
||||||
|
'{{name}} {{cmd}} INST [NAME=VALUE ...]',
|
||||||
|
'{{name}} {{cmd}} INST -f FILE # tags from file'
|
||||||
|
];
|
||||||
|
|
||||||
do_replace_all.help = [
|
do_replace_all.help = [
|
||||||
/* BEGIN JSSTYLED */
|
|
||||||
'Replace all tags on the given instance.',
|
'Replace all tags on the given instance.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} replace-all <inst> [<name>=<value> ...]',
|
|
||||||
' {{name}} replace-all <inst> -f <file> # tags from file',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where <inst> is an instance id, name, or shortid; <name> is a tag name;',
|
'Where INST is an instance id, name, or shortid; NAME is a tag name;',
|
||||||
'and <value> is a tag value (bool and numeric "value" are converted to ',
|
'and VALUE is a tag value (bool and numeric "value" are converted to ',
|
||||||
'that type).',
|
'that type).',
|
||||||
'',
|
'',
|
||||||
'Currently this dumps prettified JSON by default. That might change in the',
|
'Currently this dumps prettified JSON by default. That might change in the',
|
||||||
@ -126,7 +128,6 @@ do_replace_all.help = [
|
|||||||
'',
|
'',
|
||||||
'Changing instance tags is asynchronous. Use "--wait" to not return until',
|
'Changing instance tags is asynchronous. Use "--wait" to not return until',
|
||||||
'the changes are completed.'
|
'the changes are completed.'
|
||||||
/* END JSSTYLED */
|
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_replace_all.completionArgtypes = ['tritoninstance', 'file'];
|
do_replace_all.completionArgtypes = ['tritoninstance', 'file'];
|
||||||
|
@ -109,17 +109,20 @@ do_set.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_set.synopses = [
|
||||||
|
'{{name}} set INST [NAME=VALUE ...]',
|
||||||
|
'{{name}} set INST -f FILE # tags from file'
|
||||||
|
];
|
||||||
|
|
||||||
do_set.help = [
|
do_set.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Set one or more instance tags.',
|
'Set one or more instance tags.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} set <inst> [<name>=<value> ...]',
|
|
||||||
' {{name}} set <inst> -f <file> # tags from file',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where <inst> is an instance id, name, or shortid; <name> is a tag name;',
|
'Where INST is an instance id, name, or shortid; NAME is a tag name;',
|
||||||
'and <value> is a tag value (bool and numeric "value" are converted to ',
|
'and VALUE is a tag value (bool and numeric "value" are converted to ',
|
||||||
'that type).',
|
'that type).',
|
||||||
'',
|
'',
|
||||||
'Currently this dumps prettified JSON by default. That might change in the',
|
'Currently this dumps prettified JSON by default. That might change in the',
|
||||||
|
@ -21,7 +21,7 @@ function do_wait(subcmd, opts, args, cb) {
|
|||||||
if (opts.help) {
|
if (opts.help) {
|
||||||
return this.do_help('help', {}, [subcmd], cb);
|
return this.do_help('help', {}, [subcmd], cb);
|
||||||
} else if (args.length < 1) {
|
} else if (args.length < 1) {
|
||||||
return cb(new errors.UsageError('missing INSTANCE arg(s)'));
|
return cb(new errors.UsageError('missing INST arg(s)'));
|
||||||
}
|
}
|
||||||
var ids = args;
|
var ids = args;
|
||||||
var states = [];
|
var states = [];
|
||||||
@ -110,16 +110,19 @@ function do_wait(subcmd, opts, args, cb) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_wait.synopses = ['{{name}} {{cmd}} [-s STATES] INST [INST ...]'];
|
||||||
do_wait.help = [
|
do_wait.help = [
|
||||||
|
/* BEGIN JSSTYLED */
|
||||||
'Wait on instances changing state.',
|
'Wait on instances changing state.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} wait [-s STATES] INSTANCE [INSTANCE ...]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where "states" is a comma-separated list of target instance states,',
|
'Where "INST" is an instance name, id, or short id; and "STATES" is a',
|
||||||
'by default "running,failed". In other words, "triton inst wait foo0" will',
|
'comma-separated list of target instance states, by default "running,failed".',
|
||||||
'wait for instance "foo0" to complete provisioning.'
|
'In other words, "triton inst wait foo0" will wait for instance "foo0" to',
|
||||||
|
'complete provisioning.'
|
||||||
|
/* END JSSTYLED */
|
||||||
].join('\n');
|
].join('\n');
|
||||||
do_wait.options = [
|
do_wait.options = [
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2015 Joyent, Inc.
|
* Copyright 2016 Joyent, Inc.
|
||||||
*
|
*
|
||||||
* Shared support for:
|
* Shared support for:
|
||||||
* `triton instance start ...`
|
* `triton instance start ...`
|
||||||
@ -18,9 +18,7 @@ var assert = require('assert-plus');
|
|||||||
var vasync = require('vasync');
|
var vasync = require('vasync');
|
||||||
|
|
||||||
var common = require('../common');
|
var common = require('../common');
|
||||||
|
var errors = require('../errors');
|
||||||
|
|
||||||
var f = require('util').format;
|
|
||||||
|
|
||||||
|
|
||||||
function perror(err) {
|
function perror(err) {
|
||||||
@ -40,18 +38,20 @@ function gen_do_ACTION(opts) {
|
|||||||
function do_ACTION(subcmd, _opts, args, callback) {
|
function do_ACTION(subcmd, _opts, args, callback) {
|
||||||
return _doTheAction.call(this, action, subcmd, _opts, args, callback);
|
return _doTheAction.call(this, action, subcmd, _opts, args, callback);
|
||||||
}
|
}
|
||||||
|
do_ACTION.name = 'do_' + action;
|
||||||
|
|
||||||
if (opts.aliases) {
|
if (opts.aliases) {
|
||||||
do_ACTION.aliases = opts.aliases;
|
do_ACTION.aliases = opts.aliases;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_ACTION.synopses = ['{{name}} ' + action + ' [OPTIONS] INST [INST ...]'];
|
||||||
do_ACTION.help = [
|
do_ACTION.help = [
|
||||||
f('%s one or more instances.', common.capitalize(action)),
|
common.capitalize(action) + ' one or more instances.',
|
||||||
f(''),
|
'',
|
||||||
f('Usage:'),
|
'{{usage}}',
|
||||||
f(' {{name}} %s <alias|id> ...', action),
|
'',
|
||||||
f(''),
|
'{{options}}',
|
||||||
f('{{options}}')
|
'Where "INST" is an instance name, id, or short id.'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
do_ACTION.options = [
|
do_ACTION.options = [
|
||||||
{
|
{
|
||||||
@ -72,7 +72,8 @@ function gen_do_ACTION(opts) {
|
|||||||
do_ACTION.options.push({
|
do_ACTION.options.push({
|
||||||
names: ['snapshot'],
|
names: ['snapshot'],
|
||||||
type: 'string',
|
type: 'string',
|
||||||
help: 'Name of snapshot to start machine with.'
|
help: 'Name of snapshot with which to start the instance.',
|
||||||
|
helpArg: 'SNAPNAME'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +113,7 @@ function _doTheAction(action, subcmd, opts, args, callback) {
|
|||||||
this.do_help('help', {}, [subcmd], callback);
|
this.do_help('help', {}, [subcmd], callback);
|
||||||
return;
|
return;
|
||||||
} else if (args.length < 1) {
|
} else if (args.length < 1) {
|
||||||
callback(new Error('invalid args: ' + args));
|
callback(new errors.UsageError('missing INST arg(s)'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,11 +125,13 @@ do_add.options = [
|
|||||||
help: 'An optional name for an added key.'
|
help: 'An optional name for an added key.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_add.synopses = ['{{name}} {{cmd}} [OPTIONS] FILE'];
|
||||||
|
|
||||||
do_add.help = [
|
do_add.help = [
|
||||||
'Add an SSH key to an account.',
|
'Add an SSH key to an account.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} add [<options>] FILE',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where "FILE" must be a file path to an SSH public key, ',
|
'Where "FILE" must be a file path to an SSH public key, ',
|
||||||
|
@ -104,11 +104,13 @@ do_delete.options = [
|
|||||||
help: 'Answer yes to confirmation to delete.'
|
help: 'Answer yes to confirmation to delete.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_delete.synopses = ['{{name}} {{cmd}} [OPTIONS] KEY [KEY ...]'];
|
||||||
|
|
||||||
do_delete.help = [
|
do_delete.help = [
|
||||||
'Remove an SSH key from an account.',
|
'Remove an SSH key from an account.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} delete [<options>] KEY [KEY...]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where "KEY" is an SSH key "name" or "fingerprint".'
|
'Where "KEY" is an SSH key "name" or "fingerprint".'
|
||||||
|
@ -67,11 +67,13 @@ do_get.options = [
|
|||||||
help: 'JSON stream output.'
|
help: 'JSON stream output.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_get.synopses = ['{{name}} {{cmd}} KEY'];
|
||||||
|
|
||||||
do_get.help = [
|
do_get.help = [
|
||||||
'Show a specific SSH key in an account.',
|
'Show a specific SSH key in an account.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} get KEY',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where "KEY" is an SSH key "name" or "fingerprint".'
|
'Where "KEY" is an SSH key "name" or "fingerprint".'
|
||||||
|
@ -90,11 +90,11 @@ do_list.options = [
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
do_list.synopses = ['{{name}} {{cmd}} [OPTIONS]'];
|
||||||
do_list.help = [
|
do_list.help = [
|
||||||
'Show all of an account\'s SSH keys.',
|
'Show all of an account\'s SSH keys.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} list [<options>]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
@ -51,14 +51,17 @@ do_get.options = [
|
|||||||
help: 'JSON output.'
|
help: 'JSON output.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
do_get.help = (
|
|
||||||
'Show a network.\n'
|
do_get.synopses = ['{{name}} {{cmd}} NETWORK'];
|
||||||
+ '\n'
|
|
||||||
+ 'Usage:\n'
|
do_get.help = [
|
||||||
+ ' {{name}} get <id|name>\n'
|
'Show a network.',
|
||||||
+ '\n'
|
'',
|
||||||
+ '{{options}}'
|
'{{usage}}',
|
||||||
);
|
'',
|
||||||
|
'{{options}}',
|
||||||
|
'Where NETWORK is a network id (full UUID), name, or short id.'
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
do_get.completionArgtypes = ['tritonnetwork', 'none'];
|
do_get.completionArgtypes = ['tritonnetwork', 'none'];
|
||||||
|
|
||||||
|
@ -85,17 +85,17 @@ do_list.options = [
|
|||||||
sortDefault: sortDefault
|
sortDefault: sortDefault
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
do_list.synopses = ['{{name}} {{cmd}}'];
|
||||||
|
|
||||||
do_list.help = [
|
do_list.help = [
|
||||||
'List available networks.',
|
'List available networks.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} list',
|
|
||||||
'',
|
'',
|
||||||
|
'{{options}}',
|
||||||
'Fields (most are self explanatory, the client adds some for convenience):',
|
'Fields (most are self explanatory, the client adds some for convenience):',
|
||||||
' vlan A shorter alias for "vlan_id".',
|
' vlan A shorter alias for "vlan_id".',
|
||||||
' shortid A short ID prefix.',
|
' shortid A short ID prefix.'
|
||||||
'',
|
|
||||||
'{{options}}'
|
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
do_list.aliases = ['ls'];
|
do_list.aliases = ['ls'];
|
||||||
|
@ -50,21 +50,23 @@ do_get.options = [
|
|||||||
help: 'JSON stream output.'
|
help: 'JSON stream output.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
do_get.help = (
|
|
||||||
|
do_get.synopses = ['{{name}} {{cmd}} [OPTIONS] PACKAGE'];
|
||||||
|
|
||||||
|
do_get.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Get a package.\n' +
|
'Get a package.',
|
||||||
'\n' +
|
'',
|
||||||
'Usage:\n' +
|
'{{usage}}',
|
||||||
' {{name}} get [<options>] ID|NAME\n' +
|
'',
|
||||||
'\n' +
|
'{{options}}',
|
||||||
'{{options}}' +
|
'',
|
||||||
'\n' +
|
'Where PACKAGE is a package id (full UUID), exact name, or short id.',
|
||||||
'The given "NAME" must be a unique match.\n' +
|
'',
|
||||||
'\n' +
|
'Note: Currently this dumps prettified JSON by default. That might change',
|
||||||
'Note: Currently this dumps prettified JSON by default. That might change\n' +
|
'in the future. Use "-j" to explicitly get JSON output.'
|
||||||
'in the future. Use "-j" to explicitly get JSON output.\n'
|
|
||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
);
|
].join('\n');
|
||||||
|
|
||||||
do_get.completionArgtypes = ['tritonpackage', 'none'];
|
do_get.completionArgtypes = ['tritonpackage', 'none'];
|
||||||
|
|
||||||
|
@ -28,10 +28,10 @@ var validFilters = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
// columns default without -o
|
// columns default without -o
|
||||||
var columnsDefault = 'shortid,name,default,memory,swap,disk,vcpus';
|
var columnsDefault = 'shortid,name,memory,swap,disk,vcpus';
|
||||||
|
|
||||||
// columns default with -l
|
// columns default with -l
|
||||||
var columnsDefaultLong = 'id,name,default,memory,swap,disk,vcpus';
|
var columnsDefaultLong = 'id,name,memory,swap,disk,vcpus,description';
|
||||||
|
|
||||||
// sort default with -s
|
// sort default with -s
|
||||||
var sortDefault = '_groupPlus,memory';
|
var sortDefault = '_groupPlus,memory';
|
||||||
@ -154,12 +154,12 @@ do_list.options = [
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
do_list.synopses = ['{{name}} {{cmd}} [FILTERS]'];
|
||||||
do_list.help = [
|
do_list.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'List packages.',
|
'List packages.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} list [<filters>]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Filters:',
|
'Filters:',
|
||||||
@ -177,7 +177,7 @@ do_list.help = [
|
|||||||
' zero is shown as "-" in tabular output.',
|
' zero is shown as "-" in tabular output.',
|
||||||
'',
|
'',
|
||||||
'Examples:',
|
'Examples:',
|
||||||
' {{name}} packages memory=8192 # list packages with 8G RAM'
|
' {{name}} list memory=8192 # list packages with 8G RAM'
|
||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
|
@ -23,7 +23,11 @@ function PackageCLI(top) {
|
|||||||
name: top.name + ' package',
|
name: top.name + ' package',
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
desc: [
|
desc: [
|
||||||
'List and get Triton packages.'
|
'List and get Triton packages.',
|
||||||
|
'',
|
||||||
|
'A package is a collection of attributes -- for example disk quota,',
|
||||||
|
'amount of RAM -- used when creating an instance. They have a name',
|
||||||
|
'and ID for identification.'
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
helpOpts: {
|
helpOpts: {
|
||||||
|
@ -366,11 +366,11 @@ do_create.options = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
do_create.synopses = ['{{name}} {{cmd}} [OPTIONS]'];
|
||||||
do_create.help = [
|
do_create.help = [
|
||||||
'Create a Triton CLI profile.',
|
'Create a Triton CLI profile.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} create <options>',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'',
|
'',
|
||||||
|
@ -120,11 +120,11 @@ do_delete.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_delete.synopses = ['{{name}} {{cmd}} PROFILE'];
|
||||||
do_delete.help = [
|
do_delete.help = [
|
||||||
'Delete a Triton CLI profile.',
|
'Delete a Triton CLI profile.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} delete NAME',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
@ -33,12 +33,12 @@ do_docker_setup.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_docker_setup.synopses = ['{{name}} {{cmd}} [PROFILE]'];
|
||||||
do_docker_setup.help = [
|
do_docker_setup.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Setup for using Docker with the current Triton CLI profile.',
|
'Setup for using Docker with the current Triton CLI profile.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} docker-setup [PROFILE]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'A Triton datacenter can act as a virtual Docker Engine, where the entire',
|
'A Triton datacenter can act as a virtual Docker Engine, where the entire',
|
||||||
@ -54,5 +54,6 @@ do_docker_setup.help = [
|
|||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
|
do_docker_setup.completionArgtypes = ['tritonprofile', 'none'];
|
||||||
|
|
||||||
module.exports = do_docker_setup;
|
module.exports = do_docker_setup;
|
||||||
|
@ -154,11 +154,11 @@ do_edit.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_edit.synopses = ['{{name}} {{cmd}} [PROFILE]'];
|
||||||
do_edit.help = [
|
do_edit.help = [
|
||||||
'Edit a Triton CLI profile in your $EDITOR.',
|
'Edit a Triton CLI profile in your $EDITOR.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} edit [NAME]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}'
|
'{{options}}'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
@ -74,15 +74,16 @@ do_get.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_get.synopses = ['{{name}} {{cmd}} [PROFILE]'];
|
||||||
do_get.help = [
|
do_get.help = [
|
||||||
'Get a Triton CLI profile.',
|
'Get a Triton CLI profile.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} get [NAME]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'If NAME is not specified, the current profile is shown.'
|
'If NAME is not specified, the current profile is shown.'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
|
do_get.completionArgtypes = ['tritonprofile', 'none'];
|
||||||
|
|
||||||
module.exports = do_get;
|
module.exports = do_get;
|
||||||
|
@ -112,22 +112,21 @@ do_list.options = [
|
|||||||
includeLong: true,
|
includeLong: true,
|
||||||
sortDefault: sortDefault
|
sortDefault: sortDefault
|
||||||
}));
|
}));
|
||||||
|
do_list.synopses = ['{{name}} {{cmd}} [OPTIONS]'];
|
||||||
do_list.help = [
|
do_list.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'List Triton CLI profiles.',
|
'List Triton CLI profiles.',
|
||||||
'',
|
'',
|
||||||
|
'{{usage}}',
|
||||||
|
'',
|
||||||
|
'{{options}}',
|
||||||
'A profile is a configured Triton CloudAPI endpoint and associated info.',
|
'A profile is a configured Triton CloudAPI endpoint and associated info.',
|
||||||
'I.e. the URL, account name, SSH key fingerprint, etc. information required',
|
'I.e. the URL, account name, SSH key fingerprint, etc. information required',
|
||||||
'to call a CloudAPI endpoint in a Triton datacenter. You can then switch',
|
'to call a CloudAPI endpoint in a Triton datacenter. You can then switch',
|
||||||
'between profiles with `triton -p PROFILE`, the TRITON_PROFILE environment',
|
'between profiles with `triton -p PROFILE`, the TRITON_PROFILE environment',
|
||||||
'variable, or by setting your current profile.',
|
'variable, or by setting your current profile.',
|
||||||
'',
|
'',
|
||||||
'The "CURR" column indicates which profile is the current one.',
|
'The "CURR" column indicates which profile is the current one.'
|
||||||
'',
|
|
||||||
'Usage:',
|
|
||||||
' {{name}} list',
|
|
||||||
'',
|
|
||||||
'{{options}}'
|
|
||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
|
@ -13,8 +13,12 @@ function do_set_current(subcmd, opts, args, cb) {
|
|||||||
if (opts.help) {
|
if (opts.help) {
|
||||||
this.do_help('help', {}, [subcmd], cb);
|
this.do_help('help', {}, [subcmd], cb);
|
||||||
return;
|
return;
|
||||||
} else if (args.length !== 1) {
|
} else if (args.length === 0) {
|
||||||
return cb(new errors.UsageError('NAME argument is required'));
|
cb(new errors.UsageError('missing NAME argument'));
|
||||||
|
return;
|
||||||
|
} else if (args.length > 1) {
|
||||||
|
cb(new errors.UsageError('too many arguments: ' + args.join(' ')));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
profilecommon.setCurrentProfile({cli: this.top, name: args[0]}, cb);
|
profilecommon.setCurrentProfile({cli: this.top, name: args[0]}, cb);
|
||||||
@ -28,11 +32,11 @@ do_set_current.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_set_current.synopses = ['{{name}} {{cmd}} PROFILE'];
|
||||||
do_set_current.help = [
|
do_set_current.help = [
|
||||||
'Set the current Triton CLI profile.',
|
'Set the current Triton CLI profile.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} set-current NAME',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'NAME is the name of an existing profile, or "-" to switch to the',
|
'NAME is the name of an existing profile, or "-" to switch to the',
|
||||||
|
@ -416,6 +416,8 @@ function profileDockerSetup(opts, cb) {
|
|||||||
* `docker-compose` versions). It is debatable if we want to
|
* `docker-compose` versions). It is debatable if we want to
|
||||||
* play this game. E.g. someone moving from Docker 1.8 to newer,
|
* play this game. E.g. someone moving from Docker 1.8 to newer,
|
||||||
* *but not re-setting up envvars* may start hitting timeouts.
|
* *but not re-setting up envvars* may start hitting timeouts.
|
||||||
|
*
|
||||||
|
* TODO: consider using `docker-compose` version on PATH?
|
||||||
*/
|
*/
|
||||||
if (!arg.dockerVersion) {
|
if (!arg.dockerVersion) {
|
||||||
setup.env.DOCKER_CLIENT_TIMEOUT = '300';
|
setup.env.DOCKER_CLIENT_TIMEOUT = '300';
|
||||||
|
@ -203,12 +203,13 @@ do_apply.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_apply.synopses = ['{{name}} {{cmd}} [OPTIONS]'];
|
||||||
|
|
||||||
do_apply.help = [
|
do_apply.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Apply an RBAC configuration.',
|
'Apply an RBAC configuration.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} apply [<options>]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'If "--file FILE" is not specified, this defaults to using "./rbac.json".',
|
'If "--file FILE" is not specified, this defaults to using "./rbac.json".',
|
||||||
|
@ -211,12 +211,13 @@ do_info.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_info.synopses = ['{{name}} {{cmd}} [OPTIONS]'];
|
||||||
|
|
||||||
do_info.help = [
|
do_info.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Show current RBAC state.',
|
'Show current RBAC state.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} info [<options>]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'List RBAC users, roles and policies and. This summary does not show all',
|
'List RBAC users, roles and policies and. This summary does not show all',
|
||||||
|
@ -303,20 +303,23 @@ do_key.options = [
|
|||||||
help: 'Delete the named key.'
|
help: 'Delete the named key.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_key.synopses = [
|
||||||
|
'{{name}} {{cmd}} USER KEY # show USER\'s KEY',
|
||||||
|
'{{name}} {{cmd}} -d|--delete USER [KEY...] # delete USER\'s KEY',
|
||||||
|
'{{name}} {{cmd}} -a|--add [-n NAME] USER FILE # add an SSH key'
|
||||||
|
];
|
||||||
|
|
||||||
do_key.help = [
|
do_key.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Show, upload, and delete RBAC user SSH keys.',
|
'Show, upload, and delete RBAC user SSH keys.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} key USER KEY # show USER\'s KEY',
|
|
||||||
' {{name}} key -d|--delete USER [KEY...] # delete USER\'s KEY',
|
|
||||||
' {{name}} key -a|--add [-n NAME] USER FILE',
|
|
||||||
' # Add a new role. FILE must be a file path to an SSH public',
|
|
||||||
' # key or "-" to pass the public key in on stdin.',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where "USER" is a full RBAC user "id", "login" name or a "shortid"; and',
|
'Where "USER" is a full RBAC user "id", "login" name or a "shortid"; and',
|
||||||
'KEY is an SSH key "name" or "fingerprint".'
|
'KEY is an SSH key "name" or "fingerprint". FILE must be a file path to',
|
||||||
|
'an SSH public key or "-" to pass the public key in on stdin.'
|
||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
|
@ -84,19 +84,18 @@ do_keys.options = [
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
do_keys.help = (
|
do_keys.synopses = ['{{name}} {{cmd}} [OPTIONS] USER'];
|
||||||
/* BEGIN JSSTYLED */
|
|
||||||
'List RBAC user SSH keys.\n' +
|
|
||||||
'\n' +
|
|
||||||
'Usage:\n' +
|
|
||||||
' {{name}} keys [<options>] USER\n' +
|
|
||||||
'\n' +
|
|
||||||
'{{options}}' +
|
|
||||||
'\n' +
|
|
||||||
'Where "USER" is an RBAC user login or id (a UUID).\n'
|
|
||||||
/* END JSSTYLED */
|
|
||||||
);
|
|
||||||
|
|
||||||
|
do_keys.help = [
|
||||||
|
/* BEGIN JSSTYLED */
|
||||||
|
'List RBAC user SSH keys.',
|
||||||
|
'',
|
||||||
|
'{{usage}}',
|
||||||
|
'',
|
||||||
|
'{{options}}',
|
||||||
|
'Where "USER" is an RBAC user login or id (a UUID).'
|
||||||
|
/* END JSSTYLED */
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
|
||||||
module.exports = do_keys;
|
module.exports = do_keys;
|
||||||
|
@ -82,20 +82,17 @@ do_policies.options = [
|
|||||||
sortDefault: sortDefault
|
sortDefault: sortDefault
|
||||||
}));
|
}));
|
||||||
|
|
||||||
do_policies.help = (
|
do_policies.synopses = ['{{name}} {{cmd}} [OPTIONS]'];
|
||||||
/* BEGIN JSSTYLED */
|
|
||||||
'List RBAC policies.\n' +
|
|
||||||
'\n' +
|
|
||||||
'Usage:\n' +
|
|
||||||
' {{name}} policies [<options>]\n' +
|
|
||||||
'\n' +
|
|
||||||
'{{options}}' +
|
|
||||||
'\n' +
|
|
||||||
'Fields (most are self explanatory, the client adds some for convenience):\n' +
|
|
||||||
' nrules The number of rules in this policy.\n'
|
|
||||||
/* END JSSTYLED */
|
|
||||||
);
|
|
||||||
|
|
||||||
|
do_policies.help = [
|
||||||
|
'List RBAC policies.',
|
||||||
|
'',
|
||||||
|
'{{usage}}',
|
||||||
|
'',
|
||||||
|
'{{options}}',
|
||||||
|
'Fields (most are self explanatory, the client adds some for convenience):',
|
||||||
|
' nrules The number of rules in this policy.'
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
|
||||||
module.exports = do_policies;
|
module.exports = do_policies;
|
||||||
|
@ -512,16 +512,24 @@ do_policy.options = [
|
|||||||
help: 'Delete the named policy.'
|
help: 'Delete the named policy.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_policy.synopses = [
|
||||||
|
'{{name}} {{cmd}} POLICY # show policy POLICY',
|
||||||
|
'{{name}} {{cmd}} -e|--edit POLICY # edit policy POLICY in $EDITOR',
|
||||||
|
'{{name}} {{cmd}} -d|--delete [POLICY...] # delete policy POLICY',
|
||||||
|
'{{name}} {{cmd}} -a|--add [FILE] # add a new policy'
|
||||||
|
];
|
||||||
|
|
||||||
do_policy.help = [
|
do_policy.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Show, add, edit and delete RBAC policies.',
|
'Show, add, edit and delete RBAC policies.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'Usage:',
|
||||||
' {{name}} policy POLICY # show policy POLICY',
|
' {{name}} {{cmd}} POLICY # show policy POLICY',
|
||||||
' {{name}} policy -e|--edit POLICY # edit policy POLICY in $EDITOR',
|
' {{name}} {{cmd}} -e|--edit POLICY # edit policy POLICY in $EDITOR',
|
||||||
' {{name}} policy -d|--delete [POLICY...] # delete policy POLICY',
|
' {{name}} {{cmd}} -d|--delete [POLICY...] # delete policy POLICY',
|
||||||
'',
|
'',
|
||||||
' {{name}} policy -a|--add [FILE]',
|
' {{name}} {{cmd}} -a|--add [FILE]',
|
||||||
' # Add a new policy. FILE must be a file path to a JSON file',
|
' # Add a new policy. FILE must be a file path to a JSON file',
|
||||||
' # with the policy data or "-" to pass the policy in on stdin.',
|
' # with the policy data or "-" to pass the policy in on stdin.',
|
||||||
' # Or exclude FILE to interactively add.',
|
' # Or exclude FILE to interactively add.',
|
||||||
|
@ -104,13 +104,16 @@ do_reset.options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_reset.synopses = [
|
||||||
|
'{{name}} {{cmd}} [OPTIONS]'
|
||||||
|
];
|
||||||
|
|
||||||
do_reset.help = [
|
do_reset.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Reset RBAC state for this account.',
|
'Reset RBAC state for this account.',
|
||||||
'**Warning: This will delete all RBAC info for this account.**',
|
'**Warning: This will delete all RBAC info for this account.**',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} reset [<options>]',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Warning: Currently, RBAC state updates can take a few seconds to appear',
|
'Warning: Currently, RBAC state updates can take a few seconds to appear',
|
||||||
|
@ -490,16 +490,24 @@ do_role.options = [
|
|||||||
help: 'Delete the named role.'
|
help: 'Delete the named role.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_role.synopses = [
|
||||||
|
'{{name}} {{cmd}} ROLE # show role ROLE',
|
||||||
|
'{{name}} {{cmd}} -e|--edit ROLE # edit role ROLE in $EDITOR',
|
||||||
|
'{{name}} {{cmd}} -d|--delete [ROLE...] # delete role ROLE',
|
||||||
|
'{{name}} {{cmd}} -a|--add [FILE] # add a new role'
|
||||||
|
];
|
||||||
|
|
||||||
do_role.help = [
|
do_role.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Show, add, edit and delete RBAC roles.',
|
'Show, add, edit and delete RBAC roles.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'Usage:',
|
||||||
' {{name}} role ROLE # show role ROLE',
|
' {{name}} {{cmd}} ROLE # show role ROLE',
|
||||||
' {{name}} role -e|--edit ROLE # edit role ROLE in $EDITOR',
|
' {{name}} {{cmd}} -e|--edit ROLE # edit role ROLE in $EDITOR',
|
||||||
' {{name}} role -d|--delete [ROLE...] # delete role ROLE',
|
' {{name}} {{cmd}} -d|--delete [ROLE...] # delete role ROLE',
|
||||||
'',
|
'',
|
||||||
' {{name}} role -a|--add [FILE]',
|
' {{name}} {{cmd}} -a|--add [FILE]',
|
||||||
' # Add a new role. FILE must be a file path to a JSON file',
|
' # Add a new role. FILE must be a file path to a JSON file',
|
||||||
' # with the role data or "-" to pass the role in on stdin.',
|
' # with the role data or "-" to pass the role in on stdin.',
|
||||||
' # Or exclude FILE to interactively add.',
|
' # Or exclude FILE to interactively add.',
|
||||||
|
@ -508,7 +508,8 @@ function makeRoleTagsFunc(cfg) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
func.name = cfg.funcName;
|
func.name = cfg.funcName; // XXX
|
||||||
|
func.subcmd = cfg.funcName;
|
||||||
|
|
||||||
func.options = [
|
func.options = [
|
||||||
{
|
{
|
||||||
@ -564,24 +565,31 @@ function makeRoleTagsFunc(cfg) {
|
|||||||
helpCol: 23
|
helpCol: 23
|
||||||
};
|
};
|
||||||
|
|
||||||
|
func.synopses = [
|
||||||
|
'{{name}} {{cmd}} $argName # list role tags',
|
||||||
|
'{{name}} {{cmd}} -a ROLE[,ROLE...] $argName # add',
|
||||||
|
'{{name}} {{cmd}} -s ROLE[,ROLE...] $argName # set/replace',
|
||||||
|
'{{name}} {{cmd}} -e $argName # edit in $EDITOR',
|
||||||
|
'{{name}} {{cmd}} -d ROLE[,ROLE...] $argName # delete',
|
||||||
|
'{{name}} {{cmd}} -D $argName # delete all'
|
||||||
|
];
|
||||||
|
func.synopses = func.synopses.map(function (synopsis) {
|
||||||
|
var key = 'argName';
|
||||||
|
return synopsis.replace(new RegExp('\\$' + key, 'g'), cfg[key]);
|
||||||
|
});
|
||||||
|
|
||||||
func.help = [
|
func.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'List and manage role tags for the given $resourceType.',
|
'List and manage role tags for the given $resourceType.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'{{usage}}',
|
||||||
' {{name}} $cmdName $argName # list role tags',
|
|
||||||
' {{name}} $cmdName -a ROLE[,ROLE...] $argName # add',
|
|
||||||
' {{name}} $cmdName -s ROLE[,ROLE...] $argName # set/replace',
|
|
||||||
' {{name}} $cmdName -e $argName # edit in $EDITOR',
|
|
||||||
' {{name}} $cmdName -d ROLE[,ROLE...] $argName # delete',
|
|
||||||
' {{name}} $cmdName -D $argName # delete all',
|
|
||||||
'',
|
'',
|
||||||
'{{options}}',
|
'{{options}}',
|
||||||
'Where "ROLE" is a role tag name (see `triton rbac roles`) and',
|
'Where "ROLE" is a role tag name (see `triton rbac roles`) and',
|
||||||
'$argName is $helpArgIs.'
|
'$argName is $helpArgIs.'
|
||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
].join('\n');
|
].join('\n');
|
||||||
['resourceType', 'cmdName', 'argName', 'helpArgIs'].forEach(function (key) {
|
['resourceType', 'cmdName', 'helpArgIs'].forEach(function (key) {
|
||||||
func.help = func.help.replace(new RegExp('\\$' + key, 'g'), cfg[key]);
|
func.help = func.help.replace(new RegExp('\\$' + key, 'g'), cfg[key]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -97,20 +97,20 @@ do_roles.options = [
|
|||||||
sortDefault: sortDefault
|
sortDefault: sortDefault
|
||||||
}));
|
}));
|
||||||
|
|
||||||
do_roles.help = (
|
do_roles.synopses = ['{{name}} {{cmd}} [OPTIONS]'];
|
||||||
|
|
||||||
|
do_roles.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'List RBAC roles.\n' +
|
'List RBAC roles.',
|
||||||
'\n' +
|
'',
|
||||||
'Usage:\n' +
|
'{{usage}}',
|
||||||
' {{name}} roles [<options>]\n' +
|
'',
|
||||||
'\n' +
|
'{{options}}',
|
||||||
'{{options}}' +
|
'Fields (most are self explanatory, the client adds some for convenience):',
|
||||||
'\n' +
|
' members Non-default members (not in the "default_members")',
|
||||||
'Fields (most are self explanatory, the client adds some for convenience):\n' +
|
|
||||||
' members Non-default members (not in the "default_members")\n' +
|
|
||||||
' are shown in magenta.\n'
|
' are shown in magenta.\n'
|
||||||
/* END JSSTYLED */
|
/* END JSSTYLED */
|
||||||
);
|
].join('\n');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -497,16 +497,24 @@ do_user.options = [
|
|||||||
help: 'Delete the named user.'
|
help: 'Delete the named user.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
do_user.synopses = [
|
||||||
|
'{{name}} {{cmd}} [OPTIONS] USER # show user USER',
|
||||||
|
'{{name}} {{cmd}} -e|--edit USER # edit user USER in $EDITOR',
|
||||||
|
'{{name}} {{cmd}} -d|--delete [USER...] # delete user USER',
|
||||||
|
'{{name}} {{cmd}} -a|--add [FILE] # add a user'
|
||||||
|
];
|
||||||
|
|
||||||
do_user.help = [
|
do_user.help = [
|
||||||
/* BEGIN JSSTYLED */
|
/* BEGIN JSSTYLED */
|
||||||
'Show, add, edit and delete RBAC users.',
|
'Show, add, edit and delete RBAC users.',
|
||||||
'',
|
'',
|
||||||
'Usage:',
|
'Usage:',
|
||||||
' {{name}} user [<options>] USER # show user USER',
|
' {{name}} {{cmd}} [OPTIONS] USER # show user USER',
|
||||||
' {{name}} user -e|--edit USER # edit user USER in $EDITOR',
|
' {{name}} {{cmd}} -e|--edit USER # edit user USER in $EDITOR',
|
||||||
' {{name}} user -d|--delete [USER...] # delete user USER',
|
' {{name}} {{cmd}} -d|--delete [USER...] # delete user USER',
|
||||||
'',
|
'',
|
||||||
' {{name}} user -a|--add [FILE]',
|
' {{name}} {{cmd}} -a|--add [FILE]',
|
||||||
' # Add a new user. FILE must be a file path to a JSON file',
|
' # Add a new user. FILE must be a file path to a JSON file',
|
||||||
' # with the user data or "-" to pass the user in on stdin.',
|
' # with the user data or "-" to pass the user in on stdin.',
|
||||||
' # Or exclude FILE to interactively add.',
|
' # Or exclude FILE to interactively add.',
|
||||||
|
@ -84,22 +84,19 @@ do_users.options = [
|
|||||||
sortDefault: sortDefault
|
sortDefault: sortDefault
|
||||||
}));
|
}));
|
||||||
|
|
||||||
do_users.help = (
|
do_users.synopses = ['{{name}} {{cmd}} [OPTIONS]'];
|
||||||
/* BEGIN JSSTYLED */
|
|
||||||
'List RBAC users.\n' +
|
|
||||||
'\n' +
|
|
||||||
'Usage:\n' +
|
|
||||||
' {{name}} users [<options>]\n' +
|
|
||||||
'\n' +
|
|
||||||
'Fields (most are self explanatory, the client adds some for convenience):\n' +
|
|
||||||
' name "firstName lastName"\n' +
|
|
||||||
' cdate Just the date portion of "created"\n' +
|
|
||||||
' udate Just the date portion of "updated"\n' +
|
|
||||||
'\n' +
|
|
||||||
'{{options}}'
|
|
||||||
/* END JSSTYLED */
|
|
||||||
);
|
|
||||||
|
|
||||||
|
do_users.help = [
|
||||||
|
'List RBAC users.',
|
||||||
|
'',
|
||||||
|
'{{usage}}',
|
||||||
|
'',
|
||||||
|
'{{options}}',
|
||||||
|
'Fields (most are self explanatory, the client adds some for convenience):',
|
||||||
|
' name "firstName lastName"',
|
||||||
|
' cdate Just the date portion of "created"',
|
||||||
|
' udate Just the date portion of "updated"'
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
|
||||||
module.exports = do_users;
|
module.exports = do_users;
|
||||||
|
@ -77,13 +77,14 @@ do_services.options = [
|
|||||||
sortDefault: sortDefault
|
sortDefault: sortDefault
|
||||||
}));
|
}));
|
||||||
|
|
||||||
do_services.help = (
|
do_services.synopses = ['{{name}} {{cmd}}'];
|
||||||
'Show services information\n'
|
|
||||||
+ '\n'
|
do_services.help = [
|
||||||
+ 'Usage:\n'
|
'Show services information',
|
||||||
+ ' {{name}} services\n'
|
'',
|
||||||
+ '\n'
|
'{{usage}}',
|
||||||
+ '{{options}}'
|
'',
|
||||||
);
|
'{{options}}'
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
module.exports = do_services;
|
module.exports = do_services;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
* Error classes that the joyent CLI may produce.
|
* Error classes that the joyent CLI may produce.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var cmdln = require('cmdln');
|
||||||
var util = require('util'),
|
var util = require('util'),
|
||||||
format = util.format;
|
format = util.format;
|
||||||
var assert = require('assert-plus');
|
var assert = require('assert-plus');
|
||||||
@ -145,25 +146,6 @@ function ConfigError(cause, message) {
|
|||||||
util.inherits(ConfigError, _TritonBaseVError);
|
util.inherits(ConfigError, _TritonBaseVError);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CLI usage error
|
|
||||||
*/
|
|
||||||
function UsageError(cause, message) {
|
|
||||||
if (message === undefined) {
|
|
||||||
message = cause;
|
|
||||||
cause = undefined;
|
|
||||||
}
|
|
||||||
assert.string(message);
|
|
||||||
_TritonBaseVError.call(this, {
|
|
||||||
cause: cause,
|
|
||||||
message: message,
|
|
||||||
code: 'Usage',
|
|
||||||
exitStatus: 2
|
|
||||||
});
|
|
||||||
}
|
|
||||||
util.inherits(UsageError, _TritonBaseVError);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error in setting up (typically in profile update/creation).
|
* Error in setting up (typically in profile update/creation).
|
||||||
*/
|
*/
|
||||||
@ -299,7 +281,7 @@ module.exports = {
|
|||||||
TritonError: TritonError,
|
TritonError: TritonError,
|
||||||
InternalError: InternalError,
|
InternalError: InternalError,
|
||||||
ConfigError: ConfigError,
|
ConfigError: ConfigError,
|
||||||
UsageError: UsageError,
|
UsageError: cmdln.UsageError,
|
||||||
SetupError: SetupError,
|
SetupError: SetupError,
|
||||||
SigningError: SigningError,
|
SigningError: SigningError,
|
||||||
SelfSignedCertError: SelfSignedCertError,
|
SelfSignedCertError: SelfSignedCertError,
|
||||||
|
@ -28,7 +28,6 @@ var vasync = require('vasync');
|
|||||||
var cloudapi = require('./cloudapi2');
|
var cloudapi = require('./cloudapi2');
|
||||||
var common = require('./common');
|
var common = require('./common');
|
||||||
var errors = require('./errors');
|
var errors = require('./errors');
|
||||||
var loadConfigSync = require('./config').loadConfigSync;
|
|
||||||
|
|
||||||
|
|
||||||
// ---- globals
|
// ---- globals
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "triton",
|
"name": "triton",
|
||||||
"description": "Joyent Triton CLI and client (https://www.joyent.com/triton)",
|
"description": "Joyent Triton CLI and client (https://www.joyent.com/triton)",
|
||||||
"version": "4.12.1",
|
"version": "4.13.0",
|
||||||
"author": "Joyent (joyent.com)",
|
"author": "Joyent (joyent.com)",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"assert-plus": "0.2.0",
|
"assert-plus": "0.2.0",
|
||||||
"backoff": "2.4.1",
|
"backoff": "2.4.1",
|
||||||
"bigspinner": "3.1.0",
|
"bigspinner": "3.1.0",
|
||||||
"bunyan": "1.5.1",
|
"bunyan": "1.5.1",
|
||||||
"cmdln": "3.5.4",
|
"cmdln": "4.1.1",
|
||||||
"extsprintf": "1.0.2",
|
"extsprintf": "1.0.2",
|
||||||
"lomstream": "1.1.0",
|
"lomstream": "1.1.0",
|
||||||
"mkdirp": "0.5.1",
|
"mkdirp": "0.5.1",
|
||||||
|
Reference in New Issue
Block a user