UNPKG

azure-storage

Version:

Microsoft Azure Storage Client Library for Node.js

420 lines (362 loc) 14.5 kB
// // Copyright (c) Microsoft and contributors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // // See the License for the specific language governing permissions and // limitations under the License. // 'use strict'; var _ = require('underscore'); var url = require('url'); var util = require('../util/util'); var ServiceSettings = require('./servicesettings'); var Constants = require('../util/constants'); var StorageServiceClientConstants = Constants.StorageServiceClientConstants; var ConnectionStringKeys = Constants.ConnectionStringKeys; var Validate = require('../util/validate'); var SR = require('../util/sr'); var useDevelopmentStorageSetting = ServiceSettings.setting(ConnectionStringKeys.USE_DEVELOPMENT_STORAGE_NAME, true); var developmentStorageProxyUriSetting = ServiceSettings.settingWithFunc(ConnectionStringKeys.DEVELOPMENT_STORAGE_PROXY_URI_NAME, Validate.isValidUri); var defaultEndpointsProtocolSetting = ServiceSettings.setting(ConnectionStringKeys.DEFAULT_ENDPOINTS_PROTOCOL_NAME, 'http', 'https'); var accountNameSetting = ServiceSettings.setting(ConnectionStringKeys.ACCOUNT_NAME_NAME); var accountKeySetting = ServiceSettings.settingWithFunc(ConnectionStringKeys.ACCOUNT_KEY_NAME, Validate.isBase64Encoded); var sasSetting = ServiceSettings.settingWithFunc(ConnectionStringKeys.SHARED_ACCESS_SIGNATURE_NAME, _.isString); var blobEndpointSetting = ServiceSettings.settingWithFunc( ConnectionStringKeys.BLOB_ENDPOINT_NAME, Validate.isValidHost ); var queueEndpointSetting = ServiceSettings.settingWithFunc( ConnectionStringKeys.QUEUE_ENDPOINT_NAME, Validate.isValidHost ); var tableEndpointSetting = ServiceSettings.settingWithFunc( ConnectionStringKeys.TABLE_ENDPOINT_NAME, Validate.isValidHost ); var fileEndpointSetting = ServiceSettings.settingWithFunc( ConnectionStringKeys.FILE_ENDPOINT_NAME, Validate.isValidHost ); var endpointSuffixSetting = ServiceSettings.settingWithFunc( ConnectionStringKeys.ENDPOINT_SUFFIX_NAME, Validate.isValidHost ); var validKeys = [ ConnectionStringKeys.USE_DEVELOPMENT_STORAGE_NAME, ConnectionStringKeys.DEVELOPMENT_STORAGE_PROXY_URI_NAME, ConnectionStringKeys.DEFAULT_ENDPOINTS_PROTOCOL_NAME, ConnectionStringKeys.ACCOUNT_NAME_NAME, ConnectionStringKeys.ACCOUNT_KEY_NAME, ConnectionStringKeys.SHARED_ACCESS_SIGNATURE_NAME, ConnectionStringKeys.BLOB_ENDPOINT_NAME, ConnectionStringKeys.QUEUE_ENDPOINT_NAME, ConnectionStringKeys.TABLE_ENDPOINT_NAME, ConnectionStringKeys.FILE_ENDPOINT_NAME, ConnectionStringKeys.ENDPOINT_SUFFIX_NAME ]; /** * Creates new storage service settings instance. * * @param {string} name The storage service name. * @param {string} key The storage service key. * @param {string} sasToken The storage service shared access signature token. * @param {string} blobEndpoint The storage service blob endpoint. * @param {string} queueEndpoint The storage service queue endpoint. * @param {string} tableEndpoint The storage service table endpoint. * @param {string} fileEndpoint The storage service file endpoint. * @param {bool} usePathStyleUri Boolean value indicating wether to use path style uri or not. */ function StorageServiceSettings(name, key, sasToken, blobEndpoint, queueEndpoint, tableEndpoint, fileEndpoint, usePathStyleUri) { this._name = name; this._key = key; if (sasToken && sasToken[0] === '?') { this._sasToken = sasToken.slice(1); } else { this._sasToken = sasToken; } this._blobEndpoint = blobEndpoint; this._queueEndpoint = queueEndpoint; this._tableEndpoint = tableEndpoint; this._fileEndpoint = fileEndpoint; if (usePathStyleUri) { this._usePathStyleUri = usePathStyleUri; } else { this._usePathStyleUri = false; } } /** * Creates a StorageServiceSettings object from the given connection string. * * @param {string} connectionString The storage settings connection string. * @return {StorageServiceSettings} */ StorageServiceSettings.createFromConnectionString = function (connectionString) { var tokenizedSettings = ServiceSettings.parseAndValidateKeys(connectionString, validKeys); try { return StorageServiceSettings.createFromSettings(tokenizedSettings); } catch (e) { if (e instanceof ServiceSettings.NoMatchError) { // Replace no match settings exception by no match connection string one. ServiceSettings.noMatchConnectionString(connectionString); } else { throw e; } } }; StorageServiceSettings.createExplicitly = function (storageAccount, storageAccessKey, host, sasToken, endpointSuffix) { var settings = {}; function addIfNotNullOrEmpty(key, value){ if(typeof value === 'string' && !util.stringIsEmpty(value)){ settings[key] = value; } else if (typeof value == 'object' && !util.objectIsNull(value)) { settings[key] = value; } } // Endpoints if (host) { addIfNotNullOrEmpty('blobendpoint', host); addIfNotNullOrEmpty('tableendpoint', host); addIfNotNullOrEmpty('queueendpoint', host); addIfNotNullOrEmpty('fileendpoint', host); } else { addIfNotNullOrEmpty('defaultendpointsprotocol', ServiceSettings.DEFAULT_PROTOCOL.split(':', 1)[0]); } addIfNotNullOrEmpty('accountname', storageAccount); addIfNotNullOrEmpty('accountkey', storageAccessKey); addIfNotNullOrEmpty('sharedaccesssignature', sasToken); addIfNotNullOrEmpty('endpointsuffix', endpointSuffix); return StorageServiceSettings.createFromSettings(settings); }; StorageServiceSettings.createFromEnvironment = function () { var emulated = process.env[StorageServiceClientConstants.EnvironmentVariables.EMULATED]; if (emulated) { return StorageServiceSettings.getDevelopmentStorageAccountSettings(); } var connectionString = process.env[StorageServiceClientConstants.EnvironmentVariables.AZURE_STORAGE_CONNECTION_STRING]; if (connectionString) { return StorageServiceSettings.createFromConnectionString(connectionString); } var storageAccount = process.env[StorageServiceClientConstants.EnvironmentVariables.AZURE_STORAGE_ACCOUNT]; var storageAccessKey = process.env[StorageServiceClientConstants.EnvironmentVariables.AZURE_STORAGE_ACCESS_KEY]; if(storageAccount && storageAccessKey){ return StorageServiceSettings.createExplicitly(storageAccount, storageAccessKey, null, null, null); } throw new Error(SR.NO_CREDENTIALS_PROVIDED); }; /** * Creates a StorageServiceSettings object from a set of settings. * * @param {object} settings The settings object. * @return {StorageServiceSettings} */ StorageServiceSettings.createFromSettings = function (settings) { // Devstore case var matchedSpecs = ServiceSettings.matchedSpecification( settings, ServiceSettings.allRequired(useDevelopmentStorageSetting), ServiceSettings.optional(developmentStorageProxyUriSetting) ); if (matchedSpecs) { var proxyUri = util.tryGetValueInsensitive( ConnectionStringKeys.DEVELOPMENT_STORAGE_PROXY_URI_NAME, settings ); return this.getDevelopmentStorageAccountSettings(proxyUri); } // Account/Key automatic case matchedSpecs = ServiceSettings.matchedSpecification( settings, ServiceSettings.allRequired( defaultEndpointsProtocolSetting, accountNameSetting, accountKeySetting ), ServiceSettings.optional( blobEndpointSetting, queueEndpointSetting, tableEndpointSetting, fileEndpointSetting, endpointSuffixSetting ) ); if (matchedSpecs) { return this._createStorageServiceSettings(settings); } // Account/Key explicit case matchedSpecs = ServiceSettings.matchedSpecification( settings, ServiceSettings.allRequired( accountNameSetting, accountKeySetting ), ServiceSettings.atLeastOne( blobEndpointSetting, queueEndpointSetting, tableEndpointSetting, fileEndpointSetting, endpointSuffixSetting ) ); if (matchedSpecs) { return this._createStorageServiceSettings(settings); } // SAS case matchedSpecs = ServiceSettings.matchedSpecification( settings, ServiceSettings.allRequired( sasSetting ), ServiceSettings.atLeastOne( blobEndpointSetting, queueEndpointSetting, tableEndpointSetting, fileEndpointSetting, endpointSuffixSetting ) ); if(matchedSpecs) { return this._createStorageServiceSettings(settings); } // anonymous explicit case // Only blob anonymous access is valid. matchedSpecs = ServiceSettings.matchedSpecification( settings, ServiceSettings.allRequired( blobEndpointSetting ), ServiceSettings.optional( fileEndpointSetting, queueEndpointSetting, tableEndpointSetting, endpointSuffixSetting ) ); if(matchedSpecs) { return this._createStorageServiceSettings(settings); } ServiceSettings.noMatchSettings(settings); }; /** * Returns a StorageServiceSettings with development storage credentials using * the specified proxy Uri. * * @param {string} proxyUri The proxy endpoint to use. * @return {StorageServiceSettings} */ StorageServiceSettings.getDevelopmentStorageAccountSettings = function (proxyUri) { if (!proxyUri) { proxyUri = StorageServiceClientConstants.DEV_STORE_URI; } var parsedUri = url.parse(proxyUri); var scheme = parsedUri.protocol; var host = parsedUri.host; var prefix = scheme + '//' + host; var blobEndpoint = { primaryHost: prefix + ':10000' + '/' + StorageServiceClientConstants.DEVSTORE_STORAGE_ACCOUNT, secondaryHost: prefix + ':10000' + '/' + StorageServiceClientConstants.DEVSTORE_STORAGE_ACCOUNT + '-secondary' }; var queueEndpoint = { primaryHost: prefix + ':10001' + '/' + StorageServiceClientConstants.DEVSTORE_STORAGE_ACCOUNT, secondaryHost: prefix + ':10001' + '/' + StorageServiceClientConstants.DEVSTORE_STORAGE_ACCOUNT + '-secondary' }; var tableEndpoint = { primaryHost: prefix + ':10002' + '/' + StorageServiceClientConstants.DEVSTORE_STORAGE_ACCOUNT, secondaryHost: prefix + ':10002' + '/' + StorageServiceClientConstants.DEVSTORE_STORAGE_ACCOUNT + '-secondary' }; return new StorageServiceSettings( StorageServiceClientConstants.DEVSTORE_STORAGE_ACCOUNT, StorageServiceClientConstants.DEVSTORE_STORAGE_ACCESS_KEY, null, blobEndpoint, queueEndpoint, tableEndpoint, null, true ); }; /** * Creates StorageServiceSettings object given endpoints uri. * * @ignore * @param {array} settings The service settings. * @param {string} blobEndpointUri The blob endpoint uri. * @param {string} queueEndpointUri The queue endpoint uri. * @param {string} tableEndpointUri The table endpoint uri. * @param {string} fileEndpointUri The file endpoint uri. * @return {StorageServiceSettings} */ StorageServiceSettings._createStorageServiceSettings = function (settings) { var standardizeHost = function (host, accountName, scheme, dns){ var storageHost; if (host) { storageHost = {}; storageHost.primaryHost = _.isString(host) ? host : host.primaryHost; storageHost.secondaryHost = _.isString(host) ? undefined : host.secondaryHost; } if (scheme && accountName && dns) { storageHost = storageHost ? storageHost : {}; storageHost.primaryHost = storageHost.primaryHost ? storageHost.primaryHost : url.format({ protocol: scheme, hostname: accountName + '.' + dns}); storageHost.secondaryHost = storageHost.secondaryHost ? storageHost.secondaryHost : url.format({ protocol: scheme, hostname: accountName + '-secondary.' + dns}); } return storageHost; }; var scheme = util.tryGetValueInsensitive( ConnectionStringKeys.DEFAULT_ENDPOINTS_PROTOCOL_NAME, settings ); var accountName = util.tryGetValueInsensitive( ConnectionStringKeys.ACCOUNT_NAME_NAME, settings ); var accountKey = util.tryGetValueInsensitive( ConnectionStringKeys.ACCOUNT_KEY_NAME, settings ); var sasToken = util.tryGetValueInsensitive( ConnectionStringKeys.SHARED_ACCESS_SIGNATURE_NAME, settings ); var endpointSuffix = util.tryGetValueInsensitive( ConnectionStringKeys.ENDPOINT_SUFFIX_NAME, settings ); var blobEndpoint = standardizeHost( util.tryGetValueInsensitive(ConnectionStringKeys.BLOB_ENDPOINT_NAME, settings), accountName, scheme, endpointSuffix ? 'blob.' + endpointSuffix : StorageServiceClientConstants.CLOUD_BLOB_HOST); var queueEndpoint = standardizeHost( util.tryGetValueInsensitive(ConnectionStringKeys.QUEUE_ENDPOINT_NAME, settings), accountName, scheme, endpointSuffix ? 'queue.' + endpointSuffix : StorageServiceClientConstants.CLOUD_QUEUE_HOST); var tableEndpoint = standardizeHost( util.tryGetValueInsensitive(ConnectionStringKeys.TABLE_ENDPOINT_NAME, settings), accountName, scheme, endpointSuffix ? 'table.' + endpointSuffix : StorageServiceClientConstants.CLOUD_TABLE_HOST); var fileEndpoint = standardizeHost( util.tryGetValueInsensitive(ConnectionStringKeys.FILE_ENDPOINT_NAME, settings), accountName, scheme, endpointSuffix ? 'file.' + endpointSuffix : StorageServiceClientConstants.CLOUD_FILE_HOST); return new StorageServiceSettings( accountName, accountKey, sasToken, blobEndpoint, queueEndpoint, tableEndpoint, fileEndpoint ); }; StorageServiceSettings.validKeys = validKeys; exports = module.exports = StorageServiceSettings;