Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport/2.8/57264 update vxlan to fix bugs #57889

Merged
merged 3 commits into from Jun 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions changelogs/fragments/57264-update-vxlan-to-fix-bugs.yml
@@ -0,0 +1,8 @@
bugfixes:
- ce_dldp - tag named data of a xpath is unnecessay for old sotfware version to find a element from xml tree, but element can not be found with 'data' tag for new version, so remove.
- ce_dldp_interface - tag named data of a xpath is unnecessay for old sotfware version to find a element from xml tree, but element can not be found with 'data' tag for new version, so remove.
- ce_vxlan_arp - override 'get_config' to show specific configuration.
- ce_vxlan_gateway - override 'get_config' to show specific configuration.
- ce_vxlan_global - Netwrok_cli and netconf should be not mixed together, otherwise something bad will happen. Function get_nc_config uses netconf and load_config uses network_cli.
- ce_vxlan_tunnel - Netwrok_cli and netconf should be not mixed together, otherwise something bad will happen. Function get_nc_config uses netconf and load_config uses network_cli.
- ce_vxlan_vap - tag named data of a xpath is unnecessay for old sotfware version to find a element from xml tree, but element can not be found with 'data' tag for new version, so remove.
9 changes: 9 additions & 0 deletions changelogs/fragments/57889-update-scmp-to-fix-bugs.yml
@@ -0,0 +1,9 @@
bugfixes:
- update scmp to fix bugs.(https://github.com/ansible/ansible/pull/57264)
- ce_dldp - tag named data of a xpath is unnecessay for old sotfware version to find a element from xml tree, but element can not be found with 'data' tag for new version, so remove.
- ce_dldp_interface - tag named data of a xpath is unnecessay for old sotfware version to find a element from xml tree, but element can not be found with 'data' tag for new version, so remove.
- ce_vxlan_arp - override 'get_config' to show specific configuration.
- ce_vxlan_gateway - override 'get_config' to show specific configuration.
- ce_vxlan_global - Netwrok_cli and netconf should be not mixed together, otherwise something bad will happen. Function get_nc_config uses netconf and load_config uses network_cli.
- ce_vxlan_tunnel - Netwrok_cli and netconf should be not mixed together, otherwise something bad will happen. Function get_nc_config uses netconf and load_config uses network_cli.
- ce_vxlan_vap - tag named data of a xpath is unnecessay for old sotfware version to find a element from xml tree, but element can not be found with 'data' tag for new version, so remove.
2 changes: 1 addition & 1 deletion lib/ansible/modules/network/cloudengine/ce_dldp.py
Expand Up @@ -321,7 +321,7 @@ def get_dldp_exist_config(self):

# get global DLDP info
root = ElementTree.fromstring(xml_str)
topo = root.find("data/dldp/dldpSys")
topo = root.find("dldp/dldpSys")
if not topo:
self.module.fail_json(
msg="Error: Get current DLDP configration failed.")
Expand Down
Expand Up @@ -454,7 +454,7 @@ def get_dldp_intf_exist_config(self):

# get global DLDP info
root = ElementTree.fromstring(xml_str)
topo = root.find("data/dldp/dldpInterfaces/dldpInterface")
topo = root.find("dldp/dldpInterfaces/dldpInterface")
if topo is None:
self.module.fail_json(
msg="Error: Get current DLDP configration failed.")
Expand Down
30 changes: 26 additions & 4 deletions lib/ansible/modules/network/cloudengine/ce_vxlan_arp.py
Expand Up @@ -150,8 +150,9 @@

import re
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.cloudengine.ce import get_config, load_config
from ansible.module_utils.network.cloudengine.ce import load_config
from ansible.module_utils.network.cloudengine.ce import ce_argument_spec
from ansible.module_utils.connection import exec_command


def is_config_exist(cmp_cfg, test_cfg):
Expand Down Expand Up @@ -265,6 +266,22 @@ def cli_load_config(self, commands):
if not self.module.check_mode:
load_config(self.module, commands)

def get_config(self, flags=None):
"""Retrieves the current config from the device or cache
"""
flags = [] if flags is None else flags

cmd = 'display current-configuration '
cmd += ' '.join(flags)
cmd = cmd.strip()

rc, out, err = exec_command(self.module, cmd)
if rc != 0:
self.module.fail_json(msg=err)
cfg = str(out).strip()

return cfg

def get_current_config(self):
"""get current configuration"""

Expand All @@ -277,9 +294,14 @@ def get_current_config(self):
exp += "|^bridge-domain %s$" % self.bridge_domain_id

flags.append(exp)
config = get_config(self.module, flags)

return config
cfg_str = self.get_config(flags)
config = cfg_str.split("\n")

exist_config = ""
for cfg in config:
if not cfg.startswith("display"):
exist_config += cfg
return exist_config

def cli_add_command(self, command, undo=False):
"""add command to self.update_cmd and self.commands"""
Expand Down
22 changes: 20 additions & 2 deletions lib/ansible/modules/network/cloudengine/ce_vxlan_gateway.py
Expand Up @@ -176,8 +176,9 @@

import re
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.cloudengine.ce import get_config, load_config
from ansible.module_utils.network.cloudengine.ce import load_config
from ansible.module_utils.network.cloudengine.ce import ce_argument_spec
from ansible.module_utils.connection import exec_command


def is_config_exist(cmp_cfg, test_cfg):
Expand Down Expand Up @@ -377,6 +378,22 @@ def cli_load_config(self, commands):
if not self.module.check_mode:
load_config(self.module, commands)

def get_config(self, flags=None):
"""Retrieves the current config from the device or cache
"""
flags = [] if flags is None else flags

cmd = 'display current-configuration '
cmd += ' '.join(flags)
cmd = cmd.strip()

rc, out, err = exec_command(self.module, cmd)
if rc != 0:
self.module.fail_json(msg=err)
cfg = str(out).strip()

return cfg

def get_current_config(self):
"""get current configuration"""

Expand All @@ -387,7 +404,7 @@ def get_current_config(self):
if self.vbdif_name:
exp += "|^interface %s$" % self.vbdif_name
flags.append(exp)
return get_config(self.module, flags)
return self.get_config(flags)

def cli_add_command(self, command, undo=False):
"""add command to self.update_cmd and self.commands"""
Expand Down Expand Up @@ -579,6 +596,7 @@ def config_vbdif(self):
if self.vbdif_bind_vpn:
cmd = "ip binding vpn-instance %s" % self.vbdif_bind_vpn
exist = is_config_exist(self.config, cmd)

if self.state == "present" and not exist:
if not vbdif_view:
self.cli_add_command(vbdif_cmd)
Expand Down
61 changes: 26 additions & 35 deletions lib/ansible/modules/network/cloudengine/ce_vxlan_global.py
Expand Up @@ -123,23 +123,10 @@
'''

import re
from xml.etree import ElementTree
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.cloudengine.ce import get_config, load_config, get_nc_config
from ansible.module_utils.network.cloudengine.ce import load_config
from ansible.module_utils.network.cloudengine.ce import ce_argument_spec


CE_NC_GET_BRIDGE_DOMAIN = """
<filter type="subtree">
<evc xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
<bds>
<bd>
<bdId></bdId>
</bd>
</bds>
</evc>
</filter>
"""
from ansible.module_utils.connection import exec_command


def is_config_exist(cmp_cfg, test_cfg):
Expand Down Expand Up @@ -206,13 +193,29 @@ def cli_load_config(self, commands):
if not self.module.check_mode:
load_config(self.module, commands)

def get_config(self, flags=None):
"""Retrieves the current config from the device or cache
"""
flags = [] if flags is None else flags

cmd = 'display current-configuration '
cmd += ' '.join(flags)
cmd = cmd.strip()

rc, out, err = exec_command(self.module, cmd)
if rc != 0:
self.module.fail_json(msg=err)
cfg = str(out).strip()

return cfg

def get_current_config(self):
"""get current configuration"""

flags = list()
exp = " include-default | include vxlan|assign | exclude undo"
flags.append(exp)
return get_config(self.module, flags)
return self.get_config(flags)

def cli_add_command(self, command, undo=False):
"""add command to self.update_cmd and self.commands"""
Expand All @@ -228,27 +231,15 @@ def cli_add_command(self, command, undo=False):

def get_bd_list(self):
"""get bridge domain list"""

flags = list()
bd_info = list()
conf_str = CE_NC_GET_BRIDGE_DOMAIN
xml_str = get_nc_config(self.module, conf_str)
if "<data/>" in xml_str:
return bd_info

xml_str = xml_str.replace('\r', '').replace('\n', '').\
replace('xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"', "").\
replace('xmlns="http://www.huawei.com/netconf/vrp"', "")

# get bridge domain info
root = ElementTree.fromstring(xml_str)
bds = root.findall("data/evc/bds/bd/bdId")
if not bds:
exp = " include-default | include bridge-domain | exclude undo"
flags.append(exp)
bd_str = self.get_config(flags)
if not bd_str:
return bd_info

for bridge_domain in bds:
if bridge_domain.tag == "bdId":
bd_info.append(bridge_domain.text)

bd_num = re.findall(r'bridge-domain\s*([0-9]+)', bd_str)
bd_info.append(bd_num)
return bd_info

def config_bridge_domain(self):
Expand Down
94 changes: 56 additions & 38 deletions lib/ansible/modules/network/cloudengine/ce_vxlan_tunnel.py
Expand Up @@ -115,10 +115,10 @@
type: dict
sample: {nve_interface_name": "Nve1", nve_mode": "mode-l3", "source_ip": "0.0.0.0"}
'''

import re
from xml.etree import ElementTree
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.cloudengine.ce import get_nc_config, set_nc_config, get_config, ce_argument_spec
from ansible.module_utils.network.cloudengine.ce import get_nc_config, set_nc_config, ce_argument_spec

CE_NC_GET_VNI_BD_INFO = """
<filter type="subtree">
Expand Down Expand Up @@ -366,18 +366,6 @@ def check_response(self, xml_str, xml_name):
if "<ok/>" not in xml_str:
self.module.fail_json(msg='Error: %s failed.' % xml_name)

def get_current_config(self, vni_id, peer_ip_list):
"""get current configuration"""

flags = list()
exp = " | include vni "
exp += vni_id
exp += " head-end peer-list "
for peer_ip in peer_ip_list:
exp += "| exclude %s " % peer_ip
flags.append(exp)
return get_config(self.module, flags)

def get_vni2bd_dict(self):
""" get vni2bd attributes dict."""

Expand All @@ -393,7 +381,7 @@ def get_vni2bd_dict(self):
# get vni to bridge domain id info
root = ElementTree.fromstring(xml_str)
vni2bd_info["vni2BdInfos"] = list()
vni2bds = root.findall("data/nvo3/nvo3Vni2Bds/nvo3Vni2Bd")
vni2bds = root.findall("nvo3/nvo3Vni2Bds/nvo3Vni2Bd")

if vni2bds:
for vni2bd in vni2bds:
Expand Down Expand Up @@ -430,7 +418,8 @@ def get_nve_dict(self, nve_name):

# get nve info
root = ElementTree.fromstring(xml_str)
nvo3 = root.find("data/nvo3/nvo3Nves/nvo3Nve")

nvo3 = root.find("nvo3/nvo3Nves/nvo3Nve")
if nvo3:
for nve in nvo3:
if nve.tag in ["srcAddr", "ifName", "nveType"]:
Expand All @@ -440,7 +429,7 @@ def get_nve_dict(self, nve_name):
nve_info["vni_peer_protocols"] = list()

vni_members = root.findall(
"data/nvo3/nvo3Nves/nvo3Nve/vniMembers/vniMember")
"nvo3/nvo3Nves/nvo3Nve/vniMembers/vniMember")
if vni_members:
for member in vni_members:
vni_dict = dict()
Expand All @@ -451,15 +440,22 @@ def get_nve_dict(self, nve_name):

# get vni peer address ip info
nve_info["vni_peer_ips"] = list()
vni_peers = root.findall(
"data/nvo3/nvo3Nves/nvo3Nve/vniMembers/vniMember/nvo3VniPeers/nvo3VniPeer")
if vni_peers:
for peer_address in vni_peers:
vni_peer_dict = dict()
for ele in peer_address:
if ele.tag in ["vniId", "peerAddr"]:
vni_peer_dict[ele.tag] = ele.text
nve_info["vni_peer_ips"].append(vni_peer_dict)

re_find = re.findall(r'<vniId>(.*?)</vniId>\s*'
r'<protocol>(.*?)</protocol>\s*'
r'<nvo3VniPeers>(.*?)</nvo3VniPeers>', xml_str)

if re_find:
for vni_peers in re_find:
vni_info = dict()
vni_peer = re.findall(r'<peerAddr>(.*?)</peerAddr>', vni_peers[2])
if vni_peer:
vni_info["vniId"] = vni_peers[0]
vni_peer_list = list()
for peer in vni_peer:
vni_peer_list.append(peer)
vni_info["peerAddr"] = vni_peer_list
nve_info["vni_peer_ips"].append(vni_info)

return nve_info

Expand Down Expand Up @@ -563,7 +559,7 @@ def is_vni_peer_list_exist(self, nve_name, vni_id, peer_ip):
return False
if self.nve_info["ifName"] == nve_name:
for member in self.nve_info["vni_peer_ips"]:
if member["vniId"] == vni_id and member["peerAddr"] == peer_ip:
if member["vniId"] == vni_id and peer_ip in member["peerAddr"]:
return True
return False

Expand All @@ -572,16 +568,25 @@ def is_vni_peer_list_change(self, nve_name, vni_id, peer_ip_list):

if not self.nve_info:
return True
for peer_ip in peer_ip_list:
if self.nve_info["ifName"] == nve_name:
if not self.nve_info["vni_peer_ips"]:

if self.nve_info["ifName"] == nve_name:
if not self.nve_info["vni_peer_ips"]:
return True

nve_peer_info = list()
for nve_peer in self.nve_info["vni_peer_ips"]:
if nve_peer["vniId"] == vni_id:
nve_peer_info.append(nve_peer)

if not nve_peer_info:
return True

nve_peer_list = nve_peer_info[0]["peerAddr"]
for peer in peer_ip_list:
if peer not in nve_peer_list:
return True
for member in self.nve_info["vni_peer_ips"]:
if member["vniId"] != vni_id:
return True
elif member["vniId"] == vni_id and member["peerAddr"] != peer_ip:
return True
return False

return False

def config_merge_vni2bd(self, bd_id, vni_id):
"""config vni to bd id"""
Expand All @@ -602,7 +607,10 @@ def config_merge_mode(self, nve_name, mode):
recv_xml = set_nc_config(self.module, cfg_xml)
self.check_response(recv_xml, "MERGE_MODE")
self.updates_cmd.append("interface %s" % nve_name)
self.updates_cmd.append("mode l3")
if mode == "mode-l3":
self.updates_cmd.append("mode l3")
else:
self.updates_cmd.append("undo mode l3")
self.changed = True

def config_merge_source_ip(self, nve_name, source_ip):
Expand Down Expand Up @@ -705,7 +713,17 @@ def config_delete_vni_peer_ip(self, nve_name, vni_id, peer_ip_list):
for peer_ip in peer_ip_list:
if not self.is_vni_peer_list_exist(nve_name, vni_id, peer_ip):
self.module.fail_json(msg='Error: The %s does not exist' % peer_ip)
config = self.get_current_config(vni_id, peer_ip_list)

config = False

nve_peer_info = list()
for nve_peer in self.nve_info["vni_peer_ips"]:
if nve_peer["vniId"] == vni_id:
nve_peer_info = nve_peer.get("peerAddr")
for peer in nve_peer_info:
if peer not in peer_ip_list:
config = True

if not config:
cfg_xml = CE_NC_DELETE_VNI_PEER_ADDRESS_IP_HEAD % (
nve_name, vni_id)
Expand Down