summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXu Yuandong <yuandongdeyouxiang@gmail.com>2019-10-12 23:48:33 +0800
committerToshio Kuratomi <a.badger@gmail.com>2019-10-12 09:17:10 -0700
commit8c05339cb7af113811dd54decbd6aa26461348b3 (patch)
treeeb755640d1f3501153c44e05f6eae407d847d10e
parent2a3ce4d6ec0a339e42bcf246801f6765e40be836 (diff)
downloadansible-8c05339cb7af113811dd54decbd6aa26461348b3.tar.gz
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 commit 037401b6e0d5c500774e2a259909e6fa7e3f16e2) * 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 commit 28227c95a468b26a2bbd3d6d4338565f1cb84e34) * 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 commit d6ef7c8530ca1f45cc1a0b41a97919fa4d98e1f1)
-rw-r--r--changelogs/fragments/60569-plugins-netconf-ce.yml2
-rw-r--r--changelogs/fragments/62587-module_utils-network-cloudengine.yml3
-rw-r--r--lib/ansible/module_utils/network/cloudengine/ce.py32
-rw-r--r--lib/ansible/plugins/netconf/ce.py24
4 files changed, 59 insertions, 2 deletions
diff --git a/changelogs/fragments/60569-plugins-netconf-ce.yml b/changelogs/fragments/60569-plugins-netconf-ce.yml
new file mode 100644
index 0000000000..9d6ce19417
--- /dev/null
+++ b/changelogs/fragments/60569-plugins-netconf-ce.yml
@@ -0,0 +1,2 @@
+bugfixes:
+ - plugins-netconf-ce - to get attribute 'set-id' from rpc-reply.
diff --git a/changelogs/fragments/62587-module_utils-network-cloudengine.yml b/changelogs/fragments/62587-module_utils-network-cloudengine.yml
new file mode 100644
index 0000000000..708128caf3
--- /dev/null
+++ b/changelogs/fragments/62587-module_utils-network-cloudengine.yml
@@ -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``."
diff --git a/lib/ansible/module_utils/network/cloudengine/ce.py b/lib/ansible/module_utils/network/cloudengine/ce.py
index 168c790683..01df0e795d 100644
--- a/lib/ansible/module_utils/network/cloudengine/ce.py
+++ b/lib/ansible/module_utils/network/cloudengine/ce.py
@@ -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 """
diff --git a/lib/ansible/plugins/netconf/ce.py b/lib/ansible/plugins/netconf/ce.py
index 24066b13e0..784e283d57 100644
--- a/lib/ansible/plugins/netconf/ce.py
+++ b/lib/ansible/plugins/netconf/ce.py
@@ -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