[stable-2.9] Standardize eos resource modules (#61736)
* Fix eos_l3_interfaces case sensitivity
* Unify EOS module notes
* Add normalize_interfaces to eos_l2_interfaces
* Pull normalize_interface into eos_interfaces
* Add normalize_interface to lag_interfaces
* Add normalize_interface to lldp_interfaces
* Add normalize_interface to lacp_interfaces
* more module cleanup
* Add changelog
(cherry picked from commit 7917d4def7
)
Co-authored-by: Nathaniel Case <ncase@redhat.com>
This commit is contained in:
parent
f082d23eec
commit
9d6282e633
23 changed files with 350 additions and 265 deletions
3
changelogs/fragments/61736-eos-normalize-interface.yaml
Normal file
3
changelogs/fragments/61736-eos-normalize-interface.yaml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
bugfixes:
|
||||||
|
- Remove case sensitivity on interface names from eos_interfaces, eos_l2_interfaces, eos_l3_interfaces,
|
||||||
|
eos_lacp_interfaces, eos_lag_interfaces, and eos_lldp_interfaces.
|
|
@ -1,6 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright 2019 Red Hat
|
# Copyright 2019 Red Hat
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+
|
||||||
|
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
"""
|
"""
|
||||||
The eos_interfaces class
|
The eos_interfaces class
|
||||||
It is in this file where the current configuration (as dict)
|
It is in this file where the current configuration (as dict)
|
||||||
|
@ -12,10 +13,10 @@ created
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
from ansible.module_utils.network.common.utils import to_list, param_list_to_dict
|
|
||||||
|
|
||||||
from ansible.module_utils.network.common.cfg.base import ConfigBase
|
from ansible.module_utils.network.common.cfg.base import ConfigBase
|
||||||
|
from ansible.module_utils.network.common.utils import to_list, dict_diff, param_list_to_dict
|
||||||
from ansible.module_utils.network.eos.facts.facts import Facts
|
from ansible.module_utils.network.eos.facts.facts import Facts
|
||||||
|
from ansible.module_utils.network.eos.utils.utils import normalize_interface
|
||||||
|
|
||||||
|
|
||||||
class Interfaces(ConfigBase):
|
class Interfaces(ConfigBase):
|
||||||
|
@ -93,148 +94,143 @@ class Interfaces(ConfigBase):
|
||||||
:returns: the commands necessary to migrate the current configuration
|
:returns: the commands necessary to migrate the current configuration
|
||||||
to the desired configuration
|
to the desired configuration
|
||||||
"""
|
"""
|
||||||
|
state = self._module.params['state']
|
||||||
want = param_list_to_dict(want)
|
want = param_list_to_dict(want)
|
||||||
have = param_list_to_dict(have)
|
have = param_list_to_dict(have)
|
||||||
state = self._module.params['state']
|
|
||||||
if state == 'overridden':
|
if state == 'overridden':
|
||||||
commands = state_overridden(want, have)
|
commands = self._state_overridden(want, have)
|
||||||
elif state == 'deleted':
|
elif state == 'deleted':
|
||||||
commands = state_deleted(want, have)
|
commands = self._state_deleted(want, have)
|
||||||
elif state == 'merged':
|
elif state == 'merged':
|
||||||
commands = state_merged(want, have)
|
commands = self._state_merged(want, have)
|
||||||
elif state == 'replaced':
|
elif state == 'replaced':
|
||||||
commands = state_replaced(want, have)
|
commands = self._state_replaced(want, have)
|
||||||
|
return commands
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _state_replaced(want, have):
|
||||||
|
""" The command generator when state is replaced
|
||||||
|
|
||||||
|
:rtype: A list
|
||||||
|
:returns: the commands necessary to migrate the current configuration
|
||||||
|
to the desired configuration
|
||||||
|
"""
|
||||||
|
commands = []
|
||||||
|
for key, desired in want.items():
|
||||||
|
interface_name = normalize_interface(key)
|
||||||
|
if interface_name in have:
|
||||||
|
extant = have[interface_name]
|
||||||
|
else:
|
||||||
|
extant = dict()
|
||||||
|
|
||||||
|
add_config = dict_diff(extant, desired)
|
||||||
|
del_config = dict_diff(desired, extant)
|
||||||
|
|
||||||
|
commands.extend(generate_commands(key, add_config, del_config))
|
||||||
|
|
||||||
|
return commands
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _state_overridden(want, have):
|
||||||
|
""" The command generator when state is overridden
|
||||||
|
|
||||||
|
:rtype: A list
|
||||||
|
:returns: the commands necessary to migrate the current configuration
|
||||||
|
to the desired configuration
|
||||||
|
"""
|
||||||
|
commands = []
|
||||||
|
for key, extant in have.items():
|
||||||
|
if key in want:
|
||||||
|
desired = want[key]
|
||||||
|
else:
|
||||||
|
desired = dict()
|
||||||
|
|
||||||
|
add_config = dict_diff(extant, desired)
|
||||||
|
del_config = dict_diff(desired, extant)
|
||||||
|
|
||||||
|
commands.extend(generate_commands(key, add_config, del_config))
|
||||||
|
|
||||||
|
return commands
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _state_merged(want, have):
|
||||||
|
""" The command generator when state is merged
|
||||||
|
|
||||||
|
:rtype: A list
|
||||||
|
:returns: the commands necessary to merge the provided into
|
||||||
|
the current configuration
|
||||||
|
"""
|
||||||
|
commands = []
|
||||||
|
for key, desired in want.items():
|
||||||
|
interface_name = normalize_interface(key)
|
||||||
|
if interface_name in have:
|
||||||
|
extant = have[interface_name]
|
||||||
|
else:
|
||||||
|
extant = dict()
|
||||||
|
|
||||||
|
add_config = dict_diff(extant, desired)
|
||||||
|
|
||||||
|
commands.extend(generate_commands(key, add_config, {}))
|
||||||
|
|
||||||
|
return commands
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _state_deleted(want, have):
|
||||||
|
""" The command generator when state is deleted
|
||||||
|
|
||||||
|
:rtype: A list
|
||||||
|
:returns: the commands necessary to remove the current configuration
|
||||||
|
of the provided objects
|
||||||
|
"""
|
||||||
|
commands = []
|
||||||
|
for key in want:
|
||||||
|
desired = dict()
|
||||||
|
if key in have:
|
||||||
|
extant = have[key]
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
del_config = dict_diff(desired, extant)
|
||||||
|
|
||||||
|
commands.extend(generate_commands(key, {}, del_config))
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
|
|
||||||
def state_replaced(want, have):
|
def generate_commands(interface, to_set, to_remove):
|
||||||
""" The command generator when state is replaced
|
|
||||||
|
|
||||||
:rtype: A list
|
|
||||||
:returns: the commands necessary to migrate the current configuration
|
|
||||||
to the desired configuration
|
|
||||||
"""
|
|
||||||
commands = _compute_commands(want, have, replace=True, remove=True)
|
|
||||||
|
|
||||||
replace = commands['replace']
|
|
||||||
remove = commands['remove']
|
|
||||||
|
|
||||||
commands_by_interface = replace
|
|
||||||
for interface, commands in remove.items():
|
|
||||||
commands_by_interface[interface] = replace.get(interface, []) + commands
|
|
||||||
|
|
||||||
return _flatten_commands(commands_by_interface)
|
|
||||||
|
|
||||||
|
|
||||||
def state_overridden(want, have):
|
|
||||||
""" The command generator when state is overridden
|
|
||||||
|
|
||||||
:rtype: A list
|
|
||||||
:returns: the commands necessary to migrate the current configuration
|
|
||||||
to the desired configuration
|
|
||||||
"""
|
|
||||||
# Add empty desired state for unspecified interfaces
|
|
||||||
for key in have:
|
|
||||||
if key not in want:
|
|
||||||
want[key] = {}
|
|
||||||
|
|
||||||
# Otherwise it's the same as replaced
|
|
||||||
return state_replaced(want, have)
|
|
||||||
|
|
||||||
|
|
||||||
def state_merged(want, have):
|
|
||||||
""" The command generator when state is merged
|
|
||||||
|
|
||||||
:rtype: A list
|
|
||||||
:returns: the commands necessary to merge the provided into
|
|
||||||
the current configuration
|
|
||||||
"""
|
|
||||||
commands = _compute_commands(want, have, replace=True)
|
|
||||||
return _flatten_commands(commands['replace'])
|
|
||||||
|
|
||||||
|
|
||||||
def state_deleted(want, have):
|
|
||||||
""" The command generator when state is deleted
|
|
||||||
|
|
||||||
:rtype: A list
|
|
||||||
:returns: the commands necessary to remove the current configuration
|
|
||||||
of the provided objects
|
|
||||||
"""
|
|
||||||
commands = _compute_commands(want, have, remove=True)
|
|
||||||
return _flatten_commands(commands['remove'])
|
|
||||||
|
|
||||||
|
|
||||||
def _compute_commands(want, have, replace=False, remove=False):
|
|
||||||
replace_params = {}
|
|
||||||
remove_params = {}
|
|
||||||
for name, config in want.items():
|
|
||||||
extant = have.get(name, {})
|
|
||||||
|
|
||||||
if remove:
|
|
||||||
remove_params[name] = dict(set(extant.items()).difference(config.items()))
|
|
||||||
if replace:
|
|
||||||
replace_params[name] = dict(set(config.items()).difference(extant.items()))
|
|
||||||
if remove:
|
|
||||||
# We won't need to also clear the configuration if we've
|
|
||||||
# already set it to something
|
|
||||||
for param in replace_params[name]:
|
|
||||||
remove_params[name].pop(param, None)
|
|
||||||
|
|
||||||
returns = {}
|
|
||||||
if replace:
|
|
||||||
returns['replace'] = _replace_config(replace_params)
|
|
||||||
if remove:
|
|
||||||
returns['remove'] = _remove_config(remove_params)
|
|
||||||
|
|
||||||
return returns
|
|
||||||
|
|
||||||
|
|
||||||
def _remove_config(params):
|
|
||||||
"""
|
|
||||||
Generates commands to reset config to defaults based on keys provided.
|
|
||||||
"""
|
|
||||||
commands = {}
|
|
||||||
for interface, config in params.items():
|
|
||||||
interface_commands = []
|
|
||||||
for param in config:
|
|
||||||
if param == 'enabled':
|
|
||||||
interface_commands.append('no shutdown')
|
|
||||||
elif param in ('description', 'mtu'):
|
|
||||||
interface_commands.append('no {0}'.format(param))
|
|
||||||
elif param == 'speed':
|
|
||||||
interface_commands.append('speed auto')
|
|
||||||
if interface_commands:
|
|
||||||
commands[interface] = interface_commands
|
|
||||||
|
|
||||||
return commands
|
|
||||||
|
|
||||||
|
|
||||||
def _replace_config(params):
|
|
||||||
"""
|
|
||||||
Generates commands to replace config to new values based on provided dictionary.
|
|
||||||
"""
|
|
||||||
commands = {}
|
|
||||||
for interface, config in params.items():
|
|
||||||
interface_commands = []
|
|
||||||
for param, state in config.items():
|
|
||||||
if param == 'description':
|
|
||||||
interface_commands.append('description "{0}"'.format(state))
|
|
||||||
elif param == 'enabled':
|
|
||||||
interface_commands.append('{0}shutdown'.format('no ' if state else ''))
|
|
||||||
elif param == 'mtu':
|
|
||||||
interface_commands.append('mtu {0}'.format(state))
|
|
||||||
if 'speed' in config:
|
|
||||||
interface_commands.append('speed {0}{1}'.format(config['speed'], config['duplex']))
|
|
||||||
if interface_commands:
|
|
||||||
commands[interface] = interface_commands
|
|
||||||
|
|
||||||
return commands
|
|
||||||
|
|
||||||
|
|
||||||
def _flatten_commands(command_dict):
|
|
||||||
commands = []
|
commands = []
|
||||||
for interface, interface_commands in command_dict.items():
|
for key, value in to_set.items():
|
||||||
commands.append('interface {0}'.format(interface))
|
if value is None:
|
||||||
commands.extend(interface_commands)
|
continue
|
||||||
|
|
||||||
|
if key == "enabled":
|
||||||
|
commands.append('{0}shutdown'.format('no ' if value else ''))
|
||||||
|
elif key == "speed":
|
||||||
|
if value == "auto":
|
||||||
|
commands.append("{0} {1}".format(key, value))
|
||||||
|
else:
|
||||||
|
commands.append('speed {0}{1}'.format(value, to_set['duplex']))
|
||||||
|
elif key == "duplex":
|
||||||
|
# duplex is handled with speed
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
commands.append("{0} {1}".format(key, value))
|
||||||
|
|
||||||
|
# Don't try to also remove the same key, if present in to_remove
|
||||||
|
to_remove.pop(key, None)
|
||||||
|
|
||||||
|
for key in to_remove.keys():
|
||||||
|
if key == "enabled":
|
||||||
|
commands.append('no shutdown')
|
||||||
|
elif key == "speed":
|
||||||
|
commands.append("speed auto")
|
||||||
|
elif key == "duplex":
|
||||||
|
# duplex is handled with speed
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
commands.append("no {0}".format(key))
|
||||||
|
|
||||||
|
if commands:
|
||||||
|
commands.insert(0, "interface {0}".format(interface))
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright 2019 Red Hat
|
# Copyright 2019 Red Hat
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+
|
||||||
|
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
"""
|
"""
|
||||||
The eos_l2_interfaces class
|
The eos_l2_interfaces class
|
||||||
It is in this file where the current configuration (as dict)
|
It is in this file where the current configuration (as dict)
|
||||||
|
@ -12,10 +13,10 @@ created
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
from ansible.module_utils.network.common.utils import to_list
|
|
||||||
|
|
||||||
from ansible.module_utils.network.common.cfg.base import ConfigBase
|
from ansible.module_utils.network.common.cfg.base import ConfigBase
|
||||||
|
from ansible.module_utils.network.common.utils import to_list, param_list_to_dict
|
||||||
from ansible.module_utils.network.eos.facts.facts import Facts
|
from ansible.module_utils.network.eos.facts.facts import Facts
|
||||||
|
from ansible.module_utils.network.eos.utils.utils import normalize_interface
|
||||||
|
|
||||||
|
|
||||||
class L2_interfaces(ConfigBase):
|
class L2_interfaces(ConfigBase):
|
||||||
|
@ -94,6 +95,8 @@ class L2_interfaces(ConfigBase):
|
||||||
to the desired configuration
|
to the desired configuration
|
||||||
"""
|
"""
|
||||||
state = self._module.params['state']
|
state = self._module.params['state']
|
||||||
|
want = param_list_to_dict(want)
|
||||||
|
have = param_list_to_dict(have)
|
||||||
if state == 'overridden':
|
if state == 'overridden':
|
||||||
commands = self._state_overridden(want, have)
|
commands = self._state_overridden(want, have)
|
||||||
elif state == 'deleted':
|
elif state == 'deleted':
|
||||||
|
@ -113,15 +116,20 @@ class L2_interfaces(ConfigBase):
|
||||||
to the desired configuration
|
to the desired configuration
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for interface in want:
|
for key, desired in want.items():
|
||||||
for extant in have:
|
interface_name = normalize_interface(key)
|
||||||
if extant['name'] == interface['name']:
|
if interface_name in have:
|
||||||
break
|
extant = have[interface_name]
|
||||||
else:
|
else:
|
||||||
continue
|
extant = dict()
|
||||||
|
|
||||||
|
intf_commands = set_interface(desired, extant)
|
||||||
|
intf_commands.extend(clear_interface(desired, extant))
|
||||||
|
|
||||||
|
if intf_commands:
|
||||||
|
commands.append("interface {0}".format(interface_name))
|
||||||
|
commands.extend(intf_commands)
|
||||||
|
|
||||||
commands.extend(clear_interface(interface, extant))
|
|
||||||
commands.extend(set_interface(interface, extant))
|
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -133,19 +141,19 @@ class L2_interfaces(ConfigBase):
|
||||||
to the desired configuration
|
to the desired configuration
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for extant in have:
|
for key, extant in have.items():
|
||||||
for interface in want:
|
if key in want:
|
||||||
if extant['name'] == interface['name']:
|
desired = want[key]
|
||||||
break
|
|
||||||
else:
|
else:
|
||||||
# We didn't find a matching desired state, which means we can
|
desired = dict()
|
||||||
# pretend we recieved an empty desired state.
|
|
||||||
interface = dict(name=extant['name'])
|
intf_commands = set_interface(desired, extant)
|
||||||
commands.extend(clear_interface(interface, extant))
|
intf_commands.extend(clear_interface(desired, extant))
|
||||||
continue
|
|
||||||
|
if intf_commands:
|
||||||
|
commands.append("interface {0}".format(key))
|
||||||
|
commands.extend(intf_commands)
|
||||||
|
|
||||||
commands.extend(clear_interface(interface, extant))
|
|
||||||
commands.extend(set_interface(interface, extant))
|
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -157,14 +165,18 @@ class L2_interfaces(ConfigBase):
|
||||||
the current configuration
|
the current configuration
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for interface in want:
|
for key, desired in want.items():
|
||||||
for extant in have:
|
interface_name = normalize_interface(key)
|
||||||
if extant['name'] == interface['name']:
|
if interface_name in have:
|
||||||
break
|
extant = have[interface_name]
|
||||||
else:
|
else:
|
||||||
continue
|
extant = dict()
|
||||||
|
|
||||||
commands.extend(set_interface(interface, extant))
|
intf_commands = set_interface(desired, extant)
|
||||||
|
|
||||||
|
if intf_commands:
|
||||||
|
commands.append("interface {0}".format(interface_name))
|
||||||
|
commands.extend(intf_commands)
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
|
@ -177,29 +189,31 @@ class L2_interfaces(ConfigBase):
|
||||||
of the provided objects
|
of the provided objects
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for interface in want:
|
for key in want:
|
||||||
for extant in have:
|
desired = dict()
|
||||||
if extant['name'] == interface['name']:
|
if key in have:
|
||||||
break
|
extant = have[key]
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Use an empty configuration, just in case
|
intf_commands = clear_interface(desired, extant)
|
||||||
interface = dict(name=interface['name'])
|
|
||||||
commands.extend(clear_interface(interface, extant))
|
if intf_commands:
|
||||||
|
commands.append("interface {0}".format(key))
|
||||||
|
commands.extend(intf_commands)
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
|
|
||||||
def set_interface(want, have):
|
def set_interface(want, have):
|
||||||
commands = []
|
commands = []
|
||||||
wants_access = want["access"]
|
wants_access = want.get("access")
|
||||||
if wants_access:
|
if wants_access:
|
||||||
access_vlan = wants_access.get("vlan")
|
access_vlan = wants_access.get("vlan")
|
||||||
if access_vlan and access_vlan != have.get("access", {}).get("vlan"):
|
if access_vlan and access_vlan != have.get("access", {}).get("vlan"):
|
||||||
commands.append("switchport access vlan {0}".format(access_vlan))
|
commands.append("switchport access vlan {0}".format(access_vlan))
|
||||||
|
|
||||||
wants_trunk = want["trunk"]
|
wants_trunk = want.get("trunk")
|
||||||
if wants_trunk:
|
if wants_trunk:
|
||||||
has_trunk = have.get("trunk", {})
|
has_trunk = have.get("trunk", {})
|
||||||
native_vlan = wants_trunk.get("native_vlan")
|
native_vlan = wants_trunk.get("native_vlan")
|
||||||
|
@ -210,9 +224,6 @@ def set_interface(want, have):
|
||||||
if allowed_vlans:
|
if allowed_vlans:
|
||||||
allowed_vlans = ','.join(allowed_vlans)
|
allowed_vlans = ','.join(allowed_vlans)
|
||||||
commands.append("switchport trunk allowed vlan {0}".format(allowed_vlans))
|
commands.append("switchport trunk allowed vlan {0}".format(allowed_vlans))
|
||||||
|
|
||||||
if commands:
|
|
||||||
commands.insert(0, "interface {0}".format(want['name']))
|
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
|
|
||||||
|
@ -227,7 +238,4 @@ def clear_interface(want, have):
|
||||||
commands.append("no switchport trunk allowed vlan")
|
commands.append("no switchport trunk allowed vlan")
|
||||||
if "native_vlan" in has_trunk and "native_vlan" not in wants_trunk:
|
if "native_vlan" in has_trunk and "native_vlan" not in wants_trunk:
|
||||||
commands.append("no switchport trunk native vlan")
|
commands.append("no switchport trunk native vlan")
|
||||||
|
|
||||||
if commands:
|
|
||||||
commands.insert(0, "interface {0}".format(want["name"]))
|
|
||||||
return commands
|
return commands
|
||||||
|
|
|
@ -13,10 +13,10 @@ created
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
from ansible.module_utils.network.common.utils import to_list
|
|
||||||
|
|
||||||
from ansible.module_utils.network.common.cfg.base import ConfigBase
|
from ansible.module_utils.network.common.cfg.base import ConfigBase
|
||||||
|
from ansible.module_utils.network.common.utils import to_list, param_list_to_dict
|
||||||
from ansible.module_utils.network.eos.facts.facts import Facts
|
from ansible.module_utils.network.eos.facts.facts import Facts
|
||||||
|
from ansible.module_utils.network.eos.utils.utils import normalize_interface
|
||||||
|
|
||||||
|
|
||||||
class L3_interfaces(ConfigBase):
|
class L3_interfaces(ConfigBase):
|
||||||
|
@ -95,6 +95,8 @@ class L3_interfaces(ConfigBase):
|
||||||
to the desired configuration
|
to the desired configuration
|
||||||
"""
|
"""
|
||||||
state = self._module.params['state']
|
state = self._module.params['state']
|
||||||
|
want = param_list_to_dict(want)
|
||||||
|
have = param_list_to_dict(have)
|
||||||
if state == 'overridden':
|
if state == 'overridden':
|
||||||
commands = self._state_overridden(want, have)
|
commands = self._state_overridden(want, have)
|
||||||
elif state == 'deleted':
|
elif state == 'deleted':
|
||||||
|
@ -114,18 +116,18 @@ class L3_interfaces(ConfigBase):
|
||||||
to the desired configuration
|
to the desired configuration
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for interface in want:
|
for key, desired in want.items():
|
||||||
for extant in have:
|
interface_name = normalize_interface(key)
|
||||||
if interface["name"] == extant["name"]:
|
if interface_name in have:
|
||||||
break
|
extant = have[interface_name]
|
||||||
else:
|
else:
|
||||||
extant = dict(name=interface["name"])
|
extant = dict()
|
||||||
|
|
||||||
intf_commands = set_interface(interface, extant)
|
intf_commands = set_interface(desired, extant)
|
||||||
intf_commands.extend(clear_interface(interface, extant))
|
intf_commands.extend(clear_interface(desired, extant))
|
||||||
|
|
||||||
if intf_commands:
|
if intf_commands:
|
||||||
commands.append("interface {0}".format(interface["name"]))
|
commands.append("interface {0}".format(interface_name))
|
||||||
commands.extend(intf_commands)
|
commands.extend(intf_commands)
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
@ -139,22 +141,21 @@ class L3_interfaces(ConfigBase):
|
||||||
to the desired configuration
|
to the desired configuration
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for extant in have:
|
for key, extant in have.items():
|
||||||
for interface in want:
|
if key in want:
|
||||||
if extant["name"] == interface["name"]:
|
desired = want[key]
|
||||||
break
|
|
||||||
else:
|
else:
|
||||||
interface = dict(name=extant["name"])
|
desired = dict()
|
||||||
if interface.get("ipv4"):
|
if desired.get("ipv4"):
|
||||||
for ipv4 in interface["ipv4"]:
|
for ipv4 in desired["ipv4"]:
|
||||||
if ipv4["secondary"] is None:
|
if ipv4["secondary"] is None:
|
||||||
del ipv4["secondary"]
|
del ipv4["secondary"]
|
||||||
|
|
||||||
intf_commands = set_interface(interface, extant)
|
intf_commands = set_interface(desired, extant)
|
||||||
intf_commands.extend(clear_interface(interface, extant))
|
intf_commands.extend(clear_interface(desired, extant))
|
||||||
|
|
||||||
if intf_commands:
|
if intf_commands:
|
||||||
commands.append("interface {0}".format(interface["name"]))
|
commands.append("interface {0}".format(key))
|
||||||
commands.extend(intf_commands)
|
commands.extend(intf_commands)
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
@ -168,17 +169,17 @@ class L3_interfaces(ConfigBase):
|
||||||
the current configuration
|
the current configuration
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for interface in want:
|
for key, desired in want.items():
|
||||||
for extant in have:
|
interface_name = normalize_interface(key)
|
||||||
if extant["name"] == interface["name"]:
|
if interface_name in have:
|
||||||
break
|
extant = have[interface_name]
|
||||||
else:
|
else:
|
||||||
extant = dict(name=interface["name"])
|
extant = dict()
|
||||||
|
|
||||||
intf_commands = set_interface(interface, extant)
|
intf_commands = set_interface(desired, extant)
|
||||||
|
|
||||||
if intf_commands:
|
if intf_commands:
|
||||||
commands.append("interface {0}".format(interface["name"]))
|
commands.append("interface {0}".format(interface_name))
|
||||||
commands.extend(intf_commands)
|
commands.extend(intf_commands)
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
@ -192,19 +193,17 @@ class L3_interfaces(ConfigBase):
|
||||||
of the provided objects
|
of the provided objects
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for interface in want:
|
for key in want:
|
||||||
for extant in have:
|
desired = dict()
|
||||||
if extant["name"] == interface["name"]:
|
if key in have:
|
||||||
break
|
extant = have[key]
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Clearing all args, send empty dictionary
|
intf_commands = clear_interface(desired, extant)
|
||||||
interface = dict(name=interface["name"])
|
|
||||||
intf_commands = clear_interface(interface, extant)
|
|
||||||
|
|
||||||
if intf_commands:
|
if intf_commands:
|
||||||
commands.append("interface {0}".format(interface["name"]))
|
commands.append("interface {0}".format(key))
|
||||||
commands.extend(intf_commands)
|
commands.extend(intf_commands)
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
@ -244,7 +243,7 @@ def clear_interface(want, have):
|
||||||
if not want_ipv4:
|
if not want_ipv4:
|
||||||
commands.append("no ip address")
|
commands.append("no ip address")
|
||||||
else:
|
else:
|
||||||
for address in (have_ipv4 - want_ipv4):
|
for address in have_ipv4 - want_ipv4:
|
||||||
address = dict(address)
|
address = dict(address)
|
||||||
if "secondary" not in address:
|
if "secondary" not in address:
|
||||||
address["secondary"] = False
|
address["secondary"] = False
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright 2019 Red Hat
|
# Copyright 2019 Red Hat
|
||||||
# GNU General Public License v3.0+
|
# GNU General Public License v3.0+
|
||||||
|
@ -17,6 +16,7 @@ __metaclass__ = type
|
||||||
from ansible.module_utils.network.common.cfg.base import ConfigBase
|
from ansible.module_utils.network.common.cfg.base import ConfigBase
|
||||||
from ansible.module_utils.network.common.utils import to_list, dict_diff, param_list_to_dict
|
from ansible.module_utils.network.common.utils import to_list, dict_diff, param_list_to_dict
|
||||||
from ansible.module_utils.network.eos.facts.facts import Facts
|
from ansible.module_utils.network.eos.facts.facts import Facts
|
||||||
|
from ansible.module_utils.network.eos.utils.utils import normalize_interface
|
||||||
|
|
||||||
|
|
||||||
class Lacp_interfaces(ConfigBase):
|
class Lacp_interfaces(ConfigBase):
|
||||||
|
@ -33,9 +33,6 @@ class Lacp_interfaces(ConfigBase):
|
||||||
'lacp_interfaces',
|
'lacp_interfaces',
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, module):
|
|
||||||
super(Lacp_interfaces, self).__init__(module)
|
|
||||||
|
|
||||||
def get_lacp_interfaces_facts(self):
|
def get_lacp_interfaces_facts(self):
|
||||||
""" Get the 'facts' (the current configuration)
|
""" Get the 'facts' (the current configuration)
|
||||||
|
|
||||||
|
@ -120,8 +117,9 @@ class Lacp_interfaces(ConfigBase):
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for key, desired in want.items():
|
for key, desired in want.items():
|
||||||
if key in have:
|
interface_name = normalize_interface(key)
|
||||||
extant = have[key]
|
if interface_name in have:
|
||||||
|
extant = have[interface_name]
|
||||||
else:
|
else:
|
||||||
extant = dict()
|
extant = dict()
|
||||||
|
|
||||||
|
@ -164,8 +162,9 @@ class Lacp_interfaces(ConfigBase):
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for key, desired in want.items():
|
for key, desired in want.items():
|
||||||
if key in have:
|
interface_name = normalize_interface(key)
|
||||||
extant = have[key]
|
if interface_name in have:
|
||||||
|
extant = have[interface_name]
|
||||||
else:
|
else:
|
||||||
extant = dict()
|
extant = dict()
|
||||||
|
|
||||||
|
@ -184,12 +183,12 @@ class Lacp_interfaces(ConfigBase):
|
||||||
of the provided objects
|
of the provided objects
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for key in want.keys():
|
for key in want:
|
||||||
desired = dict()
|
desired = dict()
|
||||||
if key in have:
|
if key in have:
|
||||||
extant = have[key]
|
extant = have[key]
|
||||||
else:
|
else:
|
||||||
extant = dict()
|
continue
|
||||||
|
|
||||||
del_config = dict_diff(desired, extant)
|
del_config = dict_diff(desired, extant)
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ from ansible.module_utils.network.common.utils import to_list, dict_diff
|
||||||
|
|
||||||
from ansible.module_utils.network.common.cfg.base import ConfigBase
|
from ansible.module_utils.network.common.cfg.base import ConfigBase
|
||||||
from ansible.module_utils.network.eos.facts.facts import Facts
|
from ansible.module_utils.network.eos.facts.facts import Facts
|
||||||
|
from ansible.module_utils.network.eos.utils.utils import normalize_interface
|
||||||
|
|
||||||
|
|
||||||
class Lag_interfaces(ConfigBase):
|
class Lag_interfaces(ConfigBase):
|
||||||
|
@ -114,11 +115,12 @@ class Lag_interfaces(ConfigBase):
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for interface in want:
|
for interface in want:
|
||||||
|
interface_name = normalize_interface(interface["name"])
|
||||||
for extant in have:
|
for extant in have:
|
||||||
if extant["name"] == interface["name"]:
|
if extant["name"] == interface_name:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
extant = dict(name=interface["name"])
|
extant = dict(name=interface_name)
|
||||||
|
|
||||||
commands.extend(set_config(interface, extant))
|
commands.extend(set_config(interface, extant))
|
||||||
commands.extend(remove_config(interface, extant))
|
commands.extend(remove_config(interface, extant))
|
||||||
|
@ -135,18 +137,19 @@ class Lag_interfaces(ConfigBase):
|
||||||
commands = []
|
commands = []
|
||||||
for extant in have:
|
for extant in have:
|
||||||
for interface in want:
|
for interface in want:
|
||||||
if interface["name"] == extant["name"]:
|
if normalize_interface(interface["name"]) == extant["name"]:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
interface = dict(name=extant["name"])
|
interface = dict(name=extant["name"])
|
||||||
commands.extend(remove_config(interface, extant))
|
commands.extend(remove_config(interface, extant))
|
||||||
|
|
||||||
for interface in want:
|
for interface in want:
|
||||||
|
interface_name = normalize_interface(interface["name"])
|
||||||
for extant in have:
|
for extant in have:
|
||||||
if extant["name"] == interface["name"]:
|
if extant["name"] == interface_name:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
extant = dict(name=interface["name"])
|
extant = dict(name=interface_name)
|
||||||
commands.extend(set_config(interface, extant))
|
commands.extend(set_config(interface, extant))
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
@ -160,11 +163,12 @@ class Lag_interfaces(ConfigBase):
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for interface in want:
|
for interface in want:
|
||||||
|
interface_name = normalize_interface(interface["name"])
|
||||||
for extant in have:
|
for extant in have:
|
||||||
if extant["name"] == interface["name"]:
|
if extant["name"] == interface_name:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
extant = dict(name=interface["name"])
|
extant = dict(name=interface_name)
|
||||||
|
|
||||||
commands.extend(set_config(interface, extant))
|
commands.extend(set_config(interface, extant))
|
||||||
|
|
||||||
|
@ -179,14 +183,15 @@ class Lag_interfaces(ConfigBase):
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for interface in want:
|
for interface in want:
|
||||||
|
interface_name = normalize_interface(interface["name"])
|
||||||
for extant in have:
|
for extant in have:
|
||||||
if extant["name"] == interface["name"]:
|
if extant["name"] == interface_name:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
continue
|
extant = dict(name=interface_name)
|
||||||
|
|
||||||
# Clearing all args, send empty dictionary
|
# Clearing all args, send empty dictionary
|
||||||
interface = dict(name=interface["name"])
|
interface = dict(name=interface_name)
|
||||||
commands.extend(remove_config(interface, extant))
|
commands.extend(remove_config(interface, extant))
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright 2019 Red Hat
|
# Copyright 2019 Red Hat
|
||||||
# GNU General Public License v3.0+
|
# GNU General Public License v3.0+
|
||||||
|
@ -17,6 +16,7 @@ __metaclass__ = type
|
||||||
from ansible.module_utils.network.common.cfg.base import ConfigBase
|
from ansible.module_utils.network.common.cfg.base import ConfigBase
|
||||||
from ansible.module_utils.network.common.utils import to_list, dict_diff, param_list_to_dict
|
from ansible.module_utils.network.common.utils import to_list, dict_diff, param_list_to_dict
|
||||||
from ansible.module_utils.network.eos.facts.facts import Facts
|
from ansible.module_utils.network.eos.facts.facts import Facts
|
||||||
|
from ansible.module_utils.network.eos.utils.utils import normalize_interface
|
||||||
|
|
||||||
|
|
||||||
class Lldp_interfaces(ConfigBase):
|
class Lldp_interfaces(ConfigBase):
|
||||||
|
@ -117,15 +117,16 @@ class Lldp_interfaces(ConfigBase):
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for key, desired in want.items():
|
for key, desired in want.items():
|
||||||
if key in have:
|
interface_name = normalize_interface(key)
|
||||||
extant = have[key]
|
if interface_name in have:
|
||||||
|
extant = have[interface_name]
|
||||||
else:
|
else:
|
||||||
extant = dict(name=key)
|
extant = dict(name=interface_name)
|
||||||
|
|
||||||
add_config = dict_diff(extant, desired)
|
add_config = dict_diff(extant, desired)
|
||||||
del_config = dict_diff(desired, extant)
|
del_config = dict_diff(desired, extant)
|
||||||
|
|
||||||
commands.extend(generate_commands(key, add_config, del_config))
|
commands.extend(generate_commands(interface_name, add_config, del_config))
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
|
@ -161,14 +162,15 @@ class Lldp_interfaces(ConfigBase):
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for key, desired in want.items():
|
for key, desired in want.items():
|
||||||
if key in have:
|
interface_name = normalize_interface(key)
|
||||||
extant = have[key]
|
if interface_name in have:
|
||||||
|
extant = have[interface_name]
|
||||||
else:
|
else:
|
||||||
extant = dict(name=key)
|
extant = dict(name=interface_name)
|
||||||
|
|
||||||
add_config = dict_diff(extant, desired)
|
add_config = dict_diff(extant, desired)
|
||||||
|
|
||||||
commands.extend(generate_commands(key, add_config, {}))
|
commands.extend(generate_commands(interface_name, add_config, {}))
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
|
@ -182,15 +184,16 @@ class Lldp_interfaces(ConfigBase):
|
||||||
"""
|
"""
|
||||||
commands = []
|
commands = []
|
||||||
for key in want.keys():
|
for key in want.keys():
|
||||||
desired = dict(name=key)
|
interface_name = normalize_interface(key)
|
||||||
if key in have:
|
desired = dict(name=interface_name)
|
||||||
extant = have[key]
|
if interface_name in have:
|
||||||
|
extant = have[interface_name]
|
||||||
else:
|
else:
|
||||||
extant = dict(name=key)
|
continue
|
||||||
|
|
||||||
del_config = dict_diff(desired, extant)
|
del_config = dict_diff(desired, extant)
|
||||||
|
|
||||||
commands.extend(generate_commands(key, {}, del_config))
|
commands.extend(generate_commands(interface_name, {}, del_config))
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright 2019 Red Hat
|
# Copyright 2019 Red Hat
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+
|
||||||
|
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
"""
|
"""
|
||||||
The eos interfaces fact class
|
The eos interfaces fact class
|
||||||
It is in this file the configuration is collected from the device
|
It is in this file the configuration is collected from the device
|
||||||
|
@ -40,6 +41,7 @@ class InterfacesFacts(object):
|
||||||
""" Populate the facts for interfaces
|
""" Populate the facts for interfaces
|
||||||
|
|
||||||
:param connection: the device connection
|
:param connection: the device connection
|
||||||
|
:param ansible_facts: Facts dictionary
|
||||||
:param data: previously collected configuration
|
:param data: previously collected configuration
|
||||||
:rtype: dictionary
|
:rtype: dictionary
|
||||||
:returns: facts
|
:returns: facts
|
||||||
|
@ -55,9 +57,8 @@ class InterfacesFacts(object):
|
||||||
obj = self.render_config(self.generated_spec, conf)
|
obj = self.render_config(self.generated_spec, conf)
|
||||||
if obj:
|
if obj:
|
||||||
objs.append(obj)
|
objs.append(obj)
|
||||||
facts = {}
|
facts = {'interfaces': []}
|
||||||
if objs:
|
if objs:
|
||||||
facts['interfaces'] = []
|
|
||||||
params = utils.validate_config(self.argument_spec, {'config': objs})
|
params = utils.validate_config(self.argument_spec, {'config': objs})
|
||||||
for cfg in params['config']:
|
for cfg in params['config']:
|
||||||
facts['interfaces'].append(utils.remove_empties(cfg))
|
facts['interfaces'].append(utils.remove_empties(cfg))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright 2019 Red Hat
|
# Copyright 2019 Red Hat
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+
|
||||||
|
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
"""
|
"""
|
||||||
The eos l2_interfaces fact class
|
The eos l2_interfaces fact class
|
||||||
It is in this file the configuration is collected from the device
|
It is in this file the configuration is collected from the device
|
||||||
|
@ -39,9 +40,9 @@ class L2_interfacesFacts(object):
|
||||||
def populate_facts(self, connection, ansible_facts, data=None):
|
def populate_facts(self, connection, ansible_facts, data=None):
|
||||||
""" Populate the facts for l2_interfaces
|
""" Populate the facts for l2_interfaces
|
||||||
|
|
||||||
:param module: the module instance
|
|
||||||
:param connection: the device connection
|
:param connection: the device connection
|
||||||
:param data: previously collected conf
|
:param ansible_facts: Facts dictionary
|
||||||
|
:param data: previously collected configuration
|
||||||
:rtype: dictionary
|
:rtype: dictionary
|
||||||
:returns: facts
|
:returns: facts
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -40,11 +40,11 @@ class L3_interfacesFacts(object):
|
||||||
def populate_facts(self, connection, ansible_facts, data=None):
|
def populate_facts(self, connection, ansible_facts, data=None):
|
||||||
""" Populate the facts for l3_interfaces
|
""" Populate the facts for l3_interfaces
|
||||||
:param connection: the device connection
|
:param connection: the device connection
|
||||||
|
:param ansible_facts: Facts dictionary
|
||||||
:param data: previously collected configuration
|
:param data: previously collected configuration
|
||||||
:rtype: dictionary
|
:rtype: dictionary
|
||||||
:returns: facts
|
:returns: facts
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not data:
|
if not data:
|
||||||
data = connection.get('show running-config | section ^interface')
|
data = connection.get('show running-config | section ^interface')
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ class LacpFacts(object):
|
||||||
""" Populate the facts for lacp
|
""" Populate the facts for lacp
|
||||||
:param connection: the device connection
|
:param connection: the device connection
|
||||||
:param ansible_facts: Facts dictionary
|
:param ansible_facts: Facts dictionary
|
||||||
:param data: previously collected conf
|
:param data: previously collected configuration
|
||||||
:rtype: dictionary
|
:rtype: dictionary
|
||||||
:returns: facts
|
:returns: facts
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright 2019 Red Hat
|
# Copyright 2019 Red Hat
|
||||||
# GNU General Public License v3.0+
|
# GNU General Public License v3.0+
|
||||||
|
@ -42,7 +41,7 @@ class Lacp_interfacesFacts(object):
|
||||||
""" Populate the facts for lacp_interfaces
|
""" Populate the facts for lacp_interfaces
|
||||||
:param connection: the device connection
|
:param connection: the device connection
|
||||||
:param ansible_facts: Facts dictionary
|
:param ansible_facts: Facts dictionary
|
||||||
:param data: previously collected conf
|
:param data: previously collected configuration
|
||||||
:rtype: dictionary
|
:rtype: dictionary
|
||||||
:returns: facts
|
:returns: facts
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -40,6 +40,7 @@ class Lag_interfacesFacts(object):
|
||||||
def populate_facts(self, connection, ansible_facts, data=None):
|
def populate_facts(self, connection, ansible_facts, data=None):
|
||||||
""" Populate the facts for lag_interfaces
|
""" Populate the facts for lag_interfaces
|
||||||
:param connection: the device connection
|
:param connection: the device connection
|
||||||
|
:param ansible_facts: Facts dictionary
|
||||||
:param data: previously collected configuration
|
:param data: previously collected configuration
|
||||||
:rtype: dictionary
|
:rtype: dictionary
|
||||||
:returns: facts
|
:returns: facts
|
||||||
|
@ -69,7 +70,7 @@ class Lag_interfacesFacts(object):
|
||||||
else:
|
else:
|
||||||
objs[group_name] = obj
|
objs[group_name] = obj
|
||||||
objs = list(objs.values())
|
objs = list(objs.values())
|
||||||
facts = {}
|
facts = {'lag_interfaces': []}
|
||||||
if objs:
|
if objs:
|
||||||
params = utils.validate_config(self.argument_spec, {'config': objs})
|
params = utils.validate_config(self.argument_spec, {'config': objs})
|
||||||
facts['lag_interfaces'] = [utils.remove_empties(cfg) for cfg in params['config']]
|
facts['lag_interfaces'] = [utils.remove_empties(cfg) for cfg in params['config']]
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright 2019 Red Hat
|
# Copyright 2019 Red Hat
|
||||||
# GNU General Public License v3.0+
|
# GNU General Public License v3.0+
|
||||||
|
@ -42,7 +41,7 @@ class Lldp_interfacesFacts(object):
|
||||||
""" Populate the facts for lldp_interfaces
|
""" Populate the facts for lldp_interfaces
|
||||||
:param connection: the device connection
|
:param connection: the device connection
|
||||||
:param ansible_facts: Facts dictionary
|
:param ansible_facts: Facts dictionary
|
||||||
:param data: previously collected conf
|
:param data: previously collected configuration
|
||||||
:rtype: dictionary
|
:rtype: dictionary
|
||||||
:returns: facts
|
:returns: facts
|
||||||
"""
|
"""
|
||||||
|
|
0
lib/ansible/module_utils/network/eos/utils/__init__.py
Normal file
0
lib/ansible/module_utils/network/eos/utils/__init__.py
Normal file
54
lib/ansible/module_utils/network/eos/utils/utils.py
Normal file
54
lib/ansible/module_utils/network/eos/utils/utils.py
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright 2019 Red Hat
|
||||||
|
# GNU General Public License v3.0+
|
||||||
|
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
# utils
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
def get_interface_number(name):
|
||||||
|
digits = ''
|
||||||
|
for char in name:
|
||||||
|
if char.isdigit() or char in '/.':
|
||||||
|
digits += char
|
||||||
|
return digits
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_interface(name):
|
||||||
|
"""Return the normalized interface name
|
||||||
|
"""
|
||||||
|
if not name:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if name.lower().startswith('et'):
|
||||||
|
if_type = 'Ethernet'
|
||||||
|
elif name.lower().startswith('lo'):
|
||||||
|
if_type = 'Loopback'
|
||||||
|
elif name.lower().startswith('ma'):
|
||||||
|
if_type = 'Management'
|
||||||
|
elif name.lower().startswith('po'):
|
||||||
|
if_type = 'Port-Channel'
|
||||||
|
elif name.lower().startswith('tu'):
|
||||||
|
if_type = 'Tunnel'
|
||||||
|
elif name.lower().startswith('vl'):
|
||||||
|
if_type = 'Vlan'
|
||||||
|
elif name.lower().startswith('vx'):
|
||||||
|
if_type = 'Vxlan'
|
||||||
|
else:
|
||||||
|
if_type = None
|
||||||
|
|
||||||
|
number_list = name.split(' ')
|
||||||
|
if len(number_list) == 2:
|
||||||
|
number = number_list[-1].strip()
|
||||||
|
else:
|
||||||
|
number = get_interface_number(name)
|
||||||
|
|
||||||
|
if if_type:
|
||||||
|
proper_interface = if_type + number
|
||||||
|
else:
|
||||||
|
proper_interface = name
|
||||||
|
|
||||||
|
return proper_interface
|
|
@ -1,7 +1,8 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright 2019 Red Hat
|
# Copyright 2019 Red Hat
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+
|
||||||
|
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
# WARNING #
|
# WARNING #
|
||||||
|
@ -41,6 +42,10 @@ version_added: 2.9
|
||||||
short_description: Manages interface attributes of Arista EOS interfaces
|
short_description: Manages interface attributes of Arista EOS interfaces
|
||||||
description: ['This module manages the interface attributes of Arista EOS interfaces.']
|
description: ['This module manages the interface attributes of Arista EOS interfaces.']
|
||||||
author: ['Nathaniel Case (@qalthos)']
|
author: ['Nathaniel Case (@qalthos)']
|
||||||
|
notes:
|
||||||
|
- Tested against Arista EOS 4.20.10M
|
||||||
|
- This module works with connection C(network_cli). See the
|
||||||
|
L(EOS Platform Options,../network/user_guide/platform_eos.html).
|
||||||
options:
|
options:
|
||||||
config:
|
config:
|
||||||
description: The provided configuration
|
description: The provided configuration
|
||||||
|
|
|
@ -43,7 +43,7 @@ short_description: 'Manages L3 interface attributes of Arista EOS devices.'
|
||||||
description: 'This module provides declarative management of Layer 3 interfaces on Arista EOS devices.'
|
description: 'This module provides declarative management of Layer 3 interfaces on Arista EOS devices.'
|
||||||
author: Nathaniel Case (@qalthos)
|
author: Nathaniel Case (@qalthos)
|
||||||
notes:
|
notes:
|
||||||
- 'Tested against vEOS v4.20.x'
|
- Tested against Arista EOS 4.20.10M
|
||||||
- This module works with connection C(network_cli). See the
|
- This module works with connection C(network_cli). See the
|
||||||
L(EOS Platform Options,../network/user_guide/platform_eos.html).
|
L(EOS Platform Options,../network/user_guide/platform_eos.html).
|
||||||
options:
|
options:
|
||||||
|
|
|
@ -43,6 +43,10 @@ short_description: Manage Link Aggregation Control Protocol (LACP) attributes of
|
||||||
description:
|
description:
|
||||||
- This module manages Link Aggregation Control Protocol (LACP) attributes of interfaces on Arista EOS devices.
|
- This module manages Link Aggregation Control Protocol (LACP) attributes of interfaces on Arista EOS devices.
|
||||||
author: Nathaniel Case (@Qalthos)
|
author: Nathaniel Case (@Qalthos)
|
||||||
|
notes:
|
||||||
|
- Tested against Arista EOS 4.20.10M
|
||||||
|
- This module works with connection C(network_cli). See the
|
||||||
|
L(EOS Platform Options,../network/user_guide/platform_eos.html).
|
||||||
options:
|
options:
|
||||||
config:
|
config:
|
||||||
description: A dictionary of LACP interfaces options.
|
description: A dictionary of LACP interfaces options.
|
||||||
|
|
|
@ -44,7 +44,7 @@ short_description: Manages link aggregation groups on Arista EOS devices
|
||||||
description: This module manages attributes of link aggregation groups on Arista EOS devices.
|
description: This module manages attributes of link aggregation groups on Arista EOS devices.
|
||||||
author: Nathaniel Case (@Qalthos)
|
author: Nathaniel Case (@Qalthos)
|
||||||
notes:
|
notes:
|
||||||
- 'Tested against vEOS v4.20.x'
|
- Tested against Arista EOS 4.20.10M
|
||||||
- This module works with connection C(network_cli). See the
|
- This module works with connection C(network_cli). See the
|
||||||
L(EOS Platform Options,../network/user_guide/platform_eos.html).
|
L(EOS Platform Options,../network/user_guide/platform_eos.html).
|
||||||
options:
|
options:
|
||||||
|
|
|
@ -43,6 +43,10 @@ short_description: Manage Global Link Layer Discovery Protocol (LLDP) settings o
|
||||||
description:
|
description:
|
||||||
- This module manages Global Link Layer Discovery Protocol (LLDP) settings on Arista EOS devices.
|
- This module manages Global Link Layer Discovery Protocol (LLDP) settings on Arista EOS devices.
|
||||||
author: Nathaniel Case (@Qalthos)
|
author: Nathaniel Case (@Qalthos)
|
||||||
|
notes:
|
||||||
|
- Tested against Arista EOS 4.20.10M
|
||||||
|
- This module works with connection C(network_cli). See the
|
||||||
|
L(EOS Platform Options,../network/user_guide/platform_eos.html).
|
||||||
options:
|
options:
|
||||||
config:
|
config:
|
||||||
description: The provided global LLDP configuration.
|
description: The provided global LLDP configuration.
|
||||||
|
|
|
@ -43,6 +43,10 @@ short_description: Manage Link Layer Discovery Protocol (LLDP) attributes of int
|
||||||
description:
|
description:
|
||||||
- This module manages Link Layer Discovery Protocol (LLDP) attributes of interfaces on Arista EOS devices.
|
- This module manages Link Layer Discovery Protocol (LLDP) attributes of interfaces on Arista EOS devices.
|
||||||
author: Nathaniel Case (@Qalthos)
|
author: Nathaniel Case (@Qalthos)
|
||||||
|
notes:
|
||||||
|
- Tested against Arista EOS 4.20.10M
|
||||||
|
- This module works with connection C(network_cli). See the
|
||||||
|
L(EOS Platform Options,../network/user_guide/platform_eos.html).
|
||||||
options:
|
options:
|
||||||
config:
|
config:
|
||||||
description: A dictionary of LLDP interfaces options.
|
description: A dictionary of LLDP interfaces options.
|
||||||
|
|
|
@ -26,4 +26,4 @@
|
||||||
|
|
||||||
- assert:
|
- assert:
|
||||||
that:
|
that:
|
||||||
- "'lag_interfaces' not in ansible_facts.network_resources"
|
- "ansible_facts.network_resources.lag_interfaces == []"
|
||||||
|
|
Loading…
Reference in a new issue