Skip to content

Commit

Permalink
IOS Ping module (#595)
Browse files Browse the repository at this point in the history
IOS Ping module

SUMMARY

ios_ping Module

ISSUE TYPE


Bugfix Pull Request
Docs Pull Request
Feature Pull Request

COMPONENT NAME

ios_ping
ADDITIONAL INFORMATION


Playbook

    - name: Check ping
      cisco.ios.ios_ping:
        dest: 10.0.150.115
        count: 4

Reviewed-by: Nilashish Chakraborty <nilashishchakraborty8@gmail.com>
Reviewed-by: Sagar Paul <sagpaul@redhat.com>
  • Loading branch information
KB-perByte committed Jun 27, 2022
1 parent 32fe062 commit 1af932e
Show file tree
Hide file tree
Showing 11 changed files with 458 additions and 350 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -61,7 +61,7 @@ Name | Description
[cisco.ios.ios_ospf_interfaces](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_ospf_interfaces_module.rst)|Resource module to configure OSPF interfaces.
[cisco.ios.ios_ospfv2](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_ospfv2_module.rst)|Resource module to configure OSPFv2.
[cisco.ios.ios_ospfv3](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_ospfv3_module.rst)|Resource module to configure OSPFv3.
[cisco.ios.ios_ping](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_ping_module.rst)|Module to tests reachability using ping from network devices.
[cisco.ios.ios_ping](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_ping_module.rst)|Tests reachability using ping from IOS switch.
[cisco.ios.ios_prefix_lists](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_prefix_lists_module.rst)|Resource module to configure prefix lists.
[cisco.ios.ios_route_maps](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_route_maps_module.rst)|Resource module to configure route maps.
[cisco.ios.ios_snmp_server](https://github.com/ansible-collections/cisco.ios/blob/main/docs/cisco.ios.ios_snmp_server_module.rst)|Resource module to configure snmp server.
Expand Down
3 changes: 3 additions & 0 deletions changelogs/fragments/ios_ping_update.yml
@@ -0,0 +1,3 @@
---
minor_changes:
- "`ios_ping` - Add ipv6 options."
199 changes: 51 additions & 148 deletions docs/cisco.ios.ios_ping_module.rst

Large diffs are not rendered by default.

Empty file.
48 changes: 48 additions & 0 deletions plugins/module_utils/network/ios/argspec/ping/ping.py
@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
# Copyright 2022 Red Hat
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import absolute_import, division, print_function

__metaclass__ = type

#############################################
# WARNING #
#############################################
#
# This file is auto generated by the
# cli_rm_builder.
#
# Manually editing this file is not advised.
#
# To update the argspec make the desired changes
# in the module docstring and re-run
# cli_rm_builder.
#
#############################################

"""
The arg spec for the ios_ping module
"""


class PingArgs(object): # pylint: disable=R0903
"""The arg spec for the ios_ping module"""

argument_spec = {
"count": {"type": "int"},
"afi": {"choices": ["ip", "ipv6"], "default": "ip", "type": "str"},
"dest": {"required": True, "type": "str"},
"df_bit": {"default": False, "type": "bool"},
"source": {"type": "str"},
"ingress": {"type": "str"},
"egress": {"type": "str"},
"timeout": {"type": "int"},
"state": {
"choices": ["absent", "present"],
"default": "present",
"type": "str",
},
"vrf": {"type": "str"},
} # pylint: disable=C0301
Empty file.
100 changes: 100 additions & 0 deletions plugins/module_utils/network/ios/config/ping/ping.py
@@ -0,0 +1,100 @@
#
# -*- coding: utf-8 -*-
# Copyright 2022 Red Hat
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
#

from __future__ import absolute_import, division, print_function

__metaclass__ = type

"""
The ios_ping config file.
It is in this file where the current configuration (as dict)
is compared to the provided configuration (as dict) and the command set
necessary to bring the current configuration to its desired end-state is
created.
"""

from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import (
utils,
)
from ansible_collections.cisco.ios.plugins.module_utils.network.ios.ios import (
run_commands,
)
from ansible_collections.cisco.ios.plugins.module_utils.network.ios.rm_templates.ping import (
PingTemplate,
)


class Ping:
"""
The ios_ping config class
"""

def __init__(self, module):
self.module = module
self.result = {}

def execute_module(self):
"""Execute the module
:rtype: A dictionary
:returns: The result from module execution
"""
self.generate_command()
res = self.run_command()
return self.process_result(res)

def build_ping(self, params):
tmplt = PingTemplate()
params = utils.remove_empties(params)
cmd = tmplt.render(params, "rate", False)
return cmd

def validate_results(self, module, loss, results):
"""
This function is used to validate whether the ping results were unexpected per "state" param.
"""
state = module.params["state"]
if state == "present" and loss == 100:
module.fail_json(msg="Ping failed unexpectedly", **results)
elif state == "absent" and loss < 100:
module.fail_json(msg="Ping succeeded unexpectedly", **results)

def generate_command(self):
"""Generate configuration commands to send based on
want, have and desired state.
"""
warnings = list()
if warnings:
self.result["warnings"] = warnings
self.result["commands"] = self.build_ping(self.module.params)

def run_command(self):
ping_results = run_commands(
self.module, commands=self.result["commands"]
)
return ping_results

def process_result(self, ping_results):
"""
Function used to parse the statistical information from the ping response.
Example: "Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/8 ms"
Returns the percent of packet loss, received packets, transmitted packets, and RTT data.
"""

if type(ping_results) == list:
ping_results = ping_results[0]

ping_data = PingTemplate(lines=ping_results.splitlines())
obj = list(ping_data.parse().values())

self.result["packet_loss"] = obj[0].get("loss_percentage")
self.result["packets_rx"] = obj[0].get("rx")
self.result["packets_tx"] = obj[0].get("tx")
self.result["rtt"] = obj[0].get("rtt")
loss = obj[0].get("loss")
self.validate_results(self.module, loss, self.result)
return self.result
64 changes: 64 additions & 0 deletions plugins/module_utils/network/ios/rm_templates/ping.py
@@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
# Copyright 2022 Red Hat
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import absolute_import, division, print_function

__metaclass__ = type

"""
The Ping parser templates file. This contains
a list of parser definitions and associated functions that
facilitates both facts gathering and native command generation for
the given network resource.
"""

import re
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import (
NetworkTemplate,
)


class PingTemplate(NetworkTemplate):
def __init__(self, lines=None):
super(PingTemplate, self).__init__(lines=lines, tmplt=self)

# fmt: off
PARSERS = [
{
'name': 'rate',
'getval': re.compile(r'''
^Success\srate\sis
(\s(?P<pct>\d+))?
(\spercent\s\((?P<rx>\d+)/(?P<tx>\d+)\))?
,\s+round-trip\smin/avg/max\s=
(\s(?P<min>\d+)/(?P<avg>\d+)/(?P<max>\d+))?
(\s+\w+\s*$|.*\s*$)?
''', re.VERBOSE),
"setval": "ping"
"{{ (' vrf ' + vrf) if vrf is defined else '' }}"
"{{ (' ' + afi|string ) if afi is defined else '' }}"
"{{ (' ' + dest ) if dest is defined else '' }}"
"{{ (' repeat ' + count|string ) if count is defined else '' }}"
"{{ (' df-bit' ) if df_bit|d(False) else '' }}"
"{{ (' timeout ' + timeout|string) if timeout is defined else '' }}"
"{{ (' ingress ' + ingress) if ingress is defined else '' }}"
"{{ (' egress ' + egress) if egress is defined else '' }}"
"{{ (' source ' + source) if source is defined else '' }}",
'result': {
"ping": {
'loss_percentage': '{{ 100 - pct|int }}%',
'loss': '{{ 100 - pct|int }}',
'rx': '{{ rx|int }}',
'tx': '{{ tx|int }}',
'rtt': {
'min': '{{ min }}',
'avg': '{{ avg }}',
'max': '{{ max }}',
},
},
},
},
]
# fmt: on

0 comments on commit 1af932e

Please sign in to comment.