Backport/2.9/62587 module_utils/network/cloudengine:fix get_nc_next. (#62752)
* fix plugins/netconf/ce.py for netconf/capability/exchange (#60569) (cherry picked from commit037401b6e0
) * for capability/exchange/1.0 (#60630) * for capability/exchange/1.0 * for capability/exchange/1.0 * update for shippable * Update ce.py * Update ce.py (cherry picked from commit28227c95a4
) * module_utils-network-cloudengine: fix get_nc_next. (#62587) * fix get_nc_next. * add a changelog fragment. * upadte for changelgo fragment. * merge two prs, one depens another. * merge two prs, one depens another. * update changelog. (cherry picked from commitd6ef7c8530
)
This commit is contained in:
parent
fb897c3f48
commit
9d1f07dd03
4 changed files with 59 additions and 2 deletions
2
changelogs/fragments/60569-plugins-netconf-ce.yml
Normal file
2
changelogs/fragments/60569-plugins-netconf-ce.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
bugfixes:
|
||||
- plugins-netconf-ce - to get attribute 'set-id' from rpc-reply.
|
|
@ -0,0 +1,3 @@
|
|||
bugfixes:
|
||||
- "Cloudengine module_utils - the ``set-id`` (RPC-REPLY XML attribute) may change over the time althougth ``set-id`` is the identity of the next RPC packet."
|
||||
- "Cloudengine netconf plugin - add a dispatch RPC function,just return original RPC-REPLY, the function is used by ``Cloudengine module_utils``."
|
|
@ -35,19 +35,24 @@ import traceback
|
|||
|
||||
from ansible.module_utils.basic import env_fallback
|
||||
from ansible.module_utils.network.common.utils import to_list, ComplexList
|
||||
from ansible.module_utils.connection import exec_command
|
||||
from ansible.module_utils.connection import exec_command, ConnectionError
|
||||
from ansible.module_utils.six import iteritems
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.module_utils.network.common.netconf import NetconfConnection
|
||||
|
||||
|
||||
try:
|
||||
from ncclient.xml_ import to_xml
|
||||
from ncclient.xml_ import to_xml, new_ele_ns
|
||||
HAS_NCCLIENT = True
|
||||
except ImportError:
|
||||
HAS_NCCLIENT = False
|
||||
|
||||
|
||||
try:
|
||||
from lxml import etree
|
||||
except ImportError:
|
||||
from xml.etree import ElementTree as etree
|
||||
|
||||
_DEVICE_CLI_CONNECTION = None
|
||||
_DEVICE_NC_CONNECTION = None
|
||||
|
||||
|
@ -343,6 +348,29 @@ def set_nc_config(module, xml_str):
|
|||
return to_string(to_xml(out))
|
||||
|
||||
|
||||
def get_nc_next(module, xml_str):
|
||||
""" get_nc_next for exchange capability """
|
||||
|
||||
conn = get_nc_connection(module)
|
||||
result = None
|
||||
if xml_str is not None:
|
||||
response = conn.get(xml_str, if_rpc_reply=True)
|
||||
result = response.find('./*')
|
||||
set_id = response.get('set-id')
|
||||
while True and set_id is not None:
|
||||
try:
|
||||
fetch_node = new_ele_ns('get-next', 'http://www.huawei.com/netconf/capability/base/1.0', {'set-id': set_id})
|
||||
next_xml = conn.dispatch_rpc(etree.tostring(fetch_node))
|
||||
if next_xml is not None:
|
||||
result.extend(next_xml.find('./*'))
|
||||
set_id = next_xml.get('set-id')
|
||||
except ConnectionError:
|
||||
break
|
||||
if result is not None:
|
||||
return etree.tostring(result)
|
||||
return result
|
||||
|
||||
|
||||
def get_nc_config(module, xml_str):
|
||||
""" get_config """
|
||||
|
||||
|
|
|
@ -36,6 +36,11 @@ try:
|
|||
except (ImportError, AttributeError): # paramiko and gssapi are incompatible and raise AttributeError not ImportError
|
||||
HAS_NCCLIENT = False
|
||||
|
||||
try:
|
||||
from lxml.etree import fromstring
|
||||
except ImportError:
|
||||
from xml.etree.ElementTree import fromstring
|
||||
|
||||
|
||||
class Netconf(NetconfBase):
|
||||
|
||||
|
@ -167,6 +172,9 @@ class Netconf(NetconfBase):
|
|||
@ensure_connected
|
||||
def get(self, *args, **kwargs):
|
||||
try:
|
||||
if_rpc_reply = kwargs.pop('if_rpc_reply', False)
|
||||
if if_rpc_reply:
|
||||
return self.m.get(*args, **kwargs).xml
|
||||
return self.m.get(*args, **kwargs).data_xml
|
||||
except RPCError as exc:
|
||||
raise Exception(to_xml(exc.xml))
|
||||
|
@ -210,3 +218,19 @@ class Netconf(NetconfBase):
|
|||
@ensure_connected
|
||||
def discard_changes(self, *args, **kwargs):
|
||||
return self.m.discard_changes(*args, **kwargs).data_xml
|
||||
|
||||
@ensure_ncclient
|
||||
@ensure_connected
|
||||
def dispatch_rpc(self, rpc_command=None, source=None, filter=None):
|
||||
"""
|
||||
Execute rpc on the remote device eg. dispatch('get-next')
|
||||
:param rpc_command: specifies rpc command to be dispatched either in plain text or in xml element format (depending on command)
|
||||
:param source: name of the configuration datastore being queried
|
||||
:param filter: specifies the portion of the configuration to retrieve (by default entire configuration is retrieved)
|
||||
:return: Returns xml string containing the rpc-reply response received from remote host
|
||||
"""
|
||||
if rpc_command is None:
|
||||
raise ValueError('rpc_command value must be provided')
|
||||
resp = self.m.dispatch(fromstring(rpc_command), source=source, filter=filter)
|
||||
# just return rpc-reply xml
|
||||
return resp.xml
|
||||
|
|
Loading…
Reference in a new issue