def first_attempt(self, conn, conn_addr): self._logger.info(Tools.create_log_msg(logmsg.OSSH_SERVICE, conn_addr[0], logmsg.OSSH_CONN_ATTEMPT.format( c.oss_seen_devices[conn_addr[0]]['attempt'], conn_addr))) try: transport = paramiko.Transport(conn) transport.connect(username=c.conf.YAPT.DeviceUsr, password=Tools.get_password(pwd_type=c.YAPT_PASSWORD_TYPE_DEVICE)) with SCPClient(transport=transport) as scp: scp.put(c.conf.SERVICES.Ossh.LocalConfigFile, remote_path=c.conf.SERVICES.Ossh.RemoteConfigFile) transport.close() conn.close() except (BadHostKeyException, AuthenticationException, SSHException) as e: self._logger.info(Tools.create_log_msg(logmsg.OSSH_SERVICE, conn_addr[0], logmsg.OSSH_FILE_PROV_FAILED.format(conn_addr[0], e.message))) self._logger.info(Tools.create_log_msg(logmsg.OSSH_SERVICE, conn_addr[0], logmsg.OSSH_CLOSE_CONN)) conn.close() c.oss_seen_devices_lck.acquire() try: del c.oss_seen_devices[conn_addr[0]] finally: c.oss_seen_devices_lck.release() return
def send_message_amqp(self, message, routing_key): connection = pika.BlockingConnection( pika.ConnectionParameters(host=c.conf.AMQP.Host, port=c.conf.AMQP.Port, credentials=pika.PlainCredentials(c.conf.AMQP.User, Tools.get_password( c.YAPT_PASSWORD_TYPE_AMQP)))) channel = connection.channel() channel.queue_declare(queue=self._routing_key, durable=False) channel.basic_publish(exchange='', routing_key=routing_key, body=message, properties=pika.BasicProperties( delivery_mode=1, )) connection.close()
def __init__(self, group=None, target=None, name=None, args=(), kwargs=None): """ :param group: :param target: :type target: Processor :param name: :param args: :param kwargs: """ super(AMQPBlockingServerAdapter, self).__init__(group=group, target=target, name=name, args=args, kwargs=kwargs) self._exchange = args[0] self._type = args[1] self._routing_key = args[2] self._queue = args[3] self._logger = c.logger try: self._connection = pika.BlockingConnection( pika.ConnectionParameters(host=c.conf.AMQP.Host, port=c.conf.AMQP.Port, credentials=pika.PlainCredentials(c.conf.AMQP.User, Tools.get_password( c.YAPT_PASSWORD_TYPE_AMQP)))) self._channel = self._connection.channel() self._channel.queue_declare(queue=self._queue, durable=False) self._channel.basic_qos(prefetch_count=1) self._channel.basic_consume(self.receive_message, queue=self._routing_key) except exceptions.ConnectionClosed as err: print Tools.create_log_msg('AMQP', None, logmsg.AMQP_BUS_NOK.format(err)) self._logger.info(Tools.create_log_msg('AMQP', None, logmsg.AMQP_BUS_NOK.format(err))) sys.exit() Tools.create_amqp_startup_log(exchange=self._exchange, type=self._type, routing_key=self._routing_key, host=c.conf.AMQP.Host, channel=self._channel)
def __init__(self, exchange=None, routing_key=None): self._exchange = exchange self._routing_key = routing_key self._logger = c.logger try: self._connection = pika.BlockingConnection( pika.ConnectionParameters(host=c.conf.AMQP.Host, port=c.conf.AMQP.Port, credentials=pika.PlainCredentials(c.conf.AMQP.User, Tools.get_password( c.YAPT_PASSWORD_TYPE_AMQP)))) self._channel = self._connection.channel() self._result = self._channel.queue_declare(exclusive=True) self._callback_queue = self._result.method.queue self._channel.basic_consume(self.on_response, no_ack=True, queue=self._callback_queue) self._response = None self._corr_id = None except pika.exceptions.ConnectionClosed as err: print Tools.create_log_msg('AMQP', None, logmsg.AMQP_BUS_NOK.format(err)) self._logger.info(Tools.create_log_msg('AMQP', None, logmsg.AMQP_BUS_NOK.format(err)))
def run_task(self): status_dev_cfg, dev_data_file = Tools.get_config( lookup_type=c.CONFIG_LOOKUP_TYPE_GET_DEVICE_CFG_FILE, sample_device=self.sample_device) status_template, template_file = Tools.get_config( lookup_type=c.CONFIG_LOOKUP_TYPE_GET_TEMPLATE_FILE, sample_device=self.sample_device) if status_dev_cfg: if status_template: loader = DataLoader() try: ds = loader.load_from_file( os.getcwd() + '/' + self.grp_cfg.TASKS.Provision. Configuration.Ansibleapi.PlaybookPath + self.grp_cfg. TASKS.Provision.Configuration.Ansibleapi.Playbook) except AnsibleFileNotFound as afnf: self.update_task_state( new_task_state=c.TASK_STATE_FAILED, task_state_message=logmsg.PLAYBOOK_NOT_FOUND.format( afnf)) Tools.emit_log( task_name=self.task_name, sample_device=self.sample_device, message=logmsg.PLAYBOOK_NOT_FOUND.format(afnf)) return # Dynamic Inventory inventory = """ [YAPT] {{ hosts }} [YAPT:vars] junos_user={{ junos_user }} junos_password={{ junos_password }} template_src={{ template_src }} template_dst={{ template_dst }} device_vars={{ device_vars }} heading={{ heading }} """ inventory_template = jinja2.Template(inventory) ''' ## Last changed: 2017-10-16-2139 version 12.1X47-D35.2; ''' heading = """## Last changed: {0} version {1}; """.format( datetime.datetime.now().strftime('%Y-%m-%d-%H%M'), self.sample_device.softwareVersion) rendered_inventory = inventory_template.render({ 'hosts': self.sample_device.deviceIP, 'junos_user': c.conf.YAPT.DeviceUsr, 'junos_password': Tools.get_password(c.YAPT_PASSWORD_TYPE_DEVICE), 'template_src': template_file, 'template_dst': os.getcwd() + '/history/' + self.sample_device.deviceSerial + '-' + datetime.datetime.now().strftime('%Y-%m-%d-%H%M') + '.conf', 'device_vars': dev_data_file, 'heading': heading }) self.logger.debug( Tools.create_log_msg(self.task_name, self.sample_device.deviceSerial, rendered_inventory)) # Create a temporary file and write the template string to it hosts = NamedTemporaryFile(delete=False) hosts.write(rendered_inventory) hosts.close() inventory = InventoryManager(loader=loader, sources=hosts.name) variable_manager = VariableManager(loader=loader, inventory=inventory) Options = namedtuple('Options', [ 'listtags', 'listtasks', 'listhosts', 'syntax', 'connection', 'module_path', 'forks', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity', 'check', 'diff' ]) options = Options(listtags=False, listtasks=False, listhosts=True, syntax=False, connection='ssh', module_path=None, forks=100, remote_user=None, private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=False, become_method=None, become_user=None, verbosity=None, check=False, diff=False) passwords = dict( vault_pass=Tools.get_password(c.YAPT_PASSWORD_TYPE_DEVICE)) play = Play.load(data=ds[0], variable_manager=variable_manager, loader=loader) results_callback = CallbackModule( sample_device=self.sample_device, shared=self.shared, update_task_state=self.update_task_state) tqm = None try: tqm = TaskQueueManager( inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords, stdout_callback=results_callback, ) result = tqm.run(play) if result > 0: self.update_task_state( new_task_state=c.TASK_STATE_FAILED, task_state_message=logmsg.ANSIBLE_ERROR) Tools.emit_log(task_name=self.task_name, sample_device=self.sample_device, message=logmsg.ANSIBLE_ERROR) os.remove(hosts.name) return else: self.update_task_state( new_task_state=c.TASK_STATE_PROGRESS, task_state_message=logmsg.PLAYBOOK_FINISHED_SUCCESS ) self.sample_device.deviceConnection.facts_refresh() self.sample_device.deviceConnection.facts_refresh( keys='hostname') self.sample_device.deviceName = self.sample_device.deviceConnection.facts[ 'hostname'] self.update_task_state( new_task_state=c.TASK_STATE_DONE, task_state_message=c.TASK_STATE_MSG_DONE) Tools.emit_log( task_name=self.task_name, task_state={ 'taskState': self.task_state, 'taskStateMsg': c.TASK_STATE_MSG_DONE }, sample_device=self.sample_device, grp_cfg=self.grp_cfg, shared=self.shared, message=logmsg.PLAYBOOK_FINISHED_SUCCESS, scope=c.LOGGER_SCOPE_ALL, level=c.LOGGER_LEVEL_INFO) os.remove(hosts.name) except Exception as e: self.update_task_state( new_task_state=c.TASK_STATE_FAILED, task_state_message=logmsg.PLAYBOOK_ERROR.format(e)) Tools.emit_log(task_name=self.task_name, sample_device=self.sample_device, message=logmsg.PLAYBOOK_ERROR.format(e)) return finally: if tqm is not None: tqm.cleanup() else: self.update_task_state( new_task_state=c.TASK_STATE_FAILED, task_state_message=logmsg.ERROR_DEV_CFG_FILE) Tools.emit_log(task_name=self.task_name, sample_device=self.sample_device, message=logmsg.ERROR_DEV_TEMPLATE_FILE.format( template_file)) else: self.update_task_state( new_task_state=c.TASK_STATE_FAILED, task_state_message=logmsg.ERROR_DEV_CFG_FILE) Tools.emit_log( task_name=self.task_name, sample_device=self.sample_device, message=logmsg.ERROR_DEV_CFG_FILE.format(dev_data_file)) return
def check_for_dmi(self, conn, conn_addr): """ Verify MSG-ID, DeviceID and HMAC. If one of the three doesn't match close connection. Otherwise go ahead with provisioning steps. :param conn: :return: """ dmi = dict() msg = '' count = 5 while len(msg) < 1024 and count > 0: c_recv = conn.recv(1) c_recv = c_recv.decode() if c_recv == '\r': continue if c_recv == '\n': count -= 1 if msg.find(':'): (key, value) = msg.split(': ') dmi[key] = str(value) msg = '' else: msg += c_recv dmi['HOST-KEY'] = dmi['HOST-KEY'].strip('\x00') if dmi: if dmi['MSG-ID'] == c.DMI_MSGID: self._logger.info(Tools.create_log_msg(logmsg.OSSH_SERVICE, conn_addr[0], logmsg.OSSH_DMI_RECEIVED)) if 'HMAC' in dmi: lhmac = hmac.new(key=Tools.get_password(c.YAPT_PASSWORD_TYPE_OSSH), msg=dmi['HOST-KEY'], digestmod=hashlib.sha1).hexdigest() if hmac.compare_digest(dmi['HMAC'], lhmac): self._logger.info(Tools.create_log_msg(logmsg.OSSH_SERVICE, conn_addr[0], logmsg.OSSH_HMAC_VERIFY.format('Good'))) return True, dmi['DEVICE-ID'] else: self._logger.info(Tools.create_log_msg(logmsg.OSSH_SERVICE, conn_addr[0], logmsg.OSSH_HMAC_VERIFY.format('Failed'))) conn.close() return False, None else: self._logger.info(Tools.create_log_msg(logmsg.OSSH_SERVICE, conn_addr[0], logmsg.OSSH_HMAC_EMPTY)) conn.close() return False, None else: self._logger.info(Tools.create_log_msg(logmsg.OSSH_SERVICE, conn_addr[0], logmsg.OSSH_BAD_DMI)) conn.close() return False, None else: self._logger.info(Tools.create_log_msg(logmsg.OSSH_SERVICE, conn_addr[0], logmsg.OSSH_BAD_DMI)) conn.close() return False, None
def discover_by_space(self, sample_device=None, shared=None): with c.lrr_lock: c.lrr_counter += 1 queue = 'yaptDiscover' + str(c.lrr_counter) resp = self.create_hornet_queue(queue) if resp: self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_INIT.format(sample_device.deviceSerial))) URI = 'api/space/device-management/discover-devices?queue=https://{0}/api/hornet-q/queues/jms.queue.{1}'.format( c.conf.JUNOSSPACE.Ip, queue) HEADER = { 'Content-Type': 'application/vnd.net.juniper.space.device-management.discover-devices+xml;version=2;charset=UTF-8' } template = Template( open(c.conf.JUNOSSPACE.TemplateDir + '/discoverDevice.j2').read()) BODY = template.render(ip_address=sample_device.deviceIP, user=c.conf.YAPT.DeviceUsr, password=Tools.get_password( c.YAPT_PASSWORD_TYPE_DEVICE)) response = self.post(URI, HEADER, BODY) xmlRoot = ET.fromstring(response.text) jobId = xmlRoot.find('id').text self.logger.info( Tools.create_log_msg(logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_JOB.format(str(jobId)))) URI = 'api/hornet-q/queues/jms.queue.{0}'.format(queue) HEADER = '' BODY = '' response = self.head(URI, HEADER, BODY) pull_consumers = response.headers['msg-pull-consumers'] pattern = r'https://\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/(.*)' regex = re.compile(pattern, re.MULTILINE) result = re.findall(regex, pull_consumers) URI = result[0] HEADER = {'Accept-Wait': '5'} BODY = '' response = self.post(URI, HEADER, BODY) while True: if 'msg-consume-next' in response.headers: msg_consume_next = response.headers['msg-consume-next'] pattern = r'https://\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/(.*)' regex = re.compile(pattern, re.MULTILINE) result = re.findall(regex, msg_consume_next) URI = result[0] response = self.post(URI, HEADER, BODY) if response.status_code == 503: self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_STATE.format( 'Waiting for Junos Space response'))) elif response.status_code == 200: xmlRoot = ET.fromstring(response.text) taskId = xmlRoot.find('taskId').text if jobId == taskId: state = xmlRoot.findall("./state") if state[0].text == 'INPROGRESS': self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_STATE.format( state[0].text))) elif state[0].text == 'DONE': self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_STATE.format( state[0].text))) self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_CLENUP.format( sample_device.deviceSerial))) URI = 'api/hornet-q/queues/jms.queue.' + queue HEADER = '' # Todo: Check response code in response is 204 --> OK # Todo: If not 204 what todo? response = self.delete(URI, HEADER) if c.lrr_counter > 0: with c.lrr_lock: c.lrr_counter -= 1 summary = xmlRoot.find('summary').text self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_OK_SUM.format( sample_device.deviceSerial, summary))) pattern = r'Job was cancelled by user\s.*' regex = re.compile(pattern, re.MULTILINE) result = re.findall(regex, summary) if result: self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_JOB_CANCELED)) break else: pattern = r'Number\sof\s(.*?):\s(\d)<br>' regex = re.compile(pattern, re.MULTILINE) result = re.findall(regex, summary) result = dict( (x, int(y)) for x, y in result) # Number should always be one because we are discovering only one device. So we can use # this getting info about discovery state for current device # # Number of scanned IP: 1<br> # Number of Device Managed: 1<br> # Number of Discovery succeeded: 1<br> # Number of Already Managed: 0<br> # Number of Add Device failed: 0<br> # Number of Skipped: 0<br> # Number of scanned IP: 1<br>Number of Discovery succeeded: 0<br>Number of Add Device failed: 0<br>Number of Already Managed: 1<br>Number of Skipped: 0<br>Number of Device Managed: 0<br> if result[c.SPACE_DISCOVERY_NOAM] != 0: self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_STATE.format( 'Already managed'))) return c.TASK_STATE_DONE elif result[c.SPACE_DISCOVERY_NOADF] != 0: sample_device.deviceTasks.taskState[ 'Discovery'] = 'Failed' self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_STATE.format( 'Failed'))) return c.TASK_STATE_FAILED elif result[c.SPACE_DISCOVERY_NODS] != 0: self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_STATE.format( 'Succeeded'))) return c.TASK_STATE_DONE elif result[c.SPACE_DISCOVERY_NOS] != 0: self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_STATE.format( 'Skipped'))) return c.TASK_STATE_DONE break else: self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_UNKOWN_STATE.format( state[0].text))) return c.TASK_STATE_FAILED else: self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_UNKOWN_CODE.format( response.status_code))) return c.TASK_STATE_FAILED else: self.logger.info( Tools.create_log_msg( logmsg.SPACE, sample_device.deviceSerial, logmsg.DISCOVERY_UNKOWN_CODE.format( response.status_code))) return c.TASK_STATE_FAILED else: return c.TASK_STATE_FAILED
def discover_by_space(self, sample_device=None, shared=None): with Tools.lrr_lock: Tools.lrr_counter += 1 queue = 'yaptDiscover' + str(Tools.lrr_counter) self.create_hornet_queue(queue) self.logger.info( 'PROVSPACE-[%s]: Start Junos Space discovery process for device: %s', sample_device.deviceIP, sample_device.deviceIP) sample_device.deviceProvisionTasks.taskState['Discovery'] = 'Discover' URI = 'api/space/device-management/discover-devices?queue=https://' + Tools.conf.JUNOSSPACE.Ip + \ '/api/hornet-q/queues/jms.queue.' + queue HEADER = { 'Content-Type': 'application/vnd.net.juniper.space.device-management.discover-devices+xml;version=2;charset=UTF-8' } template = Template( open(Tools.conf.JUNOSSPACE.TemplateDir + '/discoverDevice.j2').read()) BODY = template.render(ip_address=sample_device.deviceIP, user=Tools.conf.YAPT.DeviceUsr, password=Tools.get_password( Tools.YAPT_PASSWORD_TYPE_DEVICE)) response = self.post(URI, HEADER, BODY) if response is not None: xmlRoot = ET.fromstring(response.text) jobId = xmlRoot.find('id').text self.logger.info( 'PROVSPACE-[%s]: Change is in progress - check job ID %s', sample_device.deviceIP, str(jobId)) URI = 'api/hornet-q/queues/jms.queue.' + queue HEADER = '' BODY = '' response = self.head(URI, HEADER, BODY) pull_consumers = response.headers['msg-pull-consumers'] pattern = r'https://\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/(.*)' regex = re.compile(pattern, re.MULTILINE) result = re.findall(regex, pull_consumers) URI = result[0] HEADER = {'Accept-Wait': '5'} BODY = '' response = self.post(URI, HEADER, BODY) while True: if 'msg-consume-next' in response.headers: msg_consume_next = response.headers['msg-consume-next'] pattern = r'https://\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/(.*)' regex = re.compile(pattern, re.MULTILINE) result = re.findall(regex, msg_consume_next) URI = result[0] response = self.post(URI, HEADER, BODY) if response.status_code == 503: self.logger.info( 'PROVSPACE-[%s]: Discovery for device %s state is: %s', sample_device.deviceIP, sample_device.deviceIP, 'Waiting for Junos Space response') sample_device.deviceProvisionTasks.taskState[ 'Discovery'] = 'Waiting for response' elif response.status_code == 200: xmlRoot = ET.fromstring(response.text) taskId = xmlRoot.find('taskId').text if jobId == taskId: state = xmlRoot.findall("./state") if state[0].text == 'INPROGRESS': self.logger.info( 'PROVSPACE-[%s]: Discovery for device %s state is: %s', sample_device.deviceIP, sample_device.deviceIP, state[0].text) sample_device.deviceProvisionTasks.taskState[ 'Discovery'] = state elif state[0].text == 'DONE': self.logger.info( 'PROVSPACE-[%s]: Discovery for device %s state is: %s', sample_device.deviceIP, sample_device.deviceIP, state) self.logger.info( 'PROVSPACE-[%s]: Device discovery done for device %s. Cleaning up queues', sample_device.deviceIP, sample_device.deviceIP) URI = 'api/hornet-q/queues/jms.queue.' + queue HEADER = '' # Todo: Check response code in response is 204 --> OK # Todo: If not 204 what todo? response = self.delete(URI, HEADER) if Tools.lrr_counter > 0: with Tools.lrr_lock: Tools.lrr_counter -= 1 summary = xmlRoot.find('summary').text self.logger.info( 'PROVSPACE-[%s]: Discovery for device %s Summary: %s', sample_device.deviceIP, sample_device.deviceIP, summary) pattern = r'Job was cancelled by user\s.*' regex = re.compile(pattern, re.MULTILINE) result = re.findall(regex, summary) if result: self.logger.info( 'PROVSPACE: Seems to be the job was canceled by Space user.' ) break else: pattern = r'Number\sof\s(.*?):\s(\d)<br>' regex = re.compile(pattern, re.MULTILINE) result = re.findall(regex, summary) result = dict( (x, int(y)) for x, y in result) # Number should always be one because we are discovering only one device. So we can use # this getting info about discovery state for current device # # Number of scanned IP: 1<br> # Number of Device Managed: 1<br> # Number of Discovery succeeded: 1<br> # Number of Already Managed: 0<br> # Number of Add Device failed: 0<br> # Number of Skipped: 0<br> # Number of scanned IP: 1<br>Number of Discovery succeeded: 0<br>Number of Add Device failed: 0<br>Number of Already Managed: 1<br>Number of Skipped: 0<br>Number of Device Managed: 0<br> if result[Tools.SPACE_DISCOVERY_NOAM] != 0: sample_device.deviceProvisionTasks.taskState[ 'Discovery'] = 'Already managed' self.logger.info( 'PROVSPACE: Discovery for device %s state is: Already managed', sample_device.deviceIP) shared[ Tools. TASK_SHARED_STATE] = Tools.TASK_STATE_RESULT_DONE elif result[ Tools.SPACE_DISCOVERY_NOADF] != 0: sample_device.deviceProvisionTasks.taskState[ 'Discovery'] = 'Failed' self.logger.info( 'PROVSPACE: Discovery for device %s state is: Failed', sample_device.deviceIP) shared[ Tools. TASK_SHARED_STATE] = Tools.TASK_STATE_RESULT_FAILURE elif result[ Tools.SPACE_DISCOVERY_NODS] != 0: sample_device.deviceProvisionTasks.taskState[ 'Discovery'] = 'Done' self.logger.info( 'PROVSPACE: Discovery for device %s state is: Succeeded', sample_device.deviceIP) shared[ Tools. TASK_SHARED_STATE] = Tools.TASK_STATE_RESULT_DONE elif result[ Tools.SPACE_DISCOVERY_NOS] != 0: sample_device.deviceProvisionTasks.taskState[ 'Discovery'] = 'Skipped' self.logger.info( 'PROVSPACE: Discovery for device %s state is: Skipped', sample_device.deviceIP) shared[ Tools. TASK_SHARED_STATE] = Tools.TASK_STATE_RESULT_DONE break else: self.logger.info( 'PROVSPACE: Got unknown Junos Space state in response' ) shared[ Tools. TASK_SHARED_STATE] = Tools.TASK_STATE_RESULT_FAILURE else: self.logger.info( 'PROVSPACE: Got unknown status code in Junos Space response' ) shared[ Tools. TASK_SHARED_STATE] = Tools.TASK_STATE_RESULT_FAILURE else: self.logger.info( 'PROVSPACE: Got unknown status code in Junos Space response' ) shared[Tools. TASK_SHARED_STATE] = Tools.TASK_STATE_RESULT_FAILURE break else: self.logger.info( 'PROVSPACE: Bad status code in Junos Space response') shared[Tools.TASK_SHARED_STATE] = Tools.TASK_STATE_RESULT_FAILURE