summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--changelogs/fragments/vyos_hostname_rm.yaml3
-rw-r--r--docs/vyos.vyos.vyos_hostname_module.rst386
-rw-r--r--meta/runtime.yml6
-rw-r--r--plugins/module_utils/network/vyos/argspec/hostname/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/argspec/hostname/hostname.py49
-rw-r--r--plugins/module_utils/network/vyos/config/hostname/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/config/hostname/hostname.py75
-rw-r--r--plugins/module_utils/network/vyos/facts/facts.py4
-rw-r--r--plugins/module_utils/network/vyos/facts/hostname/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/facts/hostname/hostname.py76
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/hostname.py47
-rw-r--r--plugins/modules/vyos_hostname.py284
-rw-r--r--tests/integration/targets/vyos_hostname/defaults/main.yaml3
-rw-r--r--tests/integration/targets/vyos_hostname/meta/main.yaml2
-rw-r--r--tests/integration/targets/vyos_hostname/tasks/cli.yaml19
-rw-r--r--tests/integration/targets/vyos_hostname/tasks/main.yaml4
-rw-r--r--tests/integration/targets/vyos_hostname/tests/cli/_parsed.cfg1
-rw-r--r--tests/integration/targets/vyos_hostname/tests/cli/_populate_config.yaml8
-rw-r--r--tests/integration/targets/vyos_hostname/tests/cli/_remove_config.yaml8
-rw-r--r--tests/integration/targets/vyos_hostname/tests/cli/deleted.yaml40
-rw-r--r--tests/integration/targets/vyos_hostname/tests/cli/empty_config.yaml60
-rw-r--r--tests/integration/targets/vyos_hostname/tests/cli/gathered.yaml28
-rw-r--r--tests/integration/targets/vyos_hostname/tests/cli/merged.yaml45
-rw-r--r--tests/integration/targets/vyos_hostname/tests/cli/overridden.yaml42
-rw-r--r--tests/integration/targets/vyos_hostname/tests/cli/parsed.yaml17
-rw-r--r--tests/integration/targets/vyos_hostname/tests/cli/rendered.yaml21
-rw-r--r--tests/integration/targets/vyos_hostname/tests/cli/replaced.yaml42
-rw-r--r--tests/integration/targets/vyos_hostname/vars/main.yaml12
-rw-r--r--tests/unit/modules/network/vyos/fixtures/vyos_hostname_config.cfg1
-rw-r--r--tests/unit/modules/network/vyos/test_vyos_hostname.py134
31 files changed, 1418 insertions, 0 deletions
diff --git a/README.md b/README.md
index f37e259..cf2c9ba 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,7 @@ Name | Description
[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
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
+
+ <table border=0 cellpadding=0 class="documentation-table">
+ <tr>
+ <th colspan="2">Parameter</th>
+ <th>Choices/<font color="blue">Defaults</font></th>
+ <th width="100%">Comments</th>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>config</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>Hostname configuration.</div>
+ </td>
+ </tr>
+ <tr>
+ <td class="elbow-placeholder"></td>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>hostname</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>set hostname for VYOS.</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>running_config</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ </td>
+ <td>
+ <div>This option is used only with state <em>parsed</em>.</div>
+ <div>The value of this option should be the output received from the vyos device by executing the command <b>&quot;show configuration commands | grep host-name&quot;</b>.</div>
+ <div>The state <em>parsed</em> reads the configuration from <code>running_config</code> option and transforms it into Ansible structured data as per the resource module&#x27;s argspec and the value is then returned in the <em>parsed</em> key within the result.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div class="ansibleOptionAnchor" id="parameter-"></div>
+ <b>state</b>
+ <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
+ <div style="font-size: small">
+ <span style="color: purple">string</span>
+ </div>
+ </td>
+ <td>
+ <ul style="margin: 0; padding: 0"><b>Choices:</b>
+ <li><div style="color: blue"><b>merged</b>&nbsp;&larr;</div></li>
+ <li>replaced</li>
+ <li>overridden</li>
+ <li>deleted</li>
+ <li>gathered</li>
+ <li>parsed</li>
+ <li>rendered</li>
+ </ul>
+ </td>
+ <td>
+ <div>The state the configuration should be left in</div>
+ <div>The states <em>rendered</em>, <em>gathered</em> and <em>parsed</em> does not perform any change on the device.</div>
+ <div>The state <em>rendered</em> will transform the configuration in <code>config</code> option to platform specific CLI commands which will be returned in the <em>rendered</em> key within the result. For state <em>rendered</em> active connection to remote host is not required.</div>
+ <div>The states <em>merged</em>, <em>replaced</em> and <em>overridden</em> have identical behaviour for this module.</div>
+ <div>The state <em>gathered</em> 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 <em>gathered</em> key within the result.</div>
+ <div>The state <em>parsed</em> reads the configuration from <code>running_config</code> option and transforms it into JSON format as per the resource module parameters and the value is returned in the <em>parsed</em> key within the result. The value of <code>running_config</code> option should be the same format as the output of command <em>show configuration commands | grep host-name</em> executed on device. For state <em>parsed</em> active connection to remote host is not required.</div>
+ </td>
+ </tr>
+ </table>
+ <br/>
+
+
+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 <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
+
+.. raw:: html
+
+ <table border=0 cellpadding=0 class="documentation-table">
+ <tr>
+ <th colspan="1">Key</th>
+ <th>Returned</th>
+ <th width="100%">Description</th>
+ </tr>
+ <tr>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="return-"></div>
+ <b>after</b>
+ <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>when changed</td>
+ <td>
+ <div>The resulting configuration after module execution.</div>
+ <br/>
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">This output will always be in the same format as the module argspec.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="return-"></div>
+ <b>before</b>
+ <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
+ <div style="font-size: small">
+ <span style="color: purple">dictionary</span>
+ </div>
+ </td>
+ <td>when <em>state</em> is <code>merged</code>, <code>replaced</code>, <code>overridden</code>, <code>deleted</code> or <code>purged</code></td>
+ <td>
+ <div>The configuration prior to the module execution.</div>
+ <br/>
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">This output will always be in the same format as the module argspec.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="return-"></div>
+ <b>commands</b>
+ <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ </div>
+ </td>
+ <td>when <em>state</em> is <code>merged</code>, <code>replaced</code>, <code>overridden</code>, <code>deleted</code> or <code>purged</code></td>
+ <td>
+ <div>The set of commands pushed to the remote device.</div>
+ <br/>
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">[&#x27;sample command 1&#x27;, &#x27;sample command 2&#x27;, &#x27;sample command 3&#x27;]</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="return-"></div>
+ <b>gathered</b>
+ <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ </div>
+ </td>
+ <td>when <em>state</em> is <code>gathered</code></td>
+ <td>
+ <div>Facts about the network resource gathered from the remote device as structured data.</div>
+ <br/>
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">This output will always be in the same format as the module argspec.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="return-"></div>
+ <b>parsed</b>
+ <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ </div>
+ </td>
+ <td>when <em>state</em> is <code>parsed</code></td>
+ <td>
+ <div>The device native config provided in <em>running_config</em> option parsed into structured data as per module argspec.</div>
+ <br/>
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">This output will always be in the same format as the module argspec.</div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="1">
+ <div class="ansibleOptionAnchor" id="return-"></div>
+ <b>rendered</b>
+ <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
+ <div style="font-size: small">
+ <span style="color: purple">list</span>
+ </div>
+ </td>
+ <td>when <em>state</em> is <code>rendered</code></td>
+ <td>
+ <div>The provided configuration in the task rendered in device-native format (offline).</div>
+ <br/>
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">[&#x27;sample command 1&#x27;, &#x27;sample command 2&#x27;, &#x27;sample command 3&#x27;]</div>
+ </td>
+ </tr>
+ </table>
+ <br/><br/>
+
+
+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
@@ -38,6 +38,10 @@ plugin_routing:
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:
@@ -153,6 +157,8 @@ plugin_routing:
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:
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
--- /dev/null
+++ b/plugins/module_utils/network/vyos/argspec/hostname/__init__.py
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
--- /dev/null
+++ b/plugins/module_utils/network/vyos/config/hostname/__init__.py
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
@@ -70,6 +70,9 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ntp_g
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,
@@ -98,6 +101,7 @@ FACT_RESOURCE_SUBSETS = dict(
logging_global=Logging_globalFacts,
ntp_global=Ntp_globalFacts,
snmp_server=Snmp_serverFacts,
+ hostname=HostnameFacts,
)
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
--- /dev/null
+++ b/plugins/module_utils/network/vyos/facts/hostname/__init__.py
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<name>\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 <http://www.gnu.org/licenses/>.
+
+# 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"]
+ )