Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add iosxr_vrf_global resource module #467

Merged
merged 37 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
c94fbb9
Add vrf module [WIP]
Ruchip16 Jan 24, 2024
3f15ecd
adds parsed state & gathered state
Ruchip16 Feb 5, 2024
a053529
minor changes in config
Ruchip16 Feb 5, 2024
ca39096
working state - parsed & merged
Ruchip16 Feb 15, 2024
54111bc
states implementation
Ruchip16 Feb 29, 2024
59a846c
change name vrf -> vrfs throughout
Ruchip16 Mar 6, 2024
2ab3671
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 6, 2024
07161a5
Merge branch 'main' into feature-vrf
Ruchip16 Mar 6, 2024
01de125
changes
Ruchip16 Mar 10, 2024
b590dd9
push changes
Ruchip16 Mar 21, 2024
c8da71f
unit tests running :D
Ruchip16 Mar 26, 2024
7e575c5
successful integration tests & unit tests
Ruchip16 Mar 31, 2024
3354229
Merge branch 'main' of https://github.com/ansible-collections/cisco.i…
Ruchip16 Mar 31, 2024
807b4ab
changes
Ruchip16 Mar 31, 2024
8efe0e8
changes
Ruchip16 Mar 31, 2024
3b319e9
changes
Ruchip16 Mar 31, 2024
b2124c3
sanity test fix
Ruchip16 Mar 31, 2024
04be084
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 31, 2024
573f87e
review changes
Ruchip16 Apr 4, 2024
03bf25a
Merge branch 'feature-vrf' of https://github.com/ansible-collections/…
Ruchip16 Apr 4, 2024
4d7af85
add iosxr_vrf_globl module
Ruchip16 May 6, 2024
5d6cf44
update changelog fragment
Ruchip16 May 6, 2024
13dd1b9
pylint errors
Ruchip16 May 6, 2024
1cb425f
updates
Ruchip16 May 13, 2024
f76c234
tests up and working :D
Ruchip16 May 13, 2024
e91ceaf
review changes
Ruchip16 May 16, 2024
c636434
addressing review comments
Ruchip16 May 16, 2024
8e35fc8
sanity failures
Ruchip16 May 16, 2024
d73f89e
set and reset config via config module
Ruchip16 May 30, 2024
eaea321
some minor changes
Ruchip16 May 31, 2024
ad8b5b6
add changes
Ruchip16 May 31, 2024
5681e98
line too long
Ruchip16 May 31, 2024
2869441
update doc
Ruchip16 Jun 4, 2024
94e96cc
changes
Ruchip16 Jun 4, 2024
8ea4630
Merge branch 'main' into feature-vrf
Ruchip16 Jun 4, 2024
3c473a5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 4, 2024
e97d4dc
Merge branch 'main' into feature-vrf
Ruchip16 Jun 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ Name | Description
[cisco.iosxr.iosxr_static_routes](https://github.com/ansible-collections/cisco.iosxr/blob/main/docs/cisco.iosxr.iosxr_static_routes_module.rst)|Resource module to configure static routes.
[cisco.iosxr.iosxr_system](https://github.com/ansible-collections/cisco.iosxr/blob/main/docs/cisco.iosxr.iosxr_system_module.rst)|Module to manage the system attributes.
[cisco.iosxr.iosxr_user](https://github.com/ansible-collections/cisco.iosxr/blob/main/docs/cisco.iosxr.iosxr_user_module.rst)|Module to manage the aggregates of local users.
[cisco.iosxr.iosxr_vrf_global](https://github.com/ansible-collections/cisco.iosxr/blob/main/docs/cisco.iosxr.iosxr_vrf_global_module.rst)|Manages global VRF configuration.

<!--end collection content-->

Expand Down
4 changes: 4 additions & 0 deletions changelogs/fragments/add_vrf_global_module.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
minor_changes:
- Adds a new module `iosxr_vrf_global` to manage VRF global configurations on Cisco IOS-XR devices.
- https://github.com/ansible-collections/cisco.iosxr/pull/467
2 changes: 2 additions & 0 deletions meta/runtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,5 @@ plugin_routing:
redirect: cisco.iosxr.iosxr_snmp_server
hostname:
redirect: cisco.iosxr.iosxr_hostname
vrf_global:
redirect: cisco.iosxr.iosxr_vrf_global
1 change: 1 addition & 0 deletions plugins/action/vrf_global.py
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
# Copyright 2024 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
# ansible.content_builder.
#
# Manually editing this file is not advised.
#
# To update the argspec make the desired changes
# in the documentation in the module file and re-run
# ansible.content_builder commenting out
# the path to external 'docstring' in build.yaml.
#
##############################################

"""
The arg spec for the iosxr_vrf_global module
"""


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

argument_spec = {
"config": {
"type": "list",
"elements": "dict",
"options": {
"name": {"type": "str", "required": True},
"description": {"type": "str"},
"evpn_route_sync": {"type": "int"},
"fallback_vrf": {"type": "str"},
"mhost": {
"type": "dict",
"options": {
"afi": {"type": "str", "choices": ["ipv4", "ipv6"]},
"default_interface": {"type": "str"},
},
},
"rd": {"type": "str"},
"remote_route_filtering": {
"type": "dict",
"options": {"disable": {"type": "bool"}},
},
"vpn": {"type": "dict", "options": {"id": {"type": "str"}}},
},
},
"running_config": {"type": "str"},
"state": {
"choices": [
"parsed",
"gathered",
"deleted",
"merged",
"replaced",
"rendered",
"overridden",
"purged",
],
"default": "merged",
"type": "str",
},
} # pylint: disable=C0301
Empty file.
121 changes: 121 additions & 0 deletions plugins/module_utils/network/iosxr/config/vrf_global/vrf_global.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# -*- coding: utf-8 -*-
# Copyright 2024 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 iosxr_vrf_global 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.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
ResourceModule,
)
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
dict_merge,
)

from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.facts import Facts
from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.rm_templates.vrf_global import (
Vrf_globalTemplate,
)


class Vrf_global(ResourceModule):
"""
The iosxr_vrf_global config class
"""

def __init__(self, module):
super(Vrf_global, self).__init__(
empty_fact_val=[],
facts_module=Facts(module),
module=module,
resource="vrf_global",
tmplt=Vrf_globalTemplate(),
)
self.parsers = [
"description",
"evpn_route_sync",
"fallback_vrf",
"mhost.default_interface",
"rd",
"remote_route_filtering.disable",
"vpn.id",
]

def execute_module(self):
"""Execute the module

:rtype: A dictionary
:returns: The result from module execution
"""
if self.state not in ["parsed", "gathered"]:
self.generate_commands()
self.run_commands()
return self.result

def generate_commands(self):
"""Generate configuration commands to send based on
want, have and desired state.
"""
wantd = self.want
haved = self.have

wantd = self._vrf_list_to_dict(wantd)
haved = self._vrf_list_to_dict(haved)

# if state is merged, merge want into have and then compare
if self.state == "merged":
wantd = dict_merge(haved, wantd)

# if state is deleted, empty out wantd and set haved to wantd
if self.state == "deleted":
haved = {k: v for k, v in haved.items() if k in wantd or not wantd}
wantd = {}

# remove superfluous config for overridden and deleted
if self.state in ["overridden", "deleted"]:
for k, have in haved.items():
if k not in wantd:
self._compare(want={}, have=have, vrf=k)

if self.state == "purged":
for k, have in iteritems(haved):
self.purge(have)

for k, want in wantd.items():
self._compare(want=want, have=haved.pop(k, {}), vrf=k)

def _compare(self, want, have, vrf):
"""Leverages the base class `compare()` method and
populates the list of commands to be run by comparing
the `want` and `have` data with the `parsers` defined
for the Vrf network resource.
"""
begin = len(self.commands)
self.compare(self.parsers, want=want, have=have)
if len(self.commands) != begin:
self.commands.insert(begin, self._tmplt.render({"name": vrf}, "name", False))

def _vrf_list_to_dict(self, entry):
"""Convert list of items to dict of items
for efficient diff calculation.
:params entry: data dictionary
"""
entry = {x["name"]: x for x in entry}
return entry

def purge(self, have):
"""Purge the VRF configuration"""
self.commands.append("no vrf {0}".format(have["name"]))
4 changes: 4 additions & 0 deletions plugins/module_utils/network/iosxr/facts/facts.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@
from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.static_routes.static_routes import (
Static_routesFacts,
)
from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.vrf_global.vrf_global import (
Vrf_globalFacts,
)


FACT_LEGACY_SUBSETS = dict(
Expand Down Expand Up @@ -126,6 +129,7 @@
snmp_server=Snmp_serverFacts,
hostname=HostnameFacts,
bgp_templates=Bgp_templatesFacts,
vrf_global=Vrf_globalFacts,
)


Expand Down
Empty file.
78 changes: 78 additions & 0 deletions plugins/module_utils/network/iosxr/facts/vrf_global/vrf_global.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
# Copyright 2024 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 iosxr vrf_global fact class
It is in this file the configuration is collected from the device
for a given resource, parsed, and the facts tree is populated
based on the configuration.
"""

from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils

from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.argspec.vrf_global.vrf_global import (
Vrf_globalArgs,
)
from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.rm_templates.vrf_global import (
Vrf_globalTemplate,
)
from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.utils.utils import (
flatten_config,
)


class Vrf_globalFacts(object):
"""The iosxr vrf facts class"""

def __init__(self, module, subspec="config", options="options"):
self._module = module
self.argument_spec = Vrf_globalArgs.argument_spec

def get_config(self, connection):
"""Get the configuration from the device"""

return connection.get("show running-config vrf")

def populate_facts(self, connection, ansible_facts, data=None):
"""Populate the facts for Vrf network resource
:param connection: the device connection
:param ansible_facts: Facts dictionary
:param data: previously collected conf
:rtype: dictionary
:returns: facts
"""

facts = {}
objs = []
obj = {}

if not data:
data = self.get_config(connection)

data = flatten_config(data, "vrf")

# parse native config using the Vrf_global template
vrf_global_parser = Vrf_globalTemplate(lines=data.splitlines(), module=self._module)
obj = vrf_global_parser.parse()
objs = list(obj.values())

ansible_facts["ansible_network_resources"].pop("vrf_global", None)
params = utils.remove_empties(
vrf_global_parser.validate_config(
self.argument_spec,
{"config": objs},
redact=True,
),
)

facts["vrf_global"] = params.get("config", [])
ansible_facts["ansible_network_resources"].update(facts)

return ansible_facts
Loading
Loading