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 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 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 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 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)