diff options
author | GomathiselviS <gomathiselvi@gmail.com> | 2022-01-31 19:41:29 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-01 00:41:29 +0000 |
commit | 32371e3fe712b08bc3e3b47075741234ad784586 (patch) | |
tree | 1c96caf9ac884d36c88a7692071141d63f7b3628 /plugins | |
parent | a4fc3def45320e633a773f2efa453c78d3b4afca (diff) | |
download | vyos.vyos-32371e3fe712b08bc3e3b47075741234ad784586.tar.gz vyos.vyos-32371e3fe712b08bc3e3b47075741234ad784586.zip |
Vyos snmp_server Resource Module (#227)
Vyos snmp_server Resource Module
SUMMARY
Added vyos_snmp_server resource module
ISSUE TYPE
New Module Pull Request
COMPONENT NAME
ADDITIONAL INFORMATION
Reviewed-by: Nilashish Chakraborty <nilashishchakraborty8@gmail.com>
Reviewed-by: Ashwini Mhatre <mashu97@gmail.com>
Reviewed-by: None <None>
Diffstat (limited to 'plugins')
9 files changed, 2385 insertions, 0 deletions
diff --git a/plugins/module_utils/network/vyos/argspec/snmp_server/__init__.py b/plugins/module_utils/network/vyos/argspec/snmp_server/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/module_utils/network/vyos/argspec/snmp_server/__init__.py diff --git a/plugins/module_utils/network/vyos/argspec/snmp_server/snmp_server.py b/plugins/module_utils/network/vyos/argspec/snmp_server/snmp_server.py new file mode 100644 index 0000000..2b10a51 --- /dev/null +++ b/plugins/module_utils/network/vyos/argspec/snmp_server/snmp_server.py @@ -0,0 +1,225 @@ +# -*- 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 vyos_snmp_server module +""" + + +class Snmp_serverArgs(object): # pylint: disable=R0903 + """The arg spec for the vyos_snmp_server module""" + + argument_spec = { + "config": { + "type": "dict", + "options": { + "communities": { + "type": "list", + "elements": "dict", + "options": { + "name": {"type": "str"}, + "clients": {"type": "list", "elements": "str"}, + "networks": {"type": "list", "elements": "str"}, + "authorization_type": { + "type": "str", + "choices": ["ro", "rw"], + }, + }, + }, + "contact": {"type": "str"}, + "description": {"type": "str"}, + "listen_addresses": { + "type": "list", + "elements": "dict", + "options": { + "address": {"type": "str"}, + "port": {"type": "int"}, + }, + }, + "location": {"type": "str"}, + "smux_peer": {"type": "str"}, + "trap_source": {"type": "str"}, + "trap_target": { + "type": "dict", + "options": { + "address": {"type": "str"}, + "community": {"type": "str"}, + "port": {"type": "int"}, + }, + }, + "snmp_v3": { + "type": "dict", + "options": { + "engine_id": {"type": "str"}, + "groups": { + "type": "list", + "elements": "dict", + "options": { + "group": {"type": "str"}, + "mode": { + "type": "str", + "choices": ["ro", "rw"], + }, + "seclevel": { + "type": "str", + "choices": ["auth", "priv"], + }, + "view": {"type": "str"}, + }, + }, + "trap_targets": { + "type": "list", + "elements": "dict", + "options": { + "address": {"type": "str"}, + "authentication": { + "type": "dict", + "options": { + "type": { + "type": "str", + "choices": ["md5", "sha"], + }, + "encrypted_key": { + "type": "str", + "no_log": True, + }, + "plaintext_key": { + "type": "str", + "no_log": True, + }, + }, + }, + "engine_id": {"type": "str"}, + "port": {"type": "int"}, + "privacy": { + "type": "dict", + "options": { + "type": { + "type": "str", + "choices": ["des", "aes"], + }, + "encrypted_key": { + "type": "str", + "no_log": True, + }, + "plaintext_key": { + "type": "str", + "no_log": True, + }, + }, + }, + "protocol": { + "type": "str", + "choices": ["tcp", "udp"], + }, + "type": { + "type": "str", + "choices": ["inform", "trap"], + }, + }, + }, + "tsm": { + "type": "dict", + "options": { + "local_key": {"type": "str", "no_log": True}, + "port": {"type": "int"}, + }, + }, + "users": { + "type": "list", + "elements": "dict", + "options": { + "user": {"type": "str"}, + "authentication": { + "type": "dict", + "options": { + "type": { + "type": "str", + "choices": ["md5", "sha"], + }, + "encrypted_key": { + "type": "str", + "no_log": True, + }, + "plaintext_key": { + "type": "str", + "no_log": True, + }, + }, + }, + "engine_id": {"type": "str"}, + "group": {"type": "str"}, + "mode": { + "type": "str", + "choices": ["ro", "rw"], + }, + "privacy": { + "type": "dict", + "options": { + "type": { + "type": "str", + "choices": ["des", "aes"], + }, + "encrypted_key": { + "type": "str", + "no_log": True, + }, + "plaintext_key": { + "type": "str", + "no_log": True, + }, + }, + }, + "tsm_key": {"type": "str", "no_log": True}, + }, + }, + "views": { + "type": "list", + "elements": "dict", + "options": { + "view": {"type": "str"}, + "oid": {"type": "str"}, + "exclude": {"type": "str"}, + "mask": {"type": "str"}, + }, + }, + }, + }, + }, + }, + "running_config": {"type": "str"}, + "state": { + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "parsed", + "rendered", + ], + "default": "merged", + "type": "str", + }, + } # pylint: disable=C0301 diff --git a/plugins/module_utils/network/vyos/config/snmp_server/__init__.py b/plugins/module_utils/network/vyos/config/snmp_server/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/module_utils/network/vyos/config/snmp_server/__init__.py diff --git a/plugins/module_utils/network/vyos/config/snmp_server/snmp_server.py b/plugins/module_utils/network/vyos/config/snmp_server/snmp_server.py new file mode 100644 index 0000000..5ddd429 --- /dev/null +++ b/plugins/module_utils/network/vyos/config/snmp_server/snmp_server.py @@ -0,0 +1,317 @@ +# +# -*- 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 vyos_snmp_server 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.utils import ( + dict_merge, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import ( + ResourceModule, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import ( + Facts, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.snmp_server import ( + Snmp_serverTemplate, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + get_from_dict, +) +import re + + +class Snmp_server(ResourceModule): + """ + The vyos_snmp_server config class + """ + + def __init__(self, module): + super(Snmp_server, self).__init__( + empty_fact_val={}, + facts_module=Facts(module), + module=module, + resource="snmp_server", + tmplt=Snmp_serverTemplate(), + ) + self.parsers = [ + "contact", + "description", + "location", + "smux_peer", + "trap_source", + "trap_target", + ] + + 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._snmp_server_list_to_dict(self.want) + haved = self._snmp_server_list_to_dict(self.have) + + # if state is merged, merge want onto 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": + if haved: + self.commands.append("delete service snmp") + + if self.state != "deleted": + self._compare(want=wantd, have=haved) + + if self.state not in ["merged", "deleted"]: + self._move_negate_commands() + + def _move_negate_commands(self): + command_set = [] + for cmd in self.commands: + if re.search("delete service snmp", cmd): + command_set.insert(0, cmd) + else: + command_set.append(cmd) + self.commands = command_set + + def _compare(self, want, have): + """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 Snmp_server network resource. + """ + self._compare_lists(want, have) + self._compare_snmp_v3(want, have) + for key, value in iteritems(want): + self.compare( + parsers=self.parsers, + want={key: value}, + have={key: have.pop(key, "")}, + ) + for key, entry in iteritems(have): + if entry: + self.compare(parsers=self.parsers, want={}, have={key: entry}) + + def _compare_lists(self, want, have): + parsers = [ + "communities", + "listen_addresses", + ] + for attrib in parsers: + wdict = get_from_dict(want, attrib) or {} + hdict = get_from_dict(have, attrib) or {} + for key, entry in iteritems(wdict): + # self.addcmd(entry, attrib, False) + if attrib == "communities": + for k, v in iteritems(entry): + if k in ["clients", "networks"]: + v.sort() + h = {} + if k != "name": + if hdict.get(key): + h = { + "communities": { + k: hdict[key].pop(k, ""), + "name": key, + } + } + self.compare( + parsers="communities", + want={"communities": {k: v, "name": key}}, + have=h, + ) + else: + self.compare( + parsers="listen_addresses", + want={"listen_addresses": entry}, + have={"listen_addresses": hdict.pop(key, {})}, + ) + have.pop(attrib, {}) + # remove remaining items in have for replaced + for key, entry in iteritems(hdict): + if attrib == "communities": + for k, v in iteritems(entry): + if k != "name": + self.compare( + parsers="communities", + have={"communities": {k: v, "name": key}}, + want={}, + ) + else: + self.compare( + parsers=parsers, want={}, have={attrib: entry} + ) + + def _compare_snmp_v3(self, want, have): + parsers = [ + "snmp_v3.groups", + "snmp_v3.trap_targets.port", + "snmp_v3.trap_targets.protocol", + "snmp_v3.trap_targets.type", + "snmp_v3.trap_targets.user", + "snmp_v3.users.group", + "snmp_v3.users.mode", + "snmp_v3.views", + "snmp_v3.engine_id", + ] + attribute_dict = { + "groups": "group", + "trap_targets": "address", + "users": "user", + "views": "view", + } + wdict = get_from_dict(want, "snmp_v3") or {} + hdict = get_from_dict(have, "snmp_v3") or {} + for attrib in attribute_dict.keys(): + wattrib = get_from_dict(wdict, attrib) or {} + hattrib = get_from_dict(hdict, attrib) or {} + for key, entry in iteritems(wattrib): + self._compare_snmp_v3_auth_privacy( + entry, hattrib.get(key, {}), attrib + ) + for k, v in iteritems(entry): + if k != attribute_dict[attrib]: + h = {} + if hattrib.get(key): + h = { + "snmp_v3": { + attrib: { + k: hattrib[key].pop(k, ""), + attribute_dict[attrib]: hattrib[key][ + attribute_dict[attrib] + ], + } + } + } + self.compare( + parsers=parsers, + want={ + "snmp_v3": { + attrib: { + k: v, + attribute_dict[attrib]: entry[ + attribute_dict[attrib] + ], + } + } + }, + have=h, + ) + # remove remaining items in have for replaced + for key, entry in iteritems(hattrib): + self._compare_snmp_v3_auth_privacy({}, entry, attrib) + self.compare( + parsers=parsers, want={}, have={"snmp_v3": {attrib: entry}} + ) + hdict.pop(attrib, {}) + for key, entry in iteritems(wdict): + # self.addcmd(entry, attrib, False) + self.compare( + parsers="snmp_v3.engine_id", + want={"snmp_v3": {key: entry}}, + have={"snmp_v3": {key: hdict.pop(key, {})}}, + ) + # remove remaining items in have for replaced + for key, entry in iteritems(hdict): + self.compare( + parsers=parsers, want={}, have={"snmp_v3": {key: entry}} + ) + + def _compare_snmp_v3_auth_privacy(self, wattrib, hattrib, attrib): + parsers = [ + "snmp_v3.trap_targets.authentication", + "snmp_v3.trap_targets.privacy", + "snmp_v3.users.authentication", + "snmp_v3.users.privacy", + ] + if attrib in ["trap_targets", "users"]: + if attrib == "users": + primary_key = "user" + else: + primary_key = "address" + for key, entry in iteritems(wattrib): + if key != primary_key and key in ["authentication", "privacy"]: + self.compare( + parsers=parsers, + want={ + "snmp_v3": { + attrib: { + key: entry, + primary_key: wattrib[primary_key], + } + } + }, + have={ + "snmp_v3": { + attrib: { + key: hattrib.pop(key, {}), + primary_key: wattrib[primary_key], + } + } + }, + ) + for key, entry in iteritems(hattrib): + if key != primary_key and key in ["authentication", "privacy"]: + self.compare( + parsers=parsers, + want={}, + have={ + "snmp_v3": { + attrib: { + key: entry, + primary_key: hattrib[primary_key], + } + } + }, + ) + + def _snmp_server_list_to_dict(self, entry): + param_dict = { + "communities": "name", + "listen_addresses": "address", + } + v3_param_dict = { + "groups": "group", + "users": "user", + "views": "view", + "trap_targets": "address", + } + for k, v in iteritems(param_dict): + if k in entry: + a_dict = {} + for el in entry[k]: + a_dict.update({el[v]: el}) + entry[k] = a_dict + for k, v in iteritems(v3_param_dict): + if entry.get("snmp_v3") and k in entry.get("snmp_v3"): + a_dict = {} + for el in entry["snmp_v3"][k]: + a_dict.update({el[v]: el}) + entry["snmp_v3"][k] = a_dict + return entry diff --git a/plugins/module_utils/network/vyos/facts/facts.py b/plugins/module_utils/network/vyos/facts/facts.py index e560a48..76cfd90 100644 --- a/plugins/module_utils/network/vyos/facts/facts.py +++ b/plugins/module_utils/network/vyos/facts/facts.py @@ -67,6 +67,9 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.loggi from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ntp_global.ntp_global import ( Ntp_globalFacts, ) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.snmp_server.snmp_server import ( + Snmp_serverFacts, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base import ( Default, Neighbors, @@ -94,6 +97,7 @@ FACT_RESOURCE_SUBSETS = dict( prefix_lists=Prefix_listsFacts, logging_global=Logging_globalFacts, ntp_global=Ntp_globalFacts, + snmp_server=Snmp_serverFacts, ) diff --git a/plugins/module_utils/network/vyos/facts/snmp_server/__init__.py b/plugins/module_utils/network/vyos/facts/snmp_server/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/module_utils/network/vyos/facts/snmp_server/__init__.py diff --git a/plugins/module_utils/network/vyos/facts/snmp_server/snmp_server.py b/plugins/module_utils/network/vyos/facts/snmp_server/snmp_server.py new file mode 100644 index 0000000..2a9ba48 --- /dev/null +++ b/plugins/module_utils/network/vyos/facts/snmp_server/snmp_server.py @@ -0,0 +1,117 @@ +# -*- 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 vyos snmp_server 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.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( + utils, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.snmp_server import ( + Snmp_serverTemplate, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.snmp_server.snmp_server import ( + Snmp_serverArgs, +) +import re + + +class Snmp_serverFacts(object): + """The vyos snmp_server facts class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Snmp_serverArgs.argument_spec + + def get_config(self, connection): + return connection.get("show configuration commands | grep snmp") + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for Snmp_server network resource + + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + + :rtype: dictionary + :returns: facts + """ + facts = {} + objs = [] + config_lines = [] + + if not data: + data = self.get_config(connection) + for resource in data.splitlines(): + config_lines.append(re.sub("'", "", resource)) + + # parse native config using the Snmp_server template + snmp_server_parser = Snmp_serverTemplate( + lines=config_lines, module=self._module + ) + objs = snmp_server_parser.parse() + if objs: + if "communities" in objs: + for k in objs["communities"].values(): + for param, val in iteritems(k): + if param in ["clients", "networks"]: + if None in val: + val.remove(None) + val.sort() + + objs["communities"] = sorted( + list(objs["communities"].values()), + key=lambda k, sk="name": k[sk], + ) + if "listen_addresses" in objs: + objs["listen_addresses"] = sorted( + list(objs["listen_addresses"].values()), + key=lambda k, sk="address": k[sk], + ) + if "snmp_v3" in objs: + if "groups" in objs["snmp_v3"]: + objs["snmp_v3"]["groups"] = sorted( + list(objs["snmp_v3"]["groups"].values()), + key=lambda k, sk="group": k[sk], + ) + if "trap_targets" in objs["snmp_v3"]: + objs["snmp_v3"]["trap_targets"] = sorted( + list(objs["snmp_v3"]["trap_targets"].values()), + key=lambda k, sk="address": k[sk], + ) + if "users" in objs["snmp_v3"]: + objs["snmp_v3"]["users"] = sorted( + list(objs["snmp_v3"]["users"].values()), + key=lambda k, sk="user": k[sk], + ) + if "views" in objs["snmp_v3"]: + objs["snmp_v3"]["views"] = sorted( + list(objs["snmp_v3"]["views"].values()), + key=lambda k, sk="view": k[sk], + ) + else: + objs = {} + + ansible_facts["ansible_network_resources"].pop("snmp_server", None) + + params = utils.remove_empties( + snmp_server_parser.validate_config( + self.argument_spec, {"config": objs}, redact=True + ) + ) + + facts["snmp_server"] = params.get("config", {}) + ansible_facts["ansible_network_resources"].update(facts) + + return ansible_facts diff --git a/plugins/module_utils/network/vyos/rm_templates/snmp_server.py b/plugins/module_utils/network/vyos/rm_templates/snmp_server.py new file mode 100644 index 0000000..c1e385a --- /dev/null +++ b/plugins/module_utils/network/vyos/rm_templates/snmp_server.py @@ -0,0 +1,594 @@ +# -*- 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 Snmp_server 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, +) + + +def _tmplt_snmp_server_communities(config_data): + config_data = config_data["communities"] + command = [] + cmd = "service snmp community {name}".format(**config_data) + if "authorization_type" in config_data: + auth_cmd = cmd + " authorization {authorization_type}".format( + **config_data + ) + command.append(auth_cmd) + if "clients" in config_data: + for c in config_data["clients"]: + client_cmd = cmd + " client " + c + command.append(client_cmd) + if "networks" in config_data: + for n in config_data["networks"]: + network_command = cmd + " network " + n + command.append(network_command) + if not command: + command.append(cmd) + return command + + +def _tmplt_snmp_server_trap_target(config_data): + config_data = config_data["trap_target"] + command = "service snmp trap-target {address}".format(**config_data) + if "authorization_type" in config_data: + command += " authorization {authorization_type}".format(**config_data) + if "client" in config_data: + command += " client {client}".format(**config_data) + if "network" in config_data: + command += " network {network}".format(**config_data) + return command + + +def _tmplt_snmp_server_v3_groups(config_data): + config_data = config_data["snmp_v3"]["groups"] + command = [] + cmd = "service snmp v3 group {group}".format(**config_data) + if "mode" in config_data: + mode_cmd = cmd + " mode {mode}".format(**config_data) + command.append(mode_cmd) + if "seclevel" in config_data: + sec_cmd = cmd + " seclevel {seclevel}".format(**config_data) + command.append(sec_cmd) + if "view" in config_data: + view_cmd = cmd + " view {view}".format(**config_data) + command.append(view_cmd) + return command + + +def _tmplt_snmp_server_v3_trap_target(config_data): + config_data = config_data["snmp_v3"]["trap_targets"] + command = "service snmp v3 trap-target {address} ".format(**config_data) + if "authentication" in config_data: + command += " auth" + config_data = config_data["authentication"] + if "privacy" in config_data: + command += " privacy" + config_data = config_data["privacy"] + if "type" in config_data: + command += " type {mode}".format(**config_data) + if "encrypted_key" in config_data: + command += " encrypted-key {encrypted_key}".format(**config_data) + if "plaintext_key" in config_data: + command += " plaintext-key {plaintext_key}".format(**config_data) + return command + + +def _tmplt_snmp_server_v3_user(config_data): + config_data = config_data["snmp_v3"]["users"] + command = [] + cmd = "service snmp v3 user {user}".format(**config_data) + for k in ["authentication", "privacy"]: + if config_data.get(k): + config = config_data[k] + if k == "authentication": + val = " auth" + else: + val = " privacy" + if "type" in config: + type_cmd = cmd + val + " type {type}".format(**config) + command.append(type_cmd) + if "encrypted_key" in config: + enc_cmd = ( + cmd + + val + + " encrypted-key {encrypted_key}".format(**config) + ) + command.append(enc_cmd) + if "plaintext_key" in config: + plain_cmd = ( + cmd + + val + + " plaintext-key {plaintext_key}".format(**config) + ) + command.append(plain_cmd) + return command + + +def _tmplt_snmp_server_v3_views(config_data): + config_data = config_data["snmp_v3"]["views"] + command = "service snmp v3 view {view} oid {oid}".format(**config_data) + if "exclude" in config_data: + command += " exclude {exclude}".format(**config_data) + if "mask" in config_data: + command += " mask {mask}".format(**config_data) + return command + + +class Snmp_serverTemplate(NetworkTemplate): + def __init__(self, lines=None, module=None): + prefix = {"set": "set", "remove": "delete"} + super(Snmp_serverTemplate, self).__init__( + lines=lines, tmplt=self, prefix=prefix, module=module + ) + + # fmt: off + PARSERS = [ + # service snmp community <> + { + "name": "communities", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\scommunity + \s+(?P<name>\S+) + \s*(?P<auth>authorization\srw|authorization\sro)* + \s*(client\s(?P<client>\S+))* + \s*(network\s(?P<network>\S+))* + $""", + re.VERBOSE), + "setval": _tmplt_snmp_server_communities, + "result": { + "communities": { + "{{ name }}": { + "name": "{{ name }}", + "clients": ['{{ client if client is defined else "None" }}'], + "networks": ['{{ network if network is defined else "None" }}'], + "authorization_type": '{{ auth.split(" ")[1] if auth is defined else None }}' + } + } + } + }, + # service snmp contact <> + { + "name": "contact", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\scontact + \s+(?P<name>\S+) + *$""", + re.VERBOSE), + "setval": "service snmp contact {{ contact }}", + "result": { + "contact": "{{ name }}" + } + }, + # service snmp description <> + { + "name": "description", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sdescription + \s+(?P<name>\S+) + *$""", + re.VERBOSE), + "setval": "service snmp description {{ description }}", + "result": { + "description": "{{ name }}" + } + }, + # service snmp listen-address <> port <> + { + "name": "listen_addresses", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\slisten-address + \s+(?P<addr>\S+) + \s*(port)* + \s*(?P<port>\d+)* + $""", + re.VERBOSE), + "setval": "service snmp listen-address {{ listen_addresses.address }}" + "{{ (' port ' + listen_addresses.port|string) if listen_addresses.port is defined else '' }}", + "result": { + "listen_addresses": { + "{{ addr }}": { + "address": "{{ addr }}", + "port": "{{ port }}" + } + } + } + }, + # service snmp location <> + { + "name": "location", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\slocation + \s(?P<name>.*) + $""", + re.VERBOSE), + "setval": "service snmp location {{ '\\'' + location + '\\''}}", + "result": { + "location": "{{ name }}" + } + }, + # service snmp smux-peer <> + { + "name": "smux_peer", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\ssmux-peer + \s+(?P<name>\S+) + *$""", + re.VERBOSE), + "setval": "service snmp smux-peer {{ smux_peer }}", + "result": { + "smux_peer": "{{ name }}" + } + }, + # service snmp trap-source <> + { + "name": "trap_source", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\strap-source + \s+(?P<name>\S+) + *$""", + re.VERBOSE), + "setval": "service snmp trap-source {{ trap_source }}", + "result": { + "trap_source": "{{ name }}" + } + }, + # service snmp trap-target <> + { + "name": "trap_target", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\strap-target + \s+(?P<name>\S+) + \s*(?P<comm>community\s\S+)* + \s*(?P<port>port\s\d+)* + $""", + re.VERBOSE), + "setval": _tmplt_snmp_server_trap_target, + "result": { + "trap_target": { + "address": "{{ name }}", + "community": "{{ comm.split(" ")[1] if comm is defined else None }}", + "port": "{{ port.split(" ")[1] if port is defined else None }}", + } + } + }, + # service snmp v3 engineid <> + { + "name": "snmp_v3.engine_id", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sv3\sengineid + \s+(?P<name>\S+) + *$""", + re.VERBOSE), + "setval": "service snmp v3 engineid {{ snmp_v3.engine_id }}", + "result": { + "snmp_v3": { + "engine_id": "{{ name }}", + } + } + }, + # service snmp v3 group <> + { + "name": "snmp_v3.groups", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sv3\sgroup + \s+(?P<name>\S+) + \s*(?P<mode>mode\s\S+)* + \s*(?P<sec>seclevel\s\S+)* + \s*(?P<view>view\s\S+)* + $""", + re.VERBOSE), + "setval": _tmplt_snmp_server_v3_groups, + "result": { + "snmp_v3": { + "groups": { + "{{ name }}": { + "group": "{{ name }}", + "mode": '{{ mode.split(" ")[1] if mode is defined else None }}', + "seclevel": '{{ sec.split(" ")[1] if sec is defined else None }}', + "view": '{{ view.split(" ")[1] if view is defined else None }}', + } + } + } + } + }, + # service snmp v3 trap-target <> auth <> + { + "name": "snmp_v3.trap_targets.authentication", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sv3\strap-target + \s+(?P<name>\S+) + \s+auth + \s*(?P<enc>encrypted-key\s\S+)* + \s*(?P<plain>plaintext-key\s\S+)* + \s*(?P<type>type\s\S+)* + $""", + re.VERBOSE), + "setval": _tmplt_snmp_server_v3_trap_target, + "result": { + "snmp_v3": { + "trap_targets": { + "{{ name }}": { + "address": "{{ name }}", + "authentication": { + "encrypted_key": '{{ enc.split(" ")[1] if enc is defined else None }}', + "plaintext_key": '{{ plain.split(" ")[1] if plain is defined else None }}', + "type": '{{ type.split(" ")[1] if type is defined else None }}', + } + } + } + } + } + }, + # service snmp v3 trap-target <> port <> + { + "name": "snmp_v3.trap_targets.port", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sv3\strap-target + \s+(?P<name>\S+) + \s+(?P<port>port\s\d+)* + $""", + re.VERBOSE), + "setval": "service snmp v3 trap-target port {{ snmp_v3.trap_targets.port }}", + "result": { + "snmp_v3": { + "trap_targets": { + "{{ name }}": { + "address": "{{ name }}", + "port": "{{ port }}" + } + } + } + } + }, + # service snmp v3 trap-target <> protocol <> + { + "name": "snmp_v3.trap_targets.protocol", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sv3\strap-target + \s+(?P<name>\S+) + \s+(?P<protocol>protocol\s\S+)* + $""", + re.VERBOSE), + "setval": "service snmp v3 trap-target protocol {{ snmp_v3.trap_targets.protocol }}", + "result": { + "snmp_v3": { + "trap_targets": { + "{{ name }}": { + "address": "{{ name }}", + "protocol": "{{ protocol }}" + } + } + } + } + }, + # service snmp v3 trap-target <> type <> + { + "name": "snmp_v3.trap_targets.type", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sv3\strap-target + \s+(?P<name>\S+) + \s+(?P<type>type\s\S+)* + $""", + re.VERBOSE), + "setval": "service snmp v3 trap-target type {{ snmp_v3.trap_targets.type }}", + "result": { + "snmp_v3": { + "trap_targets": { + "{{ name }}": { + "address": "{{ name }}", + "type": "{{ type }}" + } + } + } + } + }, + # service snmp v3 trap-target <> user <> + { + "name": "snmp_v3.trap_targets.user", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sv3\strap-target + \s+(?P<name>\S+) + \s+(?P<user>user\s\S+)* + $""", + re.VERBOSE), + "setval": "service snmp v3 trap-target user {{ snmp_v3.trap_targets.user }}", + "result": { + "snmp_v3": { + "trap_targets": { + "{{ name }}": { + "address": "{{ name }}", + "user": "{{ user }}" + } + } + } + } + }, + # service snmp v3 trap-target <> privacy <> + { + "name": "snmp_v3.trap_targets.privacy", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sv3\strap-target + \s+(?P<name>\S+) + \s+privacy + \s*(?P<enc>encrypted-key\s\S+)* + \s*(?P<plain>plaintext-key\s\S+)* + \s*(?P<type>type\s\S+)* + $""", + re.VERBOSE), + "setval": _tmplt_snmp_server_v3_trap_target, + "result": { + "snmp_v3": { + "trap_targets": { + "{{ name }}": { + "address": "{{ name }}", + "privacy": { + "encrypted_key": '{{ enc.split(" ")[1] if enc is defined else None }}', + "plaintext_key": '{{ plain.split(" ")[1] if plain is defined else None }}', + "type": '{{ type.split(" ")[1] if type is defined else None }}', + } + } + } + } + } + }, + # service snmp v3 user <> auth <> + { + "name": "snmp_v3.users.authentication", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sv3\suser + \s+(?P<name>\S+) + \s+auth + \s*(?P<enc>encrypted-key\s\S+)* + \s*(?P<plain>plaintext-key\s\S+)* + \s*(?P<type>type\s\S+)* + $""", + re.VERBOSE), + "setval": _tmplt_snmp_server_v3_user, + "result": { + "snmp_v3": { + "users": { + "{{ name }}": { + "user": "{{ name }}", + "authentication": { + "encrypted_key": '{{ enc.split(" ")[1] if enc is defined else None }}', + "plaintext_key": '{{ plain.split(" ")[1] if plain is defined else None }}', + "type": '{{ type.split(" ")[1] if type is defined else None }}', + } + } + } + } + } + }, + # service snmp v3 user <> privacy <> + { + "name": "snmp_v3.users.privacy", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sv3\suser + \s+(?P<name>\S+) + \s+privacy + \s*(?P<enc>encrypted-key\s\S+)* + \s*(?P<plain>plaintext-key\s\S+)* + \s*(?P<type>type\s\S+)* + $""", + re.VERBOSE), + "setval": _tmplt_snmp_server_v3_user, + "result": { + "snmp_v3": { + "users": { + "{{ name }}": { + "user": "{{ name }}", + "privacy": { + "encrypted_key": '{{ enc.split(" ")[1] if enc is defined else None }}', + "plaintext_key": '{{ plain.split(" ")[1] if plain is defined else None }}', + "type": '{{ type.split(" ")[1] if type is defined else None }}', + } + } + } + } + } + }, + # service snmp v3 user <> group <> + { + "name": "snmp_v3.users.group", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sv3\suser + \s+(?P<name>\S+) + \s+(?P<group>group\s.+)* + $""", + re.VERBOSE), + "setval": "service snmp v3 user {{ snmp_v3.users.user }} group {{ snmp_v3.users.group }}", + "result": { + "snmp_v3": { + "users": { + "{{ name }}": { + "user": "{{ name }}", + "group": "{{ group.split(" ")[1] if group is defined else None }}" + } + } + } + } + }, + # service snmp v3 user <> mode <> + { + "name": "snmp_v3.users.mode", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sv3\suser + \s+(?P<name>\S+) + \s+(?P<mode>mode\s\S+)* + $""", + re.VERBOSE), + "setval": "service snmp v3 user {{ snmp_v3.users.user }} mode {{ snmp_v3.users.mode }}", + "result": { + "snmp_v3": { + "users": { + "{{ name }}": { + "user": "{{ name }}", + "mode": "{{ mode }}" + } + } + } + } + }, + # service snmp v3 view <> + { + "name": "snmp_v3.views", + "getval": re.compile( + r""" + ^set\sservice\ssnmp\sv3\sview + \s+(?P<name>\S+) + \s+(?P<oid>oid\s\S+) + \s*(?P<ex>exclude\s\S+)* + \s*(?P<mask>mask\s\S+)* + $""", + re.VERBOSE), + "setval": _tmplt_snmp_server_v3_views, + "result": { + "snmp_v3": { + "views": { + "{{ name }}": { + "view": "{{ name }}", + "oid": '{{ oid.split(" ")[1] if oid is defined else None }}', + "exclude": '{{ ex.split(" ")[1] if ex is defined else None }}', + "mask": '{{ mask.split(" ")[1] if mask is defined else None }}', + } + } + } + } + }, + ] + # fmt: on diff --git a/plugins/modules/vyos_snmp_server.py b/plugins/modules/vyos_snmp_server.py new file mode 100644 index 0000000..1651226 --- /dev/null +++ b/plugins/modules/vyos_snmp_server.py @@ -0,0 +1,1128 @@ +#!/usr/bin/python +# -*- 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) + +""" +The module file for vyos_snmp_server +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = """ +module: vyos_snmp_server +version_added: 2.7.0 +short_description: Manages snmp_server resource module +description: This module manages the snmp server attributes of Vyos network devices +author: Gomathi Selvi Srinivasan (@GomathiselviS) +notes: + - Tested against vyos 1.1.8 + - This module works with connection C(network_cli). + - The Configuration defaults of the Vyos network devices + are supposed to hinder idempotent behavior of plays +options: + config: + description: SNMP server configuration. + type: dict + suboptions: + communities: + description: Community name configuration. + type: list + elements: dict + suboptions: + name: + description: Community name + type: str + clients: + description: IP address of SNMP client allowed to contact system + type: list + elements: str + networks: + description: Subnet of SNMP client(s) allowed to contact system + type: list + elements: str + authorization_type: + description: Authorization type (rw or ro) + type: str + choices: ['ro', 'rw'] + contact: + description: Person to contact about the system. + type: str + description: + description: Description information + type: str + listen_addresses: + description: IP address to listen for incoming SNMP requests + type: list + elements: dict + suboptions: + address: + description: IP address to listen for incoming SNMP requests. + type: str + port: + description: Port for SNMP service + type: int + location: + description: Location information + type: str + smux_peer: + description: Register a subtree for SMUX-based processing. + type: str + trap_source: + description: SNMP trap source address + type: str + trap_target: + description: Address of trap target + type: dict + suboptions: + address: + description: Address of trap target + type: str + community: + description: Community used when sending trap information + type: str + port: + description: Destination port used for trap notification + type: int + snmp_v3: + description: Simple Network Management Protocol (SNMP) v3 + type: dict + suboptions: + engine_id: + description: Specifies the EngineID as a hex value + type: str + groups: + description: Specifies the group with name groupname + type: list + elements: dict + suboptions: + group: + description: Specifies the group with name groupname + type: str + mode: + description: Defines the read/write access + type: str + choices: ['ro', 'rw'] + seclevel: + description: Defines security level + type: str + choices: ['auth', 'priv'] + view: + description: Defines the name of view + type: str + trap_targets: + description: Defines SNMP target for inform or traps for IP + type: list + elements: dict + suboptions: + address: + description: IP/IPv6 address of trap target + type: str + authentication: + description: Defines the authentication + type: dict + suboptions: + type: + description: Defines the protocol using for authentication + type: str + choices: ['md5', 'sha'] + encrypted_key: + description: Defines the encrypted password for authentication + type: str + plaintext_key: + description: Defines the clear text password for authentication + type: str + engine_id: + description: Defines the engineID. + type: str + port: + description: Specifies the TCP/UDP port of a destination for SNMP traps/informs. + type: int + privacy: + description: Defines the privacy + type: dict + suboptions: + type: + description: Defines the protocol using for privacy + type: str + choices: ['des', 'aes'] + encrypted_key: + description: Defines the encrypted password for privacy + type: str + plaintext_key: + description: Defines the clear text password for privacy + type: str + protocol: + description: Defines protocol for notification between TCP and UDP + type: str + choices: ['tcp', 'udp'] + type: + description: Specifies the type of notification between inform and trap + type: str + choices: ['inform', 'trap'] + tsm: + description: Specifies that the snmpd uses encryption + type: dict + suboptions: + local_key: + description: Defines the server certificate fingerprint or key-file name. + type: str + port: + description: Defines the port for tsm. + type: int + users: + description: Defines username for authentication + type: list + elements: dict + suboptions: + user: + description: Specifies the user with name username + type: str + authentication: + description: Defines the authentication + type: dict + suboptions: + type: + description: Defines the protocol using for authentication + type: str + choices: ['md5', 'sha'] + encrypted_key: + description: Defines the encrypted password for authentication + type: str + plaintext_key: + description: Defines the clear text password for authentication + type: str + engine_id: + description: Defines the engineID. + type: str + group: + description: Specifies group for user name + type: str + mode: + description: Specifies the mode for access rights of user, read only or write + type: str + choices: ['ro', 'rw'] + privacy: + description: Defines the privacy + type: dict + suboptions: + type: + description: Defines the protocol using for privacy + type: str + choices: ['des', 'aes'] + encrypted_key: + description: Defines the encrypted password for privacy + type: str + plaintext_key: + description: Defines the clear text password for privacy + type: str + tsm_key: + description: Specifies finger print or file name of TSM certificate. + type: str + views: + description: Specifies the view with name viewname + type: list + elements: dict + suboptions: + view: + description: view name + type: str + oid: + description: Specify oid + type: str + exclude: + description: Exclude is optional argument. + type: str + mask: + description: Defines a bit-mask that is indicating which subidentifiers of the associated subtree OID should be regarded as significant. + type: str + running_config: + description: + - The state the configuration should be left in. + - The states I(replaced) and I(overridden) have identical + behaviour for this module. + - Please refer to examples for more details. + type: str + state: + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - parsed + - rendered + default: merged + description: + - The state the configuration should be left in + type: str +""" +EXAMPLES = """ + +# Using merged +# Before State: + +# vyos@vyos:~$ show configuration commands | grep snmp +# vyos@vyos:~$ + + - name: Merge provided configuration with device configuration + vyos.vyos.vyos_snmp_server: + config: + communities: + - name: "switches" + authorization_type: "rw" + - name: "bridges" + clients: ["1.1.1.1", "12.1.1.10"] + contact: "admin2@ex.com" + listen_addresses: + - address: "20.1.1.1" + - address: "100.1.2.1" + port: 33 + snmp_v3: + users: + - user: admin_user + authentication: + plaintext_key: "abc1234567" + type: "sha" + privacy: + plaintext_key: "abc1234567" + type: "aes" + + state: merged + +# After State: + +# vyos@vyos:~$ show configuration commands | grep snmp +# set service snmp community bridges client '1.1.1.1' +# set service snmp community bridges client '12.1.1.10' +# set service snmp community switches authorization 'rw' +# set service snmp contact 'admin2@ex.com' +# set service snmp listen-address 20.1.1.1 +# set service snmp listen-address 100.1.2.1 port '33' +# set service snmp v3 user admin_user auth plaintext-key 'abc1234567' +# set service snmp v3 user admin_user auth type 'sha' +# set service snmp v3 user admin_user privacy plaintext-key 'abc1234567' +# set service snmp v3 user admin_user privacy type 'aes' +# vyos@vyos:~$ +# +# Module Execution: +# +# "after": { +# "communities": [ +# { +# "clients": [ +# "1.1.1.1", +# "12.1.1.10" +# ], +# "name": "bridges" +# }, +# { +# "authorization_type": "rw", +# "name": "switches" +# } +# ], +# "contact": "admin2@ex.com", +# "listen_addresses": [ +# { +# "address": "100.1.2.1", +# "port": 33 +# }, +# { +# "address": "20.1.1.1" +# } +# ], +# "snmp_v3": { +# "users": [ +# { +# "authentication": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "sha" +# }, +# "privacy": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "aes" +# }, +# "user": "admin_user" +# } +# ] +# } +# }, +# "before": {}, +# "changed": true, +# "commands": [ +# "set service snmp community switches authorization rw", +# "set service snmp community bridges client 1.1.1.1", +# "set service snmp community bridges client 12.1.1.10", +# "set service snmp listen-address 20.1.1.1", +# "set service snmp listen-address 100.1.2.1 port 33", +# "set service snmp v3 user admin_user auth type sha", +# "set service snmp v3 user admin_user auth plaintext-key ********", +# "set service snmp v3 user admin_user privacy type aes", +# "set service snmp v3 user admin_user privacy plaintext-key ********", +# "set service snmp contact admin2@ex.com" +# ], +# + +# using Replaced: + +# Before State +# vyos@vyos:~$ show configuration commands | grep snmp +# set service snmp community bridges client '1.1.1.1' +# set service snmp community bridges client '12.1.1.10' +# set service snmp community switches authorization 'rw' +# set service snmp contact 'admin2@ex.com' +# set service snmp listen-address 20.1.1.1 +# set service snmp listen-address 100.1.2.1 port '33' +# set service snmp v3 user admin_user auth plaintext-key 'abc1234567' +# set service snmp v3 user admin_user auth type 'sha' +# set service snmp v3 user admin_user privacy plaintext-key 'abc1234567' +# set service snmp v3 user admin_user privacy type 'aes' +# vyos@vyos:~$ + + - name: Replace + vyos.vyos.vyos_snmp_server: + config: + communities: + - name: "bridges" + networks: ["1.1.1.0/24", "12.1.1.0/24"] + location: "RDU, NC" + listen_addresses: + - address: "100.1.2.1" + port: 33 + snmp_v3: + groups: + - group: "default" + view: "default" + users: + - user: admin_user + authentication: + plaintext_key: "abc1234567" + type: "sha" + privacy: + plaintext_key: "abc1234567" + type: "aes" + group: "default" + - user: guest_user2 + authentication: + plaintext_key: "opq1234567" + type: "sha" + privacy: + plaintext_key: "opq1234567" + type: "aes" + views: + - view: "default" + oid: 1 + + state: replaced + +# After State: +# vyos@vyos:~$ show configuration commands | grep snmp +# set service snmp community bridges network '1.1.1.0/24' +# set service snmp community bridges network '12.1.1.0/24' +# set service snmp community switches +# set service snmp listen-address 100.1.2.1 port '33' +# set service snmp location 'RDU, NC' +# set service snmp v3 group default view 'default' +# set service snmp v3 user admin_user auth plaintext-key 'abc1234567' +# set service snmp v3 user admin_user auth type 'sha' +# set service snmp v3 user admin_user group 'default' +# set service snmp v3 user admin_user privacy plaintext-key 'abc1234567' +# set service snmp v3 user admin_user privacy type 'aes' +# set service snmp v3 user guest_user2 auth plaintext-key 'opq1234567' +# set service snmp v3 user guest_user2 auth type 'sha' +# set service snmp v3 user guest_user2 privacy plaintext-key 'opq1234567' +# set service snmp v3 user guest_user2 privacy type 'aes' +# set service snmp v3 view default oid 1 +# vyos@vyos:~$ +# +# +# Module Execution: +# "after": { +# "communities": [ +# { +# "name": "bridges", +# "networks": [ +# "1.1.1.0/24", +# "12.1.1.0/24" +# ] +# }, +# { +# "name": "switches" +# } +# ], +# "listen_addresses": [ +# { +# "address": "100.1.2.1", +# "port": 33 +# } +# ], +# "location": "RDU, NC", +# "snmp_v3": { +# "groups": [ +# { +# "group": "default", +# "view": "default" +# } +# ], +# "users": [ +# { +# "authentication": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "sha" +# }, +# "group": "default", +# "privacy": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "aes" +# }, +# "user": "admin_user" +# }, +# { +# "authentication": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "sha" +# }, +# "privacy": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "aes" +# }, +# "user": "guest_user2" +# } +# ], +# "views": [ +# { +# "oid": "1", +# "view": "default" +# } +# ] +# } +# }, +# "before": { +# "communities": [ +# { +# "clients": [ +# "1.1.1.1", +# "12.1.1.10" +# ], +# "name": "bridges" +# }, +# { +# "authorization_type": "rw", +# "name": "switches" +# } +# ], +# "contact": "admin2@ex.com", +# "listen_addresses": [ +# { +# "address": "100.1.2.1", +# "port": 33 +# }, +# { +# "address": "20.1.1.1" +# } +# ], +# "snmp_v3": { +# "users": [ +# { +# "authentication": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "sha" +# }, +# "privacy": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "aes" +# }, +# "user": "admin_user" +# } +# ] +# } +# }, +# "changed": true, +# "commands": [ +# "delete service snmp contact admin2@ex.com", +# "delete service snmp listen-address 20.1.1.1", +# "delete service snmp community switches authorization rw", +# "delete service snmp community bridges client 12.1.1.10", +# "delete service snmp community bridges client 1.1.1.1", +# "set service snmp community bridges network 1.1.1.0/24", +# "set service snmp community bridges network 12.1.1.0/24", +# "set service snmp v3 group default view default", +# "set service snmp v3 user admin_user group default", +# "set service snmp v3 user guest_user2 auth type sha", +# "set service snmp v3 user guest_user2 auth plaintext-key ********", +# "set service snmp v3 user guest_user2 privacy type aes", +# "set service snmp v3 user guest_user2 privacy plaintext-key ********", +# "set service snmp v3 view default oid 1", +# "set service snmp location 'RDU, NC'" +# ], + +# Using overridden: +# Before State +# vyos@vyos:~$ show configuration commands | grep snmp +# set service snmp community bridges client '1.1.1.1' +# set service snmp community bridges client '12.1.1.10' +# set service snmp community switches authorization 'rw' +# set service snmp contact 'admin2@ex.com' +# set service snmp listen-address 20.1.1.1 +# set service snmp listen-address 100.1.2.1 port '33' +# set service snmp v3 user admin_user auth plaintext-key 'abc1234567' +# set service snmp v3 user admin_user auth type 'sha' +# set service snmp v3 user admin_user privacy plaintext-key 'abc1234567' +# set service snmp v3 user admin_user privacy type 'aes' +# vyos@vyos:~$ + + - name: Override config + vyos.vyos.vyos_snmp_server: + config: + communities: + - name: "bridges" + networks: ["1.1.1.0/24", "12.1.1.0/24"] + location: "RDU, NC" + listen_addresses: + - address: "100.1.2.1" + port: 33 + snmp_v3: + groups: + - group: "default" + view: "default" + users: + - user: admin_user + authentication: + plaintext_key: "abc1234567" + type: "sha" + privacy: + plaintext_key: "abc1234567" + type: "aes" + group: "default" + - user: guest_user2 + authentication: + plaintext_key: "opq1234567" + type: "sha" + privacy: + plaintext_key: "opq1234567" + type: "aes" + views: + - view: "default" + oid: 1 + + state: overridden + +# After State: +# vyos@vyos:~$ show configuration commands | grep snmp +# set service snmp community bridges network '1.1.1.0/24' +# set service snmp community bridges network '12.1.1.0/24' +# set service snmp community switches +# set service snmp listen-address 100.1.2.1 port '33' +# set service snmp location 'RDU, NC' +# set service snmp v3 group default view 'default' +# set service snmp v3 user admin_user auth plaintext-key 'abc1234567' +# set service snmp v3 user admin_user auth type 'sha' +# set service snmp v3 user admin_user group 'default' +# set service snmp v3 user admin_user privacy plaintext-key 'abc1234567' +# set service snmp v3 user admin_user privacy type 'aes' +# set service snmp v3 user guest_user2 auth plaintext-key 'opq1234567' +# set service snmp v3 user guest_user2 auth type 'sha' +# set service snmp v3 user guest_user2 privacy plaintext-key 'opq1234567' +# set service snmp v3 user guest_user2 privacy type 'aes' +# set service snmp v3 view default oid 1 +# vyos@vyos:~$ +# +# +# Module Execution: +# "after": { +# "communities": [ +# { +# "name": "bridges", +# "networks": [ +# "1.1.1.0/24", +# "12.1.1.0/24" +# ] +# }, +# { +# "name": "switches" +# } +# ], +# "listen_addresses": [ +# { +# "address": "100.1.2.1", +# "port": 33 +# } +# ], +# "location": "RDU, NC", +# "snmp_v3": { +# "groups": [ +# { +# "group": "default", +# "view": "default" +# } +# ], +# "users": [ +# { +# "authentication": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "sha" +# }, +# "group": "default", +# "privacy": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "aes" +# }, +# "user": "admin_user" +# }, +# { +# "authentication": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "sha" +# }, +# "privacy": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "aes" +# }, +# "user": "guest_user2" +# } +# ], +# "views": [ +# { +# "oid": "1", +# "view": "default" +# } +# ] +# } +# }, +# "before": { +# "communities": [ +# { +# "clients": [ +# "1.1.1.1", +# "12.1.1.10" +# ], +# "name": "bridges" +# }, +# { +# "authorization_type": "rw", +# "name": "switches" +# } +# ], +# "contact": "admin2@ex.com", +# "listen_addresses": [ +# { +# "address": "100.1.2.1", +# "port": 33 +# }, +# { +# "address": "20.1.1.1" +# } +# ], +# "snmp_v3": { +# "users": [ +# { +# "authentication": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "sha" +# }, +# "privacy": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "aes" +# }, +# "user": "admin_user" +# } +# ] +# } +# }, +# "changed": true, +# "commands": [ +# "delete service snmp contact admin2@ex.com", +# "delete service snmp listen-address 20.1.1.1", +# "delete service snmp community switches authorization rw", +# "delete service snmp community bridges client 12.1.1.10", +# "delete service snmp community bridges client 1.1.1.1", +# "set service snmp community bridges network 1.1.1.0/24", +# "set service snmp community bridges network 12.1.1.0/24", +# "set service snmp v3 group default view default", +# "set service snmp v3 user admin_user group default", +# "set service snmp v3 user guest_user2 auth type sha", +# "set service snmp v3 user guest_user2 auth plaintext-key ********", +# "set service snmp v3 user guest_user2 privacy type aes", +# "set service snmp v3 user guest_user2 privacy plaintext-key ********", +# "set service snmp v3 view default oid 1", +# "set service snmp location 'RDU, NC'" +# ], + +# Using deleted: + +# Before State: +# vyos@vyos:~$ show configuration commands | grep snmp +# set service snmp community bridges network '1.1.1.0/24' +# set service snmp community bridges network '12.1.1.0/24' +# set service snmp community switches +# set service snmp listen-address 100.1.2.1 port '33' +# set service snmp location 'RDU, NC' +# set service snmp v3 group default view 'default' +# set service snmp v3 user admin_user auth plaintext-key 'abc1234567' +# set service snmp v3 user admin_user auth type 'sha' +# set service snmp v3 user admin_user group 'default' +# set service snmp v3 user admin_user privacy plaintext-key 'abc1234567' +# set service snmp v3 user admin_user privacy type 'aes' +# set service snmp v3 user guest_user2 auth plaintext-key 'opq1234567' +# set service snmp v3 user guest_user2 auth type 'sha' +# set service snmp v3 user guest_user2 privacy plaintext-key 'opq1234567' +# set service snmp v3 user guest_user2 privacy type 'aes' +# set service snmp v3 view default oid 1 +# vyos@vyos:~$ + + - name: Delete Config + vyos.vyos.vyos_snmp_server: + state: deleted + +# After State: +# vyos@vyos:~$ show configuration commands | grep snmp +# vyos@vyos:~$ +# +# Module Execution: +# "after": {}, +# "before": { +# "communities": [ +# { +# "name": "bridges", +# "networks": [ +# "1.1.1.0/24", +# "12.1.1.0/24" +# ] +# }, +# { +# "name": "switches" +# } +# ], +# "listen_addresses": [ +# { +# "address": "100.1.2.1", +# "port": 33 +# } +# ], +# "location": "RDU, NC", +# "snmp_v3": { +# "groups": [ +# { +# "group": "default", +# "view": "default" +# } +# ], +# "users": [ +# { +# "authentication": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "sha" +# }, +# "group": "default", +# "privacy": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "aes" +# }, +# "user": "admin_user" +# }, +# { +# "authentication": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "sha" +# }, +# "privacy": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "aes" +# }, +# "user": "guest_user2" +# } +# ], +# "views": [ +# { +# "oid": "1", +# "view": "default" +# } +# ] +# } +# }, +# "changed": true, +# "commands": [ +# "delete service snmp" +# ], + +# Using rendered: + - name: Render provided configuration + vyos.vyos.vyos_snmp_server: + config: + communities: + - name: "switches" + authorization_type: "rw" + - name: "bridges" + clients: ["1.1.1.1", "12.1.1.10"] + contact: "admin2@ex.com" + listen_addresses: + - address: "20.1.1.1" + - address: "100.1.2.1" + port: 33 + snmp_v3: + users: + - user: admin_user + authentication: + plaintext_key: "abc1234567" + type: "sha" + privacy: + plaintext_key: "abc1234567" + type: "aes" + + state: rendered + +# Module Execution: +# "rendered": [ +# "set service snmp community switches authorization rw", +# "set service snmp community bridges client 1.1.1.1", +# "set service snmp community bridges client 12.1.1.10", +# "set service snmp listen-address 20.1.1.1", +# "set service snmp listen-address 100.1.2.1 port 33", +# "set service snmp v3 user admin_user auth type sha", +# "set service snmp v3 user admin_user auth plaintext-key ********", +# "set service snmp v3 user admin_user privacy type aes", +# "set service snmp v3 user admin_user privacy plaintext-key ********", +# "set service snmp contact admin2@ex.com" +# ] +# + +# Using Gathered: +# Before State: + +# vyos@vyos:~$ show configuration commands | grep snmp +# set service snmp community bridges client '1.1.1.1' +# set service snmp community bridges client '12.1.1.10' +# set service snmp community switches authorization 'rw' +# set service snmp contact 'admin2@ex.com' +# set service snmp listen-address 20.1.1.1 +# set service snmp listen-address 100.1.2.1 port '33' +# set service snmp v3 user admin_user auth plaintext-key 'abc1234567' +# set service snmp v3 user admin_user auth type 'sha' +# set service snmp v3 user admin_user privacy plaintext-key 'abc1234567' +# set service snmp v3 user admin_user privacy type 'aes' +# vyos@vyos:~$ + + - name: gather configs + vyos.vyos.vyos_snmp_server: + state: gathered + +# Module Execution: +# "gathered": { +# "communities": [ +# { +# "clients": [ +# "1.1.1.1", +# "12.1.1.10" +# ], +# "name": "bridges" +# }, +# { +# "authorization_type": "rw", +# "name": "switches" +# } +# ], +# "contact": "admin2@ex.com", +# "listen_addresses": [ +# { +# "address": "100.1.2.1", +# "port": 33 +# }, +# { +# "address": "20.1.1.1" +# } +# ], +# "snmp_v3": { +# "users": [ +# { +# "authentication": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "sha" +# }, +# "privacy": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "aes" +# }, +# "user": "admin_user" +# } +# ] +# } +# }, + +# Using parsed: + +# _parsed_snmp.cfg +# set service snmp community routers authorization 'ro' +# set service snmp community routers client '203.0.113.10' +# set service snmp community routers client '203.0.113.20' +# set service snmp community routers network '192.0.2.0/24' +# set service snmp community routers network '2001::/64' +# set service snmp contact 'admin@example.com' +# set service snmp listen-address 172.16.254.36 port '161' +# set service snmp listen-address 2001::1 +# set service snmp location 'UK, London' +# set service snmp trap-target 203.0.113.10 +# set service snmp v3 engineid '000000000000000000000002' +# set service snmp v3 group default mode 'ro' +# set service snmp v3 group default view 'default' +# set service snmp v3 user vyos auth plaintext-key 'vyos12345678' +# set service snmp v3 user vyos auth type 'sha' +# set service snmp v3 user vyos group 'default' +# set service snmp v3 user vyos privacy plaintext-key 'vyos12345678' +# set service snmp v3 user vyos privacy type 'aes' +# set service snmp v3 view default oid 1 + + - name: parse configs + vyos.vyos.vyos_snmp_server: + running_config: "{{ lookup('file', './_parsed_snmp.cfg') }}" + state: parsed + +# Module Execution: +# "parsed": { +# "communities": [ +# { +# "authorization_type": "ro", +# "clients": [ +# "203.0.113.10", +# "203.0.113.20" +# ], +# "name": "routers", +# "networks": [ +# "192.0.2.0/24", +# "2001::/64" +# ] +# } +# ], +# "contact": "admin@example.com", +# "listen_addresses": [ +# { +# "address": "172.16.254.36", +# "port": 161 +# }, +# { +# "address": "2001::1" +# } +# ], +# "location": "UK, London", +# "snmp_v3": { +# "engine_id": "000000000000000000000002", +# "groups": [ +# { +# "group": "default", +# "mode": "ro", +# "view": "default" +# } +# ], +# "users": [ +# { +# "authentication": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "sha" +# }, +# "group": "default", +# "privacy": { +# "plaintext_key": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", +# "type": "aes" +# }, +# "user": "vyos" +# } +# ], +# "views": [ +# { +# "oid": "1", +# "view": "default" +# } +# ] +# }, +# "trap_target": { +# "address": "203.0.113.10" +# } +# } +# +""" + +RETURN = """ +before: + description: The configuration prior to the module execution. + returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged) + type: dict + sample: > + This output will always be in the same format as the + module argspec. +after: + description: The resulting configuration after module execution. + returned: when changed + type: dict + sample: > + This output will always be in the same format as the + module argspec. +commands: + description: The set of commands pushed to the remote device. + returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged) + type: list + sample: + set service snmp community routers authorization 'ro' + set service snmp community routers client '203.0.113.10' + set service snmp community routers client '203.0.113.20' + set service snmp community routers network '192.0.2.0/24' +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + set service snmp community routers authorization 'ro' + set service snmp community routers client '203.0.113.10' + set service snmp community routers client '203.0.113.20' + set service snmp community routers network '192.0.2.0/24' +gathered: + description: Facts about the network resource gathered from the remote device as structured data. + returned: when I(state) is C(gathered) + type: list + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. + returned: when I(state) is C(parsed) + type: list + sample: > + This output will always be in the same format as the + module argspec. +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.snmp_server.snmp_server import ( + Snmp_serverArgs, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.snmp_server.snmp_server import ( + Snmp_server, +) + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + module = AnsibleModule( + argument_spec=Snmp_serverArgs.argument_spec, + mutually_exclusive=[["config", "running_config"]], + required_if=[ + ["state", "merged", ["config"]], + ["state", "replaced", ["config"]], + ["state", "overridden", ["config"]], + ["state", "rendered", ["config"]], + ["state", "parsed", ["running_config"]], + ], + supports_check_mode=True, + ) + + result = Snmp_server(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() |