diff --git a/src/backups.js b/src/backups.js index d2dca2f83..58c4b2b9f 100644 --- a/src/backups.js +++ b/src/backups.js @@ -12,9 +12,10 @@ exports = module.exports = { }; var assert = require('assert'), - aws = require('./aws.js'), + caas = require('./storage/caas.js'), config = require('./config.js'), debug = require('debug')('box:backups'), + s3 = require('./storage/s3.js'), superagent = require('superagent'), util = require('util'); @@ -43,7 +44,7 @@ BackupsError.MISSING_CREDENTIALS = 'missing credentials'; // choose which storage backend we use for test purpose we use s3 function api() { - return aws; + return config.token() ? caas : s3; } function getAllPaged(page, perPage, callback) { diff --git a/src/aws.js b/src/storage/caas.js similarity index 64% rename from src/aws.js rename to src/storage/caas.js index 8ec71c16b..825af31db 100644 --- a/src/aws.js +++ b/src/storage/caas.js @@ -11,54 +11,36 @@ exports = module.exports = { var assert = require('assert'), AWS = require('aws-sdk'), - config = require('./config.js'), - debug = require('debug')('box:aws'), - BackupError = require('./backups.js').BackupError, + config = require('../config.js'), superagent = require('superagent'); function getBackupCredentials(callback) { assert.strictEqual(typeof callback, 'function'); + assert(config.token()); - // CaaS - if (config.token()) { - var url = config.apiServerOrigin() + '/api/v1/boxes/' + config.fqdn() + '/awscredentials'; - superagent.post(url).query({ token: config.token() }).end(function (error, result) { - if (error) return callback(error); - if (result.statusCode !== 201) return callback(new Error(result.text)); - if (!result.body || !result.body.credentials) return callback(new Error('Unexpected response')); - - var credentials = { - accessKeyId: result.body.credentials.AccessKeyId, - secretAccessKey: result.body.credentials.SecretAccessKey, - sessionToken: result.body.credentials.SessionToken, - region: 'us-east-1' - }; - - if (config.aws().endpoint) credentials.endpoint = new AWS.Endpoint(config.aws().endpoint); - - callback(null, credentials); - }); - } else { - if (!config.aws().accessKeyId || !config.aws().secretAccessKey) return callback(new BackupError(BackupError.MISSING_CREDENTIALS)); + var url = config.apiServerOrigin() + '/api/v1/boxes/' + config.fqdn() + '/awscredentials'; + superagent.post(url).query({ token: config.token() }).end(function (error, result) { + if (error) return callback(error); + if (result.statusCode !== 201) return callback(new Error(result.text)); + if (!result.body || !result.body.credentials) return callback(new Error('Unexpected response')); var credentials = { - accessKeyId: config.aws().accessKeyId, - secretAccessKey: config.aws().secretAccessKey, + accessKeyId: result.body.credentials.AccessKeyId, + secretAccessKey: result.body.credentials.SecretAccessKey, + sessionToken: result.body.credentials.SessionToken, region: 'us-east-1' }; if (config.aws().endpoint) credentials.endpoint = new AWS.Endpoint(config.aws().endpoint); callback(null, credentials); - } + }); } function getSignedUploadUrl(filename, callback) { assert.strictEqual(typeof filename, 'string'); assert.strictEqual(typeof callback, 'function'); - debug('getSignedUploadUrl: %s', filename); - getBackupCredentials(function (error, credentials) { if (error) return callback(error); @@ -80,8 +62,6 @@ function getSignedDownloadUrl(filename, callback) { assert.strictEqual(typeof filename, 'string'); assert.strictEqual(typeof callback, 'function'); - debug('getSignedDownloadUrl: %s', filename); - getBackupCredentials(function (error, credentials) { if (error) return callback(error); diff --git a/src/storage/s3.js b/src/storage/s3.js new file mode 100644 index 000000000..278a40c59 --- /dev/null +++ b/src/storage/s3.js @@ -0,0 +1,91 @@ +/* jslint node:true */ + +'use strict'; + +exports = module.exports = { + getSignedUploadUrl: getSignedUploadUrl, + getSignedDownloadUrl: getSignedDownloadUrl, + + copyObject: copyObject +}; + +var assert = require('assert'), + AWS = require('aws-sdk'), + config = require('../config.js'); + +function getBackupCredentials(callback) { + assert.strictEqual(typeof callback, 'function'); + + if (!config.aws().accessKeyId || !config.aws().secretAccessKey) return callback(new Error('missing credentials')); + + var credentials = { + accessKeyId: config.aws().accessKeyId, + secretAccessKey: config.aws().secretAccessKey, + region: 'us-east-1' + }; + + if (config.aws().endpoint) credentials.endpoint = new AWS.Endpoint(config.aws().endpoint); + + callback(null, credentials); +} + +function getSignedUploadUrl(filename, callback) { + assert.strictEqual(typeof filename, 'string'); + assert.strictEqual(typeof callback, 'function'); + + getBackupCredentials(function (error, credentials) { + if (error) return callback(error); + + var s3 = new AWS.S3(credentials); + + var params = { + Bucket: config.aws().backupBucket, + Key: config.aws().backupPrefix + '/' + filename, + Expires: 60 * 30 /* 30 minutes */ + }; + + var url = s3.getSignedUrl('putObject', params); + + callback(null, { url : url, sessionToken: credentials.sessionToken }); + }); +} + +function getSignedDownloadUrl(filename, callback) { + assert.strictEqual(typeof filename, 'string'); + assert.strictEqual(typeof callback, 'function'); + + getBackupCredentials(function (error, credentials) { + if (error) return callback(error); + + var s3 = new AWS.S3(credentials); + + var params = { + Bucket: config.aws().backupBucket, + Key: config.aws().backupPrefix + '/' + filename, + Expires: 60 * 30 /* 30 minutes */ + }; + + var url = s3.getSignedUrl('getObject', params); + + callback(null, { url: url, sessionToken: credentials.sessionToken }); + }); +} + +function copyObject(from, to, callback) { + assert.strictEqual(typeof from, 'string'); + assert.strictEqual(typeof to, 'string'); + assert.strictEqual(typeof callback, 'function'); + + getBackupCredentials(function (error, credentials) { + if (error) return callback(error); + + var params = { + Bucket: config.aws().backupBucket, // target bucket + Key: config.aws().backupPrefix + '/' + to, // target file + CopySource: config.aws().backupBucket + '/' + config.aws().backupPrefix + '/' + from, // source + }; + + var s3 = new AWS.S3(credentials); + s3.copyObject(params, callback); + }); +}