def test_task_manager_task_parallel_process(self): tasks = [] def _exec(task): task.userdata['executed'] = True return ts_const.TaskStatus.PENDING def _status(task): for t in tasks: if not t.userdata.get('executed'): t.userdata['resut'] = False return ts_const.TaskStatus.COMPLETED def _result(task): if (task.userdata.get('result') is None and task.status == ts_const.TaskStatus.COMPLETED): task.userdata['result'] = True else: task.userdata['result'] = False for i in range(5): name = "name-%d" % i res = 'resource-%d' % i task = ts.Task(name, res, _exec, _status, _result, {}) tasks.append(task) self.manager.add(task) for task in tasks: task.wait(ts_const.TaskState.RESULT) self.assertTrue(task.userdata['result'])
def delete_port_group(self, dvs_id, port_group_id): task_name = 'delete-port-group-%s-%s' % (port_group_id, dvs_id) userdata = {'retry_number': 1, 'retry_command': self.vcns.delete_port_group, 'args': [dvs_id, port_group_id]} task = tasks.Task(task_name, port_group_id, self._retry_task, status_callback=self._retry_task, userdata=userdata) self.task_manager.add(task)
def delete_virtual_wire(self, vw_id): task_name = 'delete-virtualwire-%s' % vw_id userdata = {'retry_number': 1, 'retry_command': self.vcns.delete_virtual_wire, 'args': [vw_id]} task = tasks.Task(task_name, vw_id, self._retry_task, status_callback=self._retry_task, userdata=userdata) self.task_manager.add(task)
def delete_portgroup(self, dvs_id, port_group_id, job_id): task_name = "delete-port-group-%s" % port_group_id userdata = {'dvs_id': dvs_id, 'port_group_id': port_group_id, 'job_id': job_id} task = tasks.Task(task_name, port_group_id, self._delete_port_group, status_callback=self._delete_port_group, userdata=userdata) self.task_manager.add(task)
def delete_edge(self, resource_id, edge_id, jobdata=None, dist=False): task_name = 'delete-%s' % edge_id userdata = { 'router_id': resource_id, 'dist': dist, 'edge_id': edge_id, 'jobdata': jobdata } task = tasks.Task(task_name, resource_id, self._delete_edge, userdata=userdata) task.add_result_monitor(self.callbacks.edge_delete_result) self.task_manager.add(task) return task
def delete_snat_rule(self, router_id, edge_id, src, jobdata=None): LOG.debug("VCNS: delete snat rule %s", src) userdata = { 'edge_id': edge_id, 'address': src, 'addrtype': 'originalAddress', 'jobdata': jobdata } task_name = "delete-snat-%s-%s" % (edge_id, src) task = tasks.Task(task_name, router_id, self._delete_nat_rule, userdata=userdata) task.add_result_monitor(self.callbacks.snat_delete_result) self.task_manager.add(task) return task
def rename_edge(self, router_id, edge_id, name): """rename edge.""" task_name = 'rename-%s' % name userdata = { 'edge_id': edge_id, 'name': name } task = tasks.Task(task_name, router_id, self._rename_edge, userdata=userdata) task.add_result_monitor(self.callbacks.edge_rename_result) self.task_manager.add(task) return task
def update_edge(self, router_id, edge_id, name, internal_network, jobdata=None, dist=False, loadbalancer_enable=True, appliance_size=nsxv_constants.LARGE, set_errors=False): """Update edge name.""" task_name = 'update-%s' % name edge_name = name edge = self._assemble_edge( edge_name, datacenter_moid=self.datacenter_moid, deployment_container_id=self.deployment_container_id, appliance_size=appliance_size, remote_access=False, dist=dist) edge['id'] = edge_id appliance = self._assemble_edge_appliance(self.resource_pool_id, self.datastore_id) if appliance: edge['appliances']['appliances'] = [appliance] if not dist: vnic_external = self._assemble_edge_vnic( constants.EXTERNAL_VNIC_NAME, constants.EXTERNAL_VNIC_INDEX, self.external_network, type="uplink") edge['vnics']['vnics'].append(vnic_external) else: edge['mgmtInterface'] = { 'connectedToId': self.external_network, 'name': "mgmtInterface"} if internal_network: internal_vnic = self._assemble_edge_vnic( constants.INTERNAL_VNIC_NAME, constants.INTERNAL_VNIC_INDEX, internal_network, constants.INTEGRATION_EDGE_IPADDRESS, constants.INTEGRATION_SUBNET_NETMASK, type="internal") edge['vnics']['vnics'].append(internal_vnic) if not dist and loadbalancer_enable: self._enable_loadbalancer(edge) userdata = { 'router_id': router_id, 'edge_id': edge_id, 'request': edge, 'jobdata': jobdata, 'set_errors': set_errors } task = tasks.Task(task_name, router_id, self._update_edge, userdata=userdata) task.add_result_monitor(self.callbacks.edge_update_result) self.task_manager.add(task) return task
def delete_interface(self, router_id, edge_id, index, jobdata=None): task_name = "delete-interface-%s-%d" % (edge_id, index) userdata = { 'router_id': router_id, 'edge_id': edge_id, 'vnic_index': index, 'jobdata': jobdata } task = tasks.Task(task_name, router_id, self._delete_interface, userdata=userdata) task.add_result_monitor(self.callbacks.interface_delete_result) self.task_manager.add(task) # avoid bug 1389358 self.check_edge_jobs(edge_id) return task
def delete_dnat_rule(self, router_id, edge_id, translated, jobdata=None): # TODO(fank): pass in rule_id for optimization LOG.debug("VCNS: delete dnat rule %s", translated) userdata = { 'edge_id': edge_id, 'address': translated, 'addrtype': 'translatedAddress', 'jobdata': jobdata } task_name = "delete-dnat-%s-%s" % (edge_id, translated) task = tasks.Task(task_name, router_id, self._delete_nat_rule, userdata=userdata) task.add_result_monitor(self.callbacks.dnat_delete_result) self.task_manager.add(task) return task
def create_snat_rule(self, router_id, edge_id, src, translated, jobdata=None, location=None): LOG.debug("VCNS: create snat rule %(src)s/%(translated)s", { 'src': src, 'translated': translated}) snat_rule = self._assemble_nat_rule("snat", src, translated) userdata = { 'router_id': router_id, 'edge_id': edge_id, 'rule': snat_rule, 'location': location, 'jobdata': jobdata } task_name = "create-snat-%s-%s-%s" % (edge_id, src, translated) task = tasks.Task(task_name, router_id, self._create_nat_rule, userdata=userdata) task.add_result_monitor(self.callbacks.snat_create_result) self.task_manager.add(task) return task
def _test_task_manager_stop(self, exec_wait=False, result_wait=False, stop_wait=0): def _exec(task): if exec_wait: greenthread.sleep(0.01) return ts_const.TaskStatus.PENDING def _status(task): greenthread.sleep(0.01) return ts_const.TaskStatus.PENDING def _result(task): if result_wait: greenthread.sleep(0) pass manager = ts.TaskManager().start(100) manager.stop() # Task manager should not leave running threads around # if _thread is None it means it was killed in stop() self.assertIsNone(manager._thread) manager.start(100) alltasks = {} for i in range(100): res = 'res-%d' % i tasks = [] for i in range(100): task = ts.Task('name', res, _exec, _status, _result) manager.add(task) tasks.append(task) alltasks[res] = tasks greenthread.sleep(stop_wait) manager.stop() # Task manager should not leave running threads around # if _thread is None it means it was killed in stop() self.assertIsNone(manager._thread) for res, tasks in six.iteritems(alltasks): for task in tasks: self.assertEqual(ts_const.TaskStatus.ABORT, task.status)
def update_routes(self, router_id, edge_id, gateway, routes, skippable=True, jobdata=None, gateway_vnic_index=constants.EXTERNAL_VNIC_INDEX): if gateway: gateway = gateway.split('/')[0] userdata = { 'edge_id': edge_id, 'gateway': gateway, 'gateway_vnic_index': gateway_vnic_index, 'routes': routes, 'skippable': skippable, 'jobdata': jobdata } task_name = "update-routes-%s" % (edge_id) task = tasks.Task(task_name, router_id, self._update_routes, userdata=userdata) task.add_result_monitor(self.callbacks.routes_update_result) self.updated_task['route'][edge_id] = task self.task_manager.add(task) return task
def create_dnat_rule(self, router_id, edge_id, dst, translated, jobdata=None, location=None): # TODO(fank): use POST for optimization # return rule_id for future reference LOG.debug("VCNS: create dnat rule %(dst)s/%(translated)s", { 'dst': dst, 'translated': translated}) dnat_rule = self._assemble_nat_rule( "dnat", dst, translated) userdata = { 'router_id': router_id, 'edge_id': edge_id, 'rule': dnat_rule, 'location': location, 'jobdata': jobdata } task_name = "create-dnat-%s-%s-%s" % (edge_id, dst, translated) task = tasks.Task(task_name, router_id, self._create_nat_rule, userdata=userdata) task.add_result_monitor(self.callbacks.dnat_create_result) self.task_manager.add(task) return task
def test_task_pending_task(self): def _exec(task): task.userdata['executing'] = True while not task.userdata['tested']: greenthread.sleep(0) task.userdata['executing'] = False return ts_const.TaskStatus.COMPLETED userdata = {'executing': False, 'tested': False} manager = ts.TaskManager().start(100) task = ts.Task('name', 'res', _exec, userdata=userdata) manager.add(task) while not userdata['executing']: greenthread.sleep(0) self.assertTrue(manager.has_pending_task()) userdata['tested'] = True while userdata['executing']: greenthread.sleep(0) self.assertFalse(manager.has_pending_task())
def test_task_manager_task_ordered_process(self): def _task_failed(task, reason): task.userdata['result'] = False task.userdata['error'] = reason def _exec(task): task.userdata['executed'] = True return ts_const.TaskStatus.PENDING def _status(task): return ts_const.TaskStatus.COMPLETED def _result(task): next_task = task.userdata.get('next') if next_task: if next_task.userdata.get('executed'): _task_failed(next_task, "executed premature") if task.userdata.get('result', True): task.userdata['result'] = True tasks = [] prev = None last_task = None for i in range(5): name = "name-%d" % i task = ts.Task(name, 'res', _exec, _status, _result, {}) tasks.append(task) if prev: prev.userdata['next'] = task prev = task last_task = task for task in tasks: self.manager.add(task) last_task.wait(ts_const.TaskState.RESULT) for task in tasks: self.assertTrue(task.userdata['result'])
def update_nat_rules(self, router_id, edge_id, snats, dnats, jobdata=None): LOG.debug("VCNS: update nat rule\n" "SNAT:%(snat)s\n" "DNAT:%(dnat)s\n", { 'snat': snats, 'dnat': dnats}) nat_rules = [] for dnat in dnats: vnic_index = constants.EXTERNAL_VNIC_INDEX if 'vnic_index' in dnat: vnic_index = dnat['vnic_index'] nat_rules.append(self._assemble_nat_rule( 'dnat', dnat['dst'], dnat['translated'], vnic_index=vnic_index )) nat_rules.append(self._assemble_nat_rule( 'snat', dnat['translated'], dnat['dst'], vnic_index=vnic_index )) for snat in snats: vnic_index = constants.EXTERNAL_VNIC_INDEX if 'vnic_index' in snat: vnic_index = snat['vnic_index'] nat_rules.append(self._assemble_nat_rule( 'snat', snat['src'], snat['translated'], vnic_index=vnic_index )) userdata = { 'edge_id': edge_id, 'rules': nat_rules, 'jobdata': jobdata, } task_name = "update-nat-%s" % edge_id task = tasks.Task(task_name, router_id, self._update_nat_rule, userdata=userdata) task.add_result_monitor(self.callbacks.nat_update_result) self.updated_task['nat'][edge_id] = task self.task_manager.add(task) return task
def asyn_update_firewall(self, router_id, edge_id, firewall, jobdata=None, allow_external=True): # TODO(berlin): Remove uncessary context input parameter. config = self._convert_firewall(None, firewall, allow_external=allow_external) userdata = { 'edge_id': edge_id, 'config': config, 'fw_config': firewall, 'jobdata': jobdata } task_name = "update-firewall-%s" % edge_id task = tasks.Task(task_name, router_id, self._asyn_update_firewall, userdata=userdata) task.add_result_monitor(self.callbacks.firewall_update_result) self.task_manager.add(task) return task
def _test_task_manager_task_process_state(self, sync_exec=False): def _task_failed(task, reason): task.userdata['result'] = False task.userdata['error'] = reason def _check_state(task, exp_state): if not task.userdata.get('result', True): return False state = task.userdata['state'] if state != exp_state: msg = "state %d expect %d" % ( state, exp_state) _task_failed(task, msg) return False task.userdata['state'] = state + 1 return True def _exec(task): if not _check_state(task, 1): return ts_const.TaskStatus.ERROR if task.userdata['sync_exec']: return ts_const.TaskStatus.COMPLETED else: return ts_const.TaskStatus.PENDING def _status(task): if task.userdata['sync_exec']: _task_failed(task, "_status callback triggered") state = task.userdata['state'] if state == 3: _check_state(task, 3) return ts_const.TaskStatus.PENDING else: _check_state(task, 4) return ts_const.TaskStatus.COMPLETED def _result(task): if task.userdata['sync_exec']: exp_state = 3 else: exp_state = 5 _check_state(task, exp_state) def _start_monitor(task): _check_state(task, 0) def _executed_monitor(task): _check_state(task, 2) def _result_monitor(task): if task.userdata['sync_exec']: exp_state = 4 else: exp_state = 6 if _check_state(task, exp_state): task.userdata['result'] = True else: task.userdata['result'] = False userdata = { 'state': 0, 'sync_exec': sync_exec } task = ts.Task('name', 'res', _exec, _status, _result, userdata) task.add_start_monitor(_start_monitor) task.add_executed_monitor(_executed_monitor) task.add_result_monitor(_result_monitor) self.manager.add(task) task.wait(ts_const.TaskState.RESULT) self.assertTrue(userdata['result'])
class EdgeApplianceDriver(object): def __init__(self): super(EdgeApplianceDriver, self).__init__() # store the last task per edge that has the latest config self.updated_task = { 'nat': {}, 'route': {}, } def _assemble_edge(self, name, appliance_size="compact", deployment_container_id=None, datacenter_moid=None, enable_aesni=True, dist=False, enable_fips=False, remote_access=False): edge = { 'name': name, 'fqdn': None, 'enableAesni': enable_aesni, 'enableFips': enable_fips, 'featureConfigs': { 'features': [ { 'featureType': 'firewall_4.0', 'globalConfig': { 'tcpTimeoutEstablished': 7200 } } ] }, 'cliSettings': { 'remoteAccess': remote_access }, 'autoConfiguration': { 'enabled': False, 'rulePriority': 'high' }, 'appliances': { 'applianceSize': appliance_size }, } if not dist: edge['type'] = "gatewayServices" edge['vnics'] = {'vnics': []} else: edge['type'] = "distributedRouter" edge['interfaces'] = {'interfaces': []} if deployment_container_id: edge['appliances']['deploymentContainerId'] = ( deployment_container_id) if datacenter_moid: edge['datacenterMoid'] = datacenter_moid if not dist and cfg.CONF.nsxv.edge_ha: self._enable_high_availability(edge) return edge def _assemble_edge_appliance(self, resource_pool_id, datastore_id): appliance = {} if resource_pool_id: appliance['resourcePoolId'] = resource_pool_id if datastore_id: appliance['datastoreId'] = datastore_id return appliance def _assemble_edge_vnic(self, name, index, portgroup_id, tunnel_index=-1, primary_address=None, subnet_mask=None, secondary=None, type="internal", enable_proxy_arp=False, enable_send_redirects=True, is_connected=True, mtu=1500, address_groups=None): vnic = { 'index': index, 'name': name, 'type': type, 'portgroupId': portgroup_id, 'mtu': mtu, 'enableProxyArp': enable_proxy_arp, 'enableSendRedirects': enable_send_redirects, 'isConnected': is_connected } if address_groups is None: address_groups = [] if not address_groups: if primary_address and subnet_mask: address_group = { 'primaryAddress': primary_address, 'subnetMask': subnet_mask } if secondary: address_group['secondaryAddresses'] = { 'ipAddress': secondary, 'type': 'secondary_addresses' } vnic['addressGroups'] = { 'addressGroups': [address_group] } else: vnic['subInterfaces'] = {'subInterfaces': address_groups} else: if tunnel_index < 0: vnic['addressGroups'] = {'addressGroups': address_groups} else: vnic['subInterfaces'] = {'subInterfaces': address_groups} return vnic def _assemble_vdr_interface(self, portgroup_id, primary_address=None, subnet_mask=None, secondary=None, type="internal", is_connected=True, mtu=1500, address_groups=None): interface = { 'type': type, 'connectedToId': portgroup_id, 'mtu': mtu, 'isConnected': is_connected } if address_groups is None: address_groups = [] if not address_groups: if primary_address and subnet_mask: address_group = { 'primaryAddress': primary_address, 'subnetMask': subnet_mask } if secondary: address_group['secondaryAddresses'] = { 'ipAddress': secondary, 'type': 'secondary_addresses' } interface['addressGroups'] = { 'addressGroups': [address_group] } else: interface['addressGroups'] = {'addressGroups': address_groups} interfaces = {'interfaces': [interface]} return interfaces def _edge_status_to_level(self, status): if status == 'GREEN': status_level = constants.RouterStatus.ROUTER_STATUS_ACTIVE elif status in ('GREY', 'YELLOW'): status_level = constants.RouterStatus.ROUTER_STATUS_DOWN else: status_level = constants.RouterStatus.ROUTER_STATUS_ERROR return status_level def _enable_loadbalancer(self, edge): if (not edge.get('featureConfigs') or not edge['featureConfigs'].get('features')): edge['featureConfigs'] = {'features': []} edge['featureConfigs']['features'].append( {'featureType': 'loadbalancer_4.0', 'enabled': True}) def _enable_high_availability(self, edge): if (not edge.get('featureConfigs') or not edge['featureConfigs'].get('features')): edge['featureConfigs'] = {'features': []} edge['featureConfigs']['features'].append( {'featureType': 'highavailability_4.0', 'enabled': True}) def get_edge_status(self, edge_id): try: response = self.vcns.get_edge_status(edge_id)[1] status_level = self._edge_status_to_level( response['edgeStatus']) except exceptions.VcnsApiException as e: LOG.exception(_LE("VCNS: Failed to get edge status:\n%s"), e.response) status_level = constants.RouterStatus.ROUTER_STATUS_ERROR try: desc = jsonutils.loads(e.response) if desc.get('errorCode') == ( constants.VCNS_ERROR_CODE_EDGE_NOT_RUNNING): status_level = constants.RouterStatus.ROUTER_STATUS_DOWN except ValueError: LOG.exception(e.response) return status_level def get_edges_statuses(self): edges_status_level = {} edges = self._get_edges() for edge in edges['edgePage'].get('data', []): edge_id = edge['id'] status = edge['edgeStatus'] edges_status_level[edge_id] = self._edge_status_to_level(status) return edges_status_level def get_interface(self, edge_id, vnic_index): self.check_edge_jobs(edge_id) # get vnic interface address groups try: return self.vcns.query_interface(edge_id, vnic_index) except exceptions.VcnsApiException: with excutils.save_and_reraise_exception(): LOG.exception(_LE("NSXv: Failed to query vnic %s"), vnic_index) def check_edge_jobs(self, edge_id): retries = max(cfg.CONF.nsxv.retries, 1) delay = 0.5 for attempt in range(1, retries + 1): if attempt != 1: time.sleep(delay) delay = min(2 * delay, 60) h, jobs = self.vcns.get_edge_jobs(edge_id) if jobs['edgeJob'] == []: return job_number = len(jobs['edgeJob']) # Assume one job would wait time out after 20 minutes and one # job takes about 1 minute to be completed. if job_number < 20: LOG.warning(_LW("NSXv: %(num)s jobs still running on edge " "%(edge_id)s."), {'num': job_number, 'edge_id': edge_id}) else: LOG.error(_LE("NSXv: %(num)s jobs still running on edge " "%(edge_id)s. Too many jobs may lead to job " "time out at the backend"), {'num': job_number, 'edge_id': edge_id}) LOG.error(_LE('NSXv: jobs are still runnings!')) def update_interface(self, router_id, edge_id, index, network, tunnel_index=-1, address=None, netmask=None, secondary=None, jobdata=None, is_connected=True, address_groups=None): LOG.debug("VCNS: update vnic %(index)d: %(addr)s %(netmask)s", { 'index': index, 'addr': address, 'netmask': netmask}) if index == constants.EXTERNAL_VNIC_INDEX: name = constants.EXTERNAL_VNIC_NAME intf_type = 'uplink' else: name = constants.INTERNAL_VNIC_NAME + str(index) if tunnel_index < 0: intf_type = 'internal' else: intf_type = 'trunk' config = self._assemble_edge_vnic( name, index, network, tunnel_index, address, netmask, secondary, type=intf_type, address_groups=address_groups, is_connected=is_connected) self.vcns.update_interface(edge_id, config) def add_vdr_internal_interface(self, edge_id, network, address=None, netmask=None, secondary=None, address_groups=None, type="internal", is_connected=True): LOG.debug("Add VDR interface on edge: %s", edge_id) if address_groups is None: address_groups = [] interface_req = ( self._assemble_vdr_interface(network, address, netmask, secondary, address_groups=address_groups, is_connected=is_connected, type=type)) self.vcns.add_vdr_internal_interface(edge_id, interface_req) header, response = self.vcns.get_edge_interfaces(edge_id) for interface in response['interfaces']: if interface['connectedToId'] == network: vnic_index = int(interface['index']) return vnic_index def update_vdr_internal_interface(self, edge_id, index, network, address_groups=None, is_connected=True): if not address_groups: address_groups = [] interface = { 'type': 'internal', 'connectedToId': network, 'mtu': 1500, 'isConnected': is_connected, 'addressGroups': {'addressGroup': address_groups} } interface_req = {'interface': interface} try: header, response = self.vcns.update_vdr_internal_interface( edge_id, index, interface_req) except exceptions.VcnsApiException: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Failed to update vdr interface on edge: " "%s"), edge_id) def delete_vdr_internal_interface(self, edge_id, interface_index): LOG.debug("Delete VDR interface on edge: %s", edge_id) try: header, response = self.vcns.delete_vdr_internal_interface( edge_id, interface_index) except exceptions.VcnsApiException: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Failed to delete vdr interface on edge: " "%s"), edge_id) # avoid bug 1389358 self.check_edge_jobs(edge_id) def _delete_interface(self, task): edge_id = task.userdata['edge_id'] vnic_index = task.userdata['vnic_index'] LOG.debug("start deleting vnic %s", vnic_index) try: self.vcns.delete_interface(edge_id, vnic_index) except exceptions.VcnsApiException: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Failed to delete vnic %(vnic_index)s: " "on edge %(edge_id)s"), {'vnic_index': vnic_index, 'edge_id': edge_id}) except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Failed to delete vnic %d"), vnic_index) return task_constants.TaskStatus.COMPLETED def delete_interface(self, router_id, edge_id, index, jobdata=None): task_name = "delete-interface-%s-%d" % (edge_id, index) userdata = { 'router_id': router_id, 'edge_id': edge_id, 'vnic_index': index, 'jobdata': jobdata } task = tasks.Task(task_name, router_id, self._delete_interface, userdata=userdata) task.add_result_monitor(self.callbacks.interface_delete_result) self.task_manager.add(task) # avoid bug 1389358 self.check_edge_jobs(edge_id) return task def _deploy_edge(self, task): userdata = task.userdata LOG.debug("NSXv: start deploying edge") request = userdata['request'] try: header = self.vcns.deploy_edge(request)[0] objuri = header['location'] job_id = objuri[objuri.rfind("/") + 1:] response = self.vcns.get_edge_id(job_id)[1] edge_id = response['edgeId'] LOG.debug("VCNS: deploying edge %s", edge_id) userdata['edge_id'] = edge_id status = task_constants.TaskStatus.PENDING except exceptions.VcnsApiException: with excutils.save_and_reraise_exception(): LOG.exception(_LE("NSXv: deploy edge failed.")) return status def _status_edge(self, task): edge_id = task.userdata['edge_id'] try: response = self.vcns.get_edge_deploy_status(edge_id)[1] task.userdata['retries'] = 0 system_status = response.get('systemStatus', None) if system_status is None: status = task_constants.TaskStatus.PENDING elif system_status == 'good': status = task_constants.TaskStatus.COMPLETED else: status = task_constants.TaskStatus.ERROR except exceptions.VcnsApiException as e: LOG.exception(_LE("VCNS: Edge %s status query failed."), edge_id) raise e except Exception as e: retries = task.userdata.get('retries', 0) + 1 if retries < 3: task.userdata['retries'] = retries LOG.exception(_LE("VCNS: Unable to retrieve edge %(edge_id)s " "status. Retry %(retries)d."), {'edge_id': edge_id, 'retries': retries}) status = task_constants.TaskStatus.PENDING else: LOG.exception(_LE("VCNS: Unable to retrieve edge %s status. " "Abort."), edge_id) status = task_constants.TaskStatus.ERROR LOG.debug("VCNS: Edge %s status", edge_id) return status def _result_edge(self, task): edge_id = task.userdata.get('edge_id') if task.status != task_constants.TaskStatus.COMPLETED: LOG.error(_LE("NSXv: Failed to deploy edge %(edge_id)s " "status %(status)d"), {'edge_id': edge_id, 'status': task.status}) else: LOG.debug("NSXv: Edge %s is deployed", edge_id) def _update_edge(self, task): edge_id = task.userdata['edge_id'] LOG.debug("start update edge %s", edge_id) request = task.userdata['request'] try: self.vcns.update_edge(edge_id, request) status = task_constants.TaskStatus.COMPLETED except exceptions.VcnsApiException as e: LOG.error(_LE("Failed to update edge: %s"), e.response) status = task_constants.TaskStatus.ERROR return status def _rename_edge(self, task): edge_id = task.userdata['edge_id'] LOG.debug("start rename edge %s", edge_id) try: # First get the current edge structure # [0] is the status, [1] is the body edge = self.vcns.get_edge(edge_id)[1] # remove some data that will make the update fail edge_utils.remove_irrelevant_keys_from_edge_request(edge) # set the new name in the request edge['name'] = task.userdata['name'] # update the edge self.vcns.update_edge(edge_id, edge) status = task_constants.TaskStatus.COMPLETED except exceptions.VcnsApiException as e: LOG.error(_LE("Failed to rename edge: %s"), e.response) status = task_constants.TaskStatus.ERROR return status def _delete_edge(self, task): edge_id = task.userdata['edge_id'] LOG.debug("VCNS: start destroying edge %s", edge_id) status = task_constants.TaskStatus.COMPLETED if edge_id: try: self.vcns.delete_edge(edge_id) except exceptions.ResourceNotFound: pass except exceptions.VcnsApiException as e: LOG.exception(_LE("VCNS: Failed to delete %(edge_id)s:\n" "%(response)s"), {'edge_id': edge_id, 'response': e.response}) status = task_constants.TaskStatus.ERROR except Exception: LOG.exception(_LE("VCNS: Failed to delete %s"), edge_id) status = task_constants.TaskStatus.ERROR return status def _get_edges(self): try: return self.vcns.get_edges()[1] except exceptions.VcnsApiException as e: LOG.exception(_LE("VCNS: Failed to get edges:\n%s"), e.response) raise e def deploy_edge(self, resource_id, name, internal_network, jobdata=None, dist=False, wait_for_exec=False, loadbalancer_enable=True, appliance_size=nsxv_constants.LARGE, async=True): task_name = 'deploying-%s' % name edge_name = name edge = self._assemble_edge( edge_name, datacenter_moid=self.datacenter_moid, deployment_container_id=self.deployment_container_id, appliance_size=appliance_size, remote_access=False, dist=dist) appliance = self._assemble_edge_appliance(self.resource_pool_id, self.datastore_id) if appliance: edge['appliances']['appliances'] = [appliance] if not dist: vnic_external = self._assemble_edge_vnic( constants.EXTERNAL_VNIC_NAME, constants.EXTERNAL_VNIC_INDEX, self.external_network, type="uplink") edge['vnics']['vnics'].append(vnic_external) else: edge['mgmtInterface'] = { 'connectedToId': self.external_network, 'name': "mgmtInterface"} if internal_network: vnic_inside = self._assemble_edge_vnic( constants.INTERNAL_VNIC_NAME, constants.INTERNAL_VNIC_INDEX, internal_network, constants.INTEGRATION_EDGE_IPADDRESS, constants.INTEGRATION_SUBNET_NETMASK, type="internal") edge['vnics']['vnics'].append(vnic_inside) # If default login credentials for Edge are set, configure accordingly if (cfg.CONF.nsxv.edge_appliance_user and cfg.CONF.nsxv.edge_appliance_password): edge['cliSettings'].update({ 'userName': cfg.CONF.nsxv.edge_appliance_user, 'password': cfg.CONF.nsxv.edge_appliance_password}) if not dist and loadbalancer_enable: self._enable_loadbalancer(edge) if async: userdata = { 'dist': dist, 'request': edge, 'router_name': name, 'jobdata': jobdata } task = tasks.Task(task_name, resource_id, self._deploy_edge, status_callback=self._status_edge, result_callback=self._result_edge, userdata=userdata) task.add_executed_monitor(self.callbacks.edge_deploy_started) task.add_result_monitor(self.callbacks.edge_deploy_result) self.task_manager.add(task) if wait_for_exec: # wait until the deploy task is executed so edge_id is # available task.wait(task_constants.TaskState.EXECUTED) return task else: edge_id = None try: header = self.vcns.deploy_edge(edge, async=False)[0] edge_id = header['location'].split('/')[-1] LOG.debug("VCNS: deploying edge %s", edge_id) self.callbacks.edge_deploy_started_sync( jobdata['context'], edge_id, name, jobdata['router_id'], dist) self.callbacks.edge_deploy_result_sync( jobdata['context'], edge_id, name, jobdata['router_id'], dist, True) except exceptions.VcnsApiException: self.callbacks.edge_deploy_result_sync( jobdata['context'], edge_id, name, jobdata['router_id'], dist, False) with excutils.save_and_reraise_exception(): LOG.exception(_LE("NSXv: deploy edge failed."))