def get_json_from_azure(**_): """Get the json of a subnet. :param ctx: The Cloudify ctx context. :return: The json of a subnet. :rtype: dictionary """ azure_config = utils.get_azure_config(ctx) subscription_id = azure_config[constants.SUBSCRIPTION_KEY] resource_group_name = azure_config[constants.RESOURCE_GROUP_KEY] api_version = constants.AZURE_API_VERSION_05_preview virtual_network_name = utils.get_target_property(ctx, constants.SUBNET_CONNECTED_TO_NETWORK, constants.VIRTUAL_NETWORK_KEY ) subnet_name = ctx.node.properties[constants.SUBNET_KEY] response = connection.AzureConnectionClient().azure_get( ctx, ('subscriptions/{}' + '/resourceGroups/{}' + '/providers/microsoft.network' + '/virtualNetworks/{}' + '/subnets/{}' + '?api-version={}').format( subscription_id, resource_group_name, virtual_network_name, subnet_name, api_version ) ) return response.json()
def delete(**_): """Delete a subnet. :param ctx: The Cloudify ctx context. :return: The status code of the REST request. :rtype: int """ utils.validate_node_property(constants.SUBNET_KEY, ctx.node.properties) azure_config = utils.get_azure_config(ctx) subscription_id = azure_config[constants.SUBSCRIPTION_KEY] resource_group_name = azure_config[constants.RESOURCE_GROUP_KEY] virtual_network_name = utils.get_target_property( ctx, constants.SUBNET_CONNECTED_TO_NETWORK, constants.VIRTUAL_NETWORK_KEY ) subnet_name = ctx.node.properties[constants.SUBNET_KEY] api_version = constants.AZURE_API_VERSION_05_preview deletable = ctx.node.properties[constants.DELETABLE_KEY] if deletable: ctx.logger.info('Propertie deletable set to True.') ctx.logger.info('Deleting subnet {}.'.format(subnet_name)) connect = connection.AzureConnectionClient() response = connect.azure_delete(ctx, ("subscriptions/{}/resourceGroups/{}/" + "providers/microsoft.network" + "/virtualNetworks/{}" + "/subnets/{}" + "?api-version={}").format( subscription_id, resource_group_name, virtual_network_name, subnet_name, api_version ) ) return response.status_code else: ctx.logger.info('Propertie deletable set to False.') ctx.logger.info('Not deleting subnet {}.'.format(subnet_name)) return 0
def get_provisioning_state(**_): """Get the provisioning state of a subnet. :param ctx: The Cloudify ctx context. :return: The provisioning state of a subnet. :rtype: string """ utils.validate_node_property(constants.SUBNET_KEY, ctx.node.properties) azure_config = utils.get_azure_config(ctx) subscription_id = azure_config[constants.SUBSCRIPTION_KEY] resource_group_name = azure_config[constants.RESOURCE_GROUP_KEY] virtual_network_name = utils.get_target_property( ctx, constants.SUBNET_CONNECTED_TO_NETWORK, constants.VIRTUAL_NETWORK_KEY ) subnet_name = ctx.node.properties[constants.SUBNET_KEY] api_version = constants.AZURE_API_VERSION_05_preview connect = connection.AzureConnectionClient() response = connect.azure_get(ctx, ("subscriptions/{}/resourceGroups/{}/" + "providers/microsoft.network" + "/virtualNetworks/{}" + "/subnets/{}" + "?api-version={}").format( subscription_id, resource_group_name, virtual_network_name, subnet_name, api_version ) ) jsonGet = response.json() status_storage = jsonGet['properties']['provisioningState'] return status_storage
def create(**_): """Create a subnet. :param ctx: The Cloudify ctx context. :return: The status code of the REST request. :rtype: int """ utils.validate_node_property(constants.SUBNET_KEY, ctx.node.properties) utils.validate_node_property(constants.SUBNET_ADDRESS_KEY, ctx.node.properties) azure_config = utils.get_azure_config(ctx) subscription_id = azure_config[constants.SUBSCRIPTION_KEY] resource_group_name = azure_config[constants.RESOURCE_GROUP_KEY] virtual_network_name = azure_config[constants.VIRTUAL_NETWORK_KEY] # virtual_network_name = utils.get_target_property( # ctx, # constants.SUBNET_CONNECTED_TO_NETWORK, # constants.VIRTUAL_NETWORK_KEY # ) subnet_name = ctx.node.properties[constants.SUBNET_KEY] subnet_address_prefix = ctx.node.properties[constants.SUBNET_ADDRESS_KEY] api_version = constants.AZURE_API_VERSION_05_preview # Place the network name in runtime_properties for relationships ctx.instance.runtime_properties[constants.VIRTUAL_NETWORK_KEY] = \ virtual_network_name ctx.instance.runtime_properties[constants.SUBNET_KEY] = \ subnet_name json = { "properties": { "addressPrefix": str(subnet_address_prefix) } } try: ctx.logger.debug("Search for an security_group") security_group_id = utils.get_target_property(ctx, constants.SUBNET_CONNECTED_TO_SECURITY_GROUP, constants.SECURITY_GROUP_ID_KEY ) ctx.logger.debug("security_group found: {}".format(security_group_id)) json['properties']['networkSecurityGroup']={'id': str(security_group_id)} except: ctx.logger.debug('Subnet not connected to a security group') pass ctx.logger.debug('JSON: {}'.format(json)) response = connection.AzureConnectionClient().azure_put(ctx, ("subscriptions/{}/resourceGroups/{}/" + "providers/microsoft.network" + "/virtualNetworks/{}" + "/subnets/{}" + "?api-version={}").format( subscription_id, resource_group_name, virtual_network_name, subnet_name, api_version ), json=json ) utils.wait_status(ctx, 'subnet') return response.status_code
def create(**_): """Create an instance. :param ctx: The Cloudify ctx context. """ utils.validate_node_property(constants.COMPUTE_KEY, ctx.node.properties) utils.validate_node_property(constants.FLAVOR_KEY, ctx.node.properties) utils.validate_node_property(constants.COMPUTE_USER_KEY, ctx.node.properties) utils.validate_node_property(constants.COMPUTE_PASSWORD_KEY, ctx.node.properties) azure_config = utils.get_azure_config(ctx) subscription_id = azure_config[constants.SUBSCRIPTION_KEY] location = azure_config[constants.LOCATION_KEY] resource_group_name = azure_config[constants.RESOURCE_GROUP_KEY] api_version = constants.AZURE_API_VERSION_06 vm_name = ctx.node.properties[constants.COMPUTE_KEY] vm_size = ctx.node.properties[constants.FLAVOR_KEY] ctx.instance.runtime_properties[constants.COMPUTE_KEY] = vm_name # check availability name if not is_available(ctx=ctx): ctx.logger.info('VM creation not possible, {} already exist' .format(vm_name) ) raise utils.WindowsAzureError(400, '{} already exist'.format(vm_name)) try: storage_account = utils.get_target_property(ctx, constants.INSTANCE_CONNECTED_TO_STORAGE_ACCOUNT, constants.STORAGE_ACCOUNT_KEY ) ctx.logger.debug("get storage account {} from relationship" .format(storage_account)) except: storage_account = azure_config[constants.STORAGE_ACCOUNT_KEY] ctx.logger.debug("get storage account {} from azure_config" .format(storage_account)) ctx.instance.runtime_properties[constants.STORAGE_ACCOUNT_KEY] = \ storage_account storage_profile = _create_storage_profile( vm_name, storage_account, ctx.node.properties[constants.IMAGE_KEY] ) os_profile = _create_os_profile( vm_name, ctx.node.properties[constants.COMPUTE_USER_KEY], ctx.node.properties[constants.COMPUTE_PASSWORD_KEY], ctx.node.properties ) nics = nic.get_ids(ctx) networkInterfaces_list = [] for _nic in nics: networkInterfaces_list.append({ 'properties': { 'primary': _nic['primary'] }, 'id': str(_nic['id']) }) ctx.logger.debug('networkInterfaces_list: {}'.format(networkInterfaces_list)) json = { 'id': ('/subscriptions/{}/resourceGroups/{}' + '/providers/Microsoft.Compute' + '/virtualMachines/{}').format(subscription_id, resource_group_name, vm_name ), 'name': str(vm_name), 'type': 'Microsoft.Compute/virtualMachines', constants.LOCATION_KEY: str(location), 'properties': { 'hardwareProfile': { 'vmSize': str(vm_size) }, 'osProfile': os_profile, 'storageProfile': storage_profile, 'networkProfile': { 'networkInterfaces': networkInterfaces_list } } } try: ctx.logger.debug("Search for an availability_set") availability_set_id = utils.get_target_property(ctx, constants.INSTANCE_CONTAINED_IN_AVAILABILITY_SET, constants.AVAILABILITY_ID_KEY ) ctx.logger.debug("availability_set found: {}" .format(availability_set_id)) json['properties']['availabilitySet']={'id': str(availability_set_id)} except: ctx.logger.debug('Instance not contained in an availability set') pass ctx.logger.debug('JSON: {}'.format(json)) ctx.logger.info('Beginning vm creation: {}'.format(ctx.instance.id)) try: cntn = connection.AzureConnectionClient() cntn.azure_put(ctx, ("subscriptions/{}/resourcegroups/{}/" + "providers/Microsoft.Compute" + "/virtualMachines/{}" + "?validating=true&api-version={}").format( subscription_id, resource_group_name, vm_name, api_version ), json=json ) utils.wait_status(ctx, 'instance') ctx.logger.info('VM has been started.') if re.search(r'manager', ctx.instance.id): # Get manager's public ip ctx.instance.runtime_properties['public_ip'] = \ nic._get_vm_ip(ctx, public=True) ctx.logger.info('Public IP manager: {}' .format( ctx.instance.runtime_properties['public_ip'] ) ) # Get agent's private ip ip = nic._get_vm_ip(ctx) ctx.logger.info( 'Machine is running at {}.'.format(ip) ) ctx.instance.runtime_properties['ip'] = ip except utils.WindowsAzureError as e: ctx.logger.info('Creation vm failed: {}'.format(ctx.instance.id)) ctx.logger.info('Error code: {}'.format(e.code)) ctx.logger.info('Error message: {}'.format(e.message)) raise utils.WindowsAzureError(e.code, e.message)
def create(**_): """Create a data disk. The datadisk can be created in the same storage account of the VM, or in its own storage account as defined in the blueprint. Within the storage account, the disk is contained in a container, its name follows this schema: <vm_name>-vhds. All disks are automatically suffixed with .vhd. :param ctx: The Cloudify ctx context. """ utils.validate_node_property(constants.DISKS_KEY, ctx.node.properties) azure_config = utils.get_azure_config(ctx) subscription_id = azure_config[constants.SUBSCRIPTION_KEY] resource_group_name = azure_config[constants.RESOURCE_GROUP_KEY] vm_name = utils.get_target_property( ctx, constants.DISK_ATTACH_TO_INSTANCE, constants.COMPUTE_KEY ) disks = ctx.node.properties[constants.DISKS_KEY] api_version = constants.AZURE_API_VERSION_06 try: storage_account = utils.get_target_property( ctx, constants.DISK_CONTAINED_IN_STORAGE_ACCOUNT, constants.STORAGE_ACCOUNT_KEY ) ctx.logger.info(("Use storage account {} in" + "DISK_CONTAINED_IN_STORAGE_ACCOUNT relationship"). format(storage_account) ) except NonRecoverableError: storage_account = utils.get_target_property( ctx, constants.DISK_ATTACH_TO_INSTANCE, constants.STORAGE_ACCOUNT_KEY ) ctx.logger.info(("Use storage account {}" + "in DISK_ATTACH_TO_INSTANCE relationship"). format(storage_account) ) # Place the vm name and storag account in runtime_properties # It is used to retrieve disks from the storage account ctx.instance.runtime_properties[constants.COMPUTE_KEY] = vm_name ctx.instance.runtime_properties[constants.STORAGE_ACCOUNT_KEY] = storage_account # Caching the list of datadisks existing in the storage account blobs_name = [] try: blobs_name = _get_datadisks_from_storage(ctx) except utils.WindowsAzureError as e: ctx.logger.debug('{} == 404: {}'.format(e.code, str(e.code) == '404')) if str(e.code) == '404' and 'ContainerNotFound' in e.message : ctx.logger.info('A container has not been found, it will be created.') else: raise e try: for disk in disks: json_VM = instance.get_json_from_azure() if 'dataDisks' in json_VM['properties']['storageProfile']: lun = len( json_VM['properties']['storageProfile']['dataDisks'] ) else: lun = 0 json_VM['properties']['storageProfile']['dataDisks'] = [] uri = "http://{}.blob.core.windows.net/{}-vhds/{}.vhd".format( storage_account, vm_name, disk['name'] ) if _is_datadisk_exists(blobs_name, disk['name']): ctx.logger.info(('Disk {} already exists,' + 'trying to attach it').format(disk['name'])) createOption = 'attach' else: ctx.logger.info('Disk {} does not exist,' + 'creating it.'.format(disk['name']) ) createOption = 'empty' json_disk = {"name": disk['name'], "diskSizeGB": disk['size'], "lun": lun, "vhd": { "uri" : uri }, "caching": disk['caching'], "createOption": createOption } json_VM['properties']['storageProfile']['dataDisks'].append( json_disk ) ctx.logger.info(('Attaching disk {} on lun {} ' + 'and machine {}.').format(disk['name'], lun, vm_name ) ) connection.AzureConnectionClient().azure_put( ctx, ("subscriptions/{}/resourcegroups/{}/" + "providers/Microsoft.Compute" + "/virtualMachines/{}" + "?validating=true&api-version={}").format( subscription_id, resource_group_name, vm_name, api_version ), json=json_VM ) utils.wait_status(ctx, 'instance', constants.SUCCEEDED) except utils.WindowsAzureError as e: # Do not interrup deployment if maximum number of disks has been reached if "The maximum number of data disks" in e.message: ctx.logger.warning("{}".format(e.message)) pass else: raise e except NonRecoverableError as e: ctx.logger.error( 'Machine has failed, check if disks do not already exist.' ) ctx.logger.info('Cancelling worflow.') raise e