Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[api] Continued to stub out core jitsu functionality. Now storing and…

… prompting for username / password pair on initial start
  • Loading branch information...
commit de3182f87c9a1db37937823ae0a380bad5f29179 1 parent 641b226
@indexzero indexzero authored
View
19 bin/jitsu
@@ -0,0 +1,19 @@
+#!/usr/bin/env node
+
+require.paths.unshift(require('path').join(__dirname, '..', 'lib'));
+
+var eyes = require('eyes'),
+ argv = require('optimist').argv,
+ jitsu = require('jitsu');
+
+var resources = [
+ 'apps',
+ 'snapshots'
+];
+
+var operations = [
+ 'password',
+
+];
+
+jitsu.start(argv._.join(''));
View
60 lib/jitsu.js
@@ -7,11 +7,15 @@
require.paths.unshift(__dirname);
+var eyes = require('eyes'),
+ winston = require('winston'),
+ colors = require('colors');
+
var jitsu = exports;
// Failure HTTP Response codes based
// off of `/lib/broodmother/slave/service.js`
-var failCodes jitsu.failCodes = {
+var failCodes = jitsu.failCodes = {
400: "Bad Request",
404: "Item not found",
500: "Internal Server Error"
@@ -24,5 +28,55 @@ var successCodes = jitsu.successCodes = {
201: "Created"
};
-jitsu.client = require('jitsu/client');
-jitsu.apps = require('jitsu/apps');
+
+jitsu.Client = require('jitsu/client').Client;
+jitsu.Apps = require('jitsu/apps').Apps;
+jitsu.Prompt = require('jitsu/prompt').Prompt;
+jitsu.config = require('jitsu/config');
+
+jitsu.start = function (command) {
+ // Setup the initial prompt but don't leave it open
+ jitsu.prompt = new jitsu.Prompt().start().pause();
+
+ winston.info('Welcome to ' + 'Nodejitsu'.grey);
+ jitsu.config.load(function (err) {
+ if (err) {
+ eyes.inspect(err);
+ }
+
+ if (!jitsu.config.settings.auth) {
+ return jitsu.setupUser(function () {
+ jitsu.exec(command)
+ });
+ }
+
+ jitsu.exec(command);
+ });
+};
+
+jitsu.exec = function (command) {
+ if (!command) {
+ return winston.error('No command supplied');
+ }
+
+ winston.info('Executing command ' + command.magenta);
+};
+
+jitsu.setupUser = function (callback) {
+ winston.info('No user has been setup on this machine')
+ jitsu.prompt.get(['username', 'password'], function (result) {
+ jitsu.prompt.pause();
+
+ //
+ // TODO (indexzero): Validate the username and password before saving
+ //
+ jitsu.config.settings.auth = result;
+ jitsu.config.save(function (err) {
+ if (err) {
+ eyes.inspect(err);
+ }
+
+ return err ? callback(err) : callback();
+ });
+ });
+};
View
47 lib/jitsu/apps.js
@@ -8,26 +8,63 @@
var util = require('util'),
jitsu = require('jitsu');
+//
+// ### function Apps (options)
+// #### @options {Object} Options for this instance
+// Constructor function for the Apps resource responsible
+// with Nodejitsu's Apps API
+//
var Apps = exports.Apps = function (options) {
jitsu.Client.call(this, options);
};
+// Inherit from Client base object
util.inherits(Apps, jitsu.Client);
+//
+// ### function list (callback)
+// #### @callback {function} Continuation to pass control to when complete
+// Lists all applications for the authenticated user
+//
Apps.prototype.list = function (callback) {
-
+ this._request('GET', ['apps'], callback, function (err, res, body) {
+
+ });
};
+//
+// ### function create (app, callback)
+// #### @app {Object} Package.json manifest for the application.
+// #### @callback {function} Continuation to pass control to when complete
+// Creates an application with the specified package.json manifest in `app`.
+//
Apps.prototype.create = function (app, callback) {
- this._request('POST', ['apps' app.name], app, callback, function (err, res, body) {
+ this._request('POST', ['apps', app.name], app, callback, function (err, res, body) {
});
};
-Apps.prototype.update = function (attrs, callback) {
-
+//
+// ### function update (name, attrs, callback)
+// #### @name {string} Name of the application to update
+// #### @attrs {Object} Attributes to update for this application.
+// #### @callback {function} Continuation to pass control to when complete
+// Updates the application with `name` with the specified attributes in `attrs`
+//
+Apps.prototype.update = function (name, attrs, callback) {
+ this._request('PUT', ['apps', name], attrs, callback, function (err, res, body) {
+
+ });
};
+//
+// ### function destroy (name, callback)
+// #### @name {string} Name of the application to destroy
+// #### @callback {function} Continuation to pass control to when complete
+// Destroys the application with `name` for the authenticated user.
+//
Apps.prototype.destory = function (name, callback) {
-
+ this._request('DELETE', ['apps', name], callback, function (err, res, body) {
+
+ });
};
View
19 lib/jitsu/client.js
@@ -8,10 +8,27 @@
var request = require('request'),
jitsu = require('jitsu');
+//
+// ### function Client (options)
+// #### @options {Object} Options for this instance
+// Constructor function for the Client base responsible
+// for communicating with Nodejitsu's API
+//
var Client = exports.Client = function (options) {
};
+//
+// ### @private function _request (method, uri, [body], success, callback)
+// #### @method {string} HTTP method to use
+// #### @uri {string} Locator for the Remote Resource
+// #### @body {Object} **optional** JSON Request Body
+// #### @success {function} Continuation to call upon successful transactions
+// #### @callback {function} Continuation to call if errors occur.
+// Makes a request to `this.remoteUri + uri` using `method` and any
+// `body` (JSON-only) if supplied. Short circuits to `callback` if the response
+// code from Nodejitsu matches `jitsu.failCodes`.
+//
Client.prototype._request = function (method, uri /* variable arguments */) {
var options, args = Array.prototype.slice.call(arguments),
success = args.pop(),
@@ -44,7 +61,7 @@ Client.prototype._request = function (method, uri /* variable arguments */) {
}
if (Object.keys(jitsu.failCodes).indexOf(statusCode) !== -1) {
- var error = new Error('Broodmother Error (' + statusCode + '): ' + jitsu.failCodes[statusCode]);
+ var error = new Error('Nodejitsu Error (' + statusCode + '): ' + jitsu.failCodes[statusCode]);
error.result = result;
return callback(error);
}
View
45 lib/jitsu/config.js
@@ -4,4 +4,47 @@
* (C) 2010, Nodejitsu Inc.
*
*/
-
+
+var path = require('path'),
+ log = require('jitsu/log');
+ fs = require('fs');
+
+var config = exports, settings = config.settings = {
+ root: process.env.HOME,
+ files: {
+ config: '.jitsuconf'
+ }
+};
+
+// Export the log configuration
+config.log = log.config;
+
+config.load = function (callback) {
+ fs.readFile(config.file('config'), function (err, data) {
+ if (err && /ENOENT, No such file/.test(err.message)) {
+ return config.save(function (err) {
+ return err ? callback(err) : callback();
+ });
+ }
+ else if (err) {
+ return callback(err);
+ }
+
+ data = JSON.parse(data.toString());
+ Object.keys(data).forEach(function (key) {
+ config.settings[key] = data[key];
+ });
+
+ callback();
+ });
+};
+
+config.save = function (callback) {
+ fs.writeFile(config.file('config'), JSON.stringify(config.settings), function (err) {
+ return err ? callback(err) : callback();
+ });
+};
+
+config.file = function (file) {
+ return path.join(settings.root, settings.files[file]);
+};
View
46 lib/jitsu/log.js
@@ -0,0 +1,46 @@
+/*
+ * log.js: Tools for configuring winston in jitsu.
+ *
+ * (C) 2010, Nodejitsu Inc.
+ *
+ */
+
+var winston = require('winston');
+
+var config = exports.config = {
+ levels: {
+ silly: 0,
+ input: 1,
+ verbose: 2,
+ prompt: 3,
+ info: 4,
+ warn: 5,
+ debug: 6,
+ error: 7
+ },
+ colors: {
+ silly: 'magenta',
+ input: 'grey',
+ verbose: 'cyan',
+ prompt: 'grey',
+ info: 'green',
+ warn: 'yellow',
+ debug: 'blue',
+ error: 'red'
+ }
+};
+
+//
+// Configure winston with the levels and colors that we've defined
+//
+winston.emitErrs = false;
+winston.defaultTransports().console.colorize = true;
+winston.defaultTransports().console.timestamp = false;
+winston.padLevels = true;
+winston.setLevels(config.levels);
+winston.addColors(config.colors);
+
+//
+// TODO (indexzero): Load this in config.js
+//
+winston.defaultTransports().console.level = 'silly';
View
101 lib/jitsu/prompt.js
@@ -0,0 +1,101 @@
+/*
+ * prompt.js: Tools for interacting with a prompt in the jitsu CLI.
+ *
+ * (C) 2010, Nodejitsu Inc.
+ *
+ */
+
+var async = require('async'),
+ colors = require('colors'),
+ winston = require('winston'),
+ readline = require('readline');
+
+function capitalize(str) {
+ return str.charAt(0).toUpperCase() + str.slice(1);
+}
+
+var Prompt = exports.Prompt = function (options) {
+ this.started = false;
+ this.paused = false;
+};
+
+Prompt.prototype.start = function () {
+ if (this.started) {
+ return;
+ }
+
+ process.openStdin();
+ this.readline = readline.createInterface(process.stdin, process.stdout);
+ this.started = true;
+
+ return this;
+};
+
+Prompt.prototype.pause = function () {
+ if (!this.started || this.paused) {
+ return;
+ }
+
+ process.stdin.pause();
+ this.paused = true;
+ return this;
+};
+
+Prompt.prototype.resume = function () {
+ if (!this.started || !this.paused) {
+ return;
+ }
+
+ process.stdin.resume();
+ this.paused = false;
+ return this;
+};
+
+Prompt.prototype.get = function (/* msg, [validator,] callback */) {
+ var self = this,
+ args = Array.prototype.slice.call(arguments),
+ msg = args.shift(),
+ callback = args.pop(),
+ validator = args.length > 0 && args[0],
+ vars = typeof msg === 'string' ? [msg] : msg,
+ result = {};
+
+ vars = vars.map(function (s) {
+ return s.toLowerCase();
+ });
+
+ function get(prompt, next) {
+ self.getInput(capitalize(prompt), validator, function (line) {
+ result[prompt] = line;
+ next();
+ });
+ }
+
+ async.forEachSeries(vars, get, function () {
+ callback(result);
+ });
+};
+
+Prompt.prototype.getInput = function (msg, validator, callback) {
+ var raw = ['prompt', ': ' + msg + ': '],
+ length = raw.join('').length,
+ prompt;
+
+ // Colorize the prompt now that we have the raw length
+ raw[0] = raw[0].magenta;
+ prompt = raw.join('');
+
+ this.readline.once('line', function (line) {
+ //
+ // TODO (indexzero): Validate this result
+ //
+
+ winston.input(line.yellow);
+ callback(line);
+ });
+
+ this.readline.setPrompt(prompt, length);
+ this.readline.prompt();
+ this.resume();
+ return this;
+};
View
23 package.json
@@ -0,0 +1,23 @@
+{
+ "name": "jitsu",
+ "description": "CLI tool for working with the Nodejitsu Cloud Platform-as-a-Service",
+ "version": "0.1.0",
+ "author": "Charlie Robbins <charlie.robbins@gmail.com>",
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/nodejitsu/jitsu.git"
+ },
+ "keywords": ["cli", "nodejitsu", "cloud hosting", "platform-as-a-service", "deployment"],
+ "dependencies": {
+ "async": ">= 0.1.8",
+ "colors": ">= 0.3.0",
+ "optimist": ">= 0.0.6",
+ "request": ">= 1.9.0",
+ "vows": ">= 0.5.2",
+ "winston": ">= 0.2.1"
+ },
+ "bin": { "jitsu": "./bin/jitsu" },
+ "main": "./lib/jitsu",
+ "scripts": { "test": "vows test/*-test.js --spec" },
+ "engines": { "node": ">= 0.4.0" }
+}

0 comments on commit de3182f

Please sign in to comment.
Something went wrong with that request. Please try again.