joyent/node-triton#4 triton networks/network to support shortId as well and to include fabric
flag
This commit is contained in:
parent
ae8a19d568
commit
58a7c9977b
@ -130,6 +130,7 @@ do_images.options = [
|
||||
help: 'JSON stream output.'
|
||||
}
|
||||
];
|
||||
|
||||
do_images.help = (
|
||||
/* BEGIN JSSTYLED */
|
||||
'List images.\n' +
|
||||
@ -144,6 +145,7 @@ do_images.help = (
|
||||
' FIELD=~SUBSTRING Field substring filter. Supported fields: name\n' +
|
||||
'\n' +
|
||||
'Fields (most are self explanatory, the client adds some for convenience):\n' +
|
||||
' shortid A short ID prefix.\n' +
|
||||
' flags This is a set of single letter flags\n' +
|
||||
' summarizing some fields. "P" indicates the\n' +
|
||||
' image is public. "I" indicates an incremental\n' +
|
||||
|
@ -4,60 +4,33 @@
|
||||
* `triton network ...`
|
||||
*/
|
||||
|
||||
var format = require('util').format;
|
||||
|
||||
var common = require('./common');
|
||||
var errors = require('./errors');
|
||||
|
||||
|
||||
function do_network(subcmd, opts, args, cb) {
|
||||
if (opts.help) {
|
||||
this.do_help('help', {}, [subcmd], cb);
|
||||
return;
|
||||
} else if (args.length !== 1) {
|
||||
cb(new Error('invalid args: ' + args));
|
||||
return;
|
||||
return cb(new errors.UsageError(format(
|
||||
'incorrect number of args (%d): %s', args.length, args.join(' '))));
|
||||
}
|
||||
|
||||
var id = args[0];
|
||||
|
||||
if (common.isUUID(id)) {
|
||||
this.triton.cloudapi.getNetwork(id, done);
|
||||
} else {
|
||||
// we have to list all networks and find the one pertaining
|
||||
// to the alias given
|
||||
this.triton.cloudapi.listNetworks(function (err, networks) {
|
||||
this.triton.getNetwork(args[0], function (err, net) {
|
||||
if (err) {
|
||||
done(err);
|
||||
return;
|
||||
}
|
||||
|
||||
var net;
|
||||
// try to find the network
|
||||
networks.forEach(function (network) {
|
||||
if (network.name === id)
|
||||
net = network;
|
||||
});
|
||||
|
||||
if (net) {
|
||||
// found!
|
||||
done(null, net);
|
||||
} else {
|
||||
// not found
|
||||
done(new Error('network ' + id + ' not found'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function done(err, network) {
|
||||
if (err) {
|
||||
cb(err);
|
||||
return;
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
if (opts.json) {
|
||||
console.log(JSON.stringify(network));
|
||||
console.log(JSON.stringify(net));
|
||||
} else {
|
||||
console.log(JSON.stringify(network, null, 4));
|
||||
console.log(JSON.stringify(net, null, 4));
|
||||
}
|
||||
cb();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
do_network.options = [
|
||||
|
@ -16,21 +16,6 @@ var validFilters = [
|
||||
'description'
|
||||
];
|
||||
|
||||
// valid output fields to be printed
|
||||
var validFields = [
|
||||
'id',
|
||||
'name',
|
||||
'public',
|
||||
'fabric',
|
||||
'gateway',
|
||||
'internet_nat',
|
||||
'provision_end_ip',
|
||||
'provision_start_ip',
|
||||
'resolvers',
|
||||
'subnet',
|
||||
'vlan_id'
|
||||
];
|
||||
|
||||
function do_networks(subcmd, opts, args, callback) {
|
||||
if (opts.help) {
|
||||
this.do_help('help', {}, [subcmd], callback);
|
||||
@ -40,18 +25,14 @@ function do_networks(subcmd, opts, args, callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
var columns = opts.o.trim().split(',');
|
||||
var sort = opts.s.trim().split(',');
|
||||
|
||||
/* not supported
|
||||
var listOpts;
|
||||
try {
|
||||
listOpts = common.kvToObj(args, validFilters);
|
||||
} catch (e) {
|
||||
callback(e);
|
||||
return;
|
||||
var columns = 'shortid,name,subnet,gateway,fabric,vlan,public'.split(',');
|
||||
if (opts.o) {
|
||||
/* JSSTYLED */
|
||||
columns = opts.o.trim().split(/\s*,\s*/g);
|
||||
} else if (opts.long) {
|
||||
columns[0] = 'id';
|
||||
}
|
||||
*/
|
||||
var sort = opts.s.trim().split(',');
|
||||
|
||||
this.triton.cloudapi.listNetworks(function (err, networks) {
|
||||
if (err) {
|
||||
@ -62,12 +43,15 @@ function do_networks(subcmd, opts, args, callback) {
|
||||
if (opts.json) {
|
||||
common.jsonStream(networks);
|
||||
} else {
|
||||
// pretty print
|
||||
for (var i = 0; i < networks.length; i++) {
|
||||
var net = networks[i];
|
||||
net.shortid = net.id.split('-', 1)[0];
|
||||
net.vlan = net.vlan_id;
|
||||
}
|
||||
tabula(networks, {
|
||||
skipHeader: opts.H,
|
||||
columns: columns,
|
||||
sort: sort,
|
||||
validFields: validFields
|
||||
sort: sort
|
||||
});
|
||||
}
|
||||
callback();
|
||||
@ -88,10 +72,14 @@ do_networks.options = [
|
||||
{
|
||||
names: ['o'],
|
||||
type: 'string',
|
||||
default: 'id,name,subnet,public,vlan_id,gateway',
|
||||
help: 'Specify fields (columns) to output.',
|
||||
helpArg: 'field1,...'
|
||||
},
|
||||
{
|
||||
names: ['long', 'l'],
|
||||
type: 'bool',
|
||||
help: 'Long/wider output. Ignored if "-o ..." is used.'
|
||||
},
|
||||
{
|
||||
names: ['s'],
|
||||
type: 'string',
|
||||
@ -105,13 +93,17 @@ do_networks.options = [
|
||||
help: 'JSON output.'
|
||||
}
|
||||
];
|
||||
do_networks.help = (
|
||||
'List available networks.\n'
|
||||
+ '\n'
|
||||
+ 'Usage:\n'
|
||||
+ ' {{name}} networks\n'
|
||||
+ '\n'
|
||||
+ '{{options}}'
|
||||
);
|
||||
do_networks.help = [
|
||||
'List available networks.',
|
||||
'',
|
||||
'Usage:',
|
||||
' {{name}} networks',
|
||||
'',
|
||||
'Fields (most are self explanatory, the client adds some for convenience):',
|
||||
' vlan A shorter alias for "vlan_id".',
|
||||
' shortid A short ID prefix.',
|
||||
'',
|
||||
'{{options}}'
|
||||
].join('\n');
|
||||
|
||||
module.exports = do_networks;
|
||||
|
@ -231,10 +231,10 @@ Triton.prototype.getImage = function getImage(name, cb) {
|
||||
cb(null, shortIdMatches[0]);
|
||||
} else if (shortIdMatches.length === 0) {
|
||||
cb(new Error(format(
|
||||
'no image with name or shortId "%s" was found', name)));
|
||||
'no image with name or short id "%s" was found', name)));
|
||||
} else {
|
||||
cb(new Error(format('no image with name "%s" was found '
|
||||
+ 'and "%s" is an ambiguous shortId', name)));
|
||||
+ 'and "%s" is an ambiguous short id', name)));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -255,7 +255,7 @@ Triton.prototype.getPackage = function getPackage(name, cb) {
|
||||
if (err) {
|
||||
cb(err);
|
||||
} else if (!pkg.active) {
|
||||
cb(new Error(format('image %s is not active', name)));
|
||||
cb(new Error(format('package %s is not active', name)));
|
||||
} else {
|
||||
cb(null, pkg);
|
||||
}
|
||||
@ -288,10 +288,65 @@ Triton.prototype.getPackage = function getPackage(name, cb) {
|
||||
cb(null, shortIdMatches[0]);
|
||||
} else if (shortIdMatches.length === 0) {
|
||||
cb(new Error(format(
|
||||
'no package with name or shortId "%s" was found', name)));
|
||||
'no package with name or short id "%s" was found', name)));
|
||||
} else {
|
||||
cb(new Error(format('no package with name "%s" was found '
|
||||
+ 'and "%s" is an ambiguous shortId', name)));
|
||||
+ 'and "%s" is an ambiguous short id', name)));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get an network by ID, exact name, or short ID, in that order.
|
||||
*
|
||||
* If the name is ambiguous, then this errors out.
|
||||
*/
|
||||
Triton.prototype.getNetwork = function getNetwork(name, cb) {
|
||||
assert.string(name, 'name');
|
||||
assert.func(cb, 'cb');
|
||||
|
||||
if (common.isUUID(name)) {
|
||||
this.cloudapi.getNetwork(name, function (err, net) {
|
||||
if (err) {
|
||||
cb(err);
|
||||
} else {
|
||||
cb(null, net);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.cloudapi.listNetworks(function (err, nets) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
var nameMatches = [];
|
||||
var shortIdMatches = [];
|
||||
for (var i = 0; i < nets.length; i++) {
|
||||
var net = nets[i];
|
||||
if (net.name === name) {
|
||||
nameMatches.push(net);
|
||||
}
|
||||
if (net.id.slice(0, 8) === name) {
|
||||
shortIdMatches.push(net);
|
||||
}
|
||||
}
|
||||
|
||||
if (nameMatches.length === 1) {
|
||||
cb(null, nameMatches[0]);
|
||||
} else if (nameMatches.length > 1) {
|
||||
cb(new Error(format(
|
||||
'network name "%s" is ambiguous: matches %d networks',
|
||||
name, nameMatches.length)));
|
||||
} else if (shortIdMatches.length === 1) {
|
||||
cb(null, shortIdMatches[0]);
|
||||
} else if (shortIdMatches.length === 0) {
|
||||
cb(new Error(format(
|
||||
'no network with name or short id "%s" was found', name)));
|
||||
} else {
|
||||
cb(new Error(format('no network with name "%s" was found '
|
||||
+ 'and "%s" is an ambiguous short id', name)));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -392,7 +447,7 @@ Triton.prototype.getInstance = function getInstance(name, cb) {
|
||||
cb(null, inst);
|
||||
} else {
|
||||
cb(new Error(format(
|
||||
'no instance with name or shortId "%s" was found', name)));
|
||||
'no instance with name or short id "%s" was found', name)));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
146
test/integration/cli-networks.test.js
Normal file
146
test/integration/cli-networks.test.js
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015, Joyent, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Integration tests for `triton network(s)`
|
||||
*/
|
||||
|
||||
var h = require('./helpers');
|
||||
var test = require('tape');
|
||||
|
||||
var common = require('../../lib/common');
|
||||
|
||||
|
||||
// --- Globals
|
||||
|
||||
var networks;
|
||||
|
||||
|
||||
// --- Tests
|
||||
|
||||
test('triton networks', function (tt) {
|
||||
|
||||
tt.test(' triton networks -h', function (t) {
|
||||
h.triton('networks -h', function (err, stdout, stderr) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
t.ok(/Usage:\s+triton networks/.test(stdout));
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' triton help networks', function (t) {
|
||||
h.triton('help networks', function (err, stdout, stderr) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
t.ok(/Usage:\s+triton networks/.test(stdout));
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' triton networks', function (t) {
|
||||
h.triton('networks', function (err, stdout, stderr) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
t.ok(/^SHORTID\b/.test(stdout));
|
||||
t.ok(/\bFABRIC\b/.test(stdout));
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' triton networks -l', function (t) {
|
||||
h.triton('networks -l', function (err, stdout, stderr) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
t.ok(/^ID\b/.test(stdout));
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' triton networks -j', function (t) {
|
||||
h.triton('networks -j', function (err, stdout, stderr) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
networks = [];
|
||||
stdout.split('\n').forEach(function (line) {
|
||||
if (!line.trim()) {
|
||||
return;
|
||||
}
|
||||
networks.push(JSON.parse(line));
|
||||
});
|
||||
t.ok(networks.length > 0, 'have at least one network');
|
||||
t.ok(common.isUUID(networks[0].id));
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
test('triton network', function (tt) {
|
||||
|
||||
tt.test(' triton network -h', function (t) {
|
||||
h.triton('network -h', function (err, stdout, stderr) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
t.ok(/Usage:\s+triton network\b/.test(stdout));
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' triton help network', function (t) {
|
||||
h.triton('help network', function (err, stdout, stderr) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
t.ok(/Usage:\s+triton network\b/.test(stdout));
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' triton network', function (t) {
|
||||
h.triton('network', function (err, stdout, stderr) {
|
||||
t.ok(err);
|
||||
t.ok(/error \(Usage\)/.test(stderr));
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' triton network ID', function (t) {
|
||||
h.triton('network ' + networks[0].id, function (err, stdout, stderr) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
var network = JSON.parse(stdout);
|
||||
t.equal(network.id, networks[0].id);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' triton network SHORTID', function (t) {
|
||||
var shortid = networks[0].id.split('-')[0];
|
||||
h.triton('network ' + shortid, function (err, stdout, stderr) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
var network = JSON.parse(stdout);
|
||||
t.equal(network.id, networks[0].id);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tt.test(' triton network NAME', function (t) {
|
||||
h.triton('network ' + networks[0].name, function (err, stdout, stderr) {
|
||||
if (h.ifErr(t, err))
|
||||
return t.end();
|
||||
var network = JSON.parse(stdout);
|
||||
t.equal(network.id, networks[0].id);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
Reference in New Issue
Block a user