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