summaryrefslogtreecommitdiff
path: root/plugins/module_utils
diff options
context:
space:
mode:
authorBradley A. Thornton <bthornto@thethorntons.net>2019-08-19 07:56:36 -0700
committerBradley A. Thornton <bthornto@thethorntons.net>2019-08-19 07:56:36 -0700
commit7d4127b40ce899b43180df68d84ec6adcda20c0e (patch)
treeb5d5a7a85b6aa288ea4d183e129d00d2b9b8d527 /plugins/module_utils
parent3fabcd898a415a724048f445dfc35e29f895fe2e (diff)
downloadvyos.vyos-7d4127b40ce899b43180df68d84ec6adcda20c0e.tar.gz
vyos.vyos-7d4127b40ce899b43180df68d84ec6adcda20c0e.zip
based on ansible/ansible 843a51628b49d7aaa1447616fe0fcdf6a4ec7b1a
Diffstat (limited to 'plugins/module_utils')
-rw-r--r--plugins/module_utils/network/vyos/argspec/facts/facts.py2
-rw-r--r--plugins/module_utils/network/vyos/argspec/lldp_global/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/argspec/lldp_global/lldp_global.py56
-rw-r--r--plugins/module_utils/network/vyos/config/lldp_global/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/config/lldp_global/lldp_global.py248
-rw-r--r--plugins/module_utils/network/vyos/facts/facts.py8
-rw-r--r--plugins/module_utils/network/vyos/facts/legacy/base.py2
-rw-r--r--plugins/module_utils/network/vyos/facts/lldp_global/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/facts/lldp_global/lldp_global.py114
-rw-r--r--plugins/module_utils/network/vyos/utils/utils.py44
10 files changed, 457 insertions, 17 deletions
diff --git a/plugins/module_utils/network/vyos/argspec/facts/facts.py b/plugins/module_utils/network/vyos/argspec/facts/facts.py
index 624d2fdb..31b1aa9a 100644
--- a/plugins/module_utils/network/vyos/argspec/facts/facts.py
+++ b/plugins/module_utils/network/vyos/argspec/facts/facts.py
@@ -24,6 +24,8 @@ class FactsArgs(object): # pylint: disable=R0903
"!l3_interfaces",
"lag_interfaces",
"!lag_interfaces",
+ "lldp_global",
+ "!lldp_global",
]
argument_spec = {
diff --git a/plugins/module_utils/network/vyos/argspec/lldp_global/__init__.py b/plugins/module_utils/network/vyos/argspec/lldp_global/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/plugins/module_utils/network/vyos/argspec/lldp_global/__init__.py
diff --git a/plugins/module_utils/network/vyos/argspec/lldp_global/lldp_global.py b/plugins/module_utils/network/vyos/argspec/lldp_global/lldp_global.py
new file mode 100644
index 00000000..84bbc00c
--- /dev/null
+++ b/plugins/module_utils/network/vyos/argspec/lldp_global/lldp_global.py
@@ -0,0 +1,56 @@
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The arg spec for the vyos_lldp_global module
+"""
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+class Lldp_globalArgs(object): # pylint: disable=R0903
+ """The arg spec for the vyos_lldp_global module
+ """
+
+ def __init__(self, **kwargs):
+ pass
+
+ argument_spec = {
+ "config": {
+ "options": {
+ "address": {"type": "str"},
+ "enable": {"type": "bool"},
+ "legacy_protocols": {
+ "choices": ["cdp", "edp", "fdp", "sonmp"],
+ "type": "list",
+ },
+ "snmp": {"type": "str"},
+ },
+ "type": "dict",
+ },
+ "state": {
+ "choices": ["merged", "replaced", "deleted"],
+ "default": "merged",
+ "type": "str",
+ },
+ } # pylint: disable=C0301
diff --git a/plugins/module_utils/network/vyos/config/lldp_global/__init__.py b/plugins/module_utils/network/vyos/config/lldp_global/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/plugins/module_utils/network/vyos/config/lldp_global/__init__.py
diff --git a/plugins/module_utils/network/vyos/config/lldp_global/lldp_global.py b/plugins/module_utils/network/vyos/config/lldp_global/lldp_global.py
new file mode 100644
index 00000000..54606fab
--- /dev/null
+++ b/plugins/module_utils/network/vyos/config/lldp_global/lldp_global.py
@@ -0,0 +1,248 @@
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+"""
+The vyos_lldp_global class
+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 it's desired end-state is
+created
+"""
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+from ansible.module_utils.network.common.cfg.base import ConfigBase
+from ansible.module_utils.network.common.utils import to_list, dict_diff
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import (
+ Facts,
+)
+from ansible.module_utils.six import iteritems
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import (
+ get_lst_diff_for_dicts,
+ list_diff_have_only,
+)
+
+
+class Lldp_global(ConfigBase):
+ """
+ The vyos_lldp_global class
+ """
+
+ gather_subset = ["!all", "!min"]
+
+ gather_network_resources = ["lldp_global"]
+
+ params = ["enable", "address", "snmp", "legacy_protocols"]
+
+ def __init__(self, module):
+ super(Lldp_global, self).__init__(module)
+
+ def get_lldp_global_facts(self):
+ """ Get the 'facts' (the current configuration)
+
+ :rtype: A dictionary
+ :returns: The current configuration as a dictionary
+ """
+ facts, _warnings = Facts(self._module).get_facts(
+ self.gather_subset, self.gather_network_resources
+ )
+ lldp_global_facts = facts["ansible_network_resources"].get(
+ "lldp_global"
+ )
+ if not lldp_global_facts:
+ return {}
+ return lldp_global_facts
+
+ def execute_module(self):
+ """ Execute the module
+
+ :rtype: A dictionary
+ :returns: The result from module execution
+ """
+ result = {"changed": False}
+ commands = list()
+ warnings = list()
+
+ existing_lldp_global_facts = self.get_lldp_global_facts()
+ commands.extend(self.set_config(existing_lldp_global_facts))
+ if commands:
+ if not self._module.check_mode:
+ self._connection.edit_config(commands)
+ result["changed"] = True
+ result["commands"] = commands
+
+ changed_lldp_global_facts = self.get_lldp_global_facts()
+
+ result["before"] = existing_lldp_global_facts
+ if result["changed"]:
+ result["after"] = changed_lldp_global_facts
+
+ result["warnings"] = warnings
+ return result
+
+ def set_config(self, existing_lldp_global_facts):
+ """ Collect the configuration from the args passed to the module,
+ collect the current configuration (as a dict from facts)
+
+ :rtype: A list
+ :returns: the commands necessary to migrate the current configuration
+ to the desired configuration
+ """
+ want = self._module.params["config"]
+ have = existing_lldp_global_facts
+ resp = self.set_state(want, have)
+ return to_list(resp)
+
+ def set_state(self, want, have):
+ """ Select the appropriate function based on the state provided
+
+ :param want: the desired configuration as a dictionary
+ :param have: the current configuration as a dictionary
+ :rtype: A list
+ :returns: the commands necessary to migrate the current configuration
+ to the desired configuration
+ """
+ commands = []
+ state = self._module.params["state"]
+ if state == "deleted":
+ commands.extend(self._state_deleted(want=None, have=have))
+ elif state == "merged":
+ commands.extend(self._state_merged(want=want, have=have))
+ elif state == "replaced":
+ commands.extend(self._state_replaced(want=want, have=have))
+ return commands
+
+ def _state_replaced(self, 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 = []
+ if have:
+ commands.extend(self._state_deleted(want, have))
+ commands.extend(self._state_merged(want, have))
+ return commands
+
+ def _state_merged(self, 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 = []
+ commands.extend(self._render_updates(want, have))
+ return commands
+
+ def _state_deleted(self, 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 = []
+ if want:
+ for item in Lldp_global.params:
+ if item == "legacy_protocols":
+ commands.extend(self._update_lldp_protocols(want, have))
+ elif (
+ have.get(item) and not want.get(item) and item != "enable"
+ ):
+ commands.append(Lldp_global.del_cmd + item)
+ elif have:
+ for item in Lldp_global.params:
+ if have.get(item):
+ if item == "legacy_protocols":
+ commands.append(
+ self._compute_command(
+ "legacy-protocols", remove=True
+ )
+ )
+ elif item == "address":
+ commands.append(
+ self._compute_command(
+ "management-address", remove=True
+ )
+ )
+ elif item == "snmp":
+ commands.append(
+ self._compute_command(item, remove=True)
+ )
+
+ return commands
+
+ def _render_updates(self, want, have):
+ commands = []
+ if have:
+ temp_have_legacy_protos = have.pop("legacy_protocols", None)
+ else:
+ have = {}
+ temp_want_legacy_protos = want.pop("legacy_protocols", None)
+
+ updates = dict_diff(have, want)
+
+ if have and temp_have_legacy_protos:
+ have["legacy_protocols"] = temp_have_legacy_protos
+ if not have and temp_want_legacy_protos:
+ want["legacy_protocols"] = temp_want_legacy_protos
+
+ commands.extend(self._add_lldp_protocols(want, have))
+
+ if updates:
+ for key, value in iteritems(updates):
+ if value:
+ if key == "enable":
+ commands.append(self._compute_command())
+ elif key == "address":
+ commands.append(
+ self._compute_command(
+ "management-address", str(value)
+ )
+ )
+ elif key == "snmp":
+ if value == "disable":
+ commands.append(
+ self._compute_command(key, remove=True)
+ )
+ else:
+ commands.append(
+ self._compute_command(key, str(value))
+ )
+ return commands
+
+ def _add_lldp_protocols(self, want, have):
+ commands = []
+ diff_members = get_lst_diff_for_dicts(want, have, "legacy_protocols")
+ for key in diff_members:
+ commands.append(self._compute_command("legacy-protocols", key))
+ return commands
+
+ def _update_lldp_protocols(self, want_item, have_item):
+ commands = []
+ want_protocols = want_item.get("legacy_protocols") or []
+ have_protocols = have_item.get("legacy_protocols") or []
+
+ members_diff = list_diff_have_only(want_protocols, have_protocols)
+ if members_diff:
+ for member in members_diff:
+ commands.append(
+ self._compute_command(
+ "legacy-protocols", member, remove=True
+ )
+ )
+ return commands
+
+ def _compute_command(self, key=None, value=None, remove=False):
+ if remove:
+ cmd = "delete service lldp"
+ else:
+ cmd = "set service lldp"
+ if key:
+ cmd += " " + key
+
+ if value:
+ cmd += " '" + value + "'"
+ return cmd
diff --git a/plugins/module_utils/network/vyos/facts/facts.py b/plugins/module_utils/network/vyos/facts/facts.py
index 9c389c91..fb05f2ac 100644
--- a/plugins/module_utils/network/vyos/facts/facts.py
+++ b/plugins/module_utils/network/vyos/facts/facts.py
@@ -6,12 +6,9 @@ The facts class for vyos
this file validates each subset of facts and selectively
calls the appropriate facts gathering function
"""
-
from __future__ import absolute_import, division, print_function
__metaclass__ = type
-
-
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.facts.facts import (
FactsArgs,
)
@@ -25,6 +22,9 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.l3_in
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.lag_interfaces.lag_interfaces import (
Lag_interfacesFacts,
)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.lldp_global.lldp_global import (
+ Lldp_globalFacts,
+)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base import (
Default,
Neighbors,
@@ -37,6 +37,7 @@ FACT_RESOURCE_SUBSETS = dict(
interfaces=InterfacesFacts,
l3_interfaces=L3_interfacesFacts,
lag_interfaces=Lag_interfacesFacts,
+ lldp_global=Lldp_globalFacts,
)
@@ -71,7 +72,6 @@ class Facts(FactsBase):
resource_facts_type,
data,
)
-
if self.VALID_LEGACY_GATHER_SUBSETS:
self.get_network_legacy_facts(
FACT_LEGACY_SUBSETS, legacy_facts_type
diff --git a/plugins/module_utils/network/vyos/facts/legacy/base.py b/plugins/module_utils/network/vyos/facts/legacy/base.py
index 34992b1b..dce93aae 100644
--- a/plugins/module_utils/network/vyos/facts/legacy/base.py
+++ b/plugins/module_utils/network/vyos/facts/legacy/base.py
@@ -12,8 +12,6 @@ based on the configuration.
from __future__ import absolute_import, division, print_function
__metaclass__ = type
-
-
import platform
import re
from ansible.module_utils.network.vyos.vyos import (
diff --git a/plugins/module_utils/network/vyos/facts/lldp_global/__init__.py b/plugins/module_utils/network/vyos/facts/lldp_global/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/plugins/module_utils/network/vyos/facts/lldp_global/__init__.py
diff --git a/plugins/module_utils/network/vyos/facts/lldp_global/lldp_global.py b/plugins/module_utils/network/vyos/facts/lldp_global/lldp_global.py
new file mode 100644
index 00000000..89543932
--- /dev/null
+++ b/plugins/module_utils/network/vyos/facts/lldp_global/lldp_global.py
@@ -0,0 +1,114 @@
+#
+# -*- 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)
+"""
+The vyos lldp_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 __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+from re import findall, M
+from copy import deepcopy
+
+from ansible.module_utils.network.common import utils
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.lldp_global.lldp_global import (
+ Lldp_globalArgs,
+)
+
+
+class Lldp_globalFacts(object):
+ """ The vyos lldp_global fact class
+ """
+
+ def __init__(self, module, subspec="config", options="options"):
+ self._module = module
+ self.argument_spec = Lldp_globalArgs.argument_spec
+ spec = deepcopy(self.argument_spec)
+ if subspec:
+ if options:
+ facts_argument_spec = spec[subspec][options]
+ else:
+ facts_argument_spec = spec[subspec]
+ else:
+ facts_argument_spec = spec
+
+ self.generated_spec = utils.generate_dict(facts_argument_spec)
+
+ def populate_facts(self, connection, ansible_facts, data=None):
+ """ Populate the facts for lldp_global
+ :param connection: the device connection
+ :param ansible_facts: Facts dictionary
+ :param data: previously collected conf
+ :rtype: dictionary
+ :returns: facts
+ """
+ if not data:
+ data = connection.get_config()
+
+ objs = {}
+ lldp_output = findall(r"^set service lldp (\S+)", data, M)
+ if lldp_output:
+ for item in set(lldp_output):
+ lldp_regex = r" %s .+$" % item
+ cfg = findall(lldp_regex, data, M)
+ obj = self.render_config(cfg)
+ if obj:
+ objs.update(obj)
+ lldp_service = findall(r"^set service (lldp)?('lldp')", data, M)
+ if lldp_service or lldp_output:
+ lldp_obj = {}
+ lldp_obj["enable"] = True
+ objs.update(lldp_obj)
+
+ facts = {}
+ params = utils.validate_config(self.argument_spec, {"config": objs})
+ facts["lldp_global"] = utils.remove_empties(params["config"])
+
+ ansible_facts["ansible_network_resources"].update(facts)
+
+ return ansible_facts
+
+ def render_config(self, conf):
+ """
+ Render config as dictionary structure and delete keys
+ from spec for null values
+ :param spec: The facts tree, generated from the argspec
+ :param conf: The configuration
+ :rtype: dictionary
+ :returns: The generated config
+ """
+ protocol_conf = "\n".join(
+ filter(lambda x: ("legacy-protocols" in x), conf)
+ )
+ att_conf = "\n".join(
+ filter(lambda x: ("legacy-protocols" not in x), conf)
+ )
+ config = self.parse_attribs(["snmp", "address"], att_conf)
+ config["legacy_protocols"] = self.parse_protocols(protocol_conf)
+ return utils.remove_empties(config)
+
+ def parse_protocols(self, conf):
+ protocol_support = None
+ if conf:
+ protocols = findall(r"^.*legacy-protocols (.+)", conf, M)
+ if protocols:
+ protocol_support = []
+ for protocol in protocols:
+ protocol_support.append(protocol.strip("'"))
+ return protocol_support
+
+ def parse_attribs(self, attribs, conf):
+ config = {}
+ for item in attribs:
+ value = utils.parse_conf_arg(conf, item)
+ if value:
+ config[item] = value.strip("'")
+ else:
+ config[item] = None
+ return utils.remove_empties(config)
diff --git a/plugins/module_utils/network/vyos/utils/utils.py b/plugins/module_utils/network/vyos/utils/utils.py
index d6c11bdc..1968cccd 100644
--- a/plugins/module_utils/network/vyos/utils/utils.py
+++ b/plugins/module_utils/network/vyos/utils/utils.py
@@ -67,7 +67,33 @@ def diff_list_of_dicts(want, have):
return diff
+def get_lst_diff_for_dicts(want, have, lst):
+ """
+ This function generates a list containing values
+ that are only in want and not in list in have dict
+ :param want: dict object to want
+ :param have: dict object to have
+ :param lst: list the diff on
+ :return: new list object with values which are only in want.
+ """
+ if not have:
+ diff = want.get(lst) or []
+
+ else:
+ want_elements = want.get(lst) or {}
+ have_elements = have.get(lst) or {}
+ diff = list_diff_want_only(want_elements, have_elements)
+ return diff
+
+
def list_diff_have_only(want_list, have_list):
+ """
+ This function generated the list containing values
+ that are only in have list.
+ :param want_list:
+ :param have_list:
+ :return: new list with values which are only in have list
+ """
if have_list and not want_list:
diff = have_list
elif not have_list:
@@ -82,6 +108,13 @@ def list_diff_have_only(want_list, have_list):
def list_diff_want_only(want_list, have_list):
+ """
+ This function generated the list containing values
+ that are only in want list.
+ :param want_list:
+ :param have_list:
+ :return: new list with values which are only in want list
+ """
if have_list and not want_list:
diff = None
elif not have_list:
@@ -93,14 +126,3 @@ def list_diff_want_only(want_list, have_list):
if i in want_list and i not in have_list
]
return diff
-
-
-def get_lst_diff_for_dicts(want, have, lst):
- if not have:
- diff = want.get(lst) or []
-
- else:
- want_elements = want.get(lst) or {}
- have_elements = have.get(lst) or {}
- diff = list_diff_want_only(want_elements, have_elements)
- return diff