diff options
-rw-r--r-- | changelogs/fragments/single_user_mode.yaml | 4 | ||||
-rw-r--r-- | plugins/cliconf/vyos.py | 49 | ||||
-rw-r--r-- | plugins/terminal/vyos.py | 2 | ||||
-rw-r--r-- | tests/integration/targets/vyos_smoke/aliases | 1 | ||||
-rw-r--r-- | tests/integration/targets/vyos_smoke/defaults/main.yaml | 3 | ||||
-rw-r--r-- | tests/integration/targets/vyos_smoke/tasks/cli.yaml | 18 | ||||
-rw-r--r-- | tests/integration/targets/vyos_smoke/tasks/main.yaml | 2 | ||||
-rw-r--r-- | tests/integration/targets/vyos_smoke/tests/cli/caching.yaml | 85 |
8 files changed, 149 insertions, 15 deletions
diff --git a/changelogs/fragments/single_user_mode.yaml b/changelogs/fragments/single_user_mode.yaml new file mode 100644 index 0000000..596b899 --- /dev/null +++ b/changelogs/fragments/single_user_mode.yaml @@ -0,0 +1,4 @@ +--- +minor_changes: + - Add support for configuration caching (single_user_mode). + - Re-use device_info dictionary in cliconf. diff --git a/plugins/cliconf/vyos.py b/plugins/cliconf/vyos.py index de9e93d..c8aaff9 100644 --- a/plugins/cliconf/vyos.py +++ b/plugins/cliconf/vyos.py @@ -28,6 +28,18 @@ description: - This vyos plugin provides low level abstraction apis for sending and receiving CLI commands from VyOS network devices. version_added: 1.0.0 +options: + config_commands: + description: + - Specifies a list of commands that can make configuration changes + to the target device. + - When `ansible_network_single_user_mode` is enabled, if a command sent + to the device is present in this list, the existing cache is invalidated. + version_added: 2.0.0 + type: list + default: [] + vars: + - name: ansible_vyos_config_commands """ import re @@ -46,27 +58,34 @@ from ansible.plugins.cliconf import CliconfBase class Cliconf(CliconfBase): + def __init__(self, *args, **kwargs): + super(Cliconf, self).__init__(*args, **kwargs) + self._device_info = {} + def get_device_info(self): - device_info = {} + if not self._device_info: + device_info = {} + + device_info["network_os"] = "vyos" + reply = self.get("show version") + data = to_text(reply, errors="surrogate_or_strict").strip() - device_info["network_os"] = "vyos" - reply = self.get("show version") - data = to_text(reply, errors="surrogate_or_strict").strip() + match = re.search(r"Version:\s*(.*)", data) + if match: + device_info["network_os_version"] = match.group(1) - match = re.search(r"Version:\s*(.*)", data) - if match: - device_info["network_os_version"] = match.group(1) + match = re.search(r"HW model:\s*(\S+)", data) + if match: + device_info["network_os_model"] = match.group(1) - match = re.search(r"HW model:\s*(\S+)", data) - if match: - device_info["network_os_model"] = match.group(1) + reply = self.get("show host name") + device_info["network_os_hostname"] = to_text( + reply, errors="surrogate_or_strict" + ).strip() - reply = self.get("show host name") - device_info["network_os_hostname"] = to_text( - reply, errors="surrogate_or_strict" - ).strip() + self._device_info = device_info - return device_info + return self._device_info def get_config(self, flags=None, format=None): if format: diff --git a/plugins/terminal/vyos.py b/plugins/terminal/vyos.py index a659002..bf9d87b 100644 --- a/plugins/terminal/vyos.py +++ b/plugins/terminal/vyos.py @@ -53,6 +53,8 @@ class TerminalModule(TerminalBase): re.compile(br"\x1b]0;[^\x07]*\x07"), ] + terminal_config_prompt = re.compile(r"^.+#$") + try: terminal_length = os.getenv("ANSIBLE_VYOS_TERMINAL_LENGTH", 10000) terminal_length = int(terminal_length) diff --git a/tests/integration/targets/vyos_smoke/aliases b/tests/integration/targets/vyos_smoke/aliases new file mode 100644 index 0000000..8071e1f --- /dev/null +++ b/tests/integration/targets/vyos_smoke/aliases @@ -0,0 +1 @@ +shippable/vyos/group1 diff --git a/tests/integration/targets/vyos_smoke/defaults/main.yaml b/tests/integration/targets/vyos_smoke/defaults/main.yaml new file mode 100644 index 0000000..a845c24 --- /dev/null +++ b/tests/integration/targets/vyos_smoke/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: '*' +test_items: [] diff --git a/tests/integration/targets/vyos_smoke/tasks/cli.yaml b/tests/integration/targets/vyos_smoke/tasks/cli.yaml new file mode 100644 index 0000000..f580816 --- /dev/null +++ b/tests/integration/targets/vyos_smoke/tasks/cli.yaml @@ -0,0 +1,18 @@ +--- +- name: collect all cli test cases + find: + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' + 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 with single_user_mode (connection=network_cli) + include: '{{ test_case_to_run }} ansible_connection=network_cli ansible_network_single_user_mode=True' + with_items: '{{ test_items }}' + loop_control: + loop_var: test_case_to_run + tags: + - network_cli diff --git a/tests/integration/targets/vyos_smoke/tasks/main.yaml b/tests/integration/targets/vyos_smoke/tasks/main.yaml new file mode 100644 index 0000000..07b0f2e --- /dev/null +++ b/tests/integration/targets/vyos_smoke/tasks/main.yaml @@ -0,0 +1,2 @@ +--- +- include: cli.yaml diff --git a/tests/integration/targets/vyos_smoke/tests/cli/caching.yaml b/tests/integration/targets/vyos_smoke/tests/cli/caching.yaml new file mode 100644 index 0000000..4230bfa --- /dev/null +++ b/tests/integration/targets/vyos_smoke/tests/cli/caching.yaml @@ -0,0 +1,85 @@ +--- +- block: + - debug: msg="START connection={{ ansible_connection }} cli/caching.yaml" + + - set_fact: + interface_cmds: + - set interfaces ethernet eth1 description 'Configured by Ansible - Interface 1' + - set interfaces ethernet eth1 mtu '1500' + - set interfaces ethernet eth1 duplex 'auto' + - set interfaces ethernet eth1 speed 'auto' + - set interfaces ethernet eth1 vif 101 description 'Eth1 - VIF 101' + - set interfaces ethernet eth2 description 'Configured by Ansible - Interface 2 (ADMIN DOWN)' + - set interfaces ethernet eth2 mtu '600' + l3_interface_cmds: + - set interfaces ethernet eth1 address '192.0.2.10/24' + - set interfaces ethernet eth1 address '2001:db8::10/32' + - set interfaces ethernet eth2 address '198.51.100.10/24' + + - name: Remove interfaces from config before actual testing + ignore_errors: true + vyos.vyos.vyos_config: &rem + lines: + - delete interfaces ethernet eth1 + - delete interfaces ethernet eth2 + match: none + + - name: Merge base interfaces configuration + register: result + vyos.vyos.vyos_interfaces: &merged + config: + - name: eth1 + description: Configured by Ansible - Interface 1 + mtu: 1500 + speed: auto + duplex: auto + vifs: + - vlan_id: 101 + description: Eth1 - VIF 101 + + - name: eth2 + description: Configured by Ansible - Interface 2 (ADMIN DOWN) + mtu: 600 + state: merged + + - assert: + that: + - "{{ interface_cmds | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Merge base interfaces configuration (IDEMPOTENT) + register: result + vyos.vyos.vyos_interfaces: *merged + + - assert: + that: + - result.changed == False + + - name: Merge L3 interfaces configuration + register: result + vyos.vyos.vyos_l3_interfaces: &mergedl3 + config: + - name: eth1 + ipv4: + - address: 192.0.2.10/24 + ipv6: + - address: 2001:db8::10/32 + - name: eth2 + ipv4: + - address: 198.51.100.10/24 + state: merged + + - assert: + that: + - "{{ l3_interface_cmds | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Merge L3 interfaces configuration (IDEMPOTENT) + register: result + vyos.vyos.vyos_l3_interfaces: *mergedl3 + + - assert: + that: + - result.changed == False + always: + - name: cleanup + vyos.vyos.vyos_config: *rem + when: ansible_connection == "network_cli" and ansible_network_single_user_mode|d(False) |