ce_sflow: update to fix bugs. (#59349)

* update to fix bugs.

* remove params which is not supported.

* update to remove some .

* update to remove some redundant code.

* update for missing import.

* Update ce_sflow.py

* Update ce_sflow.py

* Update ce_sflow.py

* Update ce_sflow.py

* Update ce_sflow.py

* Update ce_sflow.py
This commit is contained in:
Xu Yuandong 2019-09-24 17:49:42 +08:00 committed by ansibot
parent 6be46b59fa
commit 7711524718

View file

@ -33,13 +33,13 @@ author: QijunPan (@QijunPan)
options:
agent_ip:
description:
- Specifies the IPv4/IPv6 address of an sFlow agent.
- Specifies the IPv4/IPv6 address of a sFlow agent.
source_ip:
description:
- Specifies the source IPv4/IPv6 address of sFlow packets.
collector_id:
description:
- Specifies the ID of an sFlow collector. This ID is used when you specify
- Specifies the ID of a sFlow collector. This ID is used when you specify
the collector in subsequent sFlow configuration.
choices: ['1', '2']
collector_ip:
@ -72,7 +72,7 @@ options:
choices: ['meth', 'enhanced']
collector_description:
description:
- Specifies the description of an sFlow collector.
- Specifies the description of a sFlow collector.
The value is a string of 1 to 255 case-sensitive characters without spaces.
sflow_interface:
description:
@ -104,24 +104,6 @@ options:
description:
- Configures the sFlow packets sent by the switch not to carry routing information.
choices: ['enable', 'disable']
rate_limit:
description:
- Specifies the rate of sFlow packets sent from a card to the control plane.
The value is an integer that ranges from 100 to 1500, in pps.
rate_limit_slot:
description:
- Specifies the slot where the rate of output sFlow packets is limited.
If this parameter is not specified, the rate of sFlow packets sent from
all cards to the control plane is limited.
The value is an integer or a string of characters.
forward_enp_slot:
description:
- Enable the Embedded Network Processor (ENP) chip function.
The switch uses the ENP chip to perform sFlow sampling,
and the maximum sFlow sampling interval is 65535.
If you set the sampling interval to be larger than 65535,
the switch automatically restores it to 65535.
The value is an integer or 'all'.
state:
description:
- Determines whether the config should be present or not
@ -205,8 +187,7 @@ changed:
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, ce_argument_spec, check_ip_addr
from ansible.module_utils.network.cloudengine.ce import get_config, load_config
from ansible.module_utils.network.cloudengine.ce import get_nc_config, set_nc_config, ce_argument_spec, check_ip_addr, to_string
CE_NC_GET_SFLOW = """
<filter type="subtree">
@ -350,33 +331,6 @@ def get_interface_type(interface):
return iftype.lower()
def get_rate_limit(config):
"""get sflow management-plane export rate-limit info"""
get = re.findall(r"sflow management-plane export rate-limit ([0-9]+) slot ([0-9]+)", config)
if not get:
get = re.findall(r"sflow management-plane export rate-limit ([0-9]+)", config)
if not get:
return None
else:
return dict(rate_limit=get[0])
else:
limit = list()
for slot in get:
limit.append(dict(rate_limit=slot[0], slot_id=slot[1]))
return limit
def get_forward_enp(config):
"""get assign forward enp sflow enable slot info"""
get = re.findall(r"assign forward enp sflow enable slot (\S+)", config)
if not get:
return None
else:
return list(get)
class Sflow(object):
"""Manages sFlow"""
@ -391,9 +345,6 @@ class Sflow(object):
self.source_ip = self.module.params['source_ip']
self.source_version = None
self.export_route = self.module.params['export_route']
self.rate_limit = self.module.params['rate_limit']
self.rate_limit_slot = self.module.params['rate_limit_slot']
self.forward_enp_slot = self.module.params['forward_enp_slot']
self.collector_id = self.module.params['collector_id']
self.collector_ip = self.module.params['collector_ip']
self.collector_version = None
@ -443,46 +394,11 @@ class Sflow(object):
if "<ok/>" not in rcv_xml:
self.module.fail_json(msg='Error: %s failed.' % xml_name)
def cli_load_config(self, commands):
"""load config by cli"""
def netconf_get_config(self, xml_str):
"""netconf set config"""
if not self.module.check_mode:
load_config(self.module, commands)
def get_current_config(self):
"""get current configuration"""
flags = list()
exp = ""
if self.rate_limit:
exp += "assign sflow management-plane export rate-limit %s" % self.rate_limit
if self.rate_limit_slot:
exp += " slot %s" % self.rate_limit_slot
exp += "$"
if self.forward_enp_slot:
if exp:
exp += "|"
exp += "assign forward enp sflow enable slot %s$" % self.forward_enp_slot
if exp:
exp = " | ignore-case include " + exp
flags.append(exp)
return get_config(self.module, flags)
else:
return ""
def cli_add_command(self, command, undo=False):
"""add command to self.update_cmd and self.commands"""
if undo and command.lower() not in ["quit", "return"]:
cmd = "undo " + command
else:
cmd = command
self.commands.append(cmd) # set to device
if command.lower() not in ["quit", "return"]:
self.updates_cmd.append(cmd) # show updates result
if xml_str is not None:
return get_nc_config(self.module, xml_str)
def get_sflow_dict(self):
""" sflow config dict"""
@ -495,7 +411,7 @@ class Sflow(object):
if not self.collector_meth:
conf_str = conf_str.replace("<meth></meth>", "")
rcv_xml = get_nc_config(self.module, conf_str)
rcv_xml = self.netconf_get_config(conf_str)
if "<data/>" in rcv_xml:
return sflow_dict
@ -506,7 +422,7 @@ class Sflow(object):
root = ElementTree.fromstring(xml_str)
# get source info
srcs = root.findall("data/sflow/sources/source")
srcs = root.findall("sflow/sources/source")
if srcs:
for src in srcs:
attrs = dict()
@ -516,14 +432,14 @@ class Sflow(object):
sflow_dict["source"].append(attrs)
# get agent info
agent = root.find("data/sflow/agents/agent")
agent = root.find("sflow/agents/agent")
if agent:
for attr in agent:
if attr.tag in ["family", "ipv4Addr", "ipv6Addr"]:
sflow_dict["agent"][attr.tag] = attr.text
# get collector info
collectors = root.findall("data/sflow/collectors/collector")
collectors = root.findall("sflow/collectors/collector")
if collectors:
for collector in collectors:
attrs = dict()
@ -534,21 +450,21 @@ class Sflow(object):
sflow_dict["collector"].append(attrs)
# get sampling info
sample = root.find("data/sflow/samplings/sampling")
sample = root.find("sflow/samplings/sampling")
if sample:
for attr in sample:
if attr.tag in ["ifName", "collectorID", "direction", "length", "rate"]:
sflow_dict["sampling"][attr.tag] = attr.text
# get counter info
counter = root.find("data/sflow/counters/counter")
counter = root.find("sflow/counters/counter")
if counter:
for attr in counter:
if attr.tag in ["ifName", "collectorID", "interval"]:
sflow_dict["counter"][attr.tag] = attr.text
# get export info
export = root.find("data/sflow/exports/export")
export = root.find("sflow/exports/export")
if export:
for attr in export:
if attr.tag == "ExportRoute":
@ -581,11 +497,15 @@ class Sflow(object):
xml_str += '</agent></agents>'
else:
if self.agent_ip == self.sflow_dict["agent"].get("ipv4Addr") \
or self.agent_ip == self.sflow_dict["agent"].get("ipv6Addr"):
flag = False
if self.agent_ip == self.sflow_dict["agent"].get("ipv4Addr"):
self.updates_cmd.append("undo sflow agent ip %s" % self.agent_ip)
flag = True
elif self.agent_ip == self.sflow_dict["agent"].get("ipv6Addr"):
self.updates_cmd.append("undo sflow agent ipv6 %s" % self.agent_ip)
flag = True
if flag is True:
xml_str += '<agents><agent operation="delete"></agent></agents>'
self.updates_cmd.append("undo sflow agent")
return xml_str
def config_source(self):
@ -710,7 +630,7 @@ class Sflow(object):
# update or delete
if self.state == "absent":
xml_str += '<collectors><collector operation="delete"><collectorID>%s</collectorID>' % self.collector_id
self.updates_cmd.append("undo collector %s" % self.collector_id)
self.updates_cmd.append("undo sflow collector %s" % self.collector_id)
else:
xml_str += '<collectors><collector operation="merge"><collectorID>%s</collectorID>' % self.collector_id
cmd = "sflow collector %s" % self.collector_id
@ -926,29 +846,6 @@ class Sflow(object):
return xml_str
def config_assign(self):
"""configure assign"""
# assign sflow management-plane export rate-limit rate-limit [ slot slot-id ]
if self.rate_limit:
cmd = "assign sflow management-plane export rate-limit %s" % self.rate_limit
if self.rate_limit_slot:
cmd += " slot %s" % self.rate_limit_slot
exist = is_config_exist(self.config, cmd)
if self.state == "present" and not exist:
self.cli_add_command(cmd)
elif self.state == "absent" and exist:
self.cli_add_command(cmd, undo=True)
# assign forward enp sflow enable slot { slot-id | all }
if self.forward_enp_slot:
cmd = "assign forward enp sflow enable slot %s" % self.forward_enp_slot
exist = is_config_exist(self.config, cmd)
if self.state == "present" and not exist:
self.cli_add_command(cmd)
elif self.state == "absent" and exist:
self.cli_add_command(cmd, undo=True)
def netconf_load_config(self, xml_str):
"""load sflow config by netconf"""
@ -1029,11 +926,12 @@ class Sflow(object):
msg="Error: interface %s is not support sFlow." % self.sflow_interface)
# check sample_collector
if self.sample_collector:
self.sample_collector.sort()
if self.sample_collector not in [["1"], ["2"], ["1", "2"]]:
self.module.fail_json(
msg="Error: sample_collector is invalid.")
if 0 < len(self.sample_collector) < 3:
self.sample_collector = [str(i) for i in self.sample_collector]
for id in self.sample_collector:
if id not in ("1", "2"):
self.module.fail_json(
msg="Error: sample_collector is invalid.")
# check sample_rate ranges from 1 to 4294967295
if self.sample_rate:
@ -1054,11 +952,12 @@ class Sflow(object):
msg="Error: sample_length is not ranges from 18 to 512.")
# check counter_collector
if self.counter_collector:
self.counter_collector.sort()
if self.counter_collector not in [["1"], ["2"], ["1", "2"]]:
self.module.fail_json(
msg="Error: counter_collector is invalid.")
if 0 < len(self.counter_collector) < 3:
self.counter_collector = [str(i) for i in self.counter_collector]
for id in self.counter_collector:
if id not in ("1", "2"):
self.module.fail_json(
msg="Error: counter_collector is invalid.")
# counter_interval ranges from 10 to 4294967295
if self.counter_interval:
@ -1069,24 +968,6 @@ class Sflow(object):
self.module.fail_json(
msg="Error: sample_length is not ranges from 10 to 4294967295.")
# check rate_limit ranges from 100 to 1500 and check rate_limit_slot
if self.rate_limit:
if not self.rate_limit.isdigit():
self.module.fail_json(msg="Error: rate_limit is not digit.")
if int(self.rate_limit) < 100 or int(self.rate_limit) > 1500:
self.module.fail_json(
msg="Error: rate_limit is not ranges from 100 to 1500.")
if self.rate_limit_slot and not self.rate_limit_slot.isdigit():
self.module.fail_json(
msg="Error: rate_limit_slot is not digit.")
# check forward_enp_slot
if self.forward_enp_slot:
self.forward_enp_slot.lower()
if not self.forward_enp_slot.isdigit() and self.forward_enp_slot != "all":
self.module.fail_json(
msg="Error: forward_enp_slot is invalid.")
def get_proposed(self):
"""get proposed info"""
@ -1097,11 +978,6 @@ class Sflow(object):
self.proposed["source_ip"] = self.source_ip
if self.export_route:
self.proposed["export_route"] = self.export_route
if self.rate_limit:
self.proposed["rate_limit"] = self.rate_limit
self.proposed["rate_limit_slot"] = self.rate_limit_slot
if self.forward_enp_slot:
self.proposed["forward_enp_slot"] = self.forward_enp_slot
if self.collector_id:
self.proposed["collector_id"] = self.collector_id
if self.collector_ip:
@ -1139,13 +1015,6 @@ class Sflow(object):
def get_existing(self):
"""get existing info"""
if self.config:
if self.rate_limit:
self.existing["rate_limit"] = get_rate_limit(self.config)
if self.forward_enp_slot:
self.existing["forward_enp_slot"] = get_forward_enp(
self.config)
if not self.sflow_dict:
return
@ -1165,13 +1034,7 @@ class Sflow(object):
def get_end_state(self):
"""get end state info"""
config = self.get_current_config()
if config:
if self.rate_limit:
self.end_state["rate_limit"] = get_rate_limit(config)
if self.forward_enp_slot:
self.end_state["forward_enp_slot"] = get_forward_enp(config)
# else:
sflow_dict = self.get_sflow_dict()
if not sflow_dict:
return
@ -1194,7 +1057,6 @@ class Sflow(object):
self.check_params()
self.sflow_dict = self.get_sflow_dict()
self.config = self.get_current_config()
self.get_existing()
self.get_proposed()
@ -1220,13 +1082,6 @@ class Sflow(object):
if self.collector_id:
xml_str += self.config_collector()
if self.rate_limit or self.forward_enp_slot:
self.config_assign()
if self.commands:
self.cli_load_config(self.commands)
self.changed = True
if xml_str:
self.netconf_load_config(xml_str)
self.changed = True
@ -1252,9 +1107,6 @@ def main():
source_ip=dict(required=False, type='str'),
export_route=dict(required=False, type='str',
choices=['enable', 'disable']),
rate_limit=dict(required=False, type='str'),
rate_limit_slot=dict(required=False, type='str'),
forward_enp_slot=dict(required=False, type='str'),
collector_id=dict(required=False, type='str', choices=['1', '2']),
collector_ip=dict(required=False, type='str'),
collector_ip_vpn=dict(required=False, type='str'),