UNPKG

azure-cli

Version:

Microsoft Azure Cross Platform Command Line tool

167 lines (144 loc) 6.21 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. // /** * Common utils related to Azure blob storage */ exports.applyToBlobUrl = applyToBlobUrl; exports.unescape = unescape; exports.normalizeServiceName = normalizeServiceName; var path = require('path'); var qs = require('querystring'); var utils = require('./utils'); //Container names must be valid DNS names, and must conform to these rules: //* Container names must start with a letter or number, and can contain only letters, numbers, and the dash (-) character. //* Every dash (-) character must be immediately preceded and followed by a letter or number; consecutive dashes are not permitted in container names. //* All letters in a container name must be lowercase. //* Container names must be from 3 through 63 characters long. // $root is a special container that can exist at the root level and is always valid. // // prefix container name (if any) in azurizeName() should follow these rules // A blob name can contain any combination of characters, but reserved URL characters must be properly escaped. A blob name must be at least one character long and cannot be more than 1,024 characters long. var azurizeName = exports.azurizeName = function azurizeName(prefix, filename) { if (!filename || typeof prefix !== 'string') { throw new Error('Incorrect parameters for azurizeName() : ' + prefix + ', ' + filename); } if (prefix[0] !== '/') { prefix = '/' + prefix; } // assuming prefix is good // do not escape it, so that we don't use '/' var azureName = path.basename(filename); // remove dir if (azureName.slice(-1) === '.') { // do not end the name with '.', this does not work - add something at the end azureName += '<>'; // anything other than '.', '/' and '\x00' } return prefix + azureName; }; exports.getBlobName = function getBlobName(cli, storageClient, location, affinityGroup, newName, blob, prefix, filename, callback) { if (blob) { if (blob[0] === '/') { utils.getOrCreateBlobStorage(cli, storageClient, location, affinityGroup, newName, function (error, blobEndpoint) { if (error) { callback(error); } else { callback(null, blobEndpoint + blob); } }); } else { callback(null, blob); } } else { utils.getOrCreateBlobStorage(cli, storageClient, location, affinityGroup, newName, function (error, blobEndpoint) { if (error) { callback(error); } else { callback(null, blobEndpoint + azurizeName(prefix, filename)); } }); } }; var splitBlobResourceName = exports.splitBlobResourceName = function splitBlobResourceName(blobResourceName) { var blobResourceNameArray = blobResourceName.split('/'); var rootSet = blobResourceNameArray.length <= 1; var container = rootSet ? '$root' : blobResourceNameArray[0]; var blobName = rootSet ? blobResourceNameArray[0] : blobResourceNameArray.slice(1).join('/'); return { container: container, blobName: blobName, rootSet: rootSet }; }; var splitDestinationUri = exports.splitDestinationUri = function splitDestinationUri(destinationUri) { var result = {}; var protocolSplit = destinationUri.split('://'); var destNameTrimProtocol = protocolSplit.slice(-1)[0]; // last element var destHost = destNameTrimProtocol.split('/')[0]; result.accountName = destHost; var hostArray = destHost.split('.'); var protocol = ''; var host = ''; if (hostArray.length > 1) { result.accountName = hostArray[0]; host = hostArray.join('.').split('/')[0]; } result.host = host; if (protocolSplit.length > 1) { protocol = protocolSplit[0].trim().toLowerCase(); } else { protocol = 'http'; destinationUri = 'http://' + destinationUri; } protocol += '://'; if (result.host) { result.host = protocol + result.host; } result.resourceName = destNameTrimProtocol.split('/').slice(1).join('/'); var splitResource = splitBlobResourceName(result.resourceName); result.container = splitResource.container; result.blobName = splitResource.blobName; // for management operations - make sure root is using $root result.normalizedUri = protocol + host + '/' + result.container + '/' + result.blobName; return result; }; // This function does two things with an URL // 1) adds /$root for root storage and // 2) escape the name (if escape argument is true) exports.normalizeBlobUri = function normalizeBlobUri(blobUri, escape) { var res = splitDestinationUri(blobUri).normalizedUri; if (escape) { res = applyToBlobUrl(qs.escape, res); } return res; }; var applyToBlobUrl = exports.applyToBlobUrl = function applyToBlobUrl(operation, url) { var split1 = url.split('://'); var split2 = split1[split1.length - 1].split('/'); for (var i = 2; i < split2.length; ++i) { // do not escape host and container split2[i] = operation(split2[i]); } split1[split1.length - 1] = split2.join('/'); return split1.join('://'); }; var unescape = exports.unescape = function unescape(url) { return applyToBlobUrl(qs.unescape, url); }; var normalizeServiceName = exports.normalizeServiceName = function normalizeServiceName(name) { return name.replace(/[^a-zA-Z0-9]+/g, '').slice(0, 24).toLowerCase(); };