Revert "ce_sflow: update to fix bugs." (#64001)

* Revert "ce_sflow: update to fix bugs. (#59349)"

This reverts commit 7711524718.

* Update ce_sflow.py
pull/63966/head
Xu Yuandong 5 years ago committed by ansibot
parent e60cdc310d
commit 30be3a4a9f

@ -33,13 +33,13 @@ author: QijunPan (@QijunPan)
options: options:
agent_ip: agent_ip:
description: description:
- Specifies the IPv4/IPv6 address of a sFlow agent. - Specifies the IPv4/IPv6 address of an sFlow agent.
source_ip: source_ip:
description: description:
- Specifies the source IPv4/IPv6 address of sFlow packets. - Specifies the source IPv4/IPv6 address of sFlow packets.
collector_id: collector_id:
description: description:
- Specifies the ID of a sFlow collector. This ID is used when you specify - Specifies the ID of an sFlow collector. This ID is used when you specify
the collector in subsequent sFlow configuration. the collector in subsequent sFlow configuration.
choices: ['1', '2'] choices: ['1', '2']
collector_ip: collector_ip:
@ -72,7 +72,7 @@ options:
choices: ['meth', 'enhanced'] choices: ['meth', 'enhanced']
collector_description: collector_description:
description: description:
- Specifies the description of a sFlow collector. - Specifies the description of an sFlow collector.
The value is a string of 1 to 255 case-sensitive characters without spaces. The value is a string of 1 to 255 case-sensitive characters without spaces.
sflow_interface: sflow_interface:
description: description:
@ -104,6 +104,30 @@ options:
description: description:
- Configures the sFlow packets sent by the switch not to carry routing information. - Configures the sFlow packets sent by the switch not to carry routing information.
choices: ['enable', 'disable'] 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.
version_added: "2.10"
type: str
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.
version_added: "2.10"
type: str
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'.
version_added: "2.10"
type: str
state: state:
description: description:
- Determines whether the config should be present or not - Determines whether the config should be present or not
@ -187,7 +211,8 @@ changed:
import re import re
from xml.etree import ElementTree from xml.etree import ElementTree
from ansible.module_utils.basic import AnsibleModule 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, to_string 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
CE_NC_GET_SFLOW = """ CE_NC_GET_SFLOW = """
<filter type="subtree"> <filter type="subtree">
@ -331,6 +356,33 @@ def get_interface_type(interface):
return iftype.lower() 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): class Sflow(object):
"""Manages sFlow""" """Manages sFlow"""
@ -345,6 +397,9 @@ class Sflow(object):
self.source_ip = self.module.params['source_ip'] self.source_ip = self.module.params['source_ip']
self.source_version = None self.source_version = None
self.export_route = self.module.params['export_route'] 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_id = self.module.params['collector_id']
self.collector_ip = self.module.params['collector_ip'] self.collector_ip = self.module.params['collector_ip']
self.collector_version = None self.collector_version = None
@ -394,11 +449,46 @@ class Sflow(object):
if "<ok/>" not in rcv_xml: if "<ok/>" not in rcv_xml:
self.module.fail_json(msg='Error: %s failed.' % xml_name) self.module.fail_json(msg='Error: %s failed.' % xml_name)
def netconf_get_config(self, xml_str): def cli_load_config(self, commands):
"""netconf set config""" """load config by cli"""
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
if xml_str is not None: self.commands.append(cmd) # set to device
return get_nc_config(self.module, xml_str) if command.lower() not in ["quit", "return"]:
self.updates_cmd.append(cmd) # show updates result
def get_sflow_dict(self): def get_sflow_dict(self):
""" sflow config dict""" """ sflow config dict"""
@ -411,7 +501,7 @@ class Sflow(object):
if not self.collector_meth: if not self.collector_meth:
conf_str = conf_str.replace("<meth></meth>", "") conf_str = conf_str.replace("<meth></meth>", "")
rcv_xml = self.netconf_get_config(conf_str) rcv_xml = get_nc_config(self.module, conf_str)
if "<data/>" in rcv_xml: if "<data/>" in rcv_xml:
return sflow_dict return sflow_dict
@ -422,7 +512,7 @@ class Sflow(object):
root = ElementTree.fromstring(xml_str) root = ElementTree.fromstring(xml_str)
# get source info # get source info
srcs = root.findall("sflow/sources/source") srcs = root.findall("data/sflow/sources/source")
if srcs: if srcs:
for src in srcs: for src in srcs:
attrs = dict() attrs = dict()
@ -432,14 +522,14 @@ class Sflow(object):
sflow_dict["source"].append(attrs) sflow_dict["source"].append(attrs)
# get agent info # get agent info
agent = root.find("sflow/agents/agent") agent = root.find("data/sflow/agents/agent")
if agent: if agent:
for attr in agent: for attr in agent:
if attr.tag in ["family", "ipv4Addr", "ipv6Addr"]: if attr.tag in ["family", "ipv4Addr", "ipv6Addr"]:
sflow_dict["agent"][attr.tag] = attr.text sflow_dict["agent"][attr.tag] = attr.text
# get collector info # get collector info
collectors = root.findall("sflow/collectors/collector") collectors = root.findall("data/sflow/collectors/collector")
if collectors: if collectors:
for collector in collectors: for collector in collectors:
attrs = dict() attrs = dict()
@ -450,21 +540,21 @@ class Sflow(object):
sflow_dict["collector"].append(attrs) sflow_dict["collector"].append(attrs)
# get sampling info # get sampling info
sample = root.find("sflow/samplings/sampling") sample = root.find("data/sflow/samplings/sampling")
if sample: if sample:
for attr in sample: for attr in sample:
if attr.tag in ["ifName", "collectorID", "direction", "length", "rate"]: if attr.tag in ["ifName", "collectorID", "direction", "length", "rate"]:
sflow_dict["sampling"][attr.tag] = attr.text sflow_dict["sampling"][attr.tag] = attr.text
# get counter info # get counter info
counter = root.find("sflow/counters/counter") counter = root.find("data/sflow/counters/counter")
if counter: if counter:
for attr in counter: for attr in counter:
if attr.tag in ["ifName", "collectorID", "interval"]: if attr.tag in ["ifName", "collectorID", "interval"]:
sflow_dict["counter"][attr.tag] = attr.text sflow_dict["counter"][attr.tag] = attr.text
# get export info # get export info
export = root.find("sflow/exports/export") export = root.find("data/sflow/exports/export")
if export: if export:
for attr in export: for attr in export:
if attr.tag == "ExportRoute": if attr.tag == "ExportRoute":
@ -497,15 +587,11 @@ class Sflow(object):
xml_str += '</agent></agents>' xml_str += '</agent></agents>'
else: else:
flag = False if self.agent_ip == self.sflow_dict["agent"].get("ipv4Addr") \
if self.agent_ip == self.sflow_dict["agent"].get("ipv4Addr"): or self.agent_ip == self.sflow_dict["agent"].get("ipv6Addr"):
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>' xml_str += '<agents><agent operation="delete"></agent></agents>'
self.updates_cmd.append("undo sflow agent")
return xml_str return xml_str
def config_source(self): def config_source(self):
@ -630,7 +716,7 @@ class Sflow(object):
# update or delete # update or delete
if self.state == "absent": if self.state == "absent":
xml_str += '<collectors><collector operation="delete"><collectorID>%s</collectorID>' % self.collector_id xml_str += '<collectors><collector operation="delete"><collectorID>%s</collectorID>' % self.collector_id
self.updates_cmd.append("undo sflow collector %s" % self.collector_id) self.updates_cmd.append("undo collector %s" % self.collector_id)
else: else:
xml_str += '<collectors><collector operation="merge"><collectorID>%s</collectorID>' % self.collector_id xml_str += '<collectors><collector operation="merge"><collectorID>%s</collectorID>' % self.collector_id
cmd = "sflow collector %s" % self.collector_id cmd = "sflow collector %s" % self.collector_id
@ -846,6 +932,29 @@ class Sflow(object):
return xml_str 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): def netconf_load_config(self, xml_str):
"""load sflow config by netconf""" """load sflow config by netconf"""
@ -926,12 +1035,11 @@ class Sflow(object):
msg="Error: interface %s is not support sFlow." % self.sflow_interface) msg="Error: interface %s is not support sFlow." % self.sflow_interface)
# check sample_collector # check sample_collector
if 0 < len(self.sample_collector) < 3: if self.sample_collector:
self.sample_collector = [str(i) for i in self.sample_collector] self.sample_collector.sort()
for id in self.sample_collector: if self.sample_collector not in [["1"], ["2"], ["1", "2"]]:
if id not in ("1", "2"): self.module.fail_json(
self.module.fail_json( msg="Error: sample_collector is invalid.")
msg="Error: sample_collector is invalid.")
# check sample_rate ranges from 1 to 4294967295 # check sample_rate ranges from 1 to 4294967295
if self.sample_rate: if self.sample_rate:
@ -952,12 +1060,11 @@ class Sflow(object):
msg="Error: sample_length is not ranges from 18 to 512.") msg="Error: sample_length is not ranges from 18 to 512.")
# check counter_collector # check counter_collector
if 0 < len(self.counter_collector) < 3: if self.counter_collector:
self.counter_collector = [str(i) for i in self.counter_collector] self.counter_collector.sort()
for id in self.counter_collector: if self.counter_collector not in [["1"], ["2"], ["1", "2"]]:
if id not in ("1", "2"): self.module.fail_json(
self.module.fail_json( msg="Error: counter_collector is invalid.")
msg="Error: counter_collector is invalid.")
# counter_interval ranges from 10 to 4294967295 # counter_interval ranges from 10 to 4294967295
if self.counter_interval: if self.counter_interval:
@ -968,6 +1075,24 @@ class Sflow(object):
self.module.fail_json( self.module.fail_json(
msg="Error: sample_length is not ranges from 10 to 4294967295.") 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): def get_proposed(self):
"""get proposed info""" """get proposed info"""
@ -978,6 +1103,11 @@ class Sflow(object):
self.proposed["source_ip"] = self.source_ip self.proposed["source_ip"] = self.source_ip
if self.export_route: if self.export_route:
self.proposed["export_route"] = 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: if self.collector_id:
self.proposed["collector_id"] = self.collector_id self.proposed["collector_id"] = self.collector_id
if self.collector_ip: if self.collector_ip:
@ -1015,6 +1145,13 @@ class Sflow(object):
def get_existing(self): def get_existing(self):
"""get existing info""" """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: if not self.sflow_dict:
return return
@ -1034,7 +1171,13 @@ class Sflow(object):
def get_end_state(self): def get_end_state(self):
"""get end state info""" """get end state info"""
# else: 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)
sflow_dict = self.get_sflow_dict() sflow_dict = self.get_sflow_dict()
if not sflow_dict: if not sflow_dict:
return return
@ -1057,6 +1200,7 @@ class Sflow(object):
self.check_params() self.check_params()
self.sflow_dict = self.get_sflow_dict() self.sflow_dict = self.get_sflow_dict()
self.config = self.get_current_config()
self.get_existing() self.get_existing()
self.get_proposed() self.get_proposed()
@ -1082,6 +1226,13 @@ class Sflow(object):
if self.collector_id: if self.collector_id:
xml_str += self.config_collector() 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: if xml_str:
self.netconf_load_config(xml_str) self.netconf_load_config(xml_str)
self.changed = True self.changed = True
@ -1107,6 +1258,9 @@ def main():
source_ip=dict(required=False, type='str'), source_ip=dict(required=False, type='str'),
export_route=dict(required=False, type='str', export_route=dict(required=False, type='str',
choices=['enable', 'disable']), 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_id=dict(required=False, type='str', choices=['1', '2']),
collector_ip=dict(required=False, type='str'), collector_ip=dict(required=False, type='str'),
collector_ip_vpn=dict(required=False, type='str'), collector_ip_vpn=dict(required=False, type='str'),

Loading…
Cancel
Save