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:
parent
6be46b59fa
commit
7711524718
1 changed files with 37 additions and 185 deletions
|
@ -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'),
|
||||
|
|
Loading…
Reference in a new issue