def va_rollback(self, hostname, portgroup): """ rollback from microsegmentation Args: :hostname (str): hostname :portgroup (str): portgroup Returns (dict): response from roll back rest request """ logger.info('*****start roll back from segmentation*****') data = self.va_inventory_get_microseg_rollback_input_data( hostName=hostname, portGroup=portgroup) if len(data) < 5: logger.info( 'cannot generate correct input body ' 'for micro segmentation rest request') return post_data = dict() post_data['datacenter'] = data['datacenter'] post_data['vlan'] = data['vlan'] post_data['portgroup'] = data['portgroup'] post_data['host'] = data['host'] post_data['epi'] = data['epi'] logger.info('sending rollback rest request... input data:\n{}'.format(post_data)) response = self.va_rest_post_revert(data=post_data) try: if response['duration']: logger.info('rollback request success') except KeyError: raise InvalidKey('va_rollback') logger.info('*****finish roll back from segmentation*****')
def va_check_deployment_status(self, jobid=None): """ check deployment status :param jobid: job id :type jobid: str :return: """ method_name = 'va_check_dp_deployment_status' self._va_message_helper(method_name, 'start') input_params = [jobid] check_input = self._va_check_input_data(method_name, input_params) if check_input: return check_input params = {'jobid': jobid} response = self.va_get_inventory_deployment(params) if self._check_failed_message(response, method_name): return response ### status could be "complete", "complete with error, or warning" self._va_message_helper(method_name, 'end', response) if type(response) is list: for info in response: if 'status' in info.keys(): if 'complete' in info['status']: end_time = info['end_time'] start_time = info['start_time'] total_time = int(end_time) - int(start_time) logger.info( "DP Deployment is completed in {} seconds !". format(total_time)) return info['status'] else: return info['status'] return 'no status'
def va_configure_orchestration(self, **kwargs): """ configuration orchestration connection Args: **kwargs: :vcenter (inventory): inventory obj or :address (str) : vcenter ip :username (str) : vcenter username :password (str) : vcenter password :port (str) : vcenter port """ logger.info('*****start reconfiguring orchestration*****') self.va_inventory_delete_orchestration_configuration() if kwargs.get('vcenter', None): vcenter_object = kwargs.get('vcenter') self.va_inventory_set_orchestration_configuration( address=vcenter_object.get_mgmt_ip(), port='443', username=vcenter_object.get_user().get("name"), password=vcenter_object.get_user().get("password")) else: address = kwargs.get('address', None) port = kwargs.get('port', None) username = kwargs.get('username', None) password = kwargs.get('password', None) self.va_inventory_set_orchestration_configuration( address=address, port=port, username=username, password=password) logger.info('*****finish reconfiguring orchestration*****')
def va_cleanup_director(self): """ clean up all vlan mapping, change epi to tap mode and delete orchestration configuration """ logger.info('*****start cleaning director*****') seg_stats = self.va_rest_get_segmentation_stats() hostnames = [] try: hosts = [] datacenters = seg_stats['response']['datacenters'] for datacenter in datacenters: clusters = datacenter['cluster'] for cluster in clusters: hosts.append(cluster['hosts']) hosts.append(datacenter['hosts']) for host in hosts: for h in host: if h['hasEpi']: hostnames.append(h['name']) for hostname in hostnames: self.va_delete_all_vlan_mapping(hostname=hostname) self.va_change_epi_mode(hostname=hostname, mode='tap') self.va_inventory_delete_orchestration_configuration() logger.info('*****finish cleaning director*****') except KeyError: raise InvalidKey('va_director_cleanup')
def va_inventory_delete_orchestration_configuration(self): """ delete orchestration configuration """ logger.info('***deleting orchestration configuration***') path = dict() path['name'] = 'server1' self.va_rest_delete_config_orchestration(path=path) logger.info('***finish deleting orchestration configuration***') return
def va_rollback(self, **kwargs): """ roll back from microsegmentation :param kwargs: | segmentData (dict) - | { | 'instance': '', | 'vlanID': '', | 'segment': '', | 'hostUUID': '', | 'epiUUID': '', | } | | or | | instance (str) - vcenter instance | vlanID (str) - vlan id | segment (str) - segment | hostUUID (str) - host uuid | epiUUID (str) - epi uuid :return: error message :type: str """ method_name = 'va_rollback' self._va_message_helper(method_name, 'start') postData = {} segmentData = kwargs.get('segmentData', None) if not segmentData: postData['instance'] = kwargs.get('instance', None) postData['vlan'] = kwargs.get('vlanID', None) postData['endpoint_group'] = kwargs.get('segment', None) postData['host'] = kwargs.get('hostUUID', None) postData['epi'] = kwargs.get('epiUUID', None) else: postData['instance'] = segmentData['instance'] postData['vlan'] = segmentData['vlanID'] postData['endpoint_group'] = segmentData['segment'] postData['host'] = segmentData['hostUUID'] postData['epi'] = segmentData['epiUUID'] check_input = self._va_check_input_data(method_name, postData) if check_input: return check_input response = self.va_rest_post_revert(postData) if self._check_failed_message(response, method_name): return response logger.info('... sleep for 15 secs ...') time.sleep(15) self._va_message_helper(method_name, 'end')
def va_get_vlan_mapping(self, hostname): """ return vlan mapping Args: :hostname (str): hostname Returns (dict): vlan mapping of the host {'segment':['micro-vlans']} """ logger.info('*****start getting all vlan mapping*****') epi_uuid = self.va_inventory_get_epi_uuid_by_host(hostName=hostname) response = self.va_rest_get_micro_segmentation() vlan_info = dict() try: if response['status'] == 'ok': segments = response['response'] for s in segments: if s['epi'].lower() == epi_uuid: micro_vlan = s['micro-vlan'] segment = s['segment'] if vlan_info.get(segment) is None: data = list() data.append(micro_vlan) vlan_info[segment] = data else: data = vlan_info[segment] data.append(micro_vlan) vlan_info[segment] = data except KeyError: raise InvalidKey('va_get_vlan_mapping') logger.info('vlan mapping description {\'segment id\' : [\'micro-vlans\']}') logger.info('vlan mapping for host {}: {}'.format(hostname, vlanInfo)) logger.info('*****finish getting all vlan mapping*****') return vlanInfo
def _va_message_helper(self, method_name, position='start', result=None, success=True): """ print message :param method_name: method name :type method_name: str :param position: beginning or end of message :type position: str :param success: method runs successful or not :type success: bool """ if position == 'start': logger.info('%s %s start %s' % (self.STARS, method_name, self.STARS)) else: if result: if success: logger.info('%s %s returns - %s %s' % (self.DOTS, method_name, result, self.DOTS)) else: logger.error('%s %s returns empty result %s' % (self.DOTS, method_name, self.DOTS)) else: if success: logger.info('%s %s succeeded %s' % (self.DOTS, method_name, self.DOTS)) else: logger.error('%s %s failed %s' % (self.DOTS, method_name, self.DOTS)) logger.info('%s %s finish %s' % (self.STARS, method_name, self.STARS))
def va_get_plugin_connection_time(self, **kwargs): """ configure orchestration connection :param kwargs: | instance (str) - vcenter instance :return: error message if any :type: str """ method_name = 'va_check_plugin_connection_time' self._va_message_helper(method_name, 'start') instance = kwargs.get('instance', None) timeout = kwargs.get('timeout', None) if not instance: error_message = "missing vcenter instance! " return error_message if not timeout: timeout = 120 start_time = datetime.datetime.now().replace(microsecond=0) while timeout >= 0: response = self.va_inventory_get_update_status(instance) if self._check_failed_message(response, method_name): return response if response and type(response) is dict: break logger.info('waiting for plugin to add {}'.format(instance)) time.sleep(10) timeout -= 1 end_time = datetime.datetime.now().replace(microsecond=0) wait_time = end_time - start_time logger.info('... plugin ready takes {} secs ...'.format(end_time - start_time)) if timeout < 0: error_message = 'plugin not ready in {} \nreason timeout'.format( wait_time) if self._check_failed_message(error_message, method_name): return None return wait_time self._va_message_helper(method_name, 'end')
def va_change_epi_mode(self, **kwargs): """ change epi mode Args: **kwargs: :hostname (str): hostname :portgroup (str): portgroup (optional) :mode (str): inline, tap, standby """ logger.info('*****start changing epi mode*****') logger.info('changing epi on host {} to {} mode' .format(kwargs.get('hostname', None), kwargs.get('mode', None))) if kwargs.get('portgroup', None): curr_mode = self.va_get_epi_mode( hostname=kwargs.get('hostname', None), portgroup=kwargs.get('portgroup')) if kwargs.get('mode', None) == curr_mode: return epi_uuid = self.va_inventory_get_epi_uuid_by_host( hostName=kwargs.get('hostname', None)) path = dict() data = dict() path['epiuuid'] = epi_uuid data['operation-mode'] = kwargs.get('mode', None) self.va_rest_put_config_chassis_epi(path=path, data=data) logger.info('*****finish changing epi mode*****')
def va_get_non_segmented_workload(self, host_name, port_group): """ get number of non segmented workloads Args: :hostName (str): hostname :portGroup (str): portgroup Returns (int): number of non segmented workload """ logger.info('*****start getting non segment workload*****') workloads = self.va_inventory_get_workload_information( host_name=host_name, port_group=port_group) count = 0 try: for workload in workloads: vnics = workload['vnics'] for vnic in vnics: if vnic['pre-mseg']['portgroup'] == portGroup and vnic['microsegmented'] is False: count += 1 except KeyError: raise InvalidKey('va_get_non_segmented_workload') logger.info('not segmented workload on hostname: {} portgroup: {} workload: {}' .format(hostName, portGroup, count)) logger.info('*****finish getting non segment workload*****') return count
def va_check_epi_status(self): """ check epi status Returns (boolean): True if all epi are up otherwise False """ logger.info('*****start checking epi status*****') response = self.va_rest_get_chassis_epi() try: if response['status'] == 'ok': epis = response['response'] for epi in epis: if epi['state'] != 'up': logger.info('epi status: down') logger.info('*****finish checking epi status*****') return False logger.info('epi status: up') logger.info('*****finish checking epi status*****') return True else: return False except KeyError: raise InvalidKey('va_check_epi_status')
def va_check_orchestration_connection(self): """ check orchestration connection status Returns (boolean): True if orchestration is connected, False otherwise """ logger.info('*****start checking orchestration*****') responses = self.va_rest_get_orchestration() try: responses = responses['response'] for response in responses: enable = response['enable'] if enable: logger.info('orchestration connection status: connected') logger.info('*****finish checking orchestration*****') return True except KeyError: raise InvalidKey('va_check_orchestration_connection') logger.info('orchestration connection status: not connected') logger.info('*****finish checking orchestration*****') return False
def va_get_epi_mode(self, hostname, portgroup): """ return epi mode according to provided host name and port group Args: :hostname (str): hostname :portgroup (str): portgroup Returns (str): inline, tap or standby """ datacenter = self.va_inventory_get_datacenters_by_host(hostName=hostname) params = {'datacenter': datacenter} hosts_by_datacenter = self.va_rest_get_hosts_inventory(params=params) try: hosts_by_datacenter = hosts_by_datacenter['response'] hosts = [] clusters = hosts_by_datacenter['clusters'] for cluster in clusters: hosts.append(cluster['hosts']) hosts.append(hosts_by_datacenter['hosts']) for host in hosts: for h in host: if h['name'] == hostname: workloads_data = h['workloads'] for workload in workloads_data: vnics = workload['vnics'] for vnic in vnics: if vnic['pre-mseg']['portgroup'] == portgroup: epis = h['epis'] for epi in epis: logger.info('epi mode for hostname: {}, portgroup {}: mode: {}' .format(hostname, portgroup, epi['mode'])) return epi['mode'] except KeyError: raise InvalidKey('va_get_epi_mode')
def va_delete_all_vlan_mapping(self, hostname): """ delete all vlan mapping Args: :hostname (str): hostname """ logger.info('*****start delete all vlan mapping*****') epiuuid = self.va_inventory_get_epi_uuid_by_host(hostName=hostname) vlanmapping = self.va_get_vlan_mapping(hostname=hostname) try: path = dict() path['epiuuid'] = epiuuid for key, value in vlanmapping.items(): path['segment'] = key for vlan in value: path['micro-vlan'] = vlan logger.info('deleting vlan {} in segment {}' .format(vlan, key)) self.va_rest_delete_micro_segmentation(path=path) logger.info('*****finish delete all vlan mapping*****') except KeyError: raise InvalidKey('va_delete_all_vlan_mapping')
def va_configure_orchestration(self, **kwargs): """ configure orchestration connection :param kwargs: | vcenter (inventory) - inventory object | | or | | address (str) - vcenter ip | username (str) - vcenter username | password (str) - vcenter password | port (str) - vcenter port | instance (str) - vcenter instance :return: error message if any :type: str """ method_name = 'va_configure_orchestration' self._va_message_helper(method_name, 'start') vcenter_object = kwargs.get('vcenter', None) if not vcenter_object: address = kwargs.get('address', None) port = kwargs.get('port', None) username = kwargs.get('username', None) password = kwargs.get('password', None) instance = kwargs.get('instance', None) else: address = vcenter_object.get_mgmt_ip() port = '443' username = vcenter_object.get_user().get("name") password = vcenter_object.get_user().get("password") instance = vcenter_object.get_uniq_id() input_params = [instance, address, username, password, port] check_input = self._va_check_input_data(method_name, input_params) if check_input: return check_input response = self.va_inventory_get_orchestration() if self._check_failed_message(response, method_name): return response if response: for info in response: if 'name' in info.keys() and instance == info['name']: response = self.va_remove_orchestration(instance, True) if self._check_failed_message(response, method_name): return response start_time = datetime.datetime.now().replace(microsecond=0) response = self.va_inventory_add_orchestration_configuration( instance, address, username, password) if self._check_failed_message(response, method_name): return response timeout = 30 while timeout >= 0: response = self.va_inventory_get_update_status(instance) if self._check_failed_message(response, method_name): return response if response and type(response) is dict: break logger.info('waiting for plugin to add {}'.format(instance)) time.sleep(5) timeout -= 1 end_time = datetime.datetime.now().replace(microsecond=0) logger.info( '... configure orchestration takes {} secs ...'.format(end_time - start_time)) if timeout < 0: error_message = 'failed to add {} to orchestration\nreason timeout'.format( instance) if self._check_failed_message(error_message, method_name): return error_message self._va_message_helper(method_name, 'end')
def va_remove_orchestration(self, instance=None, config_orch_helper=False): """ remove orchestration :param instance: vcenter instance :type instance: str :return: error message :type: str """ method_name = None if not config_orch_helper: method_name = 'va_remove_orchestration' if not config_orch_helper: self._va_message_helper(method_name, 'start') start_time = datetime.datetime.now().replace(microsecond=0) timeout = 30 if instance: response = self.va_inventory_remove_orchestration_configuration( instance) if self._check_failed_message(response, method_name): return response while timeout >= 0: response = self.va_inventory_get_update_status(instance) if response and type( response) is str and 'not' in response.lower(): break logger.info('waiting for plugin to remove {}'.format(instance)) time.sleep(10) timeout -= 1 else: response = self.va_inventory_get_orchestration() if self._check_failed_message(response, method_name): return response instances = [] if response: for info in response: if 'name' in info.keys(): instances.append(info['name']) response = self.va_inventory_remove_orchestration_configuration( info['name']) if self._check_failed_message(response, method_name): return response if instances: while timeout >= 0: for instance in instances: response = self.va_inventory_get_update_status( instance) if self._check_failed_message(response, method_name): return response if response and type( response) is str and 'not' in response.lower(): instances.remove(instance) if not instances: break logger.info('waiting for plugin to remove all instance') time.sleep(10) timeout -= 1 end_time = datetime.datetime.now().replace(microsecond=0) logger.info( '... delete orchestration takes {} secs ...'.format(end_time - start_time)) if timeout < 0: error_message = 'failed to remove {} from orchestration\nreason timeout'.format( instance) if self._check_failed_message(error_message, method_name): return error_message if not config_orch_helper: self._va_message_helper(method_name, 'end')
def va_reboot(self, cmd=None, timeout=60, persistent=False, reconnect_delay=100, typemode='cli'): """ method to perform a system reboot on cli or shell mode on a varmour vm. Kwargs: :cmd (str): command to reboot :timeout (int): wait time for device to come back up. :persistent (bool): after reboot need access to device :reconnect_delay (int): timeout of reconnect :typemode (str) : cli or shell """ cli = self.cli cli_prompt = cli.get_prompt() mgt_ip = self._resource.get_mgmt_ip() if typemode == 'cli': self.va_cli() else: self.va_shell() self.va_log_command(cmd) if typemode == 'cli': i = 0 while i < 5: try: cli.exec_command(cmd, timeout=timeout, prompt=cli_prompt.sys_reboot()) break except Exception as err: cli.va_exec_cli('\003') logger.error(err) i += 1 continue cli.exec_command('Y', timeout=timeout, command_output=False, prompt=cli_prompt.sys_reboot_ack()) else: try: cli.exec_command(cmd) except Exception as err: logger.info(err) if persistent: logger.debug('disconnect device') self.va_disconnect() logger.debug('Sleep 30 seconds to wait device reboot') max = int(reconnect_delay / 5) + 1 time.sleep(30) logger.debug('Start to connect device after reboot') index = 1 for i in range(1, max): try: if platform.system() == 'Windows': ping_info = os.popen('ping {} -n 2'.format(mgt_ip)) match_reg = 'Packets: Sent = \d+, Received = \d+, Lost = (\d+) \(\d+% loss\)' elif platform.system() == 'Darwin': ping_info = os.popen('ping -c 2 {}'.format(mgt_ip)) match_reg = '\d+ packets transmitted, \d+ packets received, (\d+)\.\d+% packet loss' else: ping_info = os.popen('ping {} -c 2'.format(mgt_ip)) match_reg = '\d+ packets transmitted, \d+ received, (\d+)% packet loss' ping_content = ping_info.readlines() ping_content = ''.join(ping_content) loss_match = re.search(r'%s' % match_reg, ping_content, re.I | re.M) ping_info.close() logger.debug('Check the status of mgt interface') logger.debug(ping_content) if loss_match is not None and int( loss_match.group(1)) == 0: logger.debug('The management interface was UP') logger.debug( 'Try to connect device on {} time'.format(index)) time.sleep(2) self.va_init_cli(timeout=10, persistent=persistent) return True else: log_info = 'The management interface was down. sleep 5 time,' log_info += ' then try to check the interface again' logger.debug(log_info) time.sleep(5) continue except Exception as err: logger.error(err) time.sleep(5) continue index += 1
def va_microsegment(self, **kwargs): """ trigger microsegmentation :param kwargs: | network (str) - vss or vds | | if network is vss: | segmentData (dict) - | { | 'instance': '', | 'vlanID': '', | 'segment': '', | 'hostUUID': '', | 'epiUUID': '', | } | | or | | instance (str) - vcenter instance | vlanID (str) - vlan id | segment (str) - segment | hostUUID (str) - host uuid | epiUUID (str) - epi uuid | | if network is vds: | segmentData (dict) - | { | 'instance': '', | 'domain': '', | 'vlan_range': '', | } | | or | | instance (str) - vcenter instance | domain (str) - datacenter name | vlan_range (str) - vlan range :return: error message :type: str """ method_name = 'va_microsegment' self._va_message_helper(method_name, 'start') postData = {} network = kwargs.get('network', 'vss') segmentData = kwargs.get('segmentData', None) if network == 'vss': if not segmentData: postData['instance'] = kwargs.get('instance', None) postData['vlan'] = kwargs.get('vlanID', None) postData['endpoint_group'] = kwargs.get('segment', None) postData['host'] = kwargs.get('hostUUID', None) postData['epi'] = kwargs.get('epiUUID', None) else: postData['instance'] = segmentData['instance'] postData['vlan'] = segmentData['vlanID'] postData['endpoint_group'] = segmentData['segment'] postData['host'] = segmentData['hostUUID'] postData['epi'] = segmentData['epiUUID'] else: if not segmentData: postData['instance'] = kwargs.get('instance', None) postData['domain'] = kwargs.get('domain', None) postData['vlan_range'] = kwargs.get('vlan_range', None) else: postData['instance'] = segmentData['instance'] postData['domain'] = segmentData['domain'] postData['vlan_range'] = segmentData['vlan_range'] check_input = self._va_check_input_data(method_name, postData) if check_input: return check_input response = self.va_rest_post_microsegmentation(postData) if self._check_failed_message(response, method_name): return response logger.info('... sleep for 30 secs ...') time.sleep(30) self._va_message_helper(method_name, 'end')