def get_device_info(self): device_info = {} device_info['network_os'] = 'iosxr' install_meta = collections.OrderedDict() install_meta.update([ ('boot-variables', { 'xpath': 'install/boot-variables', 'tag': True }), ('boot-variable', { 'xpath': 'install/boot-variables/boot-variable', 'tag': True, 'lead': True }), ('software', { 'xpath': 'install/software', 'tag': True }), ('alias-devices', { 'xpath': 'install/software/alias-devices', 'tag': True }), ('alias-device', { 'xpath': 'install/software/alias-devices/alias-device', 'tag': True }), ('m:device-name', { 'xpath': 'install/software/alias-devices/alias-device/device-name', 'value': 'disk0:' }), ]) install_filter = build_xml('install', install_meta, opcode='filter') try: reply = self.get(install_filter) resp = remove_namespaces( re.sub(r'<\?xml version="1.0" encoding="UTF-8"\?>', '', reply)) ele_boot_variable = etree_find(resp, 'boot-variable/boot-variable') if ele_boot_variable is not None: device_info['network_os_image'] = re.split( '[:|,]', ele_boot_variable.text)[1] ele_package_name = etree_find(reply, 'package-name') if ele_package_name is not None: device_info['network_os_package'] = ele_package_name.text device_info['network_os_version'] = re.split( '-', ele_package_name.text)[-1] hostname_filter = build_xml('host-names', opcode='filter') reply = self.get(hostname_filter) resp = remove_namespaces( re.sub(r'<\?xml version="1.0" encoding="UTF-8"\?>', '', reply)) hostname_ele = etree_find(resp.strip(), 'host-name') device_info[ 'network_os_hostname'] = hostname_ele.text if hostname_ele is not None else None except Exception as exc: self._connection.queue_message( 'vvvv', 'Fail to retrieve device info %s' % exc) return device_info
def edit_config(self, config=None, format='xml', target='candidate', default_operation=None, test_option=None, error_option=None, remove_ns=False): if config is None: raise ValueError('config value must be provided') try: resp = self.m.edit_config(config, format=format, target=target, default_operation=default_operation, test_option=test_option, error_option=error_option) if remove_ns: response = remove_namespaces(resp) else: response = resp.data_xml if hasattr(resp, 'data_xml') else resp.xml return response except RPCError as exc: raise Exception(to_xml(exc.xml))
def main(): """entry point for module execution """ argument_spec = dict( rpc=dict(type="str", required=True), xmlns=dict(type="str"), content=dict(), display=dict(choices=['json', 'pretty', 'xml']) ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) rpc = module.params['rpc'] xmlns = module.params['xmlns'] content = module.params['content'] display = module.params['display'] if rpc is None: module.fail_json(msg='argument `rpc` must not be None') rpc = rpc.strip() if len(rpc) == 0: module.fail_json(msg='argument `rpc` must not be empty') if rpc in ['close-session']: # explicit close-session is not allowed, as this would make the next # NETCONF operation to the same host fail module.fail_json(msg='unsupported operation `%s`' % rpc) if display == 'json' and not HAS_JXMLEASE: module.fail_json(msg='jxmlease is required to display response in json format' 'but does not appear to be installed. ' 'It can be installed using `pip install jxmlease`') xml_req = get_xml_request(module, rpc, xmlns, content) response = dispatch(module, xml_req) xml_resp = tostring(response) output = None if display == 'xml': output = remove_namespaces(xml_resp) elif display == 'json': try: output = jxmlease.parse(xml_resp) except Exception: raise ValueError(xml_resp) elif display == 'pretty': output = tostring(response, pretty_print=True) result = { 'stdout': xml_resp, 'output': output } module.exit_json(**result)
def main(): """entry point for module execution """ argument_spec = dict( rpc=dict(type="str", required=True), xmlns=dict(type="str"), content=dict(), display=dict(choices=["json", "pretty", "xml"]), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True ) rpc = module.params["rpc"] xmlns = module.params["xmlns"] content = module.params["content"] display = module.params["display"] if rpc is None: module.fail_json(msg="argument `rpc` must not be None") rpc = rpc.strip() if len(rpc) == 0: module.fail_json(msg="argument `rpc` must not be empty") if rpc in ["close-session"]: # explicit close-session is not allowed, as this would make the next # NETCONF operation to the same host fail module.fail_json(msg="unsupported operation `%s`" % rpc) if display == "json" and not HAS_JXMLEASE: module.fail_json( msg="jxmlease is required to display response in json format" "but does not appear to be installed. " "It can be installed using `pip install jxmlease`" ) xml_req = get_xml_request(module, rpc, xmlns, content) response = dispatch(module, xml_req) xml_resp = tostring(response) output = None if display == "xml": output = remove_namespaces(xml_resp) elif display == "json": try: output = jxmlease.parse(xml_resp) except Exception: raise ValueError(xml_resp) elif display == "pretty": output = tostring(response, pretty_print=True) result = {"stdout": xml_resp, "output": output} module.exit_json(**result)
def discard_changes(self, remove_ns=False): try: resp = self.m.discard_changes() if remove_ns: response = remove_namespaces(resp) else: response = resp.data_xml if hasattr(resp, 'data_xml') else resp.xml return response except RPCError as exc: raise Exception(to_xml(exc.xml))
def validate(self, source="candidate", remove_ns=False): try: resp = self.m.validate(source=source) if remove_ns: response = remove_namespaces(resp) else: response = resp.data_xml if hasattr(resp, 'data_xml') else resp.xml return response except RPCError as exc: raise Exception(to_xml(exc.xml))
def get_config(self, source=None, filter=None, remove_ns=False): if isinstance(filter, list): filter = tuple(filter) try: resp = self.m.get_config(source=source, filter=filter) if remove_ns: response = remove_namespaces(resp) else: response = resp.data_xml if hasattr(resp, 'data_xml') else resp.xml return response except RPCError as exc: raise Exception(to_xml(exc.xml))
def commit( self, confirmed=False, timeout=None, persist=None, remove_ns=False ): try: resp = self.m.commit( confirmed=confirmed, timeout=timeout, persist=persist ) if remove_ns: response = remove_namespaces(resp) else: response = ( resp.data_xml if hasattr(resp, "data_xml") else resp.xml ) return response except RPCError as exc: raise Exception(to_xml(exc.xml))
def commit( self, confirmed=False, timeout=None, persist=None, remove_ns=False, ): timeout = to_text(timeout, errors="surrogate_or_strict") try: resp = self.m.commit( confirmed=confirmed, timeout=timeout, persist=persist, ) if remove_ns: response = remove_namespaces(resp) else: response = resp.data_xml if hasattr(resp, "data_xml") else resp.xml return response except RPCError as exc: raise Exception(to_xml(exc.xml))
def main(): """entry point for module execution""" argument_spec = dict( source=dict(choices=["running", "candidate", "startup"]), filter=dict(type="raw"), display=dict(choices=["json", "native", "pretty", "xml"]), lock=dict( default="never", choices=["never", "always", "if-supported"] ), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True ) capabilities = get_capabilities(module) operations = capabilities["device_operations"] source = module.params["source"] filter, tipe = ensure_xml_or_str(module.params["filter"], "filter") if tipe == "xml": filter_type = "subtree" elif tipe == "str": filter_type = "xpath" else: filter_type = tipe lock = module.params["lock"] display = module.params["display"] if source == "candidate" and not operations.get("supports_commit", False): module.fail_json( msg="candidate source is not supported on this device" ) if source == "startup" and not operations.get("supports_startup", False): module.fail_json(msg="startup source is not supported on this device") if filter_type == "xpath" and not operations.get("supports_xpath", False): module.fail_json( msg="filter value '%s' of type xpath is not supported on this device" % filter ) # If source is None, NETCONF <get> operation is issued, reading config/state data # from the running datastore. The python expression "(source or 'running')" results # in the value of source (if not None) or the value 'running' (if source is None). if lock == "never": execute_lock = False elif (source or "running") in operations.get("lock_datastore", []): # lock is requested (always/if-support) and supported => lets do it execute_lock = True else: # lock is requested (always/if-supported) but not supported => issue warning module.warn( "lock operation on '%s' source is not supported on this device" % (source or "running") ) execute_lock = lock == "always" if display == "json" and not HAS_JXMLEASE: module.fail_json( msg="jxmlease is required to display response in json format" "but does not appear to be installed. " "It can be installed using `pip install jxmlease`" ) filter_spec = (filter_type, filter) if filter_type else None if source is not None: response = get_config(module, source, filter_spec, execute_lock) else: response = get(module, filter_spec, execute_lock) xml_resp = to_text(tostring(response)) output = None if display == "xml": output = remove_namespaces(xml_resp) elif display == "json": try: output = jxmlease.parse(xml_resp) except Exception: raise ValueError(xml_resp) elif display == "pretty": output = to_text(tostring(response, pretty_print=True)) elif display == "native": output = xml_to_native(tostring(response), "display") result = {"stdout": xml_resp, "output": output} module.exit_json(**result)
def get_device_info(self): device_info = {} device_info["network_os"] = "iosxr" install_meta = collections.OrderedDict() install_meta.update([ ("prepare", { "xpath": "install/prepare", "tag": True }), ( "prepared-boot-image", { "xpath": "install/prepare/prepared-boot-image", "tag": True, }, ), ("version", { "xpath": "install/version", "tag": True }), ("label", { "xpath": "install/version/label", "tag": True }), ( "hardware-info", { "xpath": "install/version/hardware-info", "tag": True }, ), ("package", { "xpath": "install/version/package", "tag": True }), ], ) install_filter = build_xml( "install", install_meta, opcode="filter", namespace="install", ) try: reply = self.get(install_filter) resp = remove_namespaces( re.sub(r'<\?xml version="1.0" encoding="UTF-8"\?>', "", reply), ) ele_package_name = etree_find(resp.strip(), "name") if ele_package_name is not None: device_info["network_os_package"] = ele_package_name.text ele_label = etree_find(resp.strip(), "label") if ele_label is not None: device_info["network_os_version"] = ele_label.text model_search_strs = [ r"^[Cc]isco (.+) \(\) processor", r"^[Cc]isco (.+) \(revision", r"^[Cc]isco (\S+ \S+).+bytes of .*memory", ] ele_hardware_info = etree_find(resp.strip(), "hardware-info") if ele_hardware_info is not None: for item in model_search_strs: match = re.search(item, ele_hardware_info.text, re.M) if match: device_info["network_os_model"] = match.group(1) break except Exception as exc: error_msg = to_text(exc, errors="surrogate_or_strict").strip() if "bad-namespace" in error_msg: device_info = self.get_device_info_old_version() else: self._connection.queue_message( "vvvv", "Fail to retrieve device info %s" % exc, ) try: hostname_filter = build_xml( "host-names", opcode="filter", namespace="host-names", ) reply = self.get(hostname_filter) resp = remove_namespaces( re.sub(r'<\?xml version="1.0" encoding="UTF-8"\?>', "", reply), ) hostname_ele = etree_find(resp.strip(), "host-name") device_info["network_os_hostname"] = ( hostname_ele.text if hostname_ele is not None else None) except Exception as exc: self._connection.queue_message( "vvvv", "Fail to retrieve device info %s" % exc, ) return device_info
def get_device_info_old_version(self): device_info = {} device_info["network_os"] = "iosxr" install_meta = collections.OrderedDict() install_meta.update([ ( "boot-variables", { "xpath": "install/boot-variables", "tag": True }, ), ( "boot-variable", { "xpath": "install/boot-variables/boot-variable", "tag": True, "lead": True, }, ), ("software", { "xpath": "install/software", "tag": True }), ( "alias-devices", { "xpath": "install/software/alias-devices", "tag": True }, ), ( "alias-device", { "xpath": "install/software/alias-devices/alias-device", "tag": True, }, ), ( "m:device-name", { "xpath": "install/software/alias-devices/alias-device/device-name", "value": "disk0:", }, ), ], ) install_filter = build_xml( "install", install_meta, opcode="filter", namespace="install_old", ) try: reply = self.get(install_filter) resp = remove_namespaces( re.sub(r'<\?xml version="1.0" encoding="UTF-8"\?>', "", reply), ) ele_boot_variable = etree_find(resp, "boot-variable/boot-variable") if ele_boot_variable is not None: device_info["network_os_image"] = re.split( "[:|,]", ele_boot_variable.text, )[1] ele_package_name = etree_find(reply, "package-name") if ele_package_name is not None: device_info["network_os_package"] = ele_package_name.text device_info["network_os_version"] = re.split( "-", ele_package_name.text, )[-1] except Exception as exc: self._connection.queue_message( "vvvv", "Fail to retrieve device info %s" % exc, ) return device_info
def main(): """entry point for module execution """ argument_spec = dict( source=dict(choices=['running', 'candidate', 'startup']), filter=dict(), display=dict(choices=['json', 'pretty', 'xml']), lock=dict(default='never', choices=['never', 'always', 'if-supported'])) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) capabilities = get_capabilities(module) operations = capabilities['device_operations'] source = module.params['source'] filter = module.params['filter'] filter_type = get_filter_type(filter) lock = module.params['lock'] display = module.params['display'] if source == 'candidate' and not operations.get('supports_commit', False): module.fail_json( msg='candidate source is not supported on this device') if source == 'startup' and not operations.get('supports_startup', False): module.fail_json(msg='startup source is not supported on this device') if filter_type == 'xpath' and not operations.get('supports_xpath', False): module.fail_json( msg= "filter value '%s' of type xpath is not supported on this device" % filter) # If source is None, NETCONF <get> operation is issued, reading config/state data # from the running datastore. The python expression "(source or 'running')" results # in the value of source (if not None) or the value 'running' (if source is None). if lock == 'never': execute_lock = False elif (source or 'running') in operations.get('lock_datastore', []): # lock is requested (always/if-support) and supported => lets do it execute_lock = True else: # lock is requested (always/if-supported) but not supported => issue warning module.warn( "lock operation on '%s' source is not supported on this device" % (source or 'running')) execute_lock = (lock == 'always') if display == 'json' and not HAS_JXMLEASE: module.fail_json( msg='jxmlease is required to display response in json format' 'but does not appear to be installed. ' 'It can be installed using `pip install jxmlease`') filter_spec = (filter_type, filter) if filter_type else None if source is not None: response = get_config(module, source, filter_spec, execute_lock) else: response = get(module, filter_spec, execute_lock) xml_resp = to_text(tostring(response)) output = None if display == 'xml': output = remove_namespaces(xml_resp) elif display == 'json': try: output = jxmlease.parse(xml_resp) except Exception: raise ValueError(xml_resp) elif display == 'pretty': output = to_text(tostring(response, pretty_print=True)) result = {'stdout': xml_resp, 'output': output} module.exit_json(**result)