diff --git a/README.md b/README.md index f37e259..cf2c9ba 100644 --- a/README.md +++ b/README.md @@ -1,172 +1,173 @@ # VyOS Collection [![CI](https://zuul-ci.org/gated.svg)](https://dashboard.zuul.ansible.com/t/ansible/project/github.com/ansible-collections/vyos.vyos) The Ansible VyOS collection includes a variety of Ansible content to help automate the management of VyOS network appliances. This collection has been tested against VyOS 1.1.8 (helium). ## Ansible version compatibility This collection has been tested against following Ansible versions: **>=2.9.10**. Plugins and modules within a collection may be tested with only specific Ansible versions. A collection may contain metadata that identifies these versions. PEP440 is the schema used to describe the versions of Ansible. ### Supported connections The VyOS collection supports ``network_cli`` connections. ## Included content ### Cliconf plugins Name | Description --- | --- [vyos.vyos.vyos](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_cliconf.rst)|Use vyos cliconf to run command on VyOS platform ### Modules Name | Description --- | --- [vyos.vyos.vyos_banner](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_banner_module.rst)|Manage multiline banners on VyOS devices [vyos.vyos.vyos_bgp_address_family](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_bgp_address_family_module.rst)|BGP Address Family Resource Module. [vyos.vyos.vyos_bgp_global](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_bgp_global_module.rst)|BGP Global Resource Module. [vyos.vyos.vyos_command](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_command_module.rst)|Run one or more commands on VyOS devices [vyos.vyos.vyos_config](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_config_module.rst)|Manage VyOS configuration on remote device [vyos.vyos.vyos_facts](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_facts_module.rst)|Get facts about vyos devices. [vyos.vyos.vyos_firewall_global](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_firewall_global_module.rst)|FIREWALL global resource module [vyos.vyos.vyos_firewall_interfaces](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_firewall_interfaces_module.rst)|FIREWALL interfaces resource module [vyos.vyos.vyos_firewall_rules](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_firewall_rules_module.rst)|FIREWALL rules resource module +[vyos.vyos.vyos_hostname](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_hostname_module.rst)|Manages hostname resource module [vyos.vyos.vyos_interface](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_interface_module.rst)|(deprecated, removed after 2022-06-01) Manage Interface on VyOS network devices [vyos.vyos.vyos_interfaces](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_interfaces_module.rst)|Interfaces resource module [vyos.vyos.vyos_l3_interface](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_l3_interface_module.rst)|(deprecated, removed after 2022-06-01) Manage L3 interfaces on VyOS network devices [vyos.vyos.vyos_l3_interfaces](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_l3_interfaces_module.rst)|L3 interfaces resource module [vyos.vyos.vyos_lag_interfaces](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_lag_interfaces_module.rst)|LAG interfaces resource module [vyos.vyos.vyos_linkagg](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_linkagg_module.rst)|(deprecated, removed after 2022-06-01) Manage link aggregation groups on VyOS network devices [vyos.vyos.vyos_lldp](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_lldp_module.rst)|(deprecated, removed after 2022-06-01) Manage LLDP configuration on VyOS network devices [vyos.vyos.vyos_lldp_global](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_lldp_global_module.rst)|LLDP global resource module [vyos.vyos.vyos_lldp_interface](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_lldp_interface_module.rst)|(deprecated, removed after 2022-06-01) Manage LLDP interfaces configuration on VyOS network devices [vyos.vyos.vyos_lldp_interfaces](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_lldp_interfaces_module.rst)|LLDP interfaces resource module [vyos.vyos.vyos_logging](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_logging_module.rst)|Manage logging on network devices [vyos.vyos.vyos_logging_global](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_logging_global_module.rst)|Logging resource module [vyos.vyos.vyos_ntp_global](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_ntp_global_module.rst)|Manages ntp modules of Vyos network devices [vyos.vyos.vyos_ospf_interfaces](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_ospf_interfaces_module.rst)|OSPF Interfaces Resource Module. [vyos.vyos.vyos_ospfv2](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_ospfv2_module.rst)|OSPFv2 resource module [vyos.vyos.vyos_ospfv3](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_ospfv3_module.rst)|OSPFV3 resource module [vyos.vyos.vyos_ping](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_ping_module.rst)|Tests reachability using ping from VyOS network devices [vyos.vyos.vyos_prefix_lists](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_prefix_lists_module.rst)|Prefix-Lists resource module for VyOS [vyos.vyos.vyos_route_maps](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_route_maps_module.rst)|Route Map Resource Module. [vyos.vyos.vyos_snmp_server](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_snmp_server_module.rst)|Manages snmp_server resource module [vyos.vyos.vyos_static_route](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_static_route_module.rst)|(deprecated, removed after 2022-06-01) Manage static IP routes on Vyatta VyOS network devices [vyos.vyos.vyos_static_routes](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_static_routes_module.rst)|Static routes resource module [vyos.vyos.vyos_system](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_system_module.rst)|Run `set system` commands on VyOS devices [vyos.vyos.vyos_user](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_user_module.rst)|Manage the collection of local users on VyOS device [vyos.vyos.vyos_vlan](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_vlan_module.rst)|Manage VLANs on VyOS network devices Click the ``Content`` button to see the list of content included in this collection. ## Installing this collection You can install the VyOS collection with the Ansible Galaxy CLI: ansible-galaxy collection install vyos.vyos You can also include it in a `requirements.yml` file and install it with `ansible-galaxy collection install -r requirements.yml`, using the format: ```yaml --- collections: - name: vyos.vyos ``` ## Using this collection This collection includes [network resource modules](https://docs.ansible.com/ansible/latest/network/user_guide/network_resource_modules.html). ### Using modules from the VyOS collection in your playbooks You can call modules by their Fully Qualified Collection Namespace (FQCN), such as `vyos.vyos.vyos_static_routes`. The following example task replaces configuration changes in the existing configuration on a VyOS network device, using the FQCN: ```yaml --- - name: Replace device configurations of listed static routes with provided configurations register: result vyos.vyos.vyos_static_routes: &id001 config: - address_families: - afi: ipv4 routes: - dest: 192.0.2.32/28 blackhole_config: distance: 2 next_hops: - forward_router_address: 192.0.2.7 - forward_router_address: 192.0.2.8 - forward_router_address: 192.0.2.9 state: replaced ``` **NOTE**: For Ansible 2.9, you may not see deprecation warnings when you run your playbooks with this collection. Use this documentation to track when a module is deprecated. ### See Also: * [VyOS Platform Options](https://docs.ansible.com/ansible/latest/network/user_guide/platform_vyos.html) * [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details. ## Contributing to this collection We welcome community contributions to this collection. If you find problems, please open an issue or create a PR against the [VyOS collection repository](https://github.com/ansible-collections/vyos). See [Contributing to Ansible-maintained collections](https://docs.ansible.com/ansible/devel/community/contributing_maintained_collections.html#contributing-maintained-collections) for complete details. You can also join us on: - IRC - the ``#ansible-network`` [irc.libera.chat](https://libera.chat/) channel - Slack - https://ansiblenetwork.slack.com See the [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html) for details on contributing to Ansible. ### Code of Conduct This collection follows the Ansible project's [Code of Conduct](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html). Please read and familiarize yourself with this document. ## Changelogs ## Release notes Release notes are available [here](https://github.com/ansible-collections/vyos.vyos/blob/main/CHANGELOG.rst). ## Roadmap ## More information - [Ansible network resources](https://docs.ansible.com/ansible/latest/network/getting_started/network_resources.html) - [Ansible Collection overview](https://github.com/ansible-collections/overview) - [Ansible User guide](https://docs.ansible.com/ansible/latest/user_guide/index.html) - [Ansible Developer guide](https://docs.ansible.com/ansible/latest/dev_guide/index.html) - [Ansible Community code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html) ## Licensing GNU General Public License v3.0 or later. See [LICENSE](https://www.gnu.org/licenses/gpl-3.0.txt) to see the full text. diff --git a/changelogs/fragments/vyos_hostname_rm.yaml b/changelogs/fragments/vyos_hostname_rm.yaml new file mode 100644 index 0000000..b9d9341 --- /dev/null +++ b/changelogs/fragments/vyos_hostname_rm.yaml @@ -0,0 +1,3 @@ +--- +minor_changes: + - Add vyos_hostname resource module. diff --git a/docs/vyos.vyos.vyos_hostname_module.rst b/docs/vyos.vyos.vyos_hostname_module.rst new file mode 100644 index 0000000..569017a --- /dev/null +++ b/docs/vyos.vyos.vyos_hostname_module.rst @@ -0,0 +1,386 @@ +.. _vyos.vyos.vyos_hostname_module: + + +*********************** +vyos.vyos.vyos_hostname +*********************** + +**Manages hostname resource module** + + +Version added: 2.8.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This module manages the hostname attribute of Vyos network devices + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsComments
+
+ config + +
+ dictionary +
+
+ +
Hostname configuration.
+
+
+ hostname + +
+ string +
+
+ +
set hostname for VYOS.
+
+
+ running_config + +
+ string +
+
+ +
This option is used only with state parsed.
+
The value of this option should be the output received from the vyos device by executing the command "show configuration commands | grep host-name".
+
The state parsed reads the configuration from running_config option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
+
+
+ state + +
+ string +
+
+
    Choices: +
  • merged ←
  • +
  • replaced
  • +
  • overridden
  • +
  • deleted
  • +
  • gathered
  • +
  • parsed
  • +
  • rendered
  • +
+
+
The state the configuration should be left in
+
The states rendered, gathered and parsed does not perform any change on the device.
+
The state rendered will transform the configuration in config option to platform specific CLI commands which will be returned in the rendered key within the result. For state rendered active connection to remote host is not required.
+
The states merged, replaced and overridden have identical behaviour for this module.
+
The state gathered will fetch the running configuration from device and transform it into structured data in the format as per the resource module argspec and the value is returned in the gathered key within the result.
+
The state parsed reads the configuration from running_config option and transforms it into JSON format as per the resource module parameters and the value is returned in the parsed key within the result. The value of running_config option should be the same format as the output of command show configuration commands | grep host-name executed on device. For state parsed active connection to remote host is not required.
+
+
+ + +Notes +----- + +.. note:: + - Tested against vyos 1.1.8 + - This module works with connection ``network_cli``. + - The Configuration defaults of the Vyos network devices are supposed to hinder idempotent behavior of plays + + + +Examples +-------- + +.. code-block:: yaml + + # Using state: merged + # Before state: + # ------------- + # test#show configuration commands | grep host-name + # set system host-name 'vyostest' + # Merged play: + # ------------ + - name: Apply the provided configuration + vyos.vyos.vyos_hostname: + config: + hostname: vyos + state: merged + # Commands Fired: + # --------------- + # "commands": [ + # "hostname vyos", + # ], + # After state: + # ------------ + # test#show configuration commands | grep host-name + # set system host-name 'vyos' + + # Using state: deleted + # Before state: + # ------------- + # test#show configuration commands | grep host-name + # set system host-name 'vyos' + # Deleted play: + # ------------- + - name: Remove all existing configuration + vyos.vyos.vyos_hostname: + state: deleted + # Commands Fired: + # --------------- + # "commands": [ + # "no hostname vyosTest", + # ], + # After state: + # ------------ + # test#show configuration commands | grep host-name + + # Using state: overridden + # Before state: + # ------------- + # test#show configuration commands | grep host-name + # set system host-name 'vyos' + # Overridden play: + # ---------------- + - name: Override commands with provided configuration + vyos.vyos.vyos_hostname: + config: + hostname: vyosTest + state: overridden + # Commands Fired: + # --------------- + # "commands": [ + # "hostname vyosTest", + # ], + # After state: + # ------------ + # test#show configuration commands | grep host-name + # set system host-name 'vyosTest' + + # Using state: replaced + # Before state: + # ------------- + # test#show configuration commands | grep host-name + # set system host-name 'vyosTest' + # Replaced play: + # -------------- + - name: Replace commands with provided configuration + vyos.vyos.vyos_hostname: + config: + hostname: vyos + state: replaced + # After state: + # ------------ + # test#show configuration commands | grep host-name + # set system host-name 'vyos' + + # Using state: gathered + # Before state: + # ------------- + #test#show configuration commands | grep host-name + # set system host-name 'vyos' + # Gathered play: + # -------------- + - name: Gather listed hostname config + vyos.vyos.vyos_hostname: + state: gathered + # Module Execution Result: + # ------------------------ + # "gathered": { + # "hostname": "vyos" + # }, + + # Using state: rendered + # Rendered play: + # -------------- + - name: Render the commands for provided configuration + vyos.vyos.vyos_hostname: + config: + hostname: vyosTest + state: rendered + # Module Execution Result: + # ------------------------ + # "rendered": [ + # "set system host-name vyosTest", + # ] + + # Using state: parsed + # File: parsed.cfg + # ---------------- + # set system host-name 'vyos' + # Parsed play: + # ------------ + - name: Parse the provided configuration with the existing running configuration + vyos.vyos.vyos_hostname: + running_config: "{{ lookup('file', 'parsed.cfg') }}" + state: parsed + # Module Execution Result: + # ------------------------ + # "parsed": { + # "hostname": "vyos" + # } + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this module: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyReturnedDescription
+
+ after + +
+ dictionary +
+
when changed +
The resulting configuration after module execution.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ before + +
+ dictionary +
+
when state is merged, replaced, overridden, deleted or purged +
The configuration prior to the module execution.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ commands + +
+ list +
+
when state is merged, replaced, overridden, deleted or purged +
The set of commands pushed to the remote device.
+
+
Sample:
+
['sample command 1', 'sample command 2', 'sample command 3']
+
+
+ gathered + +
+ list +
+
when state is gathered +
Facts about the network resource gathered from the remote device as structured data.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ parsed + +
+ list +
+
when state is parsed +
The device native config provided in running_config option parsed into structured data as per module argspec.
+
+
Sample:
+
This output will always be in the same format as the module argspec.
+
+
+ rendered + +
+ list +
+
when state is rendered +
The provided configuration in the task rendered in device-native format (offline).
+
+
Sample:
+
['sample command 1', 'sample command 2', 'sample command 3']
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Gomathi Selvi Srinivasan (@GomathiselviS) diff --git a/meta/runtime.yml b/meta/runtime.yml index 73ba6a2..814c20b 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1,252 +1,258 @@ --- requires_ansible: ">=2.9.10" plugin_routing: action: vyos_banner: redirect: vyos.vyos.vyos banner: redirect: vyos.vyos.vyos vyos_bgp_global: redirect: vyos.vyos.vyos bgp_global: redirect: vyos.vyos.vyos vyos_bgp_address_family: redirect: vyos.vyos.vyos bgp_address_family: redirect: vyos.vyos.vyos vyos_command: redirect: vyos.vyos.vyos command: redirect: vyos.vyos.vyos vyos_config: redirect: vyos.vyos.vyos config: redirect: vyos.vyos.vyos vyos_facts: redirect: vyos.vyos.vyos facts: redirect: vyos.vyos.vyos vyos_firewall_global: redirect: vyos.vyos.vyos firewall_global: redirect: vyos.vyos.vyos vyos_firewall_interfaces: redirect: vyos.vyos.vyos firewall_interfaces: redirect: vyos.vyos.vyos vyos_firewall_rules: redirect: vyos.vyos.vyos firewall_rules: redirect: vyos.vyos.vyos + vyos_hostname: + redirect: vyos.vyos.vyos + hostname: + redirect: vyos.vyos.vyos vyos_interface: redirect: vyos.vyos.vyos interface: redirect: vyos.vyos.vyos vyos_interfaces: redirect: vyos.vyos.vyos interfaces: redirect: vyos.vyos.vyos vyos_l3_interface: redirect: vyos.vyos.vyos l3_interface: redirect: vyos.vyos.vyos vyos_l3_interfaces: redirect: vyos.vyos.vyos l3_interfaces: redirect: vyos.vyos.vyos vyos_lag_interfaces: redirect: vyos.vyos.vyos lag_interfaces: redirect: vyos.vyos.vyos vyos_linkagg: redirect: vyos.vyos.vyos linkagg: redirect: vyos.vyos.vyos vyos_lldp: redirect: vyos.vyos.vyos lldp: redirect: vyos.vyos.vyos vyos_lldp_global: redirect: vyos.vyos.vyos lldp_global: redirect: vyos.vyos.vyos vyos_lldp_interface: redirect: vyos.vyos.vyos lldp_interface: redirect: vyos.vyos.vyos vyos_lldp_interfaces: redirect: vyos.vyos.vyos lldp_interfaces: redirect: vyos.vyos.vyos vyos_logging: redirect: vyos.vyos.vyos vyos_logging_global: redirect: vyos.vyos.vyos logging_global: redirect: vyos.vyos.vyos logging: redirect: vyos.vyos.vyos vyos_ntp_global: redirect: vyos.vyos.vyos ntp_global: redirect: vyos.vyos.vyos vyos_ospfv2: redirect: vyos.vyos.vyos ospfv2: redirect: vyos.vyos.vyos vyos_ospfv3: redirect: vyos.vyos.vyos ospfv3: redirect: vyos.vyos.vyos vyos_ospf_interfaces: redirect: vyos.vyos.vyos ospf_interfaces: redirect: vyos.vyos.vyos vyos_ping: redirect: vyos.vyos.vyos ping: redirect: vyos.vyos.vyos vyos_prefix_lists: redirect: vyos.vyos.vyos prefix_lists: redirect: vyos.vyos.vyos vyos_snmp_server: redirect: vyos.vyos.vyos snmp_server: redirect: vyos.vyos.vyos vyos_static_route: redirect: vyos.vyos.vyos static_route: redirect: vyos.vyos.vyos vyos_static_routes: redirect: vyos.vyos.vyos static_routes: redirect: vyos.vyos.vyos vyos_system: redirect: vyos.vyos.vyos system: redirect: vyos.vyos.vyos vyos_user: redirect: vyos.vyos.vyos user: redirect: vyos.vyos.vyos vyos_vlan: redirect: vyos.vyos.vyos vlan: redirect: vyos.vyos.vyos modules: banner: redirect: vyos.vyos.vyos_banner bgp_global: redirect: vyos.vyos.vyos_bgp_global bgp_address_family: redirect: vyos.vyos.vyos_bgp_address_family command: redirect: vyos.vyos.vyos_command config: redirect: vyos.vyos.vyos_config facts: redirect: vyos.vyos.vyos_facts firewall_global: redirect: vyos.vyos.vyos_firewall_global firewall_interfaces: redirect: vyos.vyos.vyos_firewall_interfaces firewall_rules: redirect: vyos.vyos.vyos_firewall_rules + hostname: + redirect: vyos.vyos.vyos_hostname interface: redirect: vyos.vyos.vyos_interface deprecation: removal_date: "2022-06-01" warning_text: See the plugin documentation for more details vyos_interface: deprecation: removal_date: "2022-06-01" warning_text: See the plugin documentation for more details interfaces: redirect: vyos.vyos.vyos_interfaces l3_interface: redirect: vyos.vyos.vyos_l3_interface deprecation: removal_date: "2022-06-01" warning_text: See the plugin documentation for more details vyos_l3_interface: deprecation: removal_date: "2022-06-01" warning_text: See the plugin documentation for more details l3_interfaces: redirect: vyos.vyos.vyos_l3_interfaces lag_interfaces: redirect: vyos.vyos.vyos_lag_interfaces linkagg: redirect: vyos.vyos.vyos_linkagg deprecation: removal_date: "2022-06-01" warning_text: See the plugin documentation for more details vyos_linkagg: deprecation: removal_date: "2022-06-01" warning_text: See the plugin documentation for more details lldp: redirect: vyos.vyos.vyos_lldp deprecation: removal_date: "2022-06-01" warning_text: See the plugin documentation for more details vyos_lldp: deprecation: removal_date: "2022-06-01" warning_text: See the plugin documentation for more details lldp_global: redirect: vyos.vyos.vyos_lldp_global lldp_interface: redirect: vyos.vyos.vyos_lldp_interface deprecation: removal_date: "2022-06-01" warning_text: See the plugin documentation for more details vyos_lldp_interface: deprecation: removal_date: "2022-06-01" warning_text: See the plugin documentation for more details lldp_interfaces: redirect: vyos.vyos.vyos_lldp_interfaces logging: redirect: vyos.vyos.vyos_logging deprecation: removal_date: '2023-08-01' warning_text: See the plugin documentation for more details vyos_logging: deprecation: removal_date: '2023-08-01' warning_text: See the plugin documentation for more details logging_global: redirect: vyos.vyos.vyos_logging_global ntp_global: redirect: vyos.vyos.vyos_ntp_global ospfv2: redirect: vyos.vyos.vyos_ospfv2 ospfv3: redirect: vyos.vyos.vyos_ospfv3 ospf_interfaces: redirect: vyos.vyos.vyos_ospf_interfaces ping: redirect: vyos.vyos.vyos_ping prefix_lists: redirect: vyos.vyos.vyos_prefix_lists snmp_server: redirect: vyos.vyos.vyos_snmp_servers static_route: redirect: vyos.vyos.vyos_static_route deprecation: removal_date: "2022-06-01" warning_text: See the plugin documentation for more details vyos_static_route: deprecation: removal_date: "2022-06-01" warning_text: See the plugin documentation for more details static_routes: redirect: vyos.vyos.vyos_static_routes system: redirect: vyos.vyos.vyos_system user: redirect: vyos.vyos.vyos_user vlan: redirect: vyos.vyos.vyos_vlan diff --git a/plugins/module_utils/network/vyos/argspec/hostname/__init__.py b/plugins/module_utils/network/vyos/argspec/hostname/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/module_utils/network/vyos/argspec/hostname/hostname.py b/plugins/module_utils/network/vyos/argspec/hostname/hostname.py new file mode 100644 index 0000000..1a3cf91 --- /dev/null +++ b/plugins/module_utils/network/vyos/argspec/hostname/hostname.py @@ -0,0 +1,49 @@ +# -*- 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_hostname module +""" + + +class HostnameArgs(object): # pylint: disable=R0903 + """The arg spec for the vyos_hostname module""" + + argument_spec = { + "config": {"type": "dict", "options": {"hostname": {"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/hostname/__init__.py b/plugins/module_utils/network/vyos/config/hostname/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/module_utils/network/vyos/config/hostname/hostname.py b/plugins/module_utils/network/vyos/config/hostname/hostname.py new file mode 100644 index 0000000..cf2c8c2 --- /dev/null +++ b/plugins/module_utils/network/vyos/config/hostname/hostname.py @@ -0,0 +1,75 @@ +# +# -*- 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_hostname config file. +It is in this file where the current configuration (as dict) +is compared to the provided configuration (as dict) and the command set +necessary to bring the current configuration to its desired end-state is +created. +""" + +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.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.hostname import ( + HostnameTemplate, +) + + +class Hostname(ResourceModule): + """ + The vyos_hostname config class + """ + + def __init__(self, module): + super(Hostname, self).__init__( + empty_fact_val={}, + facts_module=Facts(module), + module=module, + resource="hostname", + tmplt=HostnameTemplate(), + ) + self.parsers = [] + + def execute_module(self): + """Execute the module + + :rtype: A dictionary + :returns: The result from module execution + """ + if self.state not in ["parsed", "gathered"]: + self.generate_commands() + self.run_commands() + return self.result + + def generate_commands(self): + """Generate configuration commands to send based on + want, have and desired state. + """ + wantd = self.want + haved = self.have + + if self.state == "deleted": + wantd = {} + + self._compare(want=wantd, have=haved) + + 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 Hostname network resource. + """ + self.compare(parsers="hostname", want=want, have=have) diff --git a/plugins/module_utils/network/vyos/facts/facts.py b/plugins/module_utils/network/vyos/facts/facts.py index 76cfd90..867c427 100644 --- a/plugins/module_utils/network/vyos/facts/facts.py +++ b/plugins/module_utils/network/vyos/facts/facts.py @@ -1,131 +1,135 @@ # Copyright 2019 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) """ 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.ansible.netcommon.plugins.module_utils.network.common.facts.facts import ( FactsBase, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.interfaces.interfaces import ( InterfacesFacts, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.l3_interfaces.l3_interfaces import ( L3_interfacesFacts, ) 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.lldp_interfaces.lldp_interfaces import ( Lldp_interfacesFacts, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.firewall_rules.firewall_rules import ( Firewall_rulesFacts, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.static_routes.static_routes import ( Static_routesFacts, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.firewall_global.firewall_global import ( Firewall_globalFacts, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.firewall_interfaces.firewall_interfaces import ( Firewall_interfacesFacts, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv3.ospfv3 import ( Ospfv3Facts, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv2.ospfv2 import ( Ospfv2Facts, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospf_interfaces.ospf_interfaces import ( Ospf_interfacesFacts, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.bgp_global.bgp_global import ( Bgp_globalFacts, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.bgp_address_family.bgp_address_family import ( Bgp_address_familyFacts, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.route_maps.route_maps import ( Route_mapsFacts, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.prefix_lists.prefix_lists import ( Prefix_listsFacts, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.logging_global.logging_global import ( Logging_globalFacts, ) 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.hostname.hostname import ( + HostnameFacts, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base import ( Default, Neighbors, Config, ) FACT_LEGACY_SUBSETS = dict(default=Default, neighbors=Neighbors, config=Config) FACT_RESOURCE_SUBSETS = dict( interfaces=InterfacesFacts, l3_interfaces=L3_interfacesFacts, lag_interfaces=Lag_interfacesFacts, lldp_global=Lldp_globalFacts, lldp_interfaces=Lldp_interfacesFacts, static_routes=Static_routesFacts, firewall_rules=Firewall_rulesFacts, firewall_global=Firewall_globalFacts, firewall_interfaces=Firewall_interfacesFacts, ospfv3=Ospfv3Facts, ospfv2=Ospfv2Facts, ospf_interfaces=Ospf_interfacesFacts, bgp_global=Bgp_globalFacts, bgp_address_family=Bgp_address_familyFacts, route_maps=Route_mapsFacts, prefix_lists=Prefix_listsFacts, logging_global=Logging_globalFacts, ntp_global=Ntp_globalFacts, snmp_server=Snmp_serverFacts, + hostname=HostnameFacts, ) class Facts(FactsBase): """The fact class for vyos""" VALID_LEGACY_GATHER_SUBSETS = frozenset(FACT_LEGACY_SUBSETS.keys()) VALID_RESOURCE_SUBSETS = frozenset(FACT_RESOURCE_SUBSETS.keys()) def __init__(self, module): super(Facts, self).__init__(module) def get_facts( self, legacy_facts_type=None, resource_facts_type=None, data=None ): """Collect the facts for vyos :param legacy_facts_type: List of legacy facts types :param resource_facts_type: List of resource fact types :param data: previously collected conf :rtype: dict :return: the facts gathered """ if self.VALID_RESOURCE_SUBSETS: self.get_network_resources_facts( FACT_RESOURCE_SUBSETS, resource_facts_type, data ) if self.VALID_LEGACY_GATHER_SUBSETS: self.get_network_legacy_facts( FACT_LEGACY_SUBSETS, legacy_facts_type ) return self.ansible_facts, self._warnings diff --git a/plugins/module_utils/network/vyos/facts/hostname/__init__.py b/plugins/module_utils/network/vyos/facts/hostname/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/module_utils/network/vyos/facts/hostname/hostname.py b/plugins/module_utils/network/vyos/facts/hostname/hostname.py new file mode 100644 index 0000000..acdddca --- /dev/null +++ b/plugins/module_utils/network/vyos/facts/hostname/hostname.py @@ -0,0 +1,76 @@ +# -*- 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 hostname fact class +It is in this file the configuration is collected from the device +for a given resource, parsed, and the facts tree is populated +based on the configuration. +""" + +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( + utils, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.hostname import ( + HostnameTemplate, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.hostname.hostname import ( + HostnameArgs, +) + +import re + + +class HostnameFacts(object): + """The vyos hostname facts class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = HostnameArgs.argument_spec + + def get_config(self, connection): + return connection.get("show configuration commands | grep host-name") + + 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 Hostname template + hostname_parser = HostnameTemplate( + lines=config_lines, module=self._module + ) + objs = hostname_parser.parse() + + ansible_facts["ansible_network_resources"].pop("hostname", None) + + params = utils.remove_empties( + hostname_parser.validate_config( + self.argument_spec, {"config": objs}, redact=True + ) + ) + + facts["hostname"] = params.get("config", {}) + ansible_facts["ansible_network_resources"].update(facts) + + return ansible_facts diff --git a/plugins/module_utils/network/vyos/rm_templates/hostname.py b/plugins/module_utils/network/vyos/rm_templates/hostname.py new file mode 100644 index 0000000..79caee6 --- /dev/null +++ b/plugins/module_utils/network/vyos/rm_templates/hostname.py @@ -0,0 +1,47 @@ +# -*- 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 Hostname parser templates file. This contains +a list of parser definitions and associated functions that +facilitates both facts gathering and native command generation for +the given network resource. +""" + +import re +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import ( + NetworkTemplate, +) + + +class HostnameTemplate(NetworkTemplate): + def __init__(self, lines=None, module=None): + prefix = {"set": "set", "remove": "delete"} + super(HostnameTemplate, self).__init__( + lines=lines, tmplt=self, prefix=prefix, module=module + ) + + # fmt: off + PARSERS = [ + # service snmp community <> + { + "name": "hostname", + "getval": re.compile( + r""" + ^set\ssystem\shost-name + \s+(?P\S+) + $""", + re.VERBOSE), + "setval": "system host-name {{ hostname }}", + "result": { + "hostname": "{{ name }}" + } + }, + ] + # fmt: on diff --git a/plugins/modules/vyos_hostname.py b/plugins/modules/vyos_hostname.py new file mode 100644 index 0000000..da22f41 --- /dev/null +++ b/plugins/modules/vyos_hostname.py @@ -0,0 +1,284 @@ +#!/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_hostname +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = """ +module: vyos_hostname +version_added: 2.8.0 +short_description: Manages hostname resource module +description: This module manages the hostname attribute 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: Hostname configuration. + type: dict + suboptions: + hostname: + description: set hostname for VYOS. + type: str + running_config: + description: + - This option is used only with state I(parsed). + - The value of this option should be the output received from the vyos device by + executing the command B("show configuration commands | grep host-name"). + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into Ansible structured data as per the resource module's argspec + and the value is then returned in the I(parsed) key within the result. + type: str + state: + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - parsed + - rendered + default: merged + description: + - The state the configuration should be left in + - The states I(rendered), I(gathered) and I(parsed) does not perform any change + on the device. + - The state I(rendered) will transform the configuration in C(config) option to + platform specific CLI commands which will be returned in the I(rendered) key + within the result. For state I(rendered) active connection to remote host is + not required. + - The states I(merged), I(replaced) and I(overridden) have identical + behaviour for this module. + - The state I(gathered) will fetch the running configuration from device and transform + it into structured data in the format as per the resource module argspec and + the value is returned in the I(gathered) key within the result. + - The state I(parsed) reads the configuration from C(running_config) option and + transforms it into JSON format as per the resource module parameters and the + value is returned in the I(parsed) key within the result. The value of C(running_config) + option should be the same format as the output of command + I(show configuration commands | grep host-name) executed on device. For state I(parsed) active + connection to remote host is not required. + type: str +""" + +EXAMPLES = """ +# Using state: merged +# Before state: +# ------------- +# test#show configuration commands | grep host-name +# set system host-name 'vyostest' +# Merged play: +# ------------ +- name: Apply the provided configuration + vyos.vyos.vyos_hostname: + config: + hostname: vyos + state: merged +# Commands Fired: +# --------------- +# "commands": [ +# "hostname vyos", +# ], +# After state: +# ------------ +# test#show configuration commands | grep host-name +# set system host-name 'vyos' + +# Using state: deleted +# Before state: +# ------------- +# test#show configuration commands | grep host-name +# set system host-name 'vyos' +# Deleted play: +# ------------- +- name: Remove all existing configuration + vyos.vyos.vyos_hostname: + state: deleted +# Commands Fired: +# --------------- +# "commands": [ +# "no hostname vyosTest", +# ], +# After state: +# ------------ +# test#show configuration commands | grep host-name + +# Using state: overridden +# Before state: +# ------------- +# test#show configuration commands | grep host-name +# set system host-name 'vyos' +# Overridden play: +# ---------------- +- name: Override commands with provided configuration + vyos.vyos.vyos_hostname: + config: + hostname: vyosTest + state: overridden +# Commands Fired: +# --------------- +# "commands": [ +# "hostname vyosTest", +# ], +# After state: +# ------------ +# test#show configuration commands | grep host-name +# set system host-name 'vyosTest' + +# Using state: replaced +# Before state: +# ------------- +# test#show configuration commands | grep host-name +# set system host-name 'vyosTest' +# Replaced play: +# -------------- +- name: Replace commands with provided configuration + vyos.vyos.vyos_hostname: + config: + hostname: vyos + state: replaced +# After state: +# ------------ +# test#show configuration commands | grep host-name +# set system host-name 'vyos' + +# Using state: gathered +# Before state: +# ------------- +#test#show configuration commands | grep host-name +# set system host-name 'vyos' +# Gathered play: +# -------------- +- name: Gather listed hostname config + vyos.vyos.vyos_hostname: + state: gathered +# Module Execution Result: +# ------------------------ +# "gathered": { +# "hostname": "vyos" +# }, + +# Using state: rendered +# Rendered play: +# -------------- +- name: Render the commands for provided configuration + vyos.vyos.vyos_hostname: + config: + hostname: vyosTest + state: rendered +# Module Execution Result: +# ------------------------ +# "rendered": [ +# "set system host-name vyosTest", +# ] + +# Using state: parsed +# File: parsed.cfg +# ---------------- +# set system host-name 'vyos' +# Parsed play: +# ------------ +- name: Parse the provided configuration with the existing running configuration + vyos.vyos.vyos_hostname: + running_config: "{{ lookup('file', 'parsed.cfg') }}" + state: parsed +# Module Execution Result: +# ------------------------ +# "parsed": { +# "hostname": "vyos" +# } +""" + + +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: + - sample command 1 + - sample command 2 + - sample command 3 +rendered: + description: The provided configuration in the task rendered in device-native format (offline). + returned: when I(state) is C(rendered) + type: list + sample: + - sample command 1 + - sample command 2 + - sample command 3 +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.hostname.hostname import ( + HostnameArgs, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.hostname.hostname import ( + Hostname, +) + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + module = AnsibleModule( + argument_spec=HostnameArgs.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 = Hostname(module).execute_module() + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/tests/integration/targets/vyos_hostname/defaults/main.yaml b/tests/integration/targets/vyos_hostname/defaults/main.yaml new file mode 100644 index 0000000..852a6be --- /dev/null +++ b/tests/integration/targets/vyos_hostname/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: '[^_].*' +test_items: [] diff --git a/tests/integration/targets/vyos_hostname/meta/main.yaml b/tests/integration/targets/vyos_hostname/meta/main.yaml new file mode 100644 index 0000000..91da2a7 --- /dev/null +++ b/tests/integration/targets/vyos_hostname/meta/main.yaml @@ -0,0 +1,2 @@ +--- +... diff --git a/tests/integration/targets/vyos_hostname/tasks/cli.yaml b/tests/integration/targets/vyos_hostname/tasks/cli.yaml new file mode 100644 index 0000000..93eb2fe --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tasks/cli.yaml @@ -0,0 +1,19 @@ +--- +- name: Collect all cli test cases + find: + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' + use_regex: true + register: test_cases + delegate_to: localhost + +- name: Set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }}' + vars: + ansible_connection: ansible.netcommon.network_cli + with_items: '{{ test_items }}' + loop_control: + loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_hostname/tasks/main.yaml b/tests/integration/targets/vyos_hostname/tasks/main.yaml new file mode 100644 index 0000000..b957d2f --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tasks/main.yaml @@ -0,0 +1,4 @@ +--- +- include: cli.yaml + tags: + - network_cli diff --git a/tests/integration/targets/vyos_hostname/tests/cli/_parsed.cfg b/tests/integration/targets/vyos_hostname/tests/cli/_parsed.cfg new file mode 100644 index 0000000..3353c40 --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tests/cli/_parsed.cfg @@ -0,0 +1 @@ +set system host-name 'vyosTest' diff --git a/tests/integration/targets/vyos_hostname/tests/cli/_populate_config.yaml b/tests/integration/targets/vyos_hostname/tests/cli/_populate_config.yaml new file mode 100644 index 0000000..4d33289 --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tests/cli/_populate_config.yaml @@ -0,0 +1,8 @@ +--- +- name: setup + vyos.vyos.vyos_config: + lines: + - set system host-name 'vyos' + ignore_errors: true + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/tests/integration/targets/vyos_hostname/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_hostname/tests/cli/_remove_config.yaml new file mode 100644 index 0000000..229c79c --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tests/cli/_remove_config.yaml @@ -0,0 +1,8 @@ +--- +- name: Remove pre-existing hostname config + vyos.vyos.vyos_hostname: + config: + state: deleted + ignore_errors: true + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/tests/integration/targets/vyos_hostname/tests/cli/deleted.yaml b/tests/integration/targets/vyos_hostname/tests/cli/deleted.yaml new file mode 100644 index 0000000..5f9df51 --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tests/cli/deleted.yaml @@ -0,0 +1,40 @@ +--- +- debug: + msg: START vyos_hostname deleted integration tests on connection={{ansible_connection }} + +- include_tasks: _remove_config.yaml + +- include_tasks: _populate_config.yaml + +- block: + + - name: Delete the provided configuration + register: result + vyos.vyos.vyos_hostname: &id001 + config: + state: deleted + + - name: Assert that before dicts were correctly generated + assert: + that: + - result.changed == true + - result.commands == deleted.commands + + - name: Assert that the after dicts were correctly generated + assert: + that: + - result.after == {} + + - name: Delete the existing configuration with the provided running configuration + (IDEMPOTENT) + register: result + vyos.vyos.vyos_hostname: *id001 + + - name: Assert that the previous task was idempotent + assert: + that: + - result['changed'] == false + + always: + + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_hostname/tests/cli/empty_config.yaml b/tests/integration/targets/vyos_hostname/tests/cli/empty_config.yaml new file mode 100644 index 0000000..8efead2 --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tests/cli/empty_config.yaml @@ -0,0 +1,60 @@ +--- +- debug: + msg: START vyos_hostname empty_config integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + vyos.vyos.vyos_hostname: + config: + state: merged + +- assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + vyos.vyos.vyos_hostname: + config: + state: replaced + +- assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true + vyos.vyos.vyos_hostname: + config: + state: overridden + +- assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Parsed with empty running_config should give appropriate error message + register: result + ignore_errors: true + vyos.vyos.vyos_hostname: + running_config: + state: parsed + +- assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + vyos.vyos.vyos_hostname: + config: + state: rendered + +- assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' diff --git a/tests/integration/targets/vyos_hostname/tests/cli/gathered.yaml b/tests/integration/targets/vyos_hostname/tests/cli/gathered.yaml new file mode 100644 index 0000000..0509fc5 --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tests/cli/gathered.yaml @@ -0,0 +1,28 @@ +--- +- debug: + msg: START vyos_hostname gathered integration tests on connection={{ + ansible_connection }} + +- include_tasks: _remove_config.yaml + +- include_tasks: _populate_config.yaml + +- block: + + - name: Gather config from the device in structured format. + register: result + vyos.vyos.vyos_hostname: + state: gathered + + - vyos.vyos.vyos_facts: + gather_network_resources: hostname + + - name: Assert that facts are correctly generated + assert: + that: + - result.changed == false + - result.gathered == ansible_facts['network_resources']['hostname'] + + always: + + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_hostname/tests/cli/merged.yaml b/tests/integration/targets/vyos_hostname/tests/cli/merged.yaml new file mode 100644 index 0000000..f9b28c7 --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tests/cli/merged.yaml @@ -0,0 +1,45 @@ +--- +- debug: + msg: START vyos_hostname merged integration tests on connection={{ + ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + register: result + vyos.vyos.vyos_hostname: &id001 + config: + hostname: "vyosTest" + state: merged + + - vyos.vyos.vyos_facts: + gather_network_resources: hostname + + - assert: + that: + - result.commands|length == 1 + - result.changed == true + - result.commands|symmetric_difference(merged.commands) == [] + - result.after == ansible_facts['network_resources']['hostname'] + - result.after == merged.after + + + - name: Assert that before dicts were correctly generated + assert: + that: + - result.before == {} + + - name: + Merge the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + vyos.vyos.vyos_hostname: *id001 + + - name: Assert that the previous task was idempotent + assert: + that: + - result['changed'] == false + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_hostname/tests/cli/overridden.yaml b/tests/integration/targets/vyos_hostname/tests/cli/overridden.yaml new file mode 100644 index 0000000..d9fd76d --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tests/cli/overridden.yaml @@ -0,0 +1,42 @@ +--- +- debug: + msg: START vyos_hostname overridden integration tests on connection={{ + ansible_connection }} + +- include_tasks: _remove_config.yaml + +- include_tasks: _populate_config.yaml + +- block: + - name: override the provided configuration with the existing running configuration + register: result + vyos.vyos.vyos_hostname: &id001 + config: + hostname: "vyosTest" + state: overridden + + - vyos.vyos.vyos_facts: + gather_network_resources: hostname + + - assert: + that: + - result.commands|length == 1 + - result.changed == true + - result.commands|symmetric_difference(merged.commands) == [] + - result.after == ansible_facts['network_resources']['hostname'] + - result.after == merged.after + + + - name: + override the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + vyos.vyos.vyos_hostname: *id001 + + - name: Assert that the previous task was idempotent + assert: + that: + - result['changed'] == false + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_hostname/tests/cli/parsed.yaml b/tests/integration/targets/vyos_hostname/tests/cli/parsed.yaml new file mode 100644 index 0000000..f6c00bb --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tests/cli/parsed.yaml @@ -0,0 +1,17 @@ +--- +- debug: + msg: START vyos_hostname parsed integration tests on connection={{ ansible_connection + }} + +- name: Provide the running configuration for parsing (config to be parsed) + register: result + vyos.vyos.vyos_hostname: + running_config: "{{ lookup('file', '_parsed.cfg') }}" + state: parsed + + +- name: Assert that config was correctly parsed + assert: + that: + - result.changed == false + - result.parsed == merged.after diff --git a/tests/integration/targets/vyos_hostname/tests/cli/rendered.yaml b/tests/integration/targets/vyos_hostname/tests/cli/rendered.yaml new file mode 100644 index 0000000..28ec797 --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tests/cli/rendered.yaml @@ -0,0 +1,21 @@ +--- +- debug: + msg: START vyos_hostname rendered integration tests on connection={{ + ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + - name: Render the given configuration in the form of native commands + register: result + vyos.vyos.vyos_hostname: + config: + hostname: 'vyosTest' + state: rendered + + - assert: + that: + - result.changed == false + - result.rendered|symmetric_difference(merged.commands) == [] + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_hostname/tests/cli/replaced.yaml b/tests/integration/targets/vyos_hostname/tests/cli/replaced.yaml new file mode 100644 index 0000000..6acb993 --- /dev/null +++ b/tests/integration/targets/vyos_hostname/tests/cli/replaced.yaml @@ -0,0 +1,42 @@ +--- +- debug: + msg: START vyos_hostname replaced integration tests on connection={{ + ansible_connection }} + +- include_tasks: _remove_config.yaml + +- include_tasks: _populate_config.yaml + +- block: + - name: Replace the provided configuration with the existing running configuration + register: result + vyos.vyos.vyos_hostname: &id001 + config: + hostname: "vyosTest" + state: replaced + + - vyos.vyos.vyos_facts: + gather_network_resources: hostname + + - assert: + that: + - result.commands|length == 1 + - result.changed == true + - result.commands|symmetric_difference(merged.commands) == [] + - result.after == ansible_facts['network_resources']['hostname'] + - result.after == merged.after + + + - name: + Replace the provided configuration with the existing running configuration + (IDEMPOTENT) + register: result + vyos.vyos.vyos_hostname: *id001 + + - name: Assert that the previous task was idempotent + assert: + that: + - result['changed'] == false + + always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_hostname/vars/main.yaml b/tests/integration/targets/vyos_hostname/vars/main.yaml new file mode 100644 index 0000000..a6b4986 --- /dev/null +++ b/tests/integration/targets/vyos_hostname/vars/main.yaml @@ -0,0 +1,12 @@ +--- +merged: + before: {} + commands: + - set system host-name vyosTest + after: + hostname: 'vyosTest' + +deleted: + commands: + - delete system host-name vyos + after: {} diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_hostname_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_hostname_config.cfg new file mode 100644 index 0000000..f94f7eb --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_hostname_config.cfg @@ -0,0 +1 @@ +set system host-name 'vyos_test' diff --git a/tests/unit/modules/network/vyos/test_vyos_hostname.py b/tests/unit/modules/network/vyos/test_vyos_hostname.py new file mode 100644 index 0000000..8c2fdfb --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_hostname.py @@ -0,0 +1,134 @@ +# (c) 2021 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +from ansible_collections.vyos.vyos.tests.unit.compat.mock import patch +from ansible_collections.vyos.vyos.plugins.modules import vyos_hostname +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosHostnameModule(TestVyosModule): + + module = vyos_hostname + + def setUp(self): + super(TestVyosHostnameModule, self).setUp() + + self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection" + ) + self.get_resource_connection_config = ( + self.mock_get_resource_connection_config.start() + ) + + self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection" + ) + self.get_resource_connection_facts = ( + self.mock_get_resource_connection_facts.start() + ) + + self.mock_execute_show_command = patch( + "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.hostname.hostname.HostnameFacts.get_config" + ) + + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestVyosHostnameModule, self).tearDown() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_execute_show_command.stop() + + def load_fixtures(self, commands=None, transport="cli", filename=None): + if filename is None: + filename = "vyos_hostname_config.cfg" + + def load_from_file(*args, **kwargs): + output = load_fixture(filename) + return output + + self.execute_show_command.side_effect = load_from_file + + def test_vyos_hostname_merged_idempotent(self): + set_module_args(dict(config=dict(hostname="vyos_test"))) + self.execute_module(changed=False, commands=[]) + + def test_vyos_hostname_replaced_idempotent(self): + set_module_args( + dict(config=dict(hostname="vyos_test"), state="replaced") + ) + self.execute_module(changed=False, commands=[]) + + def test_vyos_hostname_overridden_idempotent(self): + set_module_args( + dict(config=dict(hostname="vyos_test"), state="overridden") + ) + self.execute_module(changed=False, commands=[]) + + def test_vyos_hostname_merged(self): + set_module_args(dict(config=dict(hostname="vyos"))) + self.execute_module( + changed=True, commands=["set system host-name vyos"] + ) + + def test_vyos_hostname_replaced(self): + set_module_args(dict(config=dict(hostname="vyos"), state="replaced")) + self.execute_module( + changed=True, commands=["set system host-name vyos"] + ) + + def test_vyos_hostname_overridden(self): + set_module_args(dict(config=dict(hostname="vyos"), state="overridden")) + + def test_vyos_hostname_deleted(self): + set_module_args(dict(state="deleted")) + self.execute_module( + changed=True, commands=["delete system host-name vyos_test"] + ) + + def test_vyos_hostname_gathered(self): + set_module_args(dict(state="gathered")) + result = self.execute_module( + changed=False, filename="vyos_hostname_config.cfg" + ) + gathered_list = {"hostname": "vyos_test"} + self.assertEqual(sorted(gathered_list), sorted(result["gathered"])) + + def test_vyos_hostname_parsed(self): + parsed_str = "set system host-name vyos_test" + set_module_args(dict(running_config=parsed_str, state="parsed")) + result = self.execute_module(changed=False) + parsed_list = {"hostname": "vyos_test"} + self.assertEqual(sorted(parsed_list), sorted(result["parsed"])) + + def test_vyos_hostname_rendered(self): + set_module_args( + dict(state="rendered", config=dict(hostname="vyos_test")) + ) + commands = ["set system host-name vyos_test"] + result = self.execute_module(changed=False) + self.assertEqual( + sorted(result["rendered"]), sorted(commands), result["rendered"] + )