This repository has been archived on 2020-01-20. You can view files and clone it, but cannot push or open issues or pull requests.
node-spearhead/lib/joyent.js

202 lines
5.5 KiB
JavaScript

/*
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
*
* Core Joyent driver class.
*/
var p = console.log;
var assert = require('assert-plus');
var async = require('async');
var format = require('util').format;
var fs = require('fs');
var path = require('path');
var smartdc = require('smartdc');
var common = require('./common');
var loadConfigSync = require('./config').loadConfigSync;
//---- Joyent class
/**
* Create a Joyent.
*
* @param options {Object}
* - log {Bunyan Logger}
* - profile {String} Optional. Name of profile to use. Defaults to
* 'defaultProfile' in the config.
*/
function Joyent(options) {
assert.object(options, 'options');
assert.object(options.log, 'options.log');
assert.optionalString(options.profile, 'options.profile');
var self = this;
this.config = loadConfigSync();
this.profiles = this.config.profiles;
this.profile = this.getProfile(
options.profile || this.config.defaultProfile);
this.log = options.log;
this.log.trace({profile: this.profile}, 'profile data');
}
Joyent.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();
};
Joyent.prototype.getProfile = function getProfile(name) {
for (var i = 0; i < this.profiles.length; i++) {
if (this.profiles[i].name === name) {
return this.profiles[i];
}
}
};
/**
* Create or update a profile.
*
* @param profile {Object}
* @param options {Object}
* - setDefault {Boolean}
* @param callback {Function} `function (err)`
*/
Joyent.prototype.createOrUpdateProfile = function createOrUpdateProfile(
profile, options, callback) {
assert.object(profile, 'profile');
if (typeof(options) === 'function') {
callback = options;
options = {};
}
assert.object(options, 'options')
assert.optionalBool(options.setDefault, 'options.setDefault')
assert.func(callback, 'callback')
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();
};
Joyent.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();
};
Joyent.prototype._clientFromDc = function _clientFromDc(dc) {
assert.string(dc, 'dc');
if (!this._clientFromDcCache) {
this._clientFromDcCache = {};
}
if (!this._clientFromDcCache[dc]) {
var prof = this.profile;
var sign;
if (prof.privKey) {
sign = smartdc.privateKeySigner({
user: prof.account,
keyId: prof.keyId,
key: prof.privKey
});
} else {
sign = smartdc.cliSigner({keyId: prof.keyId, user: prof.account});
}
var client = smartdc.createClient({
url: this.config.dcs[dc],
account: prof.account,
version: '*',
noCache: true, //XXX
rejectUnauthorized: Boolean(prof.rejectUnauthorized),
sign: sign,
// XXX cloudapi.js stupidly uses its own logger, but takes logLevel
logLevel: this.log && this.log.level(),
// Pass our logger to underlying restify client.
log: this.log
});
this._clientFromDcCache[dc] = client;
}
return this._clientFromDcCache[dc];
};
/**
* List machines for the current profile.
*
* @param {Object} options Optional
* - {Function} onDcError `function (dc, err)` called for each DC client
* error.
*/
Joyent.prototype.listMachines = function listMachines(options, callback) {
var self = this;
if (callback === undefined) {
callback = options;
options = {}
}
assert.object(options, 'options');
assert.optionalFunc(options.onDcError, 'options.onDcError');
assert.func(callback, 'callback');
var allMachines = [];
async.each(
self.profile.dcs || Object.keys(self.config.dcs),
function oneDc(dc, next) {
var client = self._clientFromDc(dc);
client.listMachines(function (err, machines) {
if (err) {
if (options.onDcError) {
options.onDcError(dc, err);
}
} else {
for (var i = 0; i < machines.length; i++) {
machines[i].dc = dc;
allMachines.push(machines[i]);
}
}
next();
});
},
function done(err) {
callback(err, allMachines);
}
);
};
//---- exports
module.exports = Joyent;