UNPKG

nodejs-wrapper-digitalocean-v2-api

Version:
374 lines (335 loc) 13.2 kB
// Require module dependencies var fs = require('fs'); path = require('path'); https = require('https'); extend = require('node.extend'); querystring = require('querystring'); // Provider config var API_URL = 'api.digitalocean.com'; API_PATH = '/v2'; // Request config var HTTP_GET = 'GET'; HTTP_POST = 'POST'; HTTP_PUT = 'PUT'; HTTP_DELETE = 'DELETE'; /** * Digitalocean api client * * @param {string} apiKey Required, OAuth token for authenticating requests * @constructor */ var Digitalocean = function(apiKey) { this.options = { hostname: API_URL, port: 443, path: API_PATH, headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer '+apiKey } }; }; /** * OAuth Request handler * * @param {string} endpoint Required, endpoint path * @param {string} method Required, request method (GET, POST, PUT, DELETE) * @param {Object} params Request parameters * @param {Function} callback Complete * @method _request * @memberOf Digitalocean */ Digitalocean.prototype._request = function(endpoint, method, params, callback) { // Modify default request path and method this.options.path = this.options.path+'/'+endpoint; this.options.method = method; // Handle parsing request params var postDataExists = false; if (Object.keys(params).length > 0) { params = querystring.stringify(params); // Modify headers and path as it applies to the request method switch (this.options.method) { case HTTP_GET: this.options.path = this.options.path+params; break; case HTTP_POST: var contentLength = {'Content-Length': parmas.length}; this.options.headers = extend(this.options.headers, contentLength); // We can tell whether or not to write to the request body by setting this to true postDataExists = true; break; } } // Main http request var req = https.request(this.options, function(res) { // Prep response body var resBody = ''; res.setEncoding('utf8'); res.on('data', function(chunk) { // Cache each chunk of data as it arrives resBody += chunk; }); res.on('end', function() { // Done streaming, safely parse the response body resBody = JSON.parse(resBody); err = (!resBody) ? {'message': 'Invalid JSON detected in response body'} : null; callback(err, resBody); }); }); // Write post params if applicable if (this.options.method == HTTP_POST && postDataExists) req.write(params); // Reset path variable as to avoid concatenation this.options.path = API_PATH; req.end(); req.on('error', function(err) { callback(err); }); }; /** * Helper method that gets basic user account information * * @param {Function} callback Complete * @method _getUserInfo * @memberOf Digitalocean */ Digitalocean.prototype._getUserInfo = function(callback) { this._request('account', HTTP_GET, {}, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Helper method that creates or updates a record for a domain * * @param {string} method Required, request method, varies depending on action (POST, PUT) * @param {string} domainName Required, name of an account registered domain * @param {integer} recordId Unique numeric record ID * @param {string} type Required, record type (A, MX, CNAME, etc) * @param {string} name Host name, alias, or service (A, AAAA, CNAME, TXT, SRV) * @param {string} data Varies depending on record type (A, AAAA, CNAME, MX, TXT, SRV, NS) * @param {integer} priority Priority of the host (SRV and MX records, null otherwise) * @param {integer} port Port the service is accessible on (SRV records, null otherwise) * @param {integer} weight Weight of records with same priority (SRV records, null otherwise) * @param {Function} callback Complete * @method _setDomainRecord * @memberOf Digitalocean */ Digitalocean.prototype._setDomainRecord = function(method, domainName, recordId, type, name, data, priority, port, weight, callback) { var params = {type: type}; if (name) params.name = name; if (data) params.data = data; if (priority) params.priority = priority; if (port) params.port = port; if (weight) params.weight = weight; this._request('domains/'+domainName+'/records'+(method == HTTP_PUT && recordId) ? '/'+recordId : '', method, params, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; // Define our global api client variable var api; /** * Instantiates a new Digitalocean api client object * Needs to be called first with a valid OAuth token * * @param {string} apiKey Required, OAuth token for authenticating requests * @param {Function} callback Complete */ exports.connect = function(apiKey, callback) { api = new Digitalocean(apiKey); api._getUserInfo(function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Gets basic user account information * * @param {Function} callback Complete */ exports.getUserInfo = function(callback) { api._getUserInfo(function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Lists all of the actions that have been executed * * @param {integer} page Number of pages to paginate by * @param {integer} perPage Number of actions per page * @param {Function} callback Complete */ exports.getActions = function(page, perPage, callback) { var params = {}; if (page) parmas.page = page; if (perPage) params.per_page = perPage; api._request('actions', HTTP_GET, params, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Retrieves a specific action object * * @param {integer} actionId Required, unique numeric action ID * @param {Function} callback Complete */ exports.getActionById = function(actionId, callback) { api._request('actions/'+actionId, HTTP_GET, {}, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Retrieves a list of all domains * * @param {Function} callback Complete */ exports.getDomains = function(callback) { api._request('domains', HTTP_GET, {}, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Adds a new domain to the DigitalOcean DNS management interface * * @param {string} domainName Required, registered domain name to add * @param {string} ipAddress Required, IP address the domain will point to * @param {Function} callback Complete */ exports.setDomain = function(domainName, ipAddress, callback) { var params = { name: domainName, ip_address: ipAddress }; api._request('domains', HTTP_POST, params, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Gets details about a sepcific domain * * @param {string} domainName Required, name of an account registered domain * @param {Function} callback Complete */ exports.getDomainByName = function(domainName, callback) { api._request('domains/'+domainName, HTTP_GET, {}, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Deletes a specific domain * * @param {string} domainName Required, name of an account registered domain * @param {Function} callback Complete */ exports.deleteDomain = function(domainName, callback) { api._request('domains/'+domainName, HTTP_DELETE, {}, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Gets a list of all records configured for a domain * * @param {string} domainName Required, name of an account registered domain * @param {Function} callback Complete */ exports.getDomainRecords = function(domainName, callback) { api._request('domains/'+domainName+'/records', HTTP_GET, {}, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Creates a new record for a domain * * @param {string} domainName Required, name of an account registered domain * @param {string} type Record type (A, MX, CNAME, etc) * @param {string} name Host name, alias, or service (A, AAAA, CNAME, TXT, SRV) * @param {string} data Varies depending on record type (A, AAAA, CNAME, MX, TXT, SRV, NS) * @param {integer} priority Priority of the host (SRV and MX records, null otherwise) * @param {integer} port Port the service is accessible on (SRV records, null otherwise) * @param {integer} weight Weight of records with same priority (SRV records, null otherwise) * @param {Function} callback Complete */ exports.setDomainRecord = function(domainName, type, name, data, priority, port, weight, callback) { api._setDomainRecord(HTTP_POST, domainName, null, type, name, data, priority, port, weight, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Updates an existing record for a domain * * @param {string} domainName Required, name of an account registered domain * @param {integer} recordId Unique numeric record ID * @param {string} type Record type (A, MX, CNAME, etc) * @param {string} name Host name, alias, or service (A, AAAA, CNAME, TXT, SRV) * @param {string} data Varies depending on record type (A, AAAA, CNAME, MX, TXT, SRV, NS) * @param {integer} priority Priority of the host (SRV and MX records, null otherwise) * @param {integer} port Port the service is accessible on (SRV records, null otherwise) * @param {integer} weight Weight of records with same priority (SRV records, null otherwise) * @param {Function} callback Complete */ exports.updateDomainRecord = function(domainName, recordId, type, name, data, priority, port, weight, callback) { api._setDomainRecord(HTTP_PUT, domainName, recordId, type, name, data, priority, port, weight, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Deletes a record for a domain * * @param {string} domainName Required, name of an account registered domain * @param {[type]} recordId Required, unique numeric record ID * @param {Function} callback Complete */ exports.deleteDomainRecord = function(domainName, recordId, callback) { api._request('domains/'+domainName+'/records/'+recordId, HTTP_DELETE, {}, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Retrieves a list of all Droplets * * @param {Function} callback Complete */ exports.getDroplets = function(callback) { api._request('droplets', HTTP_GET, {}, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Retrieves an existing Droplet * * @param {string} dropletId Required, unique Droplet ID * @param {Function} callback Complete */ exports.getDropletById = function(dropletId, callback) { api._request('droplets/'+dropletId, HTTP_GET, {}, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); }; /** * Creates a new Droplet * * @param {string} name Required, if set to a managed domain name, a PTR record will be configured * @param {string} region Required, unique slug identifier for region to deploy in (nyc3) * @param {string} size Required, unique slug identifier for disk size (512mb) * @param {string} image Required, unique image ID or the unique slug identifier (ubuntu-14-04-x64) * @param {Array} ssh_keys Contains IDs or fingerprints of SSH keys embedded upon creation * @param {boolean} backups Indicates whether automated backups should be enabled * @param {boolean} ipv6 Indicates whether IPv6 should be enabled * @param {string} userData Currently only available in regions with metadata features * @param {boolean} privateNetworking Indicates whether private networking should be enabled * @param {Function} callback Complete */ exports.setDroplet = function(mame, region, size, image, ssh_keys, backups, ipv6, userData, privateNetworking, callback) { var params = { name: name, region: region, size: size, image: image, }; if (sshKeys) params.ssh_keys = sshKeys; if (backups) params.backups = backups; if (ipv6) parmas.ipv6 = ipv6; if (userData) params.user_data = userData; if (privateNetworking) params.private_networking = privateNetworking; api._request('droplets', HTTP_POST, params, function(err, data) { callback((err) ? err : null, (data) ? data : null); }); };