wire up Triton class and cloudapi client
This commit is contained in:
parent
1f123975ae
commit
d694f0ba19
27
lib/cli.js
27
lib/cli.js
@ -18,8 +18,7 @@ var vasync = require('vasync');
|
|||||||
|
|
||||||
var common = require('./common');
|
var common = require('./common');
|
||||||
var errors = require('./errors');
|
var errors = require('./errors');
|
||||||
//XXX
|
var Triton = require('./triton');
|
||||||
//var SDC = require('./sdc');
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -74,18 +73,28 @@ CLI.prototype.init = function (opts, args, callback) {
|
|||||||
log.src = true;
|
log.src = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//XXX
|
this.__defineGetter__('triton', function () {
|
||||||
//this.__defineGetter__('sdc', function () {
|
if (self._triton === undefined) {
|
||||||
// if (self._sdc === undefined) {
|
self._triton = new Triton({log: log, profile: opts.profile});
|
||||||
// self._sdc = new SDC({log: log, profile: opts.profile});
|
}
|
||||||
// }
|
return self._triton;
|
||||||
// return self._sdc;
|
});
|
||||||
//});
|
|
||||||
|
|
||||||
// Cmdln class handles `opts.help`.
|
// Cmdln class handles `opts.help`.
|
||||||
Cmdln.prototype.init.apply(this, arguments);
|
Cmdln.prototype.init.apply(this, arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CLI.prototype.do_foo = function do_foo(subcmd, opts, args, callback) {
|
||||||
|
console.log('XXX', subcmd, opts, args);
|
||||||
|
|
||||||
|
this.triton.cloudapi.getAccount(function (err, body, res) {
|
||||||
|
console.log('XXX getAccount', err);
|
||||||
|
console.log('XXX getAccount', body);
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CLI.prototype.do_profile = require('./do_profile');
|
CLI.prototype.do_profile = require('./do_profile');
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2015, Joyent, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Client library for the SmartDataCenter Cloud API (cloudapi).
|
* Client library for the SmartDataCenter Cloud API (cloudapi).
|
||||||
* http://apidocs.joyent.com/cloudapi/
|
* http://apidocs.joyent.com/cloudapi/
|
||||||
@ -27,12 +27,12 @@
|
|||||||
var p = console.log;
|
var p = console.log;
|
||||||
|
|
||||||
var assert = require('assert-plus');
|
var assert = require('assert-plus');
|
||||||
var async = require('async');
|
|
||||||
var auth = require('smartdc-auth');
|
var auth = require('smartdc-auth');
|
||||||
var os = require('os');
|
var os = require('os');
|
||||||
var querystring = require('querystring');
|
var querystring = require('querystring');
|
||||||
var restify = require('restify');
|
var restifyClients = require('restify-clients');
|
||||||
var sprintf = require('util').format;
|
var sprintf = require('util').format;
|
||||||
|
var vasync = require('vasync');
|
||||||
|
|
||||||
var errors = require('./errors');
|
var errors = require('./errors');
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ var errors = require('./errors');
|
|||||||
|
|
||||||
// ---- globals
|
// ---- globals
|
||||||
|
|
||||||
var SDC_VERSION = require('../package.json').version;
|
var VERSION = require('../package.json').version;
|
||||||
var OS_ARCH = os.arch();
|
var OS_ARCH = os.arch();
|
||||||
var OS_PLATFORM = os.platform();
|
var OS_PLATFORM = os.platform();
|
||||||
|
|
||||||
@ -105,8 +105,8 @@ function CloudAPI(options) {
|
|||||||
options.version = '*';
|
options.version = '*';
|
||||||
}
|
}
|
||||||
if (!options.userAgent) {
|
if (!options.userAgent) {
|
||||||
options.userAgent = sprintf('sdc/%s (%s-%s; node/%s)',
|
options.userAgent = sprintf('triton/%s (%s-%s; node/%s)',
|
||||||
SDC_VERSION, OS_ARCH, OS_PLATFORM, process.versions.node);
|
VERSION, OS_ARCH, OS_PLATFORM, process.versions.node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX relevant?
|
// XXX relevant?
|
||||||
@ -117,7 +117,7 @@ function CloudAPI(options) {
|
|||||||
// XXX relevant?
|
// XXX relevant?
|
||||||
//this.token = options.token;
|
//this.token = options.token;
|
||||||
|
|
||||||
this.client = restify.createJsonClient(options);
|
this.client = restifyClients.createJsonClient(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,14 +13,13 @@ var common = require('./common');
|
|||||||
var errors = require('./errors');
|
var errors = require('./errors');
|
||||||
|
|
||||||
|
|
||||||
var CONFIG_PATH = path.resolve(process.env.HOME, '.sdcconfig.json');
|
var CONFIG_PATH = path.resolve(process.env.HOME, '.triton', 'config.json');
|
||||||
var DEFAULTS_PATH = path.resolve(__dirname, '..', 'etc', 'defaults.json');
|
var DEFAULTS_PATH = path.resolve(__dirname, '..', 'etc', 'defaults.json');
|
||||||
var OVERRIDE_KEYS = ['dc', 'dcAlias'];
|
var OVERRIDE_KEYS = []; // config object keys to do a one-level deep override
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the 'sdc' config. This is a merge of the built-in "defaults" (at
|
* Load the Triton client config. This is a merge of the built-in "defaults" (at
|
||||||
* etc/defaults.json) and the "user" config (at ~/.sdcconfig.json if it
|
* etc/defaults.json) and the "user" config (at ~/.triton/config.json if it
|
||||||
* exists).
|
* exists).
|
||||||
*
|
*
|
||||||
* This includes some internal data on keys with a leading underscore.
|
* This includes some internal data on keys with a leading underscore.
|
||||||
@ -61,13 +60,13 @@ function loadConfigSync() {
|
|||||||
if (!config.profiles) {
|
if (!config.profiles) {
|
||||||
config.profiles = [];
|
config.profiles = [];
|
||||||
}
|
}
|
||||||
|
//XXX Add TRITON_* envvars.
|
||||||
config.profiles.push({
|
config.profiles.push({
|
||||||
name: 'env',
|
name: 'env',
|
||||||
dcs: ['joyent'],
|
account: process.env.SDC_USER || process.env.SDC_ACCOUNT,
|
||||||
user: process.env.SDC_USER || process.env.SDC_ACCOUNT,
|
url: process.env.SDC_URL,
|
||||||
keyId: process.env.SDC_KEY_ID,
|
keyId: process.env.SDC_KEY_ID,
|
||||||
rejectUnauthorized: common.boolFromString(
|
insecure: common.boolFromString(process.env.SDC_TESTING)
|
||||||
process.env.SDC_TESTING || process.env.SDC_TLS_INSECURE)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
@ -90,8 +89,6 @@ function updateUserConfigSync(config, updates) {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
CONFIG_PATH: CONFIG_PATH,
|
CONFIG_PATH: CONFIG_PATH,
|
||||||
loadConfigSync: loadConfigSync,
|
loadConfigSync: loadConfigSync
|
||||||
//XXX
|
|
||||||
//updateConfigSync: updateConfigSync
|
|
||||||
};
|
};
|
||||||
// vim: set softtabstop=4 shiftwidth=4:
|
// vim: set softtabstop=4 shiftwidth=4:
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2015, Joyent, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Core SDC driver class.
|
* Core Triton client driver class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var p = console.log;
|
var p = console.log;
|
||||||
var assert = require('assert-plus');
|
var assert = require('assert-plus');
|
||||||
var async = require('async');
|
|
||||||
var auth = require('smartdc-auth');
|
var auth = require('smartdc-auth');
|
||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var once = require('once');
|
var once = require('once');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var restify = require('restify');
|
var restifyClients = require('restify-clients');
|
||||||
var sprintf = require('util').format;
|
var sprintf = require('util').format;
|
||||||
|
|
||||||
var cloudapi = require('./cloudapi2');
|
var cloudapi = require('./cloudapi2');
|
||||||
@ -22,17 +21,17 @@ var loadConfigSync = require('./config').loadConfigSync;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---- SDC class
|
//---- Triton class
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a SDC client.
|
* Create a Triton client.
|
||||||
*
|
*
|
||||||
* @param options {Object}
|
* @param options {Object}
|
||||||
* - log {Bunyan Logger}
|
* - log {Bunyan Logger}
|
||||||
* - profile {String} Optional. Name of profile to use. Defaults to
|
* - profile {String} Optional. Name of profile to use. Defaults to
|
||||||
* 'defaultProfile' in the config.
|
* 'defaultProfile' in the config.
|
||||||
*/
|
*/
|
||||||
function SDC(options) {
|
function Triton(options) {
|
||||||
assert.object(options, 'options');
|
assert.object(options, 'options');
|
||||||
assert.object(options.log, 'options.log');
|
assert.object(options.log, 'options.log');
|
||||||
assert.optionalString(options.profile, 'options.profile');
|
assert.optionalString(options.profile, 'options.profile');
|
||||||
@ -43,8 +42,10 @@ function SDC(options) {
|
|||||||
if (options.log.serializers &&
|
if (options.log.serializers &&
|
||||||
(!options.log.serializers.client_req ||
|
(!options.log.serializers.client_req ||
|
||||||
!options.log.serializers.client_req)) {
|
!options.log.serializers.client_req)) {
|
||||||
|
console.log('XXX here');
|
||||||
this.log = options.log.child({
|
this.log = options.log.child({
|
||||||
serializers: restify.bunyan.serializers
|
// XXX cheating. restify-clients should export its 'bunyan'.
|
||||||
|
serializers: require('restify-clients/lib/helpers/bunyan').serializers
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.log = options.log;
|
this.log = options.log;
|
||||||
@ -54,20 +55,13 @@ function SDC(options) {
|
|||||||
this.profile = this.getProfile(
|
this.profile = this.getProfile(
|
||||||
options.profile || this.config.defaultProfile);
|
options.profile || this.config.defaultProfile);
|
||||||
this.log.trace({profile: this.profile}, 'profile data');
|
this.log.trace({profile: this.profile}, 'profile data');
|
||||||
|
|
||||||
|
this.cloudapi = this._cloudapiFromProfile(this.profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SDC.prototype.setDefaultProfile =
|
|
||||||
function setDefaultProfile(name, callback) {
|
|
||||||
if (!this.getProfile(name)) {
|
|
||||||
return callback(new Error('no such profile: ' + name));
|
|
||||||
}
|
|
||||||
this.defaultProfileName = this.config.defaultProfile = name;
|
|
||||||
common.saveConfigSync(this.config);
|
|
||||||
callback();
|
|
||||||
};
|
|
||||||
|
|
||||||
SDC.prototype.getProfile = function getProfile(name) {
|
Triton.prototype.getProfile = function getProfile(name) {
|
||||||
for (var i = 0; i < this.profiles.length; i++) {
|
for (var i = 0; i < this.profiles.length; i++) {
|
||||||
if (this.profiles[i].name === name) {
|
if (this.profiles[i].name === name) {
|
||||||
return this.profiles[i];
|
return this.profiles[i];
|
||||||
@ -75,121 +69,39 @@ SDC.prototype.getProfile = function getProfile(name) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Create or update a profile.
|
Triton.prototype._cloudapiFromProfile = function _cloudapiFromProfile(profile) {
|
||||||
*
|
|
||||||
* @param profile {Object}
|
|
||||||
* @param options {Object}
|
|
||||||
* - setDefault {Boolean}
|
|
||||||
* @param callback {Function} `function (err)`
|
|
||||||
*/
|
|
||||||
SDC.prototype.createOrUpdateProfile = function createOrUpdateProfile(
|
|
||||||
profile, options, callback) {
|
|
||||||
assert.object(profile, 'profile');
|
assert.object(profile, 'profile');
|
||||||
if (typeof (options) === 'function') {
|
assert.string(profile.account, 'profile.account');
|
||||||
callback = options;
|
assert.string(profile.keyId, 'profile.keyId');
|
||||||
options = {};
|
assert.string(profile.url, 'profile.url');
|
||||||
}
|
assert.optionalString(profile.privKey, 'profile.privKey');
|
||||||
assert.object(options, 'options');
|
assert.optionalBool(profile.insecure, 'profile.insecure');
|
||||||
assert.optionalBool(options.setDefault, 'options.setDefault');
|
var rejectUnauthorized = (profile.insecure === undefined
|
||||||
assert.func(callback, 'callback');
|
? true : !profile.insecure);
|
||||||
|
|
||||||
var found = false;
|
|
||||||
for (var i = 0; i < this.profiles.length; i++) {
|
|
||||||
if (this.profiles[i].name === profile.name) {
|
|
||||||
this.profiles[i] = profile;
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
this.profiles.push(profile);
|
|
||||||
}
|
|
||||||
if (options.setDefault) {
|
|
||||||
this.defaultProfileName = this.config.defaultProfile = profile.name;
|
|
||||||
}
|
|
||||||
common.saveConfigSync(this.config);
|
|
||||||
callback();
|
|
||||||
};
|
|
||||||
|
|
||||||
SDC.prototype.deleteProfile = function deleteProfile(name, callback) {
|
|
||||||
var found = false;
|
|
||||||
for (var i = 0; i < this.profiles.length; i++) {
|
|
||||||
if (this.profiles[i].name === name) {
|
|
||||||
found = true;
|
|
||||||
this.profiles.splice(i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
return callback(new Error('no such profile: ' + name));
|
|
||||||
}
|
|
||||||
if (this.defaultProfileName === name) {
|
|
||||||
this.defaultProfileName = this.config.defaultProfile = null;
|
|
||||||
}
|
|
||||||
common.saveConfigSync(this.config);
|
|
||||||
callback();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
SDC.prototype._clientFromDc = function _clientFromDc(dc) {
|
|
||||||
assert.string(dc, 'dc');
|
|
||||||
|
|
||||||
if (!this._clientFromDcCache) {
|
|
||||||
this._clientFromDcCache = {};
|
|
||||||
}
|
|
||||||
if (!this._clientFromDcCache[dc]) {
|
|
||||||
var prof = this.profile;
|
|
||||||
var sign;
|
var sign;
|
||||||
if (prof.privKey) {
|
if (profile.privKey) {
|
||||||
sign = auth.privateKeySigner({
|
sign = auth.privateKeySigner({
|
||||||
user: prof.user,
|
user: profile.account,
|
||||||
keyId: prof.keyId,
|
keyId: profile.keyId,
|
||||||
key: prof.privKey
|
key: profile.privKey
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
sign = auth.cliSigner({
|
sign = auth.cliSigner({
|
||||||
keyId: prof.keyId,
|
keyId: profile.keyId,
|
||||||
user: prof.user
|
user: profile.account
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var client = cloudapi.createClient({
|
var client = cloudapi.createClient({
|
||||||
url: this.config.dcs[dc],
|
url: profile.url,
|
||||||
user: prof.user,
|
user: profile.account,
|
||||||
version: '*',
|
version: '*',
|
||||||
rejectUnauthorized: Boolean(prof.rejectUnauthorized),
|
rejectUnauthorized: rejectUnauthorized,
|
||||||
sign: sign,
|
sign: sign,
|
||||||
log: this.log
|
log: this.log
|
||||||
});
|
});
|
||||||
this._clientFromDcCache[dc] = client;
|
return client;
|
||||||
}
|
|
||||||
return this._clientFromDcCache[dc];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the resolved array of `{name: <dc-name>, url: <dc-url>}` for all
|
|
||||||
* DCs for the current profile.
|
|
||||||
*
|
|
||||||
* @throws {Error} If an unknown DC name is encountered.
|
|
||||||
* XXX make that UnknownDcError.
|
|
||||||
*/
|
|
||||||
SDC.prototype.dcs = function dcs() {
|
|
||||||
var self = this;
|
|
||||||
var aliases = self.config.dcAlias || {};
|
|
||||||
var resolved = [];
|
|
||||||
(self.profile.dcs || Object.keys(self.config.dcs)).forEach(function (n) {
|
|
||||||
var names = aliases[n] || [n];
|
|
||||||
names.forEach(function (name) {
|
|
||||||
if (!self.config.dcs[name]) {
|
|
||||||
throw new Error(sprintf('unknown dc "%s" for "%s" profile',
|
|
||||||
name, self.profile.name));
|
|
||||||
}
|
|
||||||
resolved.push({
|
|
||||||
name: name,
|
|
||||||
url: self.config.dcs[name]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return resolved;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -204,7 +116,7 @@ SDC.prototype.dcs = function dcs() {
|
|||||||
* Returns the machine object (as from cloudapi GetMachine) and the `dc`,
|
* Returns the machine object (as from cloudapi GetMachine) and the `dc`,
|
||||||
* e.g. "us-west-1".
|
* e.g. "us-west-1".
|
||||||
*/
|
*/
|
||||||
SDC.prototype.findMachine = function findMachine(options, callback) {
|
Triton.prototype.findMachine = function findMachine(options, callback) {
|
||||||
//XXX Eventually this can be cached for a *full* uuid. Arguably for a
|
//XXX Eventually this can be cached for a *full* uuid. Arguably for a
|
||||||
// uuid prefix or machine alias match, it cannot be cached, because an
|
// uuid prefix or machine alias match, it cannot be cached, because an
|
||||||
// ambiguous machine could have been added.
|
// ambiguous machine could have been added.
|
||||||
@ -267,7 +179,7 @@ SDC.prototype.findMachine = function findMachine(options, callback) {
|
|||||||
*
|
*
|
||||||
* @param {Object} options Optional
|
* @param {Object} options Optional
|
||||||
*/
|
*/
|
||||||
SDC.prototype.listMachines = function listMachines(options) {
|
Triton.prototype.listMachines = function listMachines(options) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (options === undefined) {
|
if (options === undefined) {
|
||||||
options = {};
|
options = {};
|
||||||
@ -304,7 +216,7 @@ SDC.prototype.listMachines = function listMachines(options) {
|
|||||||
* XXX support `machine` being more than just the UUID.
|
* XXX support `machine` being more than just the UUID.
|
||||||
* @param {Function} callback of the form `function (err, audit, dc)`
|
* @param {Function} callback of the form `function (err, audit, dc)`
|
||||||
*/
|
*/
|
||||||
SDC.prototype.machineAudit = function machineAudit(options, callback) {
|
Triton.prototype.machineAudit = function machineAudit(options, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
assert.object(options, 'options');
|
assert.object(options, 'options');
|
||||||
assert.string(options.machine, 'options.machine');
|
assert.string(options.machine, 'options.machine');
|
||||||
@ -324,4 +236,4 @@ SDC.prototype.machineAudit = function machineAudit(options, callback) {
|
|||||||
|
|
||||||
//---- exports
|
//---- exports
|
||||||
|
|
||||||
module.exports = SDC;
|
module.exports = Triton;
|
Reference in New Issue
Block a user