Permalink
Browse files

Add array support for virtual machine building block

  • Loading branch information...
atoakley committed Aug 22, 2017
1 parent b08f334 commit 792a2182ead65bad4f7ab76a8dc94b0ab76f220c
@@ -441,7 +441,7 @@ module.exports = (application) => {
let existingCosmosDbNames = _.filter(cosmosDbNames, (value) => {
let child = az.spawnAz({
args: ['cosmosdb', 'check-name-exists', '--name', value],
options: {
spawnOptions: {
stdio: 'pipe',
shell: true
}
@@ -467,7 +467,7 @@ module.exports = (application) => {
args: ['cosmosdb', 'database', 'create', '--name', value.name,
'--resource-group', value.resourceGroupName,
'--db-name', database.name],
options: {
spawnOptions: {
stdio: 'inherit',
shell: true
}
@@ -488,7 +488,7 @@ module.exports = (application) => {
az.spawnAz({
args: args,
options: {
spawnOptions: {
stdio: 'inherit',
shell: true
}
@@ -305,7 +305,7 @@ module.exports = (application) => {
}
az.spawnAz({
args: args,
options: {
spawnOptions: {
stdio: 'inherit',
shell: true
}
@@ -333,7 +333,7 @@ module.exports = (application) => {
let objectIds = _.map(upns, (upn) => {
let child = az.spawnAz({
args: ['ad', 'user', 'show', '--query', 'objectId', '--upn-or-object-id', upn],
options: {
spawnOptions: {
stdio: 'pipe',
shell: true
}
View
@@ -1,58 +1,60 @@
'use strict';
const childProcess = require('child_process');
const os = require('os');
const _ = require('lodash');
const v = require('./core/validation');
let spawnAz = ({args, options}) => {
if (_.isNil(options)) {
// Assign default options so nothing unexpected happens
options = {
stdio: 'pipe',
shell: true
};
let spawnAz = ({args = [], spawnOptions = {
stdio: 'pipe',
shell: true
}, azOptions = {
debug: false
}}) => {
if (azOptions.debug === true) {
args.push('--debug');
}
let child = childProcess.spawnSync('az', args, options);
let child = childProcess.spawnSync('az', args, spawnOptions);
if (child.status !== 0) {
throw new Error(`error executing az${os.EOL} status: ${child.status}${os.EOL} arguments: ${args.join(' ')}`);
}
return child;
};
let setSubscription = ({subscriptionId}) => {
let setSubscription = ({subscriptionId, azOptions}) => {
if (v.utilities.isNullOrWhitespace(subscriptionId)) {
throw new Error('subscriptionId cannot be undefined, null, empty, or only whitespace');
}
let child = spawnAz({
args: ['account', 'set', '--subscription', subscriptionId],
options: {
spawnOptions: {
stdio: 'inherit',
shell: true
}
},
azOptions: azOptions
});
return child;
};
let setCloud = ({name}) => {
let setCloud = ({name, azOptions}) => {
if (v.utilities.isNullOrWhitespace(name)) {
throw new Error('name cannot be undefined, null, empty, or only whitespace');
}
let child = spawnAz({
args: ['cloud', 'set', '--name', name],
options: {
spawnOptions: {
stdio: 'inherit',
shell: true
}
},
azOptions: azOptions
});
return child;
};
let createResourceGroupIfNotExists = ({resourceGroupName, location}) => {
let createResourceGroupIfNotExists = ({resourceGroupName, location, azOptions}) => {
if (v.utilities.isNullOrWhitespace(resourceGroupName)) {
throw new Error('resourceGroupName cannot be undefined, null, empty, or only whitespace');
@@ -65,7 +67,7 @@ let createResourceGroupIfNotExists = ({resourceGroupName, location}) => {
// See if the resource group exists, and if not create it.
let child = spawnAz({
args: ['group', 'exists', '--name', resourceGroupName],
options: {
spawnOptions: {
stdio: 'pipe',
shell: true
}
@@ -76,34 +78,39 @@ let createResourceGroupIfNotExists = ({resourceGroupName, location}) => {
// Create the resource group
child = spawnAz({
args: ['group', 'create', '--location', location, '--name', resourceGroupName],
options: {
spawnOptions: {
stdio: 'inherit',
shell: true
}
},
azOptions: azOptions
});
}
return child;
};
let deployTemplate = ({deploymentName, resourceGroupName, templateUri, parameterFile}) => {
let deployTemplate = ({deploymentName, resourceGroupName, templateUri, parameterFile, azOptions}) => {
let args = ['group', 'deployment', 'create', '--name', deploymentName,
'--resource-group', resourceGroupName,
'--template-uri', templateUri.replace(/&/g, (os.platform() === 'win32' ? '^^^&' : '\\&')),
'--parameters', `@${parameterFile}`];
let child = spawnAz({
args: ['group', 'deployment', 'create', '--name', deploymentName,
'--resource-group', resourceGroupName,
'--template-uri', templateUri.replace(/&/g, (os.platform() === 'win32' ? '^^^&' : '\\&')),
'--parameters', `@${parameterFile}`],
options: {
args: args,
spawnOptions: {
stdio: 'inherit',
shell: true
}
},
azOptions: azOptions
});
return child;
};
let getRegisteredClouds = () => {
let getRegisteredClouds = ({azOptions} = {}) => {
let child = spawnAz({
args: ['cloud', 'list']
args: ['cloud', 'list'],
azOptions: azOptions
});
return JSON.parse(child.stdout.toString());
@@ -4,7 +4,7 @@ let _ = require('lodash');
let v = require('./validation');
const AVAILABILITYSET_SETTINGS_DEFAULTS = {
platformFaultDomainCount: 3,
platformFaultDomainCount: 2,
platformUpdateDomainCount: 5
};
@@ -821,13 +821,6 @@ let virtualMachineValidations = {
message: 'createOption attach is not allowed for scaleset data disks'
};
}
// TODO - Revisit this when VMSS fromImage is complete.
// if (!_.isNil(parent.dataDisks.properties.image)) {
// return {
// result: false,
// message: '.dataDisks.properties.image cannot be provided for scalesets.'
// };
// }
if (value.location !== parent.virtualNetwork.location || value.subscriptionId !== parent.virtualNetwork.subscriptionId) {
return {
@@ -1193,7 +1186,15 @@ function processVMStamps(param) {
}
function transform(settings, buildingBlockSettings) {
let accumulator = { publicIpAddresses: [], networkInterfaces: [] };
let accumulator = {
publicIpAddresses: [],
networkInterfaces: [],
availabilitySet: [],
scaleSet: [],
autoScaleSettings: [],
loadBalancer: [],
applicationGateways: []
};
// process storageAccounts
accumulator.storageAccounts = (storageSettings.transform(settings.storageAccounts, settings)).accounts;
@@ -1204,8 +1205,6 @@ function transform(settings, buildingBlockSettings) {
// process availabilitySet
if (!v.utilities.isNullOrWhitespace(settings.availabilitySet.name)) {
_.merge(accumulator, avSetSettings.transform(settings.availabilitySet, settings));
} else {
accumulator.availabilitySet = [];
}
// process VMs
@@ -1263,13 +1262,19 @@ function transform(settings, buildingBlockSettings) {
accumulator.availabilitySet = [];
}
// process secrets
// Process secrets. We need to put them into a shape that can be assigned to a secureString parameter.
if (settings.osType === 'linux' && !_.isNil(settings.sshPublicKey)) {
accumulator.secret = settings.sshPublicKey;
} else {
accumulator.secret = settings.adminPassword;
}
if (_.isUndefined(accumulator.secret.reference)) {
accumulator.secret = {
value: accumulator.secret
};
}
// process load balancer if specified
if (settings.loadBalancerSettings) {
let lbResults = lbSettings.transform(settings.loadBalancerSettings, buildingBlockSettings);
@@ -1292,11 +1297,15 @@ function transform(settings, buildingBlockSettings) {
}
function process({ settings, buildingBlockSettings, defaultSettings }) {
settings = _.castArray(settings);
// Merge
let mergedSettings = merge({
settings: settings,
buildingBlockSettings: buildingBlockSettings,
defaultSettings: defaultSettings
let mergedSettings = _.map(settings, (value) => {
return merge({
settings: value,
buildingBlockSettings: buildingBlockSettings,
defaultSettings: defaultSettings
});
});
// Validate
@@ -1307,24 +1316,50 @@ function process({ settings, buildingBlockSettings, defaultSettings }) {
}
// Transform
let results = transform(mergedSettings, buildingBlockSettings);
let resourceGroups = resources.extractResourceGroups(
results.availabilitySet,
results.diagnosticStorageAccounts,
results.loadBalancer,
results.applicationGateways,
results.scaleSet,
results.autoScaleSettings,
results.networkInterfaces,
results.publicIpAddresses,
results.storageAccounts,
results.virtualMachines,
results.applicationGateways
);
let results = _.map(mergedSettings, (value) => {
let result = transform(value, buildingBlockSettings);
let resourceGroups = resources.extractResourceGroups(
result.availabilitySet,
result.diagnosticStorageAccounts,
result.loadBalancer,
result.applicationGateways,
result.scaleSet,
result.autoScaleSettings,
result.networkInterfaces,
result.publicIpAddresses,
result.storageAccounts,
result.virtualMachines,
result.applicationGateways
);
return {
resourceGroups: resourceGroups,
parameters: result
};
});
// We need to merge and unique-ify the resource groups and get things into the right shape
let uniqueResourceGroups = _.uniqWith(_.reduce(results, (result, value) => {
return result.concat(value.resourceGroups);
}, []), _.isEqual);
// Extract the secrets into their own object and delete them from the virtual machine parameters
results = _.transform(results, (result, value) => {
result.secrets.secrets.push(value.parameters.secret);
delete value.parameters.secret;
result.virtualMachineParameters.push(value.parameters);
}, {
virtualMachineParameters: [],
secrets: {
secrets: []
}
});
return {
resourceGroups: resourceGroups,
parameters: results
resourceGroups: uniqueResourceGroups,
parameters: {
virtualMachines: results.virtualMachineParameters,
secrets: results.secrets
}
};
}
View
@@ -515,7 +515,7 @@ try {
console.log(output);
} else if (options.outputFormat === 'files') {
_.forEach(results, (value) => {
let output = JSON.stringify(value.templateParameters, null, 2);
let output = JSON.stringify(value.templateParameters);
fs.writeFileSync(value.outputFilename, output);
console.log();
console.log(` parameters written to ${value.outputFilename}`);
Oops, something went wrong.

0 comments on commit 792a218

Please sign in to comment.