def test_get_vcloud_config(self): # context.NODE_INSTANCE fake_ctx = self.generate_node_context( properties={'vcloud_config': { 'vdc': 'vdc_name' }}) fake_ctx._instance = mock.Mock() with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertEqual(vcloud_plugin_common.get_vcloud_config(), {'vdc': 'vdc_name'}) # context.RELATIONSHIP_INSTANCE fake_ctx = self.generate_relation_context() fake_ctx._source.node.properties = { 'vcloud_config': { 'vdc': 'vdc_name' } } with mock.patch('vcloud_plugin_common.ctx', fake_ctx): self.assertEqual(vcloud_plugin_common.get_vcloud_config(), {'vdc': 'vdc_name'}) # context.DEPLOYMENT fake_ctx = self.generate_node_context( properties={'vcloud_config': { 'vdc': 'vdc_name' }}) fake_ctx._source = None fake_ctx._instance = None with mock.patch('vcloud_plugin_common.ctx', fake_ctx): with self.assertRaises(cfy_exc.NonRecoverableError): vcloud_plugin_common.get_vcloud_config()
def test_get_vcloud_config(self): # context.NODE_INSTANCE fake_ctx = self.generate_node_context( properties={ 'vcloud_config': { 'vdc': 'vdc_name' } } ) fake_ctx._instance = mock.Mock() with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): self.assertEqual( vcloud_plugin_common.get_vcloud_config(), { 'vdc': 'vdc_name' } ) # context.RELATIONSHIP_INSTANCE fake_ctx = self.generate_relation_context() fake_ctx._source.node.properties = { 'vcloud_config': { 'vdc': 'vdc_name' } } with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): self.assertEqual( vcloud_plugin_common.get_vcloud_config(), { 'vdc': 'vdc_name' } ) # context.DEPLOYMENT fake_ctx = self.generate_node_context( properties={ 'vcloud_config': { 'vdc': 'vdc_name' } } ) fake_ctx._source = None fake_ctx._instance = None with mock.patch( 'vcloud_plugin_common.ctx', fake_ctx ): with self.assertRaises(cfy_exc.NonRecoverableError): vcloud_plugin_common.get_vcloud_config()
def _get_state(vca_client): vapp_name = get_vapp_name(ctx.instance.runtime_properties) config = get_vcloud_config() vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) nw_connections = _get_vm_network_connections(vapp) if len(nw_connections) == 0: ctx.logger.info("No networks connected") ctx.instance.runtime_properties['ip'] = None ctx.instance.runtime_properties['networks'] = {} return True management_network_name = _get_management_network_from_node() if not all([connection['ip'] for connection in nw_connections]): ctx.logger.info("Network configuration is not finished yet.") return False ctx.instance.runtime_properties['networks'] = { connection['network_name']: connection['ip'] for connection in nw_connections} for connection in nw_connections: if connection['network_name'] == management_network_name: ctx.logger.info("Management network ip address {0}" .format(connection['ip'])) ctx.instance.runtime_properties['ip'] = connection['ip'] return True return False
def create_volume(vca_client, **kwargs): """ create new volume, e.g.: { 'use_external_resource': False, 'volume': { 'name': 'some-other', 'size': 11 } } """ if ctx.node.properties.get('use_external_resource'): ctx.logger.info("External resource has been used") return vdc_name = get_vcloud_config()['vdc'] name = ctx.node.properties['volume']['name'] size = ctx.node.properties['volume']['size'] size_in_Mb = size * 1024 * 1024 ctx.logger.info("Create volume '{0}' to '{1}' with size {2}Mb.".format( name, vdc_name, size_in_Mb)) success, disk = vca_client.add_disk(vdc_name, name, size_in_Mb) if success: wait_for_task(vca_client, disk.get_Tasks()[0]) ctx.logger.info("Volume node '{0}' has been created".format(name)) else: raise cfy_exc.NonRecoverableError( "Disk creation error: {0}".format(disk))
def delete(vca_client, **kwargs): """ delete vcloud air network """ if ctx.node.properties['use_external_resource'] is True: del ctx.instance.runtime_properties[VCLOUD_NETWORK_NAME] ctx.logger.info("Network was not deleted - external resource has" " been used") return network_name = get_network_name(ctx.node.properties) if not _dhcp_operation(vca_client, network_name, DELETE_POOL): return set_retry(ctx) ctx.logger.info("Delete network '{0}'".format(network_name)) success, task = vca_client.delete_vdc_network( get_vcloud_config()['vdc'], network_name) if success: wait_for_task(vca_client, task) ctx.logger.info( "Network '{0}' has been successful deleted.".format(network_name)) else: if task and CANT_DELETE in task: ctx.logger.info("Network {} in use. Deleting the network skipped.". format(network_name)) return raise cfy_exc.NonRecoverableError( "Could not delete network '{0}': {1}".format(network_name, task))
def _get_state(vca_client): """ check network connection availability for host """ vapp_name = get_vapp_name(ctx.instance.runtime_properties) config = get_vcloud_config() vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) nw_connections = _get_vm_network_connections(vapp) if len(nw_connections) == 0: ctx.logger.info("No networks connected") ctx.instance.runtime_properties['ip'] = None ctx.instance.runtime_properties['networks'] = {} return True if not all([connection['ip'] for connection in nw_connections]): ctx.logger.info("Network configuration is not finished yet.") return False ctx.instance.runtime_properties['networks'] = { connection['network_name']: connection['ip'] for connection in nw_connections} for connection in nw_connections: if connection['is_primary']: ctx.logger.info("Primary network ip address '{0}' for" " network '{1}'." .format(connection['ip'], connection['network_name'])) ctx.instance.runtime_properties['ip'] = connection['ip'] return True return False
def _save_configuration(gateway, vca_client, operation, public_ip): """ save/refresh nat rules on gateway """ ctx.logger.info("Save NAT configuration.") success = save_gateway_configuration(gateway, vca_client, ctx) if not success: return False ctx.logger.info("NAT configuration has been saved.") if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = public_ip else: service_type = get_vcloud_config().get('service_type') if is_ondemand(service_type): if not ctx.target.node.properties['nat'].get(PUBLIC_IP): del_ondemand_public_ip( vca_client, gateway, ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) if PUBLIC_IP in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[PUBLIC_IP] if PORT_REPLACEMENT in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[PORT_REPLACEMENT] if SSH_PORT in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[SSH_PORT] if SSH_PUBLIC_IP in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[SSH_PUBLIC_IP] return True
def create(vca_client, **kwargs): """ create server by template, if external_resource set return without creation, e.g.: { 'management_network': '_management_network', 'server': { 'template': 'template', 'catalog': 'catalog', 'guest_customization': { 'pre_script': 'pre_script', 'post_script': 'post_script', 'public_keys': [{ 'key': True }] } } } """ config = get_vcloud_config() server = { 'name': ctx.instance.id, } server.update(ctx.node.properties.get('server', {})) transform_resource_name(server, ctx) if ctx.node.properties.get('use_external_resource'): res_id = ctx.node.properties['resource_id'] ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] = res_id ctx.logger.info("External resource {0} has been used".format(res_id)) else: _create(vca_client, config, server)
def create(vca_client, **kwargs): """create vdc""" config = get_vcloud_config() # Subscription service does not support vdc create, # you must use predefined vdc only if is_subscription(config['service_type']): raise cfy_exc.NonRecoverableError( "Unable create VDC on subscription service.") if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): # use external resource, does not create anything res_id = ctx.node.properties[RESOURCE_ID] ctx.instance.runtime_properties[VDC_NAME] = res_id vdc = vca_client.get_vdc(res_id) if not vdc: raise cfy_exc.NonRecoverableError( "Unable to find external VDC {0}." .format(res_id)) ctx.logger.info( "External resource {0} has been used".format(res_id)) else: # create new vdc vdc_name = ctx.node.properties.get('name') if not vdc_name: raise cfy_exc.NonRecoverableError("'vdc_name' not specified.") task = vca_client.create_vdc(vdc_name) if not task: raise cfy_exc.NonRecoverableError("Could not create VDC: {0}" .format(error_response(vca_client))) wait_for_task(vca_client, task)
def create(vca_client, **kwargs): """create vdc""" config = get_vcloud_config() # Subscription service does not support vdc create, # you must use predefined vdc only if is_subscription(config['service_type']): raise cfy_exc.NonRecoverableError( "Unable create VDC on subscription service.") if ctx.node.properties.get(USE_EXTERNAL_RESOURCE): # use external resource, does not create anything res_id = ctx.node.properties[RESOURCE_ID] ctx.instance.runtime_properties[VDC_NAME] = res_id vdc = vca_client.get_vdc(res_id) if not vdc: raise cfy_exc.NonRecoverableError( "Unable to find external VDC {0}.".format(res_id)) ctx.logger.info("External resource {0} has been used".format(res_id)) else: # create new vdc vdc_name = ctx.node.properties.get('name') if not vdc_name: raise cfy_exc.NonRecoverableError("'vdc_name' not specified.") task = vca_client.create_vdc(vdc_name) if not task: raise cfy_exc.NonRecoverableError( "Could not create VDC: {0}".format(error_response(vca_client))) wait_for_task(vca_client, task)
def start(vca_client, **kwargs): """ power on server and wait network connection availability for host """ if ctx.node.properties.get('use_external_resource'): ctx.logger.info('not starting server since an external server is ' 'being used') else: vapp_name = get_vapp_name(ctx.instance.runtime_properties) config = get_vcloud_config() vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) if _vapp_is_on(vapp) is False: ctx.logger.info("Power-on VApp {0}".format(vapp_name)) task = vapp.poweron() if not task: raise cfy_exc.NonRecoverableError( "Could not power-on vApp. {0}". format(error_response(vapp))) wait_for_task(vca_client, task) if not _get_state(vca_client): return ctx.operation.retry( message="Waiting for VM's configuration to complete", retry_after=5)
def _dhcp_operation(vca_client, network_name, operation): """ update dhcp setting for network """ dhcp_settings = ctx.node.properties["network"].get("dhcp") if dhcp_settings is None: return gateway_name = ctx.node.properties["network"]["edge_gateway"] gateway = vca_client.get_gateway(get_vcloud_config()["vdc"], gateway_name) if not gateway: raise cfy_exc.NonRecoverableError("Gateway {0} not found!".format(gateway_name)) if operation == ADD_POOL: ip = _split_adresses(dhcp_settings["dhcp_range"]) low_ip_address = check_ip(ip.start) hight_ip_address = check_ip(ip.end) default_lease = dhcp_settings.get("default_lease") max_lease = dhcp_settings.get("max_lease") gateway.add_dhcp_pool(network_name, low_ip_address, hight_ip_address, default_lease, max_lease) ctx.logger.info("DHCP rule successful created for network {0}".format(network_name)) if operation == DELETE_POOL: gateway.delete_dhcp_pool(network_name) ctx.logger.info("DHCP rule successful deleted for network {0}".format(network_name)) if not save_gateway_configuration(gateway, vca_client): return ctx.operation.retry(message="Waiting for gateway.", retry_after=10)
def create(vca_client, **kwargs): """ create server by template, if external_resource set return without creation, e.g.: { 'management_network': '_management_network', 'server': { 'template': 'template', 'catalog': 'catalog', 'guest_customization': { 'pre_script': 'pre_script', 'post_script': 'post_script', 'admin_password': '******', 'computer_name': 'computer' } } } """ config = get_vcloud_config() server = { 'name': ctx.instance.id, } server.update(ctx.node.properties.get('server', {})) transform_resource_name(server, ctx) if ctx.node.properties.get('use_external_resource'): res_id = ctx.node.properties['resource_id'] ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] = res_id ctx.logger.info( "External resource {0} has been used".format(res_id)) else: _create(vca_client, config, server)
def get_gateway(vca_client, gateway_name): gateway = vca_client.get_gateway(get_vcloud_config()['vdc'], gateway_name) if not gateway: raise cfy_exc.NonRecoverableError( "Gateway {0} not found".format(gateway_name)) return gateway
def create_volume(vca_client, **kwargs): """ create new volume, e.g.: { 'use_external_resource': False, 'volume': { 'name': 'some-other', 'size': 11 } } """ if ctx.node.properties.get('use_external_resource'): ctx.logger.info("External resource has been used") return vdc_name = get_vcloud_config()['vdc'] name = ctx.node.properties['volume']['name'] size = ctx.node.properties['volume']['size'] size_in_Mb = size * 1024 * 1024 success, disk = vca_client.add_disk(vdc_name, name, size_in_Mb) if success: wait_for_task(vca_client, disk.get_Tasks()[0]) ctx.logger.info("Volume node {} has been created".format(name)) else: raise cfy_exc.NonRecoverableError( "Disk creation error: {0}".format(disk))
def _save_configuration(gateway, vca_client, operation, public_ip): """ save/refresh nat rules on gateway """ ctx.logger.info("Save NAT configuration.") success = save_gateway_configuration(gateway, vca_client, ctx) if not success: return False ctx.logger.info("NAT configuration has been saved.") if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = public_ip else: service_type = get_vcloud_config().get('service_type') if is_ondemand(service_type): if not ctx.target.node.properties['nat'].get(PUBLIC_IP): del_ondemand_public_ip( vca_client, gateway, ctx.target.instance.runtime_properties[PUBLIC_IP], ctx ) if PUBLIC_IP in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[PUBLIC_IP] if PORT_REPLACEMENT in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[PORT_REPLACEMENT] if SSH_PORT in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[SSH_PORT] if SSH_PUBLIC_IP in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[SSH_PUBLIC_IP] return True
def _dhcp_operation(vca_client, network_name, operation): """ update dhcp setting for network """ dhcp_settings = ctx.node.properties['network'].get('dhcp') if dhcp_settings is None: return gateway_name = ctx.node.properties["network"]['edge_gateway'] gateway = vca_client.get_gateway(get_vcloud_config()['vdc'], gateway_name) if not gateway: raise cfy_exc.NonRecoverableError( "Gateway {0} not found!".format(gateway_name)) if operation == ADD_POOL: ip = _split_adresses(dhcp_settings['dhcp_range']) low_ip_address = check_ip(ip.start) hight_ip_address = check_ip(ip.end) default_lease = dhcp_settings.get('default_lease') max_lease = dhcp_settings.get('max_lease') gateway.add_dhcp_pool(network_name, low_ip_address, hight_ip_address, default_lease, max_lease) ctx.logger.info("DHCP rule successful created for network {0}".format( network_name)) if operation == DELETE_POOL: gateway.delete_dhcp_pool(network_name) ctx.logger.info("DHCP rule successful deleted for network {0}".format( network_name)) if not save_gateway_configuration(gateway, vca_client): return ctx.operation.retry(message='Waiting for gateway.', retry_after=10)
def start(vca_client, **kwargs): """ power on server and wait network connection availability for host """ if ctx.node.properties.get('use_external_resource'): ctx.logger.info('not starting server since an external server is ' 'being used') else: vapp_name = get_vapp_name(ctx.instance.runtime_properties) config = get_vcloud_config() vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) if _vapp_is_on(vapp) is False: ctx.logger.info("Power-on VApp {0}".format(vapp_name)) task = vapp.poweron() if not task: raise cfy_exc.NonRecoverableError( "Could not power-on vApp. {0}".format( error_response(vapp))) wait_for_task(vca_client, task) if not _get_state(vca_client): return ctx.operation.retry( message="Waiting for VM's configuration to complete", retry_after=5)
def _get_gateway_name(properties): security_group = properties.get('security_group') if security_group and 'edge_gateway' in security_group: getaway_name = security_group.get('edge_gateway') else: getaway_name = get_vcloud_config()['edge_gateway'] return getaway_name
def _get_state(vca_client): """ check network connection availability for host """ vapp_name = get_vapp_name(ctx.instance.runtime_properties) config = get_vcloud_config() vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) nw_connections = _get_vm_network_connections(vapp) if len(nw_connections) == 0: ctx.logger.info("No networks connected") ctx.instance.runtime_properties['ip'] = None ctx.instance.runtime_properties['networks'] = {} return True management_network_name = _get_management_network_from_node() if not all([connection['ip'] for connection in nw_connections]): ctx.logger.info("Network configuration is not finished yet.") return False ctx.instance.runtime_properties['networks'] = { connection['network_name']: connection['ip'] for connection in nw_connections } for connection in nw_connections: if connection['network_name'] == management_network_name: ctx.logger.info("Management network ip address {0}".format( connection['ip'])) ctx.instance.runtime_properties['ip'] = connection['ip'] return True return False
def get_vm_ip(vca_client, ctx, gateway): """ get ip assigned to current vm from connected primary network. """ try: vappName = get_vapp_name(ctx.source.instance.runtime_properties) vdc = vca_client.get_vdc(get_vcloud_config()['vdc']) vapp = vca_client.get_vapp(vdc, vappName) if not vapp: raise cfy_exc.NonRecoverableError( "Could not find vApp {0}".format(vappName)) vm_info = vapp.get_vms_network_info() # assume that we have 1 vm per vApp for connection in vm_info[0]: if connection['is_connected'] and connection['is_primary']: if is_network_routed(vca_client, connection['network_name'], gateway): return connection['ip'] else: raise cfy_exc.NonRecoverableError( "Primary network {0} not routed" .format(connection['network_name'])) raise cfy_exc.NonRecoverableError("No connected primary network") except IndexError: raise cfy_exc.NonRecoverableError("Could not get vm IP address")
def configure(vca_client, **kwargs): ctx.logger.info("Configure server") server = {'name': ctx.instance.id} server.update(ctx.node.properties.get('server', {})) vapp_name = server['name'] config = get_vcloud_config() custom = server.get(GUEST_CUSTOMIZATION, {}) public_keys = _get_connected_keypairs() if custom or public_keys: vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) script = _build_script(custom, public_keys) password = custom.get('admin_password') computer_name = custom.get('computer_name') task = vapp.customize_guest_os( vapp_name, customization_script=script, computer_name=computer_name, admin_password=password ) if task is None: raise cfy_exc.NonRecoverableError( "Could not set guest customization parameters. {0}". format(error_response(vapp))) wait_for_task(vca_client, task) if vapp.customize_on_next_poweron(): ctx.logger.info("Customizations successful") else: raise cfy_exc.NonRecoverableError( "Can't run customization in next power on. {0}". format(error_response(vapp))) hardware = server.get('hardware') if hardware: cpu = hardware.get('cpu') memory = hardware.get('memory') _check_hardware(cpu, memory) vapp = vca_client.get_vapp( vca_client.get_vdc(config['vdc']), vapp_name ) if memory: try: task = vapp.modify_vm_memory(vapp_name, memory) wait_for_task(vca_client, task) ctx.logger.info("Customize VM memory: '{0}'.".format(memory)) except Exception: raise cfy_exc.NonRecoverableError( "Customize VM memory failed: '{0}'. {1}". format(task, error_response(vapp))) if cpu: try: task = vapp.modify_vm_cpu(vapp_name, cpu) wait_for_task(vca_client, task) ctx.logger.info("Customize VM cpu: '{0}'.".format(cpu)) except Exception: raise cfy_exc.NonRecoverableError( "Customize VM cpu failed: '{0}'. {1}". format(task, error_response(vapp)))
def get_network(vca_client, network_name): if not network_name: raise cfy_exc.NonRecoverableError( "Network name is empty".format(network_name)) network = vca_client.get_network(get_vcloud_config()['vdc'], network_name) if not network: raise cfy_exc.NonRecoverableError( "Network {0} could not be found".format(network_name)) return network
def _floatingip_operation(operation, vca_client, ctx): """ create/release floating ip by nat rules for this ip with relation to internal ip for current node, save selected public_ip in runtime properties """ service_type = get_vcloud_config().get('service_type') gateway = get_gateway( vca_client, ctx.target.node.properties['floatingip']['edge_gateway']) internal_ip = get_vm_ip(vca_client, ctx, gateway) nat_operation = None public_ip = (ctx.target.instance.runtime_properties.get(PUBLIC_IP) or ctx.target.node.properties['floatingip'].get(PUBLIC_IP)) if operation == CREATE: CheckAssignedInternalIp(internal_ip, gateway) if public_ip: CheckAssignedExternalIp(public_ip, gateway) else: public_ip = get_public_ip(vca_client, gateway, service_type, ctx) nat_operation = _add_nat_rule elif operation == DELETE: if not public_ip: ctx.logger.info("Can't get external IP".format(public_ip)) return True nat_operation = _del_nat_rule else: raise cfy_exc.NonRecoverableError( "Unknown operation {0}".format(operation) ) external_ip = check_ip(public_ip) nat_operation(gateway, "SNAT", internal_ip, external_ip) nat_operation(gateway, "DNAT", external_ip, internal_ip) success = save_gateway_configuration(gateway, vca_client, ctx) if not success: return False if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip save_ssh_parameters(ctx, '22', external_ip) else: if is_ondemand(service_type): if not ctx.target.node.properties['floatingip'].get(PUBLIC_IP): del_ondemand_public_ip( vca_client, gateway, ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) if PUBLIC_IP in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[PUBLIC_IP] if SSH_PUBLIC_IP in ctx.source.instance.runtime_properties: del ctx.source.instance.runtime_properties[SSH_PUBLIC_IP] if SSH_PORT in ctx.target.instance.runtime_properties: del ctx.source.instance.runtime_properties[SSH_PORT] return True
def configure(vca_client, **kwargs): ctx.logger.info("Configure server") server = {'name': ctx.instance.id} server.update(ctx.node.properties.get('server', {})) vapp_name = server['name'] config = get_vcloud_config() custom = server.get(GUEST_CUSTOMIZATION, {}) public_keys = _get_connected_keypairs() if custom or public_keys: vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) script = _build_script(custom, public_keys) password = custom.get('admin_password') computer_name = custom.get('computer_name') ctx.logger.info("Customize guest OS") task = vapp.customize_guest_os(vapp_name, customization_script=script, computer_name=computer_name, admin_password=password) if task is None: raise cfy_exc.NonRecoverableError( "Could not set guest customization parameters. {0}".format( error_response(vapp))) wait_for_task(vca_client, task) if vapp.customize_on_next_poweron(): ctx.logger.info("Customizations successful") else: raise cfy_exc.NonRecoverableError( "Can't run customization in next power on. {0}".format( error_response(vapp))) hardware = server.get('hardware') if hardware: cpu = hardware.get('cpu') memory = hardware.get('memory') _check_hardware(cpu, memory) vapp = vca_client.get_vapp(vca_client.get_vdc(config['vdc']), vapp_name) if memory: try: ctx.logger.info("Customize VM memory: '{0}'.".format(memory)) task = vapp.modify_vm_memory(vapp_name, memory) wait_for_task(vca_client, task) except Exception: raise cfy_exc.NonRecoverableError( "Customize VM memory failed: '{0}'. {1}".format( task, error_response(vapp))) if cpu: try: ctx.logger.info("Customize VM cpu: '{0}'.".format(cpu)) task = vapp.modify_vm_cpu(vapp_name, cpu) wait_for_task(vca_client, task) except Exception: raise cfy_exc.NonRecoverableError( "Customize VM cpu failed: '{0}'. {1}".format( task, error_response(vapp)))
def get_gateway(vca_client, gateway_name): """ return gateway by name """ gateway = vca_client.get_gateway(get_vcloud_config()['vdc'], gateway_name) if not gateway: raise cfy_exc.NonRecoverableError( "Gateway {0} not found".format(gateway_name)) return gateway
def _get_gateway_name(properties): """ return geteway for current node from vcloud config or security group settings """ security_group = properties.get('security_group') if security_group and 'edge_gateway' in security_group: getaway_name = security_group.get('edge_gateway') else: getaway_name = get_vcloud_config()['edge_gateway'] return getaway_name
def _floatingip_operation(operation, vca_client, ctx): """ create/release floating ip by nat rules for this ip with relation to internal ip for current node, save selected public_ip in runtime properties """ service_type = get_vcloud_config().get('service_type') gateway = get_gateway( vca_client, ctx.target.node.properties['floatingip']['edge_gateway']) internal_ip = get_vm_ip(vca_client, ctx, gateway) nat_operation = None public_ip = (ctx.target.instance.runtime_properties.get(PUBLIC_IP) or ctx.target.node.properties['floatingip'].get(PUBLIC_IP)) if operation == CREATE: CheckAssignedInternalIp(internal_ip, gateway) if public_ip: CheckAssignedExternalIp(public_ip, gateway) else: public_ip = get_public_ip(vca_client, gateway, service_type, ctx) nat_operation = _add_nat_rule elif operation == DELETE: if not public_ip: ctx.logger.info("Can't get external IP".format(public_ip)) return True nat_operation = _del_nat_rule else: raise cfy_exc.NonRecoverableError( "Unknown operation {0}".format(operation)) external_ip = check_ip(public_ip) nat_operation(gateway, "SNAT", internal_ip, external_ip) nat_operation(gateway, "DNAT", external_ip, internal_ip) success = save_gateway_configuration(gateway, vca_client, ctx) if not success: return False if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip save_ssh_parameters(ctx, '22', external_ip) else: if is_ondemand(service_type): if not ctx.target.node.properties['floatingip'].get(PUBLIC_IP): del_ondemand_public_ip( vca_client, gateway, ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) if PUBLIC_IP in ctx.target.instance.runtime_properties: del ctx.target.instance.runtime_properties[PUBLIC_IP] if SSH_PUBLIC_IP in ctx.source.instance.runtime_properties: del ctx.source.instance.runtime_properties[SSH_PUBLIC_IP] if SSH_PORT in ctx.source.instance.runtime_properties: del ctx.source.instance.runtime_properties[SSH_PORT] return True
def creation_validation(vca_client, **kwargs): floatingip = get_mandatory(ctx.node.properties, 'floatingip') edge_gateway = get_mandatory(floatingip, 'edge_gateway') gateway = get_gateway(vca_client, edge_gateway) service_type = get_vcloud_config().get('service_type') public_ip = floatingip.get(PUBLIC_IP) if public_ip: check_ip(public_ip) CheckAssignedExternalIp(public_ip, gateway) else: if is_subscription(service_type): getFreeIP(gateway)
def get_network(vca_client, network_name): """ return network by name """ if not network_name: raise cfy_exc.NonRecoverableError( "Network name is empty".format(network_name)) network = vca_client.get_network(get_vcloud_config()['vdc'], network_name) if not network: raise cfy_exc.NonRecoverableError( "Network {0} could not be found".format(network_name)) return network
def _create_ip_range(vca_client, gateway): network_name = ctx.source.instance.runtime_properties[VCLOUD_NETWORK_NAME] org_name = get_vcloud_config()['org'] net = _get_network_ip_range(vca_client, org_name, network_name) gate = _get_gateway_ip_range(gateway, network_name) if not net: raise cfy_exc.NonRecoverableError( "Unknown network: {0}".format(network_name)) if gate: return "{} - {}".format(min(net[0], gate[0]), max(net[1], gate[1])) else: return "{} - {}".format(min(net), max(net))
def _isDhcpAvailable(vca_client, network_name): vdc_name = get_vcloud_config()['vdc'] network = vca_client.get_network(vdc_name, network_name) if network.get_Configuration().get_FenceMode() == "bridged": # NOTE(nmishkin) Can't tell whether bridged networks have DHCP # so just hope for the best return True # TODO: Why not just get the gateway directly from the network? admin_href = vca_client.get_admin_network_href(vdc_name, network_name) for gate in vca_client.get_gateways(vdc_name): for pool in gate.get_dhcp_pools(): if admin_href == pool.get_Network().get_href(): return True return False
def stop(vca_client, **kwargs): if ctx.node.properties.get('use_external_resource'): ctx.logger.info('not stopping server since an external server is ' 'being used') else: vapp_name = get_vapp_name(ctx.instance.runtime_properties) config = get_vcloud_config() vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) ctx.logger.info("Power-off and undeploy VApp {0}".format(vapp_name)) task = vapp.undeploy() if not task: raise cfy_exc.NonRecoverableError("Could not undeploy vApp") wait_for_task(vca_client, task)
def create(vca_client, **kwargs): config = get_vcloud_config() server = { 'name': ctx.instance.id, } server.update(ctx.node.properties.get('server', {})) transform_resource_name(server, ctx) if ctx.node.properties.get('use_external_resource'): res_id = ctx.node.properties['resource_id'] ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] = res_id ctx.logger.info( "External resource {0} has been used".format(res_id)) else: _create(vca_client, config, server)
def _create_ip_range(vca_client, gateway): """ return ip range by avaible ranges from gateway and current network """ network_name = ctx.source.instance.runtime_properties[VCLOUD_NETWORK_NAME] org_name = get_vcloud_config()['org'] net = _get_network_ip_range(vca_client, org_name, network_name) gate = _get_gateway_ip_range(gateway, network_name) if not net: raise cfy_exc.NonRecoverableError( "Unknown network: {0}".format(network_name)) if gate: return "{} - {}".format(min(net[0], gate[0]), max(net[1], gate[1])) else: return "{} - {}".format(min(net), max(net))
def _save_configuration(gateway, vca_client, operation, public_ip): if not save_gateway_configuration(gateway, vca_client): return ctx.operation.retry(message='Waiting for gateway.', retry_after=10) ctx.logger.info("NAT configuration has been saved") if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = public_ip else: service_type = get_vcloud_config().get('service_type') if is_ondemand(service_type): if not ctx.target.node.properties['nat'].get(PUBLIC_IP): del_ondemand_public_ip( vca_client, gateway, ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) del ctx.target.instance.runtime_properties[PUBLIC_IP]
def delete_volume(vca_client, **kwargs): """ drop volume """ if ctx.node.properties.get('use_external_resource'): ctx.logger.info("External resource has been used") return vdc_name = get_vcloud_config()['vdc'] name = ctx.node.properties['volume']['name'] success, task = vca_client.delete_disk(vdc_name, name) if success: wait_for_task(vca_client, task) ctx.logger.info("Volume node {} has been deleted".format(name)) else: raise cfy_exc.NonRecoverableError( "Disk deletion error: {0}".format(task))
def _create_ip_range(vca_client, gateway): """ return ip range by avaible ranges from gateway and current network, on error - raise error, never return None """ network_name = ctx.source.instance.runtime_properties[VCLOUD_NETWORK_NAME] vdc_name = get_vcloud_config()['vdc'] net = _get_network_ip_range(vca_client, vdc_name, network_name) gate = _get_gateway_ip_range(gateway, network_name) if not net: raise cfy_exc.NonRecoverableError( "Unknown network: {0}".format(network_name)) if gate: return "{} - {}".format(min(net[0], gate[0]), max(net[1], gate[1])) else: return "{} - {}".format(min(net), max(net))
def delete(vca_client, **kwargs): """ delete vcloud air network """ if ctx.node.properties["use_external_resource"] is True: del ctx.instance.runtime_properties[VCLOUD_NETWORK_NAME] ctx.logger.info("Network was not deleted - external resource has" " been used") return network_name = get_network_name(ctx.node.properties) _dhcp_operation(vca_client, network_name, DELETE_POOL) success, task = vca_client.delete_vdc_network(get_vcloud_config()["vdc"], network_name) if success: ctx.logger.info("Network {0} has been successful deleted.".format(network_name)) else: raise cfy_exc.NonRecoverableError("Could not delete network {0}".format(network_name)) wait_for_task(vca_client, task)
def delete(vca_client, **kwargs): if ctx.node.properties.get('use_external_resource'): ctx.logger.info('not deleting server since an external server is ' 'being used') else: vapp_name = get_vapp_name(ctx.instance.runtime_properties) config = get_vcloud_config() vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) ctx.logger.info("Deleting VApp {0}".format(vapp_name)) task = vapp.delete() if not task: raise cfy_exc.NonRecoverableError("Could not delete vApp") wait_for_task(vca_client, task) del ctx.instance.runtime_properties[VCLOUD_VAPP_NAME]
def stop(vca_client, **kwargs): """ poweroff server, if external resource - server stay poweroned """ if ctx.node.properties.get('use_external_resource'): ctx.logger.info('not stopping server since an external server is ' 'being used') else: vapp_name = get_vapp_name(ctx.instance.runtime_properties) config = get_vcloud_config() vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) ctx.logger.info("Power-off and undeploy VApp {0}".format(vapp_name)) task = vapp.undeploy() if not task: raise cfy_exc.NonRecoverableError("Could not undeploy vApp") wait_for_task(vca_client, task)
def _isDhcpAvailable(vca_client, network_name): """ check dhcp availability for network """ vdc_name = get_vcloud_config()['vdc'] network = vca_client.get_network(vdc_name, network_name) if network.get_Configuration().get_FenceMode() == "bridged": # NOTE(nmishkin) Can't tell whether bridged networks have DHCP # so just hope for the best return True # TODO: Why not just get the gateway directly from the network? admin_href = vca_client.get_admin_network_href(vdc_name, network_name) for gate in vca_client.get_gateways(vdc_name): for pool in gate.get_dhcp_pools(): if admin_href == pool.get_Network().get_href(): return True return False
def _floatingip_operation(operation, vca_client, ctx): service_type = get_vcloud_config().get('service_type') gateway = get_gateway( vca_client, ctx.target.node.properties['floatingip']['edge_gateway']) internal_ip = get_vm_ip(vca_client, ctx, gateway) nat_operation = None public_ip = (ctx.target.instance.runtime_properties.get(PUBLIC_IP) or ctx.target.node.properties['floatingip'].get(PUBLIC_IP)) if operation == CREATE: CheckAssignedInternalIp(internal_ip, gateway) if public_ip: CheckAssignedExternalIp(public_ip, gateway) else: public_ip = get_public_ip(vca_client, gateway, service_type, ctx) nat_operation = _add_nat_rule elif operation == DELETE: if not public_ip: ctx.logger.info("Can't get external IP".format(public_ip)) return nat_operation = _del_nat_rule else: raise cfy_exc.NonRecoverableError( "Unknown operation {0}").format(operation) external_ip = check_ip(public_ip) nat_operation(gateway, "SNAT", internal_ip, external_ip) nat_operation(gateway, "DNAT", external_ip, internal_ip) if not save_gateway_configuration(gateway, vca_client): return ctx.operation.retry(message='Waiting for gateway.', retry_after=10) if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = external_ip else: if is_ondemand(service_type): if not ctx.target.node.properties['floatingip'].get(PUBLIC_IP): del_ondemand_public_ip( vca_client, gateway, ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) del ctx.target.instance.runtime_properties[PUBLIC_IP]
def _save_configuration(gateway, vca_client, operation, public_ip): """ save/refresh nat rules on gateway """ if not save_gateway_configuration(gateway, vca_client): return ctx.operation.retry(message='Waiting for gateway.', retry_after=10) ctx.logger.info("NAT configuration has been saved") if operation == CREATE: ctx.target.instance.runtime_properties[PUBLIC_IP] = public_ip else: service_type = get_vcloud_config().get('service_type') if is_ondemand(service_type): if not ctx.target.node.properties['nat'].get(PUBLIC_IP): del_ondemand_public_ip( vca_client, gateway, ctx.target.instance.runtime_properties[PUBLIC_IP], ctx) del ctx.target.instance.runtime_properties[PUBLIC_IP]
def start(vca_client, **kwargs): """ power on server and wait network connection availability for host """ if ctx.node.properties.get('use_external_resource'): ctx.logger.info('not starting server since an external server is ' 'being used') else: vapp_name = get_vapp_name(ctx.instance.runtime_properties) config = get_vcloud_config() vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) _power_on_vm(vca_client, vapp, vapp_name) if not _get_state(vca_client): return ctx.operation.retry( message="Waiting for VM's configuration to complete", retry_after=5)
def get_ondemand_public_ip(vca_client, gateway, ctx): old_public_ips = set(gateway.get_public_ips()) task = gateway.allocate_public_ip() if task: wait_for_task(vca_client, task) else: raise cfy_exc.NonRecoverableError( "Can't get public ip for ondemand service") # update gateway for new IP address gateway = vca_client.get_gateways(get_vcloud_config()['vdc'])[0] new_public_ips = set(gateway.get_public_ips()) new_ip = new_public_ips - old_public_ips if new_ip: ctx.logger.info("Assign public IP {0}".format(new_ip)) else: raise cfy_exc.NonRecoverableError( "Can't get new public IP address") return list(new_ip)[0]
def creation_validation(vca_client, **kwargs): """ check network description from node description """ network_name = get_network_name(ctx.node.properties) ctx.logger.info( "Validation cloudify.vcloud.nodes.Network node: {0}".format( network_name)) if is_network_exists(vca_client, network_name): if ctx.node.properties.get('use_external_resource'): # TODO: check: default gateway must exists return else: raise cfy_exc.NonRecoverableError( "Network already exsists: {0}".format(network_name)) net_prop = get_mandatory(ctx.node.properties, "network") gateway_name = get_mandatory(net_prop, 'edge_gateway') if not vca_client.get_gateway(get_vcloud_config()['vdc'], gateway_name): raise cfy_exc.NonRecoverableError( "Gateway {0} not found".format(gateway_name)) static_ip = _split_adresses(get_mandatory(net_prop, 'static_range')) check_ip(static_ip.start) check_ip(static_ip.end) dns_list = net_prop.get("dns") if dns_list: for ip in dns_list: check_ip(ip) gateway_ip = check_ip(get_mandatory(net_prop, "gateway_ip")) netmask = check_ip(get_mandatory(net_prop, "netmask")) ips = [gateway_ip, static_ip.start, static_ip.end] dhcp = net_prop.get("dhcp") if dhcp: dhcp_range = get_mandatory(net_prop["dhcp"], "dhcp_range") dhcp_ip = _split_adresses(dhcp_range) if not is_separate_ranges(static_ip, dhcp_ip): raise cfy_exc.NonRecoverableError( "Static_range and dhcp_range is overlapped.") ips.extend([dhcp_ip.start, dhcp_ip.end]) if not is_ips_in_same_subnet(ips, netmask): raise cfy_exc.NonRecoverableError("IP addresses in different subnets.")
def delete(vca_client, **kwargs): """ delete server """ if ctx.node.properties.get('use_external_resource'): ctx.logger.info('not deleting server since an external server is ' 'being used') else: vapp_name = get_vapp_name(ctx.instance.runtime_properties) config = get_vcloud_config() vdc = vca_client.get_vdc(config['vdc']) vapp = vca_client.get_vapp(vdc, vapp_name) ctx.logger.info("Deleting VApp {0}".format(vapp_name)) task = vapp.delete() if not task: raise cfy_exc.NonRecoverableError("Could not delete vApp") wait_for_task(vca_client, task) del ctx.instance.runtime_properties[VCLOUD_VAPP_NAME]
def _volume_operation(vca_client, operation): """ attach/detach volume """ vdc_name = get_vcloud_config()['vdc'] vdc = vca_client.get_vdc(vdc_name) vmName = get_vapp_name(ctx.target.instance.runtime_properties) if ctx.source.node.properties.get('use_external_resource'): volumeName = ctx.source.node.properties['resource_id'] else: volumeName = ctx.source.node.properties['volume']['name'] vapp = vca_client.get_vapp(vdc, vmName) for ref in vca_client.get_diskRefs(vdc): if ref.name == volumeName: if operation == 'ATTACH': ctx.logger.info("Attach volume node '{0}'.".format(volumeName)) task = vapp.attach_disk_to_vm(vmName, ref) if task: wait_for_task(vca_client, task) ctx.logger.info( "Volume node '{0}' has been attached".format( volumeName)) else: raise cfy_exc.NonRecoverableError( "Can't attach disk: '{0}' with error: {1}".format( volumeName, error_response(vapp))) elif operation == 'DETACH': ctx.logger.info("Detach volume node '{0}'.".format(volumeName)) task = vapp.detach_disk_from_vm(vmName, ref) if task: wait_for_task(vca_client, task) ctx.logger.info( "Volume node '{0}' has been detached.".format( volumeName)) else: raise cfy_exc.NonRecoverableError( "Can't detach disk: '{0}'. With error: {1}".format( volumeName, error_response(vapp))) else: raise cfy_exc.NonRecoverableError( "Unknown operation '{0}'".format(operation))
def creation_validation(vca_client, **kwargs): """ check volume description """ vdc_name = get_vcloud_config()['vdc'] disks_names = [ disk.name for [disk, _vms] in vca_client.get_disks(vdc_name) ] if ctx.node.properties.get('use_external_resource'): resource_id = get_mandatory(ctx.node.properties, 'resource_id') if resource_id not in disks_names: raise cfy_exc.NonRecoverableError( "Disk {} does't exists".format(resource_id)) else: volume = get_mandatory(ctx.node.properties, 'volume') name = get_mandatory(volume, 'name') if name in disks_names: raise cfy_exc.NonRecoverableError( "Disk {} already exists".format(name)) get_mandatory(volume, 'size')
def delete(vca_client, **kwargs): """ delete vcloud air network """ if ctx.node.properties['use_external_resource'] is True: del ctx.instance.runtime_properties[VCLOUD_NETWORK_NAME] ctx.logger.info("Network was not deleted - external resource has" " been used") return network_name = get_network_name(ctx.node.properties) _dhcp_operation(vca_client, network_name, DELETE_POOL) success, task = vca_client.delete_vdc_network(get_vcloud_config()['vdc'], network_name) if success: ctx.logger.info( "Network {0} has been successful deleted.".format(network_name)) else: raise cfy_exc.NonRecoverableError( "Could not delete network {0}".format(network_name)) wait_for_task(vca_client, task)
def get_ondemand_public_ip(vca_client, gateway, ctx): """ try to allocate new public ip for ondemand service """ old_public_ips = set(gateway.get_public_ips()) task = gateway.allocate_public_ip() if task: wait_for_task(vca_client, task) else: raise cfy_exc.NonRecoverableError( "Can't get public ip for ondemand service") # update gateway for new IP address gateway = vca_client.get_gateways(get_vcloud_config()['vdc'])[0] new_public_ips = set(gateway.get_public_ips()) new_ip = new_public_ips - old_public_ips if new_ip: ctx.logger.info("Assign public IP {0}".format(new_ip)) else: raise cfy_exc.NonRecoverableError( "Can't get new public IP address") return list(new_ip)[0]
def creation_validation(vca_client, **kwargs): nat = get_mandatory(ctx.node.properties, 'nat') rules = get_mandatory(ctx.node.properties, 'rules') gateway = get_gateway(vca_client, get_mandatory(nat, 'edge_gateway')) service_type = get_vcloud_config().get('service_type') public_ip = nat.get(PUBLIC_IP) if public_ip: check_ip(public_ip) CheckAssignedExternalIp(public_ip, gateway) else: if isSubscription(service_type): getFreeIP(gateway) check_protocol(rules.get('protocol', "any")) original_port = rules.get('original_port') if original_port and not isinstance(original_port, int): raise cfy_exc.NonRecoverableError( "Parameter 'original_port' must be integer") translated_port = rules.get('translated_port') if translated_port and not isinstance(translated_port, int): raise cfy_exc.NonRecoverableError( "Parameter 'translated_port' must be integer")
def create(vca_client, **kwargs): """ create server by template, if external_resource set return without creation, e.g.: { 'management_network': '_management_network', 'server': { 'template': 'template', 'catalog': 'catalog', 'guest_customization': { 'pre_script': 'pre_script', 'post_script': 'post_script', 'admin_password': '******', 'computer_name': 'computer' } } } """ config = get_vcloud_config() server = { 'name': ctx.instance.id, } server.update(ctx.node.properties.get('server', {})) transform_resource_name(server, ctx) if ctx.node.properties.get('use_external_resource'): res_id = ctx.node.properties['resource_id'] ctx.instance.runtime_properties[VCLOUD_VAPP_NAME] = res_id vdc = vca_client.get_vdc(config['vdc']) if not vca_client.get_vapp(vdc, res_id): raise cfy_exc.NonRecoverableError( "Unable to find external vAPP server resource {0}." .format(res_id)) server.update({'name': res_id}) ctx.logger.info( "External resource {0} has been used".format(res_id)) else: _create(vca_client, config, server)
def creation_validation(vca_client, **kwargs): """ validate node context, fields from floatingip dict: * edge_gateway - mandatory, * public_ip - prefered ip for node, can be empty fields from vcloud_config: * service_type - ondemand, subscription also check availability of public ip if set or exist some free ip in subscription case """ floatingip = get_mandatory(ctx.node.properties, 'floatingip') edge_gateway = get_mandatory(floatingip, 'edge_gateway') gateway = get_gateway(vca_client, edge_gateway) service_type = get_vcloud_config().get('service_type') public_ip = floatingip.get(PUBLIC_IP) if public_ip: check_ip(public_ip) CheckAssignedExternalIp(public_ip, gateway) else: if is_subscription(service_type): getFreeIP(gateway)