added validation for azure profile configuration

This commit is contained in:
Arjun Roy Chaudhuri 2016-11-18 15:18:04 -08:00
parent c5c7290208
commit b0e0e9ab45
5 changed files with 230 additions and 201 deletions

View File

@ -695,6 +695,8 @@ public class AzureVMCloud extends Cloud {
@QueryParameter String clientSecret,
@QueryParameter String oauth2TokenEndpoint,
@QueryParameter String serviceManagementURL,
@QueryParameter String maxVirtualMachinesLimit,
@QueryParameter String deploymentTimeout,
@QueryParameter String resourceGroupName) {
if (StringUtils.isBlank(subscriptionId)) {
@ -715,6 +717,17 @@ public class AzureVMCloud extends Cloud {
if (StringUtils.isBlank(resourceGroupName)) {
resourceGroupName = Constants.DEFAULT_RESOURCE_GROUP_NAME;
}
if (StringUtils.isBlank(maxVirtualMachinesLimit) || !maxVirtualMachinesLimit.matches(Constants.REG_EX_DIGIT)) {
maxVirtualMachinesLimit = Integer.toString(Constants.DEFAULT_MAX_VM_LIMIT);
} else {
maxVirtualMachinesLimit = maxVirtualMachinesLimit;
}
if (StringUtils.isBlank(deploymentTimeout) || !deploymentTimeout.matches(Constants.REG_EX_DIGIT)) {
deploymentTimeout = Integer.toString(Constants.DEFAULT_DEPLOYMENT_TIMEOUT_SEC);
} else {
deploymentTimeout = deploymentTimeout;
}
String response = AzureVMManagementServiceDelegate.verifyConfiguration(
subscriptionId,

View File

@ -34,15 +34,15 @@ import java.util.logging.Level;
import jenkins.model.Jenkins;
/**
* Performs a few types of verification:
* 1. Overall subscription verification.
2. Approximate VM count verification
3. Template verification.
When a new AzureVMCloud is constructed or a new template is added via CLI interface, then we will
manually trigger this workload.
This thread serves as a gate for whether we can create VMs from a certain template
* Performs a few types of verification: 1. Overall subscription verification.
* 2. Approximate VM count verification 3. Template verification.
*
* When a new AzureVMCloud is constructed or a new template is added via CLI
* interface, then we will manually trigger this workload.
*
* This thread serves as a gate for whether we can create VMs from a certain
* template
*
* @author mmitche
*/
@Extension
@ -52,21 +52,21 @@ public final class AzureVMCloudVerificationTask extends AsyncPeriodicWork {
// Templates that need verification
private static Map<String, String> cloudTemplates;
// Set of clouds that need verification.
private static Set<String> cloudNames;
public AzureVMCloudVerificationTask() {
super("AzureVMCloudVerificationTask");
}
private static final Object cloudNamesLock = new Object();
private static final Object templatesLock = new Object();
@Override
public void execute(final TaskListener arg0) throws IOException, InterruptedException {
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: execute: start");
if (cloudNames != null && !cloudNames.isEmpty()) {
// Walk the list of clouds and verify the configuration. If an element
// is not found (perhaps a removed cloud, removes from the list)
@ -114,7 +114,7 @@ public final class AzureVMCloudVerificationTask extends AsyncPeriodicWork {
}
}
}
if (cloudTemplates != null && !cloudTemplates.isEmpty()) {
// Now walk the templates and verify.
// Unlike the clouds, verified templates are removed from the list upon
@ -126,15 +126,15 @@ public final class AzureVMCloudVerificationTask extends AsyncPeriodicWork {
for (Map.Entry<String, String> entry : cloudTemplates.entrySet()) {
String templateName = entry.getKey();
String cloudName = entry.getValue();
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: execute: verifying {0} in {1}",
new Object[] { templateName, cloudName });
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: execute: verifying {0} in {1}",
new Object[]{templateName, cloudName});
AzureVMCloud cloud = getCloud(cloudName);
// If the cloud is null, could mean that the cloud details changed
// between the last time we ran this task
if (cloud == null) {
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: execute: parent cloud not found for {0} in {1}",
new Object[] { templateName, cloudName });
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: execute: parent cloud not found for {0} in {1}",
new Object[]{templateName, cloudName});
toRemove.add(templateName);
continue;
}
@ -142,16 +142,16 @@ public final class AzureVMCloudVerificationTask extends AsyncPeriodicWork {
AzureVMAgentTemplate agentTemplate = cloud.getAzureAgentTemplate(templateName);
// Template could have been removed since the last time we ran verification
if (agentTemplate == null) {
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: execute: could not retrieve agent template named {0} in {1}",
new Object[] { templateName, cloudName });
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: execute: could not retrieve agent template named {0} in {1}",
new Object[]{templateName, cloudName});
toRemove.add(templateName);
continue;
}
// Determine whether we need to verify the template
if (agentTemplate.isTemplateVerified()) {
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: execute: template {0} in {1} already verified",
new Object[] { templateName, cloudName });
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: execute: template {0} in {1} already verified",
new Object[]{templateName, cloudName});
// Good to go, nothing more to check here. Add to removal list.
toRemove.add(templateName);
continue;
@ -165,19 +165,17 @@ public final class AzureVMCloudVerificationTask extends AsyncPeriodicWork {
agentTemplate.setTemplateVerified(true);
// Reset the status details
agentTemplate.setTemplateStatusDetails("");
}
else {
String details = StringUtils.join(errors, "\n");
} else {
String details = String.join("\n", errors);
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: execute: {0} could not be verified:\n{1}",
new Object [] { templateName, details });
new Object[]{templateName, details});
// Set the status details to the set of messages
agentTemplate.setTemplateStatusDetails(details);
}
}
catch (Exception e) {
} catch (Exception e) {
// Log, but ignore overall
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: execute: got exception while verifying {0}:\n{1}",
new Object [] { templateName, e.toString() });
new Object[]{templateName, e.toString()});
}
}
@ -187,36 +185,36 @@ public final class AzureVMCloudVerificationTask extends AsyncPeriodicWork {
}
}
}
LOGGER.info("AzureVMCloudVerificationTask: execute: end");
}
/**
* Checks the subscription for validity if needed
* @param cloud
* @return True if the subscription is valid, false otherwise.
* Updates the cloud state if it is. If subscription is
* not valid, then we can just return
* @return True if the subscription is valid, false otherwise. Updates the
* cloud state if it is. If subscription is not valid, then we can just
* return
*/
public boolean verifyConfiguration(AzureVMCloud cloud) {
LOGGER.info("AzureVMCloudVerificationTask: verifyConfiguration: start");
// Check the sub and off we go
String result = AzureVMManagementServiceDelegate.verifyConfiguration(cloud.getSubscriptionId(),
cloud.getClientId(), cloud.getClientSecret(), cloud.getOauth2TokenEndpoint(), cloud.getServiceManagementURL(), cloud.getResourceGroupName());
String result = AzureVMManagementServiceDelegate.verifyConfiguration(cloud.getSubscriptionId(),
cloud.getClientId(), cloud.getClientSecret(), cloud.getOauth2TokenEndpoint(), cloud.getServiceManagementURL(), cloud.getResourceGroupName());
if (result != Constants.OP_SUCCESS) {
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: verifyConfiguration: {0}", result);
cloud.setConfigurationValid(false);
return false;
}
return true;
}
/**
* Retrieve the current VM count.
* @param cloud
* @return
* @param cloud
* @return
*/
public int getVirtualMachineCount(AzureVMCloud cloud) {
LOGGER.info("AzureVMCloudVerificationTask: getVirtualMachineCount: start");
@ -225,22 +223,21 @@ public final class AzureVMCloudVerificationTask extends AsyncPeriodicWork {
int vmCount = AzureVMManagementServiceDelegate.getVirtualMachineCount(config, cloud.getResourceGroupName());
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: getVirtualMachineCount: end, currently {0} vms", vmCount);
return vmCount;
}
catch(Exception e) {
} catch (Exception e) {
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: getVirtualMachineCount: failed to retrieve vm count:\n{0}",
e.toString());
e.toString());
// We could have failed for any number of reasons. Just return the current
// number of virtual machines.
return cloud.getApproximateVirtualMachineCount();
}
}
/**
* Register more than one template at once
* @param templatesToRegister List of templates to register
*/
public static void registerTemplates(final List<AzureVMAgentTemplate> templatesToRegister) {
synchronized(templatesLock) {
synchronized (templatesLock) {
for (AzureVMAgentTemplate template : templatesToRegister) {
registerTemplateHelper(template);
}
@ -252,33 +249,35 @@ public final class AzureVMCloudVerificationTask extends AsyncPeriodicWork {
* @param template Template to register
*/
public static void registerTemplate(final AzureVMAgentTemplate template) {
synchronized(templatesLock) {
synchronized (templatesLock) {
registerTemplateHelper(template);
}
}
/**
* Registers a single template. The lock should be held while calling this method
* Registers a single template. The lock should be held while calling this
* method
*
* @param template Template to register
*/
private static void registerTemplateHelper(final AzureVMAgentTemplate template) {
String cloudName = AzureUtil.getCloudName(template.getAzureCloud().getSubscriptionId());
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: registerTemplateHelper: Registering template {0} on {1} for verification",
new Object [] { template.getTemplateName(), cloudName });
new Object[]{template.getTemplateName(), cloudName});
if (cloudTemplates == null) {
cloudTemplates = new HashMap<String, String>();
}
cloudTemplates.put(template.getTemplateName(), cloudName);
}
/**
* Register a cloud for verification
* @param cloudName
* @param cloudName
*/
public static void registerCloud(final String cloudName) {
LOGGER.log(Level.INFO, "AzureVMCloudVerificationTask: registerCloud: Registering cloud {0} for verification",
cloudName);
synchronized(cloudNamesLock) {
cloudName);
synchronized (cloudNamesLock) {
if (cloudNames == null) {
cloudNames = new HashSet<String>();
}
@ -295,9 +294,10 @@ public final class AzureVMCloudVerificationTask extends AsyncPeriodicWork {
public AzureVMCloud getCloud(final String cloudName) {
return Jenkins.getInstance() == null ? null : (AzureVMCloud) Jenkins.getInstance().getCloud(cloudName);
}
/**
* Retrieve the verification task worker. Can be used to force work
* Retrieve the verification task worker. Can be used to force work
*
* @return The AzureVMCloudVerificationTask worker class
*/
public static AzureVMCloudVerificationTask get() {

View File

@ -65,8 +65,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;
import com.microsoft.windowsazure.Configuration;
import com.microsoft.windowsazure.exception.ServiceException;
import com.microsoft.azure.exceptions.AzureCloudException;
@ -100,13 +98,13 @@ public class AzureVMManagementServiceDelegate {
private static final Logger LOGGER = Logger.getLogger(AzureVMManagementServiceDelegate.class.getName());
private static final String EMBEDDED_TEMPLATE_FILENAME = "/referenceImageTemplate.json";
private static final String EMBEDDED_TEMPLATE_WITH_SCRIPT_FILENAME = "/referenceImageTemplateWithScript.json";
private static final String EMBEDDED_TEMPLATE_IMAGE_FILENAME = "/customImageTemplate.json";
private static final String EMBEDDED_TEMPLATE_IMAGE_WITH_SCRIPT_FILENAME = "/customImageTemplateWithScript.json";
private static final String VIRTUAL_NETWORK_TEMPLATE_FRAGMENT_FILENAME = "/virtualNetworkFragment.json";
private static final String IMAGE_CUSTOM_REFERENCE = "custom";
@ -116,15 +114,16 @@ public class AzureVMManagementServiceDelegate {
private static final Map<String, String> AVAILABLE_LOCATIONS_STD = getAvailableLocationsStandard();
private static final Map<String, String> AVAILABLE_LOCATIONS_CHINA = getAvailableLocationsChina();
private static final Map<String, String> AVAILABLE_LOCATIONS_ALL = getAvailableLocationsAll();
/**
* Creates a new deployment of VMs based on the provided template
*
* @param template Template to deploy
* @param numberOfAgents Number of agents to create
* @return The base name for the VMs that were created
* @throws AzureCloudException
* @throws AzureCloudException
*/
public static AzureVMDeploymentInfo createDeployment(final AzureVMAgentTemplate template, final int numberOfAgents)
throws AzureCloudException {
@ -140,47 +139,50 @@ public class AzureVMManagementServiceDelegate {
final String deploymentName = AzureUtil.getDeploymentName(template.getTemplateName(), timestamp);
final String vmBaseName = AzureUtil.getVMBaseName(template.getTemplateName(), deploymentName, template.getOsType(), numberOfAgents);
final String locationName = getLocationName(template.getLocation());
if (!template.getResourceGroupName().matches(Constants.DEFAULT_RESOURCE_GROUP_PATTERN)) {
LOGGER.log(Level.SEVERE,
"AzureVMManagementServiceDelegate: createDeployment: ResourceGroup Name {0} is invalid. It should be 1-64 alphanumeric characters",
new Object[]{template.getResourceGroupName()});
throw new Exception("ResourceGroup Name is invalid");
}
final String resourceGroupName = template.getResourceGroupName();
LOGGER.log(Level.INFO,
"AzureVMManagementServiceDelegate: createDeployment: Creating a new deployment {0} with VM base name {1}",
new Object[] { deploymentName, vmBaseName} );
new Object[]{deploymentName, vmBaseName});
client.getResourceGroupsOperations().createOrUpdate(
resourceGroupName,
new ResourceGroup(locationName));
final Deployment deployment = new Deployment();
final DeploymentProperties properties = new DeploymentProperties();
deployment.setProperties(properties);
final InputStream embeddedTemplate;
final boolean useCustomScriptExtension =
template.getOsType().equals(Constants.OS_TYPE_WINDOWS) && !StringUtils.isBlank(template.getInitScript()) &&
template.getAgentLaunchMethod().equals(Constants.LAUNCH_METHOD_JNLP);
final boolean useCustomScriptExtension
= template.getOsType().equals(Constants.OS_TYPE_WINDOWS) && !StringUtils.isBlank(template.getInitScript())
&& template.getAgentLaunchMethod().equals(Constants.LAUNCH_METHOD_JNLP);
// check if a custom image id has been provided otherwise work with publisher and offer
if (template.getImageReferenceType().equals(IMAGE_CUSTOM_REFERENCE)) {
if (useCustomScriptExtension) {
LOGGER.log(Level.INFO, "AzureVMManagementServiceDelegate: createDeployment: Use embedded deployment template {0}", EMBEDDED_TEMPLATE_IMAGE_WITH_SCRIPT_FILENAME);
embeddedTemplate
= AzureVMManagementServiceDelegate.class.getResourceAsStream(EMBEDDED_TEMPLATE_IMAGE_WITH_SCRIPT_FILENAME);
}
else {
= AzureVMManagementServiceDelegate.class.getResourceAsStream(EMBEDDED_TEMPLATE_IMAGE_WITH_SCRIPT_FILENAME);
} else {
LOGGER.log(Level.INFO, "AzureVMManagementServiceDelegate: createDeployment: Use embedded deployment template (with script) {0}", EMBEDDED_TEMPLATE_IMAGE_FILENAME);
embeddedTemplate
= AzureVMManagementServiceDelegate.class.getResourceAsStream(EMBEDDED_TEMPLATE_IMAGE_FILENAME);
= AzureVMManagementServiceDelegate.class.getResourceAsStream(EMBEDDED_TEMPLATE_IMAGE_FILENAME);
}
} else {
if (useCustomScriptExtension) {
LOGGER.log(Level.INFO, "AzureVMManagementServiceDelegate: createDeployment: Use embedded deployment template (with script) {0}", EMBEDDED_TEMPLATE_WITH_SCRIPT_FILENAME);
embeddedTemplate
= AzureVMManagementServiceDelegate.class.getResourceAsStream(EMBEDDED_TEMPLATE_WITH_SCRIPT_FILENAME);
}
else {
= AzureVMManagementServiceDelegate.class.getResourceAsStream(EMBEDDED_TEMPLATE_WITH_SCRIPT_FILENAME);
} else {
LOGGER.log(Level.INFO, "AzureVMManagementServiceDelegate: createDeployment: Use embedded deployment template {0}", EMBEDDED_TEMPLATE_FILENAME);
embeddedTemplate
= AzureVMManagementServiceDelegate.class.getResourceAsStream(EMBEDDED_TEMPLATE_FILENAME);
= AzureVMManagementServiceDelegate.class.getResourceAsStream(EMBEDDED_TEMPLATE_FILENAME);
}
}
@ -192,7 +194,7 @@ public class AzureVMManagementServiceDelegate {
count.put("type", "int");
count.put("defaultValue", numberOfAgents);
ObjectNode.class.cast(tmp.get("parameters")).replace("count", count);
ObjectNode.class.cast(tmp.get("variables")).put("vmName", vmBaseName);
ObjectNode.class.cast(tmp.get("variables")).put("location", locationName);
@ -215,7 +217,7 @@ public class AzureVMManagementServiceDelegate {
if (StringUtils.isNotBlank(template.getImage())) {
ObjectNode.class.cast(tmp.get("variables")).put("image", template.getImage());
}
// If using the custom script extension (vs. SSH) to startup the powershell scripts,
// add variables for that and upload the init script to the storage account
if (useCustomScriptExtension) {
@ -224,14 +226,14 @@ public class AzureVMManagementServiceDelegate {
ArrayNode clientSecretsNode = ObjectNode.class.cast(tmp.get("variables")).putArray("clientSecrets");
for (int i = 0; i < numberOfAgents; i++) {
clientSecretsNode.add(
JnlpSlaveAgentProtocol.SLAVE_SECRET.mac(String.format("%s%d", vmBaseName, i)));
JnlpSlaveAgentProtocol.SLAVE_SECRET.mac(String.format("%s%d", vmBaseName, i)));
}
// Upload the startup script to blob storage
String scriptName = String.format("%s%s", deploymentName, "init.ps1");
String scriptUri = uploadCustomScript(template, scriptName);
ObjectNode.class.cast(tmp.get("variables")).put("startupScriptURI", scriptUri);
ObjectNode.class.cast(tmp.get("variables")).put("startupScriptName", scriptName);
String storageAccountKey = ServiceDelegateHelper.getStorageManagementClient(config).getStorageAccountsOperations().listKeys(
template.getResourceGroupName(), template.getStorageAccountName())
.getStorageAccountKeys().getKey1();
@ -239,7 +241,7 @@ public class AzureVMManagementServiceDelegate {
final ObjectNode storageAccountKeyNode = mapper.createObjectNode();
storageAccountKeyNode.put("type", "secureString");
storageAccountKeyNode.put("defaultValue", storageAccountKey);
// Add the storage account key
ObjectNode.class.cast(tmp.get("parameters")).replace("storageAccountKey", storageAccountKeyNode);
}
@ -257,29 +259,28 @@ public class AzureVMManagementServiceDelegate {
if (StringUtils.isNotBlank(template.getVirtualNetworkName())) {
ObjectNode.class.cast(tmp.get("variables")).put("virtualNetworkName", template.getVirtualNetworkName());
ObjectNode.class.cast(tmp.get("variables")).put("subnetName", template.getSubnetName());
}
else {
} else {
// Add the definition of the vnet and subnet into the template
final String virtualNetworkName = Constants.DEFAULT_VNET_NAME;
final String subnetName = Constants.DEFAULT_SUBNET_NAME;
ObjectNode.class.cast(tmp.get("variables")).put("virtualNetworkName", virtualNetworkName);
ObjectNode.class.cast(tmp.get("variables")).put("subnetName", subnetName);
// Read the vnet fragment
InputStream fragmentStream =
AzureVMManagementServiceDelegate.class.getResourceAsStream(VIRTUAL_NETWORK_TEMPLATE_FRAGMENT_FILENAME);
InputStream fragmentStream
= AzureVMManagementServiceDelegate.class.getResourceAsStream(VIRTUAL_NETWORK_TEMPLATE_FRAGMENT_FILENAME);
final JsonNode virtualNetworkFragment = mapper.readTree(fragmentStream);
// Add the virtual network fragment
ArrayNode.class.cast(tmp.get("resources")).add(virtualNetworkFragment);
// Because we created/updated this in the template, we need to add the appropriate
// dependsOn node to the networkInterface
// Microsoft.Network/virtualNetworks/<vnet name>
// Find the network interfaces node
ArrayNode resourcesNodes = ArrayNode.class.cast(tmp.get("resources"));
Iterator<JsonNode> resourcesNodesIter = resourcesNodes.elements();
while(resourcesNodesIter.hasNext()) {
while (resourcesNodesIter.hasNext()) {
JsonNode resourcesNode = resourcesNodesIter.next();
JsonNode typeNode = resourcesNode.get("type");
if (typeNode == null || !typeNode.asText().equals("Microsoft.Network/networkInterfaces")) {
@ -301,7 +302,7 @@ public class AzureVMManagementServiceDelegate {
AzureVMAgentCleanUpTask.registerDeployment(template.getAzureCloud().name, template.getResourceGroupName(), deploymentName);
// Create the deployment
client.getDeploymentsOperations().createOrUpdate(template.getResourceGroupName(), deploymentName, deployment);
return new AzureVMDeploymentInfo(deploymentName, vmBaseName, numberOfAgents);
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "AzureVMManagementServiceDelegate: deployment: Unable to deploy", e);
@ -310,26 +311,27 @@ public class AzureVMManagementServiceDelegate {
throw new AzureCloudException(e);
}
}
/**
* Uploads the custom script for a template to blob storage
*
* @param template Template containing script to upload
* @return URI of script
*/
private static String uploadCustomScript(final AzureVMAgentTemplate template, final String targetScriptName) throws Exception {
Configuration config = ServiceDelegateHelper.getConfiguration(template);
StorageManagementClient client = ServiceDelegateHelper.getStorageManagementClient(config);
// Get the storage account name and key
String targetStorageAccount = template.getStorageAccountName();
String resourceGroupName = template.getResourceGroupName();
String storageAccountKey = client.getStorageAccountsOperations().listKeys(resourceGroupName, targetStorageAccount)
.getStorageAccountKeys().getKey1();
String scriptText = template.getInitScript();
String blobURL = StorageServiceDelegate.uploadFileToStorage(
config, targetStorageAccount, storageAccountKey,
client.getBaseUri().toString(), resourceGroupName, Constants.CONFIG_CONTAINER_NAME,
client.getBaseUri().toString(), resourceGroupName, Constants.CONFIG_CONTAINER_NAME,
targetScriptName, scriptText.getBytes("UTF-8"));
return blobURL;
}
@ -371,17 +373,18 @@ public class AzureVMManagementServiceDelegate {
azureAgent.setPublicDNSName(pubIP.getDnsSettings().getFqdn());
azureAgent.setSshPort(Constants.DEFAULT_SSH_PORT);
LOGGER.log(Level.INFO, "Azure agent details:\nnodeName{0}\nadminUserName={1}\nshutdownOnIdle={2}\nretentionTimeInMin={3}\nlabels={4}",
new Object[] { azureAgent.getNodeName(), azureAgent.getAdminUserName(), azureAgent.isShutdownOnIdle(),
azureAgent.getRetentionTimeInMin(), azureAgent.getLabelString()});
LOGGER.log(Level.INFO, "Azure agent details:\nnodeName{0}\nadminUserName={1}\nshutdownOnIdle={2}\nretentionTimeInMin={3}\nlabels={4}",
new Object[]{azureAgent.getNodeName(), azureAgent.getAdminUserName(), azureAgent.isShutdownOnIdle(),
azureAgent.getRetentionTimeInMin(), azureAgent.getLabelString()});
}
/**
* Determines whether a virtual machine exists.
*
* @param configuration Configuration for the subscription
* @param vmName Name of the VM.
* @param resourceGroupName Resource group of the VM.
* @return
* @return
*/
private static boolean virtualMachineExists(final Configuration config, final String vmName, final String resourceGroupName) {
LOGGER.log(Level.INFO, "AzureVMManagementServiceDelegate: virtualMachineExists: check for {0}", vmName);
@ -406,6 +409,7 @@ public class AzureVMManagementServiceDelegate {
/**
* Determines whether a given agent exists.
*
* @param agent to check
* @return True if the agent exists, false otherwise
*/
@ -413,10 +417,9 @@ public class AzureVMManagementServiceDelegate {
try {
Configuration config = ServiceDelegateHelper.getConfiguration(agent);
return virtualMachineExists(config, agent.getNodeName(), agent.getResourceGroupName());
}
catch (Exception e) {
LOGGER.log(Level.INFO,
"AzureVMManagementServiceDelegate: virtualMachineExists: error while determining whether vm exists", e);
} catch (Exception e) {
LOGGER.log(Level.INFO,
"AzureVMManagementServiceDelegate: virtualMachineExists: error while determining whether vm exists", e);
return false;
}
}
@ -442,7 +445,7 @@ public class AzureVMManagementServiceDelegate {
+ "\tfound agent {0}\n"
+ "\tOS type {1}\n"
+ "\tnumber of executors {2}",
new Object[] { vmname, osType, template.getNoOfParallelJobs() });
new Object[]{vmname, osType, template.getNoOfParallelJobs()});
AzureVMCloud azureCloud = template.getAzureCloud();
@ -498,8 +501,10 @@ public class AzureVMManagementServiceDelegate {
}
/**
* Gets a map of available locations mapping display name -> name (usable in template)
* @return
* Gets a map of available locations mapping display name -> name (usable in
* template)
*
* @return
*/
private static Map<String, String> getAvailableLocationsStandard() {
final Map<String, String> locations = new HashMap<String, String>();
@ -522,55 +527,56 @@ public class AzureVMManagementServiceDelegate {
locations.put("West India", "westindia");
return locations;
}
private static Map<String, String> getAvailableLocationsChina() {
final Map<String, String> locations = new HashMap<String, String>();
locations.put("China North", "chinanorth");
locations.put("China East", "chinaeast");
return locations;
}
private static Map<String, String> getAvailableLocationsAll() {
final Map<String, String> locations = new HashMap<String, String>();
locations.putAll(getAvailableLocationsStandard());
locations.putAll(getAvailableLocationsChina());
return locations;
}
/**
* Creates a map containing location -> vm role size list.
* This is hard coded and should be removed eventually once a transition to
* the 1.0.0 SDK is made
* @return New map
* Creates a map containing location -> vm role size list. This is hard
* coded and should be removed eventually once a transition to the 1.0.0 SDK
* is made
*
* @return New map
*/
private static Map<String, List<String>> getAvailableRoleSizes() {
final Map<String, List<String>> sizes = new HashMap<String, List<String>>();
sizes.put("East US", Arrays.asList(new String[] {"A10","A11","A5","A6","A7","A8","A9","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS1_v2","Standard_DS11","Standard_DS11_v2","Standard_DS12","Standard_DS12_v2","Standard_DS13","Standard_DS13_v2","Standard_DS14","Standard_DS14_v2","Standard_DS2","Standard_DS2_v2","Standard_DS3","Standard_DS3_v2","Standard_DS4","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s"}));
sizes.put("West US", Arrays.asList(new String[] {"A10","A11","A5","A6","A7","A8","A9","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS1_v2","Standard_DS11","Standard_DS11_v2","Standard_DS12","Standard_DS12_v2","Standard_DS13","Standard_DS13_v2","Standard_DS14","Standard_DS14_v2","Standard_DS2","Standard_DS2_v2","Standard_DS3","Standard_DS3_v2","Standard_DS4","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s","Standard_G1","Standard_G2","Standard_G3","Standard_G4","Standard_G5","Standard_GS1","Standard_GS2","Standard_GS3","Standard_GS4","Standard_GS5"}));
sizes.put("South Central US", Arrays.asList(new String[] {"A10","A11","A5","A6","A7","A8","A9","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS1_v2","Standard_DS11","Standard_DS11_v2","Standard_DS12","Standard_DS12_v2","Standard_DS13","Standard_DS13_v2","Standard_DS14","Standard_DS14_v2","Standard_DS2","Standard_DS2_v2","Standard_DS3","Standard_DS3_v2","Standard_DS4","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s"}));
sizes.put("Central US", Arrays.asList(new String[] {"A5","A6","A7","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS1_v2","Standard_DS11","Standard_DS11_v2","Standard_DS12","Standard_DS12_v2","Standard_DS13","Standard_DS13_v2","Standard_DS14","Standard_DS14_v2","Standard_DS2","Standard_DS2_v2","Standard_DS3","Standard_DS3_v2","Standard_DS4","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s"}));
sizes.put("North Central US", Arrays.asList(new String[] {"A10","A11","A5","A6","A7","A8","A9","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1_v2","Standard_DS11_v2","Standard_DS12_v2","Standard_DS13_v2","Standard_DS14_v2","Standard_DS2_v2","Standard_DS3_v2","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s"}));
sizes.put("East US 2", Arrays.asList(new String[] {"A5","A6","A7","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS1_v2","Standard_DS11","Standard_DS11_v2","Standard_DS12","Standard_DS12_v2","Standard_DS13","Standard_DS13_v2","Standard_DS14","Standard_DS14_v2","Standard_DS2","Standard_DS2_v2","Standard_DS3","Standard_DS3_v2","Standard_DS4","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s","Standard_G1","Standard_G2","Standard_G3","Standard_G4","Standard_G5","Standard_GS1","Standard_GS2","Standard_GS3","Standard_GS4","Standard_GS5"}));
sizes.put("North Europe", Arrays.asList(new String[] {"A10","A11","A5","A6","A7","A8","A9","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS1_v2","Standard_DS11","Standard_DS11_v2","Standard_DS12","Standard_DS12_v2","Standard_DS13","Standard_DS13_v2","Standard_DS14","Standard_DS14_v2","Standard_DS2","Standard_DS2_v2","Standard_DS3","Standard_DS3_v2","Standard_DS4","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s"}));
sizes.put("West Europe", Arrays.asList(new String[] {"A10","A11","A5","A6","A7","A8","A9","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS1_v2","Standard_DS11","Standard_DS11_v2","Standard_DS12","Standard_DS12_v2","Standard_DS13","Standard_DS13_v2","Standard_DS14","Standard_DS14_v2","Standard_DS2","Standard_DS2_v2","Standard_DS3","Standard_DS3_v2","Standard_DS4","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s","Standard_G1","Standard_G2","Standard_G3","Standard_G4","Standard_G5","Standard_GS1","Standard_GS2","Standard_GS3","Standard_GS4","Standard_GS5"}));
sizes.put("Southeast Asia", Arrays.asList(new String[] {"A5","A6","A7","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS1_v2","Standard_DS11","Standard_DS11_v2","Standard_DS12","Standard_DS12_v2","Standard_DS13","Standard_DS13_v2","Standard_DS14","Standard_DS14_v2","Standard_DS2","Standard_DS2_v2","Standard_DS3","Standard_DS3_v2","Standard_DS4","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s","Standard_G1","Standard_G2","Standard_G3","Standard_G4","Standard_G5","Standard_GS1","Standard_GS2","Standard_GS3","Standard_GS4","Standard_GS5"}));
sizes.put("East Asia", Arrays.asList(new String[] {"A5","A6","A7","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS11","Standard_DS12","Standard_DS13","Standard_DS14","Standard_DS2","Standard_DS3","Standard_DS4","Standard_F1","Standard_F16","Standard_F2","Standard_F4","Standard_F8"}));
sizes.put("Japan West", Arrays.asList(new String[] {"A5","A6","A7","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS1_v2","Standard_DS11","Standard_DS11_v2","Standard_DS12","Standard_DS12_v2","Standard_DS13","Standard_DS13_v2","Standard_DS14","Standard_DS14_v2","Standard_DS2","Standard_DS2_v2","Standard_DS3","Standard_DS3_v2","Standard_DS4","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s"}));
sizes.put("Japan East", Arrays.asList(new String[] {"A10","A11","A5","A6","A7","A8","A9","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS1_v2","Standard_DS11","Standard_DS11_v2","Standard_DS12","Standard_DS12_v2","Standard_DS13","Standard_DS13_v2","Standard_DS14","Standard_DS14_v2","Standard_DS2","Standard_DS2_v2","Standard_DS3","Standard_DS3_v2","Standard_DS4","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s"}));
sizes.put("Brazil South", Arrays.asList(new String[] {"A5","A6","A7","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1_v2","Standard_DS11_v2","Standard_DS12_v2","Standard_DS13_v2","Standard_DS14_v2","Standard_DS2_v2","Standard_DS3_v2","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s"}));
sizes.put("Australia Southeast", Arrays.asList(new String[] {"A5","A6","A7","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS1_v2","Standard_DS11","Standard_DS11_v2","Standard_DS12","Standard_DS12_v2","Standard_DS13","Standard_DS13_v2","Standard_DS14","Standard_DS14_v2","Standard_DS2","Standard_DS2_v2","Standard_DS3","Standard_DS3_v2","Standard_DS4","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s"}));
sizes.put("Australia East", Arrays.asList(new String[] {"A5","A6","A7","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS1_v2","Standard_DS11","Standard_DS11_v2","Standard_DS12","Standard_DS12_v2","Standard_DS13","Standard_DS13_v2","Standard_DS14","Standard_DS14_v2","Standard_DS2","Standard_DS2_v2","Standard_DS3","Standard_DS3_v2","Standard_DS4","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s","Standard_G1","Standard_G2","Standard_G3","Standard_G4","Standard_G5","Standard_GS1","Standard_GS2","Standard_GS3","Standard_GS4","Standard_GS5"}));
sizes.put("Central India", Arrays.asList(new String[] {"A5","A6","A7","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1_v2","Standard_D11_v2","Standard_D12_v2","Standard_D13_v2","Standard_D14_v2","Standard_D2_v2","Standard_D3_v2","Standard_D4_v2","Standard_D5_v2","Standard_DS1_v2","Standard_DS11_v2","Standard_DS12_v2","Standard_DS13_v2","Standard_DS14_v2","Standard_DS2_v2","Standard_DS3_v2","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s"}));
sizes.put("South India", Arrays.asList(new String[] {"A5","A6","A7","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1_v2","Standard_D11_v2","Standard_D12_v2","Standard_D13_v2","Standard_D14_v2","Standard_D2_v2","Standard_D3_v2","Standard_D4_v2","Standard_D5_v2","Standard_DS1_v2","Standard_DS11_v2","Standard_DS12_v2","Standard_DS13_v2","Standard_DS14_v2","Standard_DS2_v2","Standard_DS3_v2","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s"}));
sizes.put("West India", Arrays.asList(new String[] {"A5","A6","A7","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1_v2","Standard_D11_v2","Standard_D12_v2","Standard_D13_v2","Standard_D14_v2","Standard_D2_v2","Standard_D3_v2","Standard_D4_v2","Standard_D5_v2","Standard_F1","Standard_F16","Standard_F2","Standard_F4","Standard_F8"}));
sizes.put("East US", Arrays.asList(new String[]{"A10", "A11", "A5", "A6", "A7", "A8", "A9", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS1_v2", "Standard_DS11", "Standard_DS11_v2", "Standard_DS12", "Standard_DS12_v2", "Standard_DS13", "Standard_DS13_v2", "Standard_DS14", "Standard_DS14_v2", "Standard_DS2", "Standard_DS2_v2", "Standard_DS3", "Standard_DS3_v2", "Standard_DS4", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s"}));
sizes.put("West US", Arrays.asList(new String[]{"A10", "A11", "A5", "A6", "A7", "A8", "A9", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS1_v2", "Standard_DS11", "Standard_DS11_v2", "Standard_DS12", "Standard_DS12_v2", "Standard_DS13", "Standard_DS13_v2", "Standard_DS14", "Standard_DS14_v2", "Standard_DS2", "Standard_DS2_v2", "Standard_DS3", "Standard_DS3_v2", "Standard_DS4", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s", "Standard_G1", "Standard_G2", "Standard_G3", "Standard_G4", "Standard_G5", "Standard_GS1", "Standard_GS2", "Standard_GS3", "Standard_GS4", "Standard_GS5"}));
sizes.put("South Central US", Arrays.asList(new String[]{"A10", "A11", "A5", "A6", "A7", "A8", "A9", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS1_v2", "Standard_DS11", "Standard_DS11_v2", "Standard_DS12", "Standard_DS12_v2", "Standard_DS13", "Standard_DS13_v2", "Standard_DS14", "Standard_DS14_v2", "Standard_DS2", "Standard_DS2_v2", "Standard_DS3", "Standard_DS3_v2", "Standard_DS4", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s"}));
sizes.put("Central US", Arrays.asList(new String[]{"A5", "A6", "A7", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS1_v2", "Standard_DS11", "Standard_DS11_v2", "Standard_DS12", "Standard_DS12_v2", "Standard_DS13", "Standard_DS13_v2", "Standard_DS14", "Standard_DS14_v2", "Standard_DS2", "Standard_DS2_v2", "Standard_DS3", "Standard_DS3_v2", "Standard_DS4", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s"}));
sizes.put("North Central US", Arrays.asList(new String[]{"A10", "A11", "A5", "A6", "A7", "A8", "A9", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1_v2", "Standard_DS11_v2", "Standard_DS12_v2", "Standard_DS13_v2", "Standard_DS14_v2", "Standard_DS2_v2", "Standard_DS3_v2", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s"}));
sizes.put("East US 2", Arrays.asList(new String[]{"A5", "A6", "A7", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS1_v2", "Standard_DS11", "Standard_DS11_v2", "Standard_DS12", "Standard_DS12_v2", "Standard_DS13", "Standard_DS13_v2", "Standard_DS14", "Standard_DS14_v2", "Standard_DS2", "Standard_DS2_v2", "Standard_DS3", "Standard_DS3_v2", "Standard_DS4", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s", "Standard_G1", "Standard_G2", "Standard_G3", "Standard_G4", "Standard_G5", "Standard_GS1", "Standard_GS2", "Standard_GS3", "Standard_GS4", "Standard_GS5"}));
sizes.put("North Europe", Arrays.asList(new String[]{"A10", "A11", "A5", "A6", "A7", "A8", "A9", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS1_v2", "Standard_DS11", "Standard_DS11_v2", "Standard_DS12", "Standard_DS12_v2", "Standard_DS13", "Standard_DS13_v2", "Standard_DS14", "Standard_DS14_v2", "Standard_DS2", "Standard_DS2_v2", "Standard_DS3", "Standard_DS3_v2", "Standard_DS4", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s"}));
sizes.put("West Europe", Arrays.asList(new String[]{"A10", "A11", "A5", "A6", "A7", "A8", "A9", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS1_v2", "Standard_DS11", "Standard_DS11_v2", "Standard_DS12", "Standard_DS12_v2", "Standard_DS13", "Standard_DS13_v2", "Standard_DS14", "Standard_DS14_v2", "Standard_DS2", "Standard_DS2_v2", "Standard_DS3", "Standard_DS3_v2", "Standard_DS4", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s", "Standard_G1", "Standard_G2", "Standard_G3", "Standard_G4", "Standard_G5", "Standard_GS1", "Standard_GS2", "Standard_GS3", "Standard_GS4", "Standard_GS5"}));
sizes.put("Southeast Asia", Arrays.asList(new String[]{"A5", "A6", "A7", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS1_v2", "Standard_DS11", "Standard_DS11_v2", "Standard_DS12", "Standard_DS12_v2", "Standard_DS13", "Standard_DS13_v2", "Standard_DS14", "Standard_DS14_v2", "Standard_DS2", "Standard_DS2_v2", "Standard_DS3", "Standard_DS3_v2", "Standard_DS4", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s", "Standard_G1", "Standard_G2", "Standard_G3", "Standard_G4", "Standard_G5", "Standard_GS1", "Standard_GS2", "Standard_GS3", "Standard_GS4", "Standard_GS5"}));
sizes.put("East Asia", Arrays.asList(new String[]{"A5", "A6", "A7", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS11", "Standard_DS12", "Standard_DS13", "Standard_DS14", "Standard_DS2", "Standard_DS3", "Standard_DS4", "Standard_F1", "Standard_F16", "Standard_F2", "Standard_F4", "Standard_F8"}));
sizes.put("Japan West", Arrays.asList(new String[]{"A5", "A6", "A7", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS1_v2", "Standard_DS11", "Standard_DS11_v2", "Standard_DS12", "Standard_DS12_v2", "Standard_DS13", "Standard_DS13_v2", "Standard_DS14", "Standard_DS14_v2", "Standard_DS2", "Standard_DS2_v2", "Standard_DS3", "Standard_DS3_v2", "Standard_DS4", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s"}));
sizes.put("Japan East", Arrays.asList(new String[]{"A10", "A11", "A5", "A6", "A7", "A8", "A9", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS1_v2", "Standard_DS11", "Standard_DS11_v2", "Standard_DS12", "Standard_DS12_v2", "Standard_DS13", "Standard_DS13_v2", "Standard_DS14", "Standard_DS14_v2", "Standard_DS2", "Standard_DS2_v2", "Standard_DS3", "Standard_DS3_v2", "Standard_DS4", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s"}));
sizes.put("Brazil South", Arrays.asList(new String[]{"A5", "A6", "A7", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1_v2", "Standard_DS11_v2", "Standard_DS12_v2", "Standard_DS13_v2", "Standard_DS14_v2", "Standard_DS2_v2", "Standard_DS3_v2", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s"}));
sizes.put("Australia Southeast", Arrays.asList(new String[]{"A5", "A6", "A7", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS1_v2", "Standard_DS11", "Standard_DS11_v2", "Standard_DS12", "Standard_DS12_v2", "Standard_DS13", "Standard_DS13_v2", "Standard_DS14", "Standard_DS14_v2", "Standard_DS2", "Standard_DS2_v2", "Standard_DS3", "Standard_DS3_v2", "Standard_DS4", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s"}));
sizes.put("Australia East", Arrays.asList(new String[]{"A5", "A6", "A7", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS1_v2", "Standard_DS11", "Standard_DS11_v2", "Standard_DS12", "Standard_DS12_v2", "Standard_DS13", "Standard_DS13_v2", "Standard_DS14", "Standard_DS14_v2", "Standard_DS2", "Standard_DS2_v2", "Standard_DS3", "Standard_DS3_v2", "Standard_DS4", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s", "Standard_G1", "Standard_G2", "Standard_G3", "Standard_G4", "Standard_G5", "Standard_GS1", "Standard_GS2", "Standard_GS3", "Standard_GS4", "Standard_GS5"}));
sizes.put("Central India", Arrays.asList(new String[]{"A5", "A6", "A7", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1_v2", "Standard_D11_v2", "Standard_D12_v2", "Standard_D13_v2", "Standard_D14_v2", "Standard_D2_v2", "Standard_D3_v2", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1_v2", "Standard_DS11_v2", "Standard_DS12_v2", "Standard_DS13_v2", "Standard_DS14_v2", "Standard_DS2_v2", "Standard_DS3_v2", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s"}));
sizes.put("South India", Arrays.asList(new String[]{"A5", "A6", "A7", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1_v2", "Standard_D11_v2", "Standard_D12_v2", "Standard_D13_v2", "Standard_D14_v2", "Standard_D2_v2", "Standard_D3_v2", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1_v2", "Standard_DS11_v2", "Standard_DS12_v2", "Standard_DS13_v2", "Standard_DS14_v2", "Standard_DS2_v2", "Standard_DS3_v2", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s"}));
sizes.put("West India", Arrays.asList(new String[]{"A5", "A6", "A7", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1_v2", "Standard_D11_v2", "Standard_D12_v2", "Standard_D13_v2", "Standard_D14_v2", "Standard_D2_v2", "Standard_D3_v2", "Standard_D4_v2", "Standard_D5_v2", "Standard_F1", "Standard_F16", "Standard_F2", "Standard_F4", "Standard_F8"}));
// China sizes, may not be exact
sizes.put("China North", Arrays.asList(new String[] {"A5","A6","A7","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS1_v2","Standard_DS11","Standard_DS11_v2","Standard_DS12","Standard_DS12_v2","Standard_DS13","Standard_DS13_v2","Standard_DS14","Standard_DS14_v2","Standard_DS2","Standard_DS2_v2","Standard_DS3","Standard_DS3_v2","Standard_DS4","Standard_DS4_v2","Standard_DS5_v2","Standard_F1","Standard_F16","Standard_F16s","Standard_F1s","Standard_F2","Standard_F2s","Standard_F4","Standard_F4s","Standard_F8","Standard_F8s","Standard_G1","Standard_G2","Standard_G3","Standard_G4","Standard_G5","Standard_GS1","Standard_GS2","Standard_GS3","Standard_GS4","Standard_GS5"}));
sizes.put("China East", Arrays.asList(new String[] {"A5","A6","A7","Basic_A0","Basic_A1","Basic_A2","Basic_A3","Basic_A4","ExtraLarge","ExtraSmall","Large","Medium","Small","Standard_D1","Standard_D1_v2","Standard_D11","Standard_D11_v2","Standard_D12","Standard_D12_v2","Standard_D13","Standard_D13_v2","Standard_D14","Standard_D14_v2","Standard_D2","Standard_D2_v2","Standard_D3","Standard_D3_v2","Standard_D4","Standard_D4_v2","Standard_D5_v2","Standard_DS1","Standard_DS11","Standard_DS12","Standard_DS13","Standard_DS14","Standard_DS2","Standard_DS3","Standard_DS4","Standard_F1","Standard_F16","Standard_F2","Standard_F4","Standard_F8"}));
sizes.put("China North", Arrays.asList(new String[]{"A5", "A6", "A7", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS1_v2", "Standard_DS11", "Standard_DS11_v2", "Standard_DS12", "Standard_DS12_v2", "Standard_DS13", "Standard_DS13_v2", "Standard_DS14", "Standard_DS14_v2", "Standard_DS2", "Standard_DS2_v2", "Standard_DS3", "Standard_DS3_v2", "Standard_DS4", "Standard_DS4_v2", "Standard_DS5_v2", "Standard_F1", "Standard_F16", "Standard_F16s", "Standard_F1s", "Standard_F2", "Standard_F2s", "Standard_F4", "Standard_F4s", "Standard_F8", "Standard_F8s", "Standard_G1", "Standard_G2", "Standard_G3", "Standard_G4", "Standard_G5", "Standard_GS1", "Standard_GS2", "Standard_GS3", "Standard_GS4", "Standard_GS5"}));
sizes.put("China East", Arrays.asList(new String[]{"A5", "A6", "A7", "Basic_A0", "Basic_A1", "Basic_A2", "Basic_A3", "Basic_A4", "ExtraLarge", "ExtraSmall", "Large", "Medium", "Small", "Standard_D1", "Standard_D1_v2", "Standard_D11", "Standard_D11_v2", "Standard_D12", "Standard_D12_v2", "Standard_D13", "Standard_D13_v2", "Standard_D14", "Standard_D14_v2", "Standard_D2", "Standard_D2_v2", "Standard_D3", "Standard_D3_v2", "Standard_D4", "Standard_D4_v2", "Standard_D5_v2", "Standard_DS1", "Standard_DS11", "Standard_DS12", "Standard_DS13", "Standard_DS14", "Standard_DS2", "Standard_DS3", "Standard_DS4", "Standard_F1", "Standard_F16", "Standard_F2", "Standard_F4", "Standard_F8"}));
return sizes;
}
/**
* Gets map of Azure datacenter locations which supports Persistent VM role.
* Today this is hardcoded pulling from the array, because the old form of
@ -582,11 +588,11 @@ public class AzureVMManagementServiceDelegate {
}
return AVAILABLE_LOCATIONS_STD;
}
/**
* Gets list of virtual machine sizes.
* Currently hardcoded because the old vm size API does not support
* the new method of authentication
* Gets list of virtual machine sizes. Currently hardcoded because the old
* vm size API does not support the new method of authentication
*
* @param location Location to obtain VM sizes for
*/
public static List<String> getVMSizes(final String location) {
@ -623,12 +629,14 @@ public class AzureVMManagementServiceDelegate {
// Load up the configuration now and do a live verification
Configuration config = ServiceDelegateHelper.loadConfiguration(
subscriptionId, clientId, clientSecret, oauth2TokenEndpoint, serviceManagementURL);
if (!resourceGroupName.matches(Constants.DEFAULT_RESOURCE_GROUP_PATTERN)) {
return Messages.Azure_GC_Template_ResourceGroupName_Err();
}
if (!verifyConfiguration(config, resourceGroupName).equals(Constants.OP_SUCCESS)) {
return Messages.Azure_GC_Template_Val_Profile_Err();
}
}
catch (Exception e) {
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Error validating profile", e);
return Messages.Azure_GC_Template_Val_Profile_Err();
}
@ -637,13 +645,13 @@ public class AzureVMManagementServiceDelegate {
}
public static String verifyConfiguration(final Configuration config, final String resourceGroupName) {
Callable<String> task = new Callable<String>() {
@Override
public String call() throws Exception {
ServiceDelegateHelper.getStorageManagementClient(config).getStorageAccountsOperations().
checkNameAvailability("CI_SYSTEM");
checkNameAvailability("CI_SYSTEM");
return Constants.OP_SUCCESS;
}
};
@ -686,14 +694,15 @@ public class AzureVMManagementServiceDelegate {
}
LOGGER.log(Level.INFO, "AzureVMManagementServiceDelegate: getVirtualMachineStatus:\n\tPowerState: {0}\n\tProvisioning: {1}",
new Object[] { powerstatus, provisioning });
new Object[]{powerstatus, provisioning});
return "succeeded".equalsIgnoreCase(provisioning)
? powerstatus.toUpperCase() : Constants.PROVISIONING_OR_DEPROVISIONING_VM_STATUS;
}
/**
* Checks if VM is reachable and in a valid state to connect (or getting ready to do so).
* Checks if VM is reachable and in a valid state to connect (or getting
* ready to do so).
*
* @param agent
* @return
@ -704,16 +713,16 @@ public class AzureVMManagementServiceDelegate {
String status = getVirtualMachineStatus(config, agent.getNodeName(), agent.getResourceGroupName());
LOGGER.log(Level.INFO, "AzureVMManagementServiceDelegate: isVMAliveOrHealthy: status {0}", status);
return !(Constants.PROVISIONING_OR_DEPROVISIONING_VM_STATUS.equalsIgnoreCase(status)
|| Constants.STOPPING_VM_STATUS.equalsIgnoreCase(status)
|| Constants.STOPPED_VM_STATUS.equalsIgnoreCase(status)
|| Constants.DEALLOCATED_VM_STATUS.equalsIgnoreCase(status));
|| Constants.STOPPING_VM_STATUS.equalsIgnoreCase(status)
|| Constants.STOPPED_VM_STATUS.equalsIgnoreCase(status)
|| Constants.DEALLOCATED_VM_STATUS.equalsIgnoreCase(status));
}
/**
* Retrieves count of virtual machine in a azure subscription. This count
* is based off of the VMs that the current credential set has access to. It also
* does not deal with the classic, model. So keep this in mind.
*
* Retrieves count of virtual machine in a azure subscription. This count is
* based off of the VMs that the current credential set has access to. It
* also does not deal with the classic, model. So keep this in mind.
*
* @param config Subscription configuration
* @return Total VM count
* @throws Exception
@ -747,15 +756,14 @@ public class AzureVMManagementServiceDelegate {
*/
public static void shutdownVirtualMachine(final AzureVMAgent agent) {
LOGGER.log(Level.INFO, "AzureVMManagementServiceDelegate: shutdownVirtualMachine: called for {0}",
agent.getNodeName() );
agent.getNodeName());
try {
ServiceDelegateHelper.getComputeManagementClient(agent).
getVirtualMachinesOperations().powerOff(agent.getResourceGroupName(), agent.getNodeName());
}
catch (Exception e) {
getVirtualMachinesOperations().powerOff(agent.getResourceGroupName(), agent.getNodeName());
} catch (Exception e) {
LOGGER.log(Level.INFO, "AzureVMManagementServiceDelegate: provision: could not terminate or shutdown {0}, {1}",
new Object[] {agent.getNodeName(), e});
new Object[]{agent.getNodeName(), e});
}
}
@ -773,12 +781,13 @@ public class AzureVMManagementServiceDelegate {
/**
* Terminates a virtual machine
*
* @param config Azure configuration
* @param vmName VM name
* @param resourceGroupName Resource group containing the VM
* @throws Exception
* @throws Exception
*/
public static void terminateVirtualMachine(final Configuration config, final String vmName,
public static void terminateVirtualMachine(final Configuration config, final String vmName,
final String resourceGroupName) throws Exception {
try {
try {
@ -786,34 +795,34 @@ public class AzureVMManagementServiceDelegate {
final ComputeManagementClient client = ServiceDelegateHelper.getComputeManagementClient(config);
List<URI> diskUrisToRemove = new ArrayList<URI>();
StorageProfile storageProfile =
client.getVirtualMachinesOperations().get(resourceGroupName, vmName).getVirtualMachine().getStorageProfile();
StorageProfile storageProfile
= client.getVirtualMachinesOperations().get(resourceGroupName, vmName).getVirtualMachine().getStorageProfile();
// Remove the OS disks
diskUrisToRemove.add(new URI(storageProfile.getOSDisk().getVirtualHardDisk().getUri()));
// TODO: Remove data disks or add option to do so?
// Remove the VM
LOGGER.log(Level.INFO, "AzureVMManagementServiceDelegate: terminateVirtualMachine: Removing virtual machine {0}", vmName);
client.getVirtualMachinesOperations().delete(resourceGroupName, vmName);
// Now remove the disks
for (URI diskUri : diskUrisToRemove) {
// Obtain container, storage account, and blob name
String storageAccountName = diskUri.getHost().split("\\.")[0];
String containerName = PathUtility.getContainerNameFromUri(diskUri, false);
String blobName = PathUtility.getBlobNameFromURI(diskUri, false);
LOGGER.log(Level.INFO, "AzureVMManagementServiceDelegate: terminateVirtualMachine: Removing disk blob {0}, in container {1} of storage account {2}",
new Object [] { blobName, containerName, storageAccountName } );
LOGGER.log(Level.INFO, "AzureVMManagementServiceDelegate: terminateVirtualMachine: Removing disk blob {0}, in container {1} of storage account {2}",
new Object[]{blobName, containerName, storageAccountName});
final StorageManagementClient storageClient = ServiceDelegateHelper.getStorageManagementClient(config);
StorageAccountKeys storageKeys =
storageClient.getStorageAccountsOperations().listKeys(resourceGroupName, storageAccountName).getStorageAccountKeys();
StorageAccountKeys storageKeys
= storageClient.getStorageAccountsOperations().listKeys(resourceGroupName, storageAccountName).getStorageAccountKeys();
URI blobURI = storageClient.getStorageAccountsOperations().getProperties(resourceGroupName, storageAccountName).getStorageAccount().getPrimaryEndpoints().getBlob();
CloudBlobContainer container = StorageServiceDelegate.getBlobContainerReference(
storageAccountName, storageKeys.getKey1(), blobURI.toString(), containerName);
storageAccountName, storageKeys.getKey1(), blobURI.toString(), containerName);
container.getBlockBlobReference(blobName).deleteIfExists();
}
// Also remove the init script (if it exists)
}
} catch (ExecutionException ee) {
@ -852,16 +861,17 @@ public class AzureVMManagementServiceDelegate {
}
/**
* Remove the IP name
* Remove the IP name
*
* @param config
* @param resourceGroupName
* @param vmName
* @throws AzureCloudException
* We probably should record and pass in NIC/IP names.
* Also, if we go away from 1 public IP address per system, then we will need to update this.
*
* @throws AzureCloudException We probably should record and pass in NIC/IP
* names. Also, if we go away from 1 public IP address per system, then we
* will need to update this.
*
*/
private static void removeIPName(final Configuration config,
private static void removeIPName(final Configuration config,
final String resourceGroupName, final String vmName) throws AzureCloudException {
final NetworkResourceProviderClient client = ServiceDelegateHelper.getNetworkManagementClient(config);
@ -926,7 +936,7 @@ public class AzureVMManagementServiceDelegate {
} catch (Exception e) {
LOGGER.log(Level.INFO, "AzureVMManagementServiceDelegate: startVirtualMachine: got exception while "
+ "starting VM {0}. Will retry again after 30 seconds. Current retry count {1} / {2}\n",
new Object[] { agent.getNodeName(), retryCount, Constants.MAX_PROV_RETRIES });
new Object[]{agent.getNodeName(), retryCount, Constants.MAX_PROV_RETRIES});
if (retryCount > Constants.MAX_PROV_RETRIES) {
throw e;
} else {
@ -965,17 +975,18 @@ public class AzureVMManagementServiceDelegate {
}
return null;
}
/**
* Gets a final location name from a display name location.
*
* @param location
* @return
* @return
*/
private static String getLocationName(String location) {
if (AVAILABLE_LOCATIONS_ALL.containsKey(location)) {
return AVAILABLE_LOCATIONS_ALL.get(location);
}
return null;
}
@ -1043,7 +1054,7 @@ public class AzureVMManagementServiceDelegate {
List<String> errors = new ArrayList<String>();
Configuration config = null;
// Load configuration
try {
config = ServiceDelegateHelper.loadConfiguration(
@ -1051,14 +1062,13 @@ public class AzureVMManagementServiceDelegate {
String validationResult;
// Verify basic info about the template
//Verify number of parallel jobs
validationResult = verifyNoOfExecutors(noOfParallelJobs);
addValidationResultIfFailed(validationResult, errors);
if (returnOnSingleError && errors.size() > 0) {
return errors;
}
validationResult = verifyRetentionTime(retentionTimeInMin);
addValidationResultIfFailed(validationResult, errors);
if (returnOnSingleError && errors.size() > 0) {
@ -1084,7 +1094,7 @@ public class AzureVMManagementServiceDelegate {
if (returnOnSingleError && errors.size() > 0) {
return errors;
}
validationResult = verifyLocation(location, serviceManagementURL);
addValidationResultIfFailed(validationResult, errors);
if (returnOnSingleError && errors.size() > 0) {
@ -1163,6 +1173,8 @@ public class AzureVMManagementServiceDelegate {
errors.add("Exception occured while validating temaplate " + executionException);
} catch (TimeoutException timeoutException) {
errors.add("Exception occured while validating temaplate " + timeoutException);
} catch (Exception others) {
errors.add(others.getMessage() + others);
}
}
} catch (InterruptedException interruptedException) {
@ -1251,7 +1263,7 @@ public class AzureVMManagementServiceDelegate {
// storage account is the same as the target storage account.
// The URI for he storage account should be https://<storageaccountname>.
// Parse that out and verify agaisnt the image storageAccountName
// Check that the image string is a URI by attempting to create
// a URI
final URI u;
@ -1272,8 +1284,7 @@ public class AzureVMManagementServiceDelegate {
return Messages.Azure_GC_Template_ImageURI_Not_Valid();
}
return Constants.OP_SUCCESS;
}
catch (Exception e) {
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Invalid virtual machine image", e);
return Messages.Azure_GC_Template_ImageURI_Not_Valid();
}
@ -1293,14 +1304,12 @@ public class AzureVMManagementServiceDelegate {
// to the empty string
if (imageVersion.equalsIgnoreCase("latest")) {
params.setVersion("");
}
else {
} else {
params.setVersion(imageVersion);
}
client.get(params);
}
catch (Exception e) {
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Invalid virtual machine image", e);
return Messages.Azure_GC_Template_ImageReference_Not_Valid(e.getMessage());
}
@ -1327,11 +1336,11 @@ public class AzureVMManagementServiceDelegate {
return Messages.Azure_GC_JVM_Option_Err();
}
}
/**
* Check the location. This location is the display name.
* @param location
* @return
* @param location
* @return
*/
private static String verifyLocation(final String location, final String serviceManagementURL) {
String locationName = getLocationName(location);
@ -1343,14 +1352,16 @@ public class AzureVMManagementServiceDelegate {
}
/**
* Verify the validity of the image parameters (does not verify actual values)
* Verify the validity of the image parameters (does not verify actual
* values)
*
* @param image
* @param osType
* @param imagePublisher
* @param imageOffer
* @param imageSku
* @param imageVersion
* @return
* @return
*/
private static String verifyImageParameters(
final String image,
@ -1369,8 +1380,7 @@ public class AzureVMManagementServiceDelegate {
Messages.Azure_GC_Template_ImageURI_Not_Valid();
}
return Constants.OP_SUCCESS;
}
else if (StringUtils.isNotBlank(imagePublisher)
} else if (StringUtils.isNotBlank(imagePublisher)
&& StringUtils.isNotBlank(imageOffer)
&& StringUtils.isNotBlank(imageSku)
&& StringUtils.isNotBlank(imageVersion)) {

View File

@ -136,4 +136,6 @@ public class Constants {
public static final String DEFAULT_VNET_NAME = "jenkinsarm-vnet";
public static final String DEFAULT_SUBNET_NAME = "jenkinsarm-snet";
public static final String DEFAULT_RESOURCE_GROUP_PATTERN = "^[a-zA-Z0-9][a-zA-Z\\-_0-9]{0,62}[a-zA-Z0-9]$";
}

View File

@ -13,6 +13,10 @@ Azure_GC_JVM_Option_Err=Error: Not a valid JVM Option. JVM options should start
Azure_GC_Template_Error_List=The following errors occurred while validating the template.
Azure_GC_Template_Val_Profile_Missing=The profile configuration is missing. Configure an Azure profile first.
Azure_GC_Template_ResourceGroupName_Err=Resource Group Name is invalid. Valid characters are Alphanumeric, underscore(_) and hyphen(-), length 2-64 \
\nAvoid having - or _ as the first or last character in name.
Azure_GC_Template_Deployment_Timeout_Err=Deployment Timeout value is invalid. Should be a positive integer and more than 1200 seconds.
Azure_GC_Template_Val_Profile_Err=Failed to validate the Azure profile. Verify the subscription Id, client Id and secret, OAUth 2.0 Token Endpoint and the URL information.
Azure_GC_Template_max_VM_Err=The current number of virtual machines in this Azure subscription is {0}, which is more than or equal to the default value {1} \
\n.Consider increasing Max Virtual Machines Limit value or delete existing virtual machines from your subscription.