diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-26 10:25:15 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-26 10:25:15 +0000 |
commit | 62c52cf63e6e722d8d32f0103c8bc440947e649a (patch) | |
tree | fd883d584bbfb1c0298058d61abb8e8f3906df0c | |
parent | Releasing progress-linux version 2.17.2-1~progress7.99u1. (diff) | |
download | ansible-core-62c52cf63e6e722d8d32f0103c8bc440947e649a.tar.xz ansible-core-62c52cf63e6e722d8d32f0103c8bc440947e649a.zip |
Merging upstream version 2.17.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
87 files changed, 179 insertions, 6149 deletions
@@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: ansible-core -Version: 2.17.2 +Version: 2.17.3 Summary: Radically simple IT automation Home-page: https://ansible.com/ Author: Ansible, Inc. diff --git a/changelogs/CHANGELOG-v2.17.rst b/changelogs/CHANGELOG-v2.17.rst index 1ac8c02..0387f0f 100644 --- a/changelogs/CHANGELOG-v2.17.rst +++ b/changelogs/CHANGELOG-v2.17.rst @@ -4,6 +4,29 @@ ansible-core 2.17 "Gallows Pole" Release Notes .. contents:: Topics +v2.17.3 +======= + +Release Summary +--------------- + +| Release Date: 2024-08-12 +| `Porting Guide <https://docs.ansible.com/ansible-core/2.17/porting_guides/porting_guide_core_2.17.html>`__ + +Minor Changes +------------- + +- ansible-test - Improve the error message shown when an unknown ``--remote`` or ``--docker`` option is given. +- ansible-test - Removed the ``vyos/1.1.8`` network remote as it is no longer functional. + +Bugfixes +-------- + +- Warning now includes filename and line number of variable when specifying a list of dictionaries for vars (https://github.com/ansible/ansible/issues/82528). +- config, restored the ability to set module compression via a variable +- debconf - fix normalization of value representation for boolean vtypes in new packages (https://github.com/ansible/ansible/issues/83594) +- linear strategy: fix handlers included via ``include_tasks`` handler to be executed in lockstep (https://github.com/ansible/ansible/issues/83019) + v2.17.2 ======= diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index c4da406..d4fba89 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -784,3 +784,44 @@ releases: - dnf-revert.yaml - package_facts_apk.yml release_date: '2024-07-09' + 2.17.3: + changes: + release_summary: '| Release Date: 2024-08-12 + + | `Porting Guide <https://docs.ansible.com/ansible-core/2.17/porting_guides/porting_guide_core_2.17.html>`__ + + ' + codename: Gallows Pole + fragments: + - 2.17.3_summary.yaml + release_date: '2024-08-12' + 2.17.3rc1: + changes: + bugfixes: + - Warning now includes filename and line number of variable when specifying + a list of dictionaries for vars (https://github.com/ansible/ansible/issues/82528). + - config, restored the ability to set module compression via a variable + - debconf - fix normalization of value representation for boolean vtypes in + new packages (https://github.com/ansible/ansible/issues/83594) + - 'linear strategy: fix handlers included via ``include_tasks`` handler to be + executed in lockstep (https://github.com/ansible/ansible/issues/83019)' + minor_changes: + - ansible-test - Improve the error message shown when an unknown ``--remote`` + or ``--docker`` option is given. + - ansible-test - Removed the ``vyos/1.1.8`` network remote as it is no longer + functional. + release_summary: '| Release Date: 2024-08-05 + + | `Porting Guide <https://docs.ansible.com/ansible-core/2.17/porting_guides/porting_guide_core_2.17.html>`__ + + ' + codename: Gallows Pole + fragments: + - 2.17.3rc1_summary.yaml + - 82528summary.yml + - 83019-linear-handlers-lockstep-fix.yml + - 83601-debconf-normalize-bools.yml + - ansible-test-error-message-improvement.yml + - ansible-test-vyos.yml + - mc_fix.yml + release_date: '2024-08-05' diff --git a/lib/ansible/config/base.yml b/lib/ansible/config/base.yml index b4c2ae5..c6f6dee 100644 --- a/lib/ansible/config/base.yml +++ b/lib/ansible/config/base.yml @@ -855,8 +855,8 @@ DEFAULT_MODULE_COMPRESSION: env: [] ini: - {key: module_compression, section: defaults} -# vars: -# - name: ansible_module_compression + vars: + - name: ansible_module_compression DEFAULT_MODULE_NAME: name: Default adhoc module default: command diff --git a/lib/ansible/module_utils/ansible_release.py b/lib/ansible/module_utils/ansible_release.py index 8d3f49b..b264d43 100644 --- a/lib/ansible/module_utils/ansible_release.py +++ b/lib/ansible/module_utils/ansible_release.py @@ -17,6 +17,6 @@ from __future__ import annotations -__version__ = '2.17.2' +__version__ = '2.17.3' __author__ = 'Ansible, Inc.' __codename__ = "Gallows Pole" diff --git a/lib/ansible/modules/debconf.py b/lib/ansible/modules/debconf.py index 779952e..259d92b 100644 --- a/lib/ansible/modules/debconf.py +++ b/lib/ansible/modules/debconf.py @@ -173,8 +173,6 @@ def set_selection(module, pkg, question, vtype, value, unseen): if unseen: cmd.append('-u') - if vtype == 'boolean': - value = value.lower() data = ' '.join([pkg, question, vtype, value]) return module.run_command(cmd, data=data) @@ -209,15 +207,17 @@ def main(): if vtype is None or value is None: module.fail_json(msg="when supplying a question you must supply a valid vtype and value") + # ensure we compare booleans supplied to the way debconf sees them (true/false strings) + if vtype == 'boolean': + value = to_text(value).lower() + # if question doesn't exist, value cannot match if question not in prev: changed = True else: existing = prev[question] - # ensure we compare booleans supplied to the way debconf sees them (true/false strings) if vtype == 'boolean': - value = to_text(value).lower() existing = to_text(prev[question]).lower() elif vtype == 'password': existing = get_password_value(module, pkg, question, vtype) diff --git a/lib/ansible/playbook/base.py b/lib/ansible/playbook/base.py index 96c3b98..df18ecb 100644 --- a/lib/ansible/playbook/base.py +++ b/lib/ansible/playbook/base.py @@ -589,10 +589,11 @@ class FieldAttributeBase: _validate_variable_keys(ds) return combine_vars(self.vars, ds) elif isinstance(ds, list): + line_file = getattr(ds, 'ansible_pos', ("unknown", 0)) display.deprecated( ( 'Specifying a list of dictionaries for vars is deprecated in favor of ' - 'specifying a dictionary.' + 'specifying a dictionary. Error occurred in the file: %s, line: %d' % (line_file[0], line_file[1]) ), version='2.18' ) diff --git a/lib/ansible/plugins/strategy/linear.py b/lib/ansible/plugins/strategy/linear.py index d9e5d42..3c974e9 100644 --- a/lib/ansible/plugins/strategy/linear.py +++ b/lib/ansible/plugins/strategy/linear.py @@ -31,7 +31,6 @@ DOCUMENTATION = ''' from ansible import constants as C from ansible.errors import AnsibleError, AnsibleAssertionError, AnsibleParserError -from ansible.executor.play_iterator import IteratingStates from ansible.module_utils.common.text.converters import to_text from ansible.playbook.handler import Handler from ansible.playbook.included_file import IncludedFile @@ -46,12 +45,6 @@ display = Display() class StrategyModule(StrategyBase): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - # used for the lockstep to indicate to run handlers - self._in_handlers = False - def _get_next_task_lockstep(self, hosts, iterator): ''' Returns a list of (host, task) tuples, where the task may @@ -73,52 +66,35 @@ class StrategyModule(StrategyBase): if not state_task_per_host: return [(h, None) for h in hosts] - if self._in_handlers and not any(filter( - lambda rs: rs == IteratingStates.HANDLERS, - (s.run_state for s, dummy in state_task_per_host.values())) - ): - self._in_handlers = False - - if self._in_handlers: - lowest_cur_handler = min( - s.cur_handlers_task for s, t in state_task_per_host.values() - if s.run_state == IteratingStates.HANDLERS - ) - else: - task_uuids = [t._uuid for s, t in state_task_per_host.values()] - _loop_cnt = 0 - while _loop_cnt <= 1: - try: - cur_task = iterator.all_tasks[iterator.cur_task] - except IndexError: - # pick up any tasks left after clear_host_errors - iterator.cur_task = 0 - _loop_cnt += 1 - else: - iterator.cur_task += 1 - if cur_task._uuid in task_uuids: - break + task_uuids = {t._uuid for s, t in state_task_per_host.values()} + _loop_cnt = 0 + while _loop_cnt <= 1: + try: + cur_task = iterator.all_tasks[iterator.cur_task] + except IndexError: + # pick up any tasks left after clear_host_errors + iterator.cur_task = 0 + _loop_cnt += 1 else: - # prevent infinite loop - raise AnsibleAssertionError( - 'BUG: There seems to be a mismatch between tasks in PlayIterator and HostStates.' - ) + iterator.cur_task += 1 + if cur_task._uuid in task_uuids: + break + else: + # prevent infinite loop + raise AnsibleAssertionError( + 'BUG: There seems to be a mismatch between tasks in PlayIterator and HostStates.' + ) host_tasks = [] for host, (state, task) in state_task_per_host.items(): - if ((self._in_handlers and lowest_cur_handler == state.cur_handlers_task) or - (not self._in_handlers and cur_task._uuid == task._uuid)): + if cur_task._uuid == task._uuid: iterator.set_state_for_host(host.name, state) host_tasks.append((host, task)) else: host_tasks.append((host, noop_task)) - # once hosts synchronize on 'flush_handlers' lockstep enters - # '_in_handlers' phase where handlers are run instead of tasks - # until at least one host is in IteratingStates.HANDLERS - if (not self._in_handlers and cur_task.action in C._ACTION_META and - cur_task.args.get('_raw_params') == 'flush_handlers'): - self._in_handlers = True + if cur_task.action in C._ACTION_META and cur_task.args.get('_raw_params') == 'flush_handlers': + iterator.all_tasks[iterator.cur_task:iterator.cur_task] = [h for b in iterator._play.handlers for h in b.block] return host_tasks @@ -310,7 +286,7 @@ class StrategyModule(StrategyBase): final_block = new_block.filter_tagged_tasks(task_vars) display.debug("done filtering new block on tags") - included_tasks.extend(final_block.get_tasks()) + included_tasks.extend(final_block.get_tasks()) for host in hosts_left: if host in included_file._hosts: diff --git a/lib/ansible/plugins/test/any.yml b/lib/ansible/plugins/test/any.yml index 42b9182..e30ff22 100644 --- a/lib/ansible/plugins/test/any.yml +++ b/lib/ansible/plugins/test/any.yml @@ -2,7 +2,7 @@ DOCUMENTATION: name: any author: Ansible Core version_added: "2.4" - short_description: is any conditions in a list true + short_description: is any condition in a list true description: - This test checks each condition in a list for truthiness. - Same as the C(any) Python function. @@ -14,7 +14,7 @@ DOCUMENTATION: required: True EXAMPLES: | varexpression: "{{ 3 == 3 }}" - # are all statements true? + # is any statement true? {{ [false, booleanvar, varexpression] is any}} RETURN: diff --git a/lib/ansible/release.py b/lib/ansible/release.py index 8d3f49b..b264d43 100644 --- a/lib/ansible/release.py +++ b/lib/ansible/release.py @@ -17,6 +17,6 @@ from __future__ import annotations -__version__ = '2.17.2' +__version__ = '2.17.3' __author__ = 'Ansible, Inc.' __codename__ = "Gallows Pole" diff --git a/lib/ansible_core.egg-info/PKG-INFO b/lib/ansible_core.egg-info/PKG-INFO index b62b8dd..ff50c3a 100644 --- a/lib/ansible_core.egg-info/PKG-INFO +++ b/lib/ansible_core.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: ansible-core -Version: 2.17.2 +Version: 2.17.3 Summary: Radically simple IT automation Home-page: https://ansible.com/ Author: Ansible, Inc. diff --git a/lib/ansible_core.egg-info/SOURCES.txt b/lib/ansible_core.egg-info/SOURCES.txt index 6aa9d9d..97e8061 100644 --- a/lib/ansible_core.egg-info/SOURCES.txt +++ b/lib/ansible_core.egg-info/SOURCES.txt @@ -2051,6 +2051,9 @@ test/integration/targets/handlers/force_handlers_blocks_81533-2.yml test/integration/targets/handlers/from_handlers.yml test/integration/targets/handlers/handlers.yml test/integration/targets/handlers/handlers_lockstep_82307.yml +test/integration/targets/handlers/handlers_lockstep_83019-include-nested.yml +test/integration/targets/handlers/handlers_lockstep_83019-include.yml +test/integration/targets/handlers/handlers_lockstep_83019.yml test/integration/targets/handlers/include_handlers_fail_force-handlers.yml test/integration/targets/handlers/include_handlers_fail_force.yml test/integration/targets/handlers/inventory.handlers @@ -2189,37 +2192,6 @@ test/integration/targets/incidental_ios_file/tasks/cli.yaml test/integration/targets/incidental_ios_file/tasks/main.yaml test/integration/targets/incidental_ios_file/tests/cli/net_get.yaml test/integration/targets/incidental_ios_file/tests/cli/net_put.yaml -test/integration/targets/incidental_vyos_config/aliases -test/integration/targets/incidental_vyos_config/defaults/main.yaml -test/integration/targets/incidental_vyos_config/tasks/cli.yaml -test/integration/targets/incidental_vyos_config/tasks/cli_config.yaml -test/integration/targets/incidental_vyos_config/tasks/main.yaml -test/integration/targets/incidental_vyos_config/tests/cli/backup.yaml -test/integration/targets/incidental_vyos_config/tests/cli/check_config.yaml -test/integration/targets/incidental_vyos_config/tests/cli/comment.yaml -test/integration/targets/incidental_vyos_config/tests/cli/config.cfg -test/integration/targets/incidental_vyos_config/tests/cli/save.yaml -test/integration/targets/incidental_vyos_config/tests/cli/simple.yaml -test/integration/targets/incidental_vyos_config/tests/cli_config/cli_backup.yaml -test/integration/targets/incidental_vyos_config/tests/cli_config/cli_basic.yaml -test/integration/targets/incidental_vyos_config/tests/cli_config/cli_comment.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/aliases -test/integration/targets/incidental_vyos_lldp_interfaces/defaults/main.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/meta/main.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/tasks/cli.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/tasks/main.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/_populate.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/_populate_intf.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/_remove_config.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/deleted.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/empty_config.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/merged.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/overridden.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/replaced.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/rtt.yaml -test/integration/targets/incidental_vyos_lldp_interfaces/vars/main.yaml -test/integration/targets/incidental_vyos_prepare_tests/aliases -test/integration/targets/incidental_vyos_prepare_tests/tasks/main.yaml test/integration/targets/incidental_win_reboot/aliases test/integration/targets/incidental_win_reboot/tasks/main.yml test/integration/targets/incidental_win_reboot/templates/post_reboot.ps1 @@ -2979,11 +2951,6 @@ test/integration/targets/module_utils_urls/aliases test/integration/targets/module_utils_urls/library/test_peercert.py test/integration/targets/module_utils_urls/meta/main.yml test/integration/targets/module_utils_urls/tasks/main.yml -test/integration/targets/network_cli/aliases -test/integration/targets/network_cli/passworded_user.yml -test/integration/targets/network_cli/runme.sh -test/integration/targets/network_cli/setup.yml -test/integration/targets/network_cli/teardown.yml test/integration/targets/no_log/aliases test/integration/targets/no_log/dynamic.yml test/integration/targets/no_log/no_log_config.yml @@ -4319,34 +4286,6 @@ test/support/network-integration/collections/ansible_collections/cisco/ios/plugi test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/modules/ios_command.py test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/modules/ios_config.py test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/terminal/ios.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/action/vyos.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/cliconf/vyos.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/doc_fragments/vyos.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/vyos.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/facts/facts.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/firewall_rules/firewall_rules.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/interfaces/interfaces.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/l3_interfaces/l3_interfaces.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/lag_interfaces/lag_interfaces.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/lldp_global/lldp_global.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/lldp_interfaces/lldp_interfaces.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/static_routes/static_routes.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/facts.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/interfaces/interfaces.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/lag_interfaces/lag_interfaces.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/legacy/base.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/lldp_global/lldp_global.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/lldp_interfaces/lldp_interfaces.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/static_routes/static_routes.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/utils/utils.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_command.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_config.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_facts.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_lldp_interfaces.py -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/terminal/vyos.py test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/action/win_copy.py test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/action/win_reboot.py test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/module_utils/WebRequest.psm1 diff --git a/test/integration/targets/apt_repository/tasks/apt.yml b/test/integration/targets/apt_repository/tasks/apt.yml index d3175f4..65cbe45 100644 --- a/test/integration/targets/apt_repository/tasks/apt.yml +++ b/test/integration/targets/apt_repository/tasks/apt.yml @@ -56,7 +56,10 @@ - 'cache_before.stat.mtime != cache_after.stat.mtime' - name: 'ensure ppa key is installed (expect: pass)' - apt_key: id='{{test_ppa_key}}' state=present + apt_key: + id: '{{test_ppa_key}}' + state: present + keyserver: keyserver.ubuntu.com # # TEST: apt_repository: repo=<name> update_cache=no @@ -87,7 +90,10 @@ - 'cache_before.stat.mtime == cache_after.stat.mtime' - name: 'ensure ppa key is installed (expect: pass)' - apt_key: id='{{test_ppa_key}}' state=present + apt_key: + id: '{{test_ppa_key}}' + state: present + keyserver: keyserver.ubuntu.com # # TEST: apt_repository: repo=<name> update_cache=yes @@ -118,7 +124,10 @@ - 'cache_before.stat.mtime != cache_after.stat.mtime' - name: 'ensure ppa key is installed (expect: pass)' - apt_key: id='{{test_ppa_key}}' state=present + apt_key: + id: '{{test_ppa_key}}' + state: present + keyserver: keyserver.ubuntu.com # # TEST: apt_repository: repo=<spec> @@ -130,7 +139,10 @@ register: cache_before - name: ensure ppa key is present before adding repo that requires authentication - apt_key: keyserver=keyserver.ubuntu.com id='{{test_ppa_key}}' state=present + apt_key: + id: '{{test_ppa_key}}' + state: present + keyserver: keyserver.ubuntu.com - name: 'name=<spec> (expect: pass)' apt_repository: repo='{{test_ppa_spec}}' state=present @@ -191,7 +203,10 @@ register: cache_before - name: ensure ppa key is present before adding repo that requires authentication - apt_key: keyserver=keyserver.ubuntu.com id='{{test_ppa_key}}' state=present + apt_key: + id: '{{test_ppa_key}}' + state: present + keyserver: keyserver.ubuntu.com - name: 'name=<spec> filename=<filename> (expect: pass)' apt_repository: repo='{{test_ppa_spec}}' filename='{{test_ppa_filename}}' state=present @@ -260,13 +275,13 @@ path: /etc/apt/sources.list.d/local-apt-repository.list register: stat_result -- name: Assert if local apt repo file is a symlink +- name: Assert if local apt repo file is a symlink assert: that: - stat_result.stat.islnk is defined and stat_result.stat.islnk - stat_result.stat.lnk_source == "/usr/lib/local-apt-repository/local-apt-repository.list" -- name: Try installing an invalid repo +- name: Try installing an invalid repo apt_repository: repo: deb http://dl.google.com/linux/chrome/deb2/ stable main state: present @@ -282,7 +297,7 @@ assert: that: - stat_result2.stat.islnk is defined and stat_result2.stat.islnk - - stat_result2.stat.lnk_source == "/usr/lib/local-apt-repository/local-apt-repository.list" + - stat_result2.stat.lnk_source == "/usr/lib/local-apt-repository/local-apt-repository.list" - name: uninstall local-apt-repository with apt apt: pkg=local-apt-repository state=absent purge=yes diff --git a/test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-boo/pyproject.toml b/test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-boo/pyproject.toml index feec734..509374b 100644 --- a/test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-boo/pyproject.toml +++ b/test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-boo/pyproject.toml @@ -1,6 +1,5 @@ [build-system] requires = [ "setuptools >= 44", - "wheel", ] build-backend = "setuptools.build_meta" diff --git a/test/integration/targets/collections_runtime_pythonpath/runme.sh b/test/integration/targets/collections_runtime_pythonpath/runme.sh index 2ec8e7d..9540784 100755 --- a/test/integration/targets/collections_runtime_pythonpath/runme.sh +++ b/test/integration/targets/collections_runtime_pythonpath/runme.sh @@ -19,11 +19,11 @@ ansible \ >&2 echo '=== Test that the module gets picked up if installed into site-packages ===' -python -m pip install pep517 -( # Build a binary Python dist (a wheel) using PEP517: +python -m pip install build +( # Build a binary Python dist (a wheel) using build: cp -r ansible-collection-python-dist-boo "${OUTPUT_DIR}/" cd "${OUTPUT_DIR}/ansible-collection-python-dist-boo" - python -m pep517.build --binary --out-dir dist . + python -m build -w -o dist . ) # Install a pre-built dist with pip: python -m pip install \ diff --git a/test/integration/targets/debconf/tasks/main.yml b/test/integration/targets/debconf/tasks/main.yml index 4021349..1b5877e 100644 --- a/test/integration/targets/debconf/tasks/main.yml +++ b/test/integration/targets/debconf/tasks/main.yml @@ -146,6 +146,32 @@ - not debconf_multiselect_test_idem_4.changed - '"Invalid value provided" in debconf_multiselect_test_idem_4.msg' + - name: Boolean vtype from boolean value + debconf: + name: libnns-ldap + question: libnss-ldapd/clean_nsswitch + vtype: boolean + value: true + register: debconf_bool_test_bool_1 + + - name: validate results for boolean vtype from boolean value + assert: + that: + - debconf_bool_test_bool_1.changed + + - name: Boolean vtype from string value + debconf: + name: libnns-ldap + question: libnss-ldapd/clean_nsswitch + vtype: boolean + value: "FALSE" + register: debconf_bool_test_bool_2 + + - name: validate results for boolean vtype from string value + assert: + that: + - debconf_bool_test_bool_2.changed + always: - name: uninstall debconf-utils apt: @@ -153,4 +179,4 @@ state: absent when: debconf_utils_deb_install is changed - when: ansible_distribution in ('Ubuntu', 'Debian')
\ No newline at end of file + when: ansible_distribution in ('Ubuntu', 'Debian') diff --git a/test/integration/targets/handlers/handlers_lockstep_83019-include-nested.yml b/test/integration/targets/handlers/handlers_lockstep_83019-include-nested.yml new file mode 100644 index 0000000..bc763b9 --- /dev/null +++ b/test/integration/targets/handlers/handlers_lockstep_83019-include-nested.yml @@ -0,0 +1,3 @@ +- name: handler1 + debug: + msg: handler1 diff --git a/test/integration/targets/handlers/handlers_lockstep_83019-include.yml b/test/integration/targets/handlers/handlers_lockstep_83019-include.yml new file mode 100644 index 0000000..06acb3c --- /dev/null +++ b/test/integration/targets/handlers/handlers_lockstep_83019-include.yml @@ -0,0 +1,6 @@ +- include_tasks: handlers_lockstep_83019-include-nested.yml + when: inventory_hostname == "A" + +- name: handler2 + debug: + msg: handler2 diff --git a/test/integration/targets/handlers/handlers_lockstep_83019.yml b/test/integration/targets/handlers/handlers_lockstep_83019.yml new file mode 100644 index 0000000..f7cf6b5 --- /dev/null +++ b/test/integration/targets/handlers/handlers_lockstep_83019.yml @@ -0,0 +1,8 @@ +- hosts: A,B + gather_facts: false + tasks: + - command: echo + notify: handler + handlers: + - name: handler + include_tasks: handlers_lockstep_83019-include.yml diff --git a/test/integration/targets/handlers/runme.sh b/test/integration/targets/handlers/runme.sh index 9250fc8..6b4e8fb 100755 --- a/test/integration/targets/handlers/runme.sh +++ b/test/integration/targets/handlers/runme.sh @@ -219,3 +219,6 @@ ansible-playbook 82241.yml -i inventory.handlers "$@" 2>&1 | tee out.txt ansible-playbook handlers_lockstep_82307.yml -i inventory.handlers "$@" 2>&1 | tee out.txt [ "$(grep out.txt -ce 'TASK \[handler2\]')" = "0" ] + +ansible-playbook handlers_lockstep_83019.yml -i inventory.handlers "$@" 2>&1 | tee out.txt +[ "$(grep out.txt -ce 'TASK \[handler1\]')" = "0" ] diff --git a/test/integration/targets/incidental_vyos_config/aliases b/test/integration/targets/incidental_vyos_config/aliases deleted file mode 100644 index fae06ba..0000000 --- a/test/integration/targets/incidental_vyos_config/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/vyos/incidental -network/vyos diff --git a/test/integration/targets/incidental_vyos_config/defaults/main.yaml b/test/integration/targets/incidental_vyos_config/defaults/main.yaml deleted file mode 100644 index 9ef5ba5..0000000 --- a/test/integration/targets/incidental_vyos_config/defaults/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -testcase: "*" -test_items: [] diff --git a/test/integration/targets/incidental_vyos_config/tasks/cli.yaml b/test/integration/targets/incidental_vyos_config/tasks/cli.yaml deleted file mode 100644 index d601bb7..0000000 --- a/test/integration/targets/incidental_vyos_config/tasks/cli.yaml +++ /dev/null @@ -1,26 +0,0 @@ ---- -- 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 (connection=ansible.netcommon.network_cli) - include_tasks: "file={{ test_case_to_run }}" - vars: - ansible_connection: ansible.netcommon.network_cli - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - -- name: run test case (connection=local) - include_tasks: "file={{ test_case_to_run }}" - vars: - ansible_connection: local - with_first_found: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run diff --git a/test/integration/targets/incidental_vyos_config/tasks/cli_config.yaml b/test/integration/targets/incidental_vyos_config/tasks/cli_config.yaml deleted file mode 100644 index 7e67356..0000000 --- a/test/integration/targets/incidental_vyos_config/tasks/cli_config.yaml +++ /dev/null @@ -1,18 +0,0 @@ ---- -- name: collect all cli_config test cases - find: - paths: "{{ role_path }}/tests/cli_config" - 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 (connection=ansible.netcommon.network_cli) - include_tasks: "file={{ 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/test/integration/targets/incidental_vyos_config/tasks/main.yaml b/test/integration/targets/incidental_vyos_config/tasks/main.yaml deleted file mode 100644 index 0d4e8fd..0000000 --- a/test/integration/targets/incidental_vyos_config/tasks/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -- {import_tasks: cli.yaml, tags: ['cli']} -- {import_tasks: cli_config.yaml, tags: ['cli_config']} diff --git a/test/integration/targets/incidental_vyos_config/tests/cli/backup.yaml b/test/integration/targets/incidental_vyos_config/tests/cli/backup.yaml deleted file mode 100644 index af6a772..0000000 --- a/test/integration/targets/incidental_vyos_config/tests/cli/backup.yaml +++ /dev/null @@ -1,113 +0,0 @@ ---- -- debug: msg="START vyos/backup.yaml on connection={{ ansible_connection }}" - -- name: collect any backup files - find: - paths: "{{ role_path }}/backup" - pattern: "{{ inventory_hostname_short }}_config*" - register: backup_files - connection: local - -- name: delete backup files - file: - path: "{{ item.path }}" - state: absent - with_items: "{{backup_files.files|default([])}}" - -- name: take configure backup - vyos.vyos.vyos_config: - backup: true - register: result - -- assert: - that: - - "result.changed == true" - -- name: collect any backup files - find: - paths: "{{ role_path }}/backup" - pattern: "{{ inventory_hostname_short }}_config*" - register: backup_files - connection: local - -- assert: - that: - - "backup_files.files is defined" - -- name: delete configurable backup file path - file: - path: "{{ item }}" - state: absent - with_items: - - "{{ role_path }}/backup_test_dir/" - - "{{ role_path }}/backup/backup.cfg" - -- name: take configuration backup in custom filename and directory path - vyos.vyos.vyos_config: - backup: true - backup_options: - filename: backup.cfg - dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - become: true - register: result - -- assert: - that: - - "result.changed == true" - -- name: check if the backup file-1 exist - find: - paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup.cfg" - register: backup_file - connection: local - -- assert: - that: - - "backup_file.files is defined" - -- name: take configuration backup in custom filename - vyos.vyos.vyos_config: - backup: true - backup_options: - filename: backup.cfg - become: true - register: result - -- assert: - that: - - "result.changed == true" - -- name: check if the backup file-2 exist - find: - paths: "{{ role_path }}/backup/backup.cfg" - register: backup_file - connection: local - -- assert: - that: - - "backup_file.files is defined" - -- name: take configuration backup in custom path and default filename - vyos.vyos.vyos_config: - backup: true - backup_options: - dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - become: true - register: result - -- assert: - that: - - "result.changed == true" - -- name: check if the backup file-3 exist - find: - paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - pattern: "{{ inventory_hostname_short }}_config*" - register: backup_file - connection: local - -- assert: - that: - - "backup_file.files is defined" - -- debug: msg="END vyos/backup.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/incidental_vyos_config/tests/cli/check_config.yaml b/test/integration/targets/incidental_vyos_config/tests/cli/check_config.yaml deleted file mode 100644 index e45331a..0000000 --- a/test/integration/targets/incidental_vyos_config/tests/cli/check_config.yaml +++ /dev/null @@ -1,63 +0,0 @@ ---- -- debug: msg="START cli/config_check.yaml on connection={{ ansible_connection }}" - -- name: setup- ensure interface is not present - vyos.vyos.vyos_config: - lines: delete interfaces loopback lo - -- name: setup- create interface - vyos.vyos.vyos_config: - lines: - - interfaces - - interfaces loopback lo - - interfaces loopback lo description test - register: result - -# note collapsing the duplicate lines doesn't work if -# lines: -# - interfaces loopback lo description test -# - interfaces loopback lo -# - interfaces - -- name: Check that multiple duplicate lines collapse into a single commands - assert: - that: - - "result.commands|length == 1" - -- name: Check that set is correctly prepended - assert: - that: - - "result.commands[0] == 'set interfaces loopback lo description test'" - -- name: configure config_check config command - vyos.vyos.vyos_config: - lines: delete interfaces loopback lo - register: result - -- assert: - that: - - "result.changed == true" - -- name: check config_check config command idempontent - vyos.vyos.vyos_config: - lines: delete interfaces loopback lo - register: result - -- assert: - that: - - "result.changed == false" - -- name: check multiple line config filter is working - vyos.vyos.vyos_config: - lines: - - set system login user esa level admin - - set system login user esa authentication encrypted-password '!abc!' - - set system login user vyos level admin - - set system login user vyos authentication encrypted-password 'abc' - register: result - -- assert: - that: - - "result.filtered|length == 2" - -- debug: msg="END cli/config_check.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/incidental_vyos_config/tests/cli/comment.yaml b/test/integration/targets/incidental_vyos_config/tests/cli/comment.yaml deleted file mode 100644 index 2cd1350..0000000 --- a/test/integration/targets/incidental_vyos_config/tests/cli/comment.yaml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- debug: msg="START cli/comment.yaml on connection={{ ansible_connection }}" - -- name: setup - vyos.vyos.vyos_config: - lines: set system host-name {{ inventory_hostname_short }} - match: none - -- name: configure using comment - vyos.vyos.vyos_config: - lines: set system host-name foo - comment: this is a test - register: result - -- assert: - that: - - "result.changed == true" - - "'set system host-name foo' in result.commands" - -- name: collect system commits - vyos.vyos.vyos_command: - commands: show system commit - register: result - -- assert: - that: - - "'this is a test' in result.stdout_lines[0][1]" - -- name: teardown - vyos.vyos.vyos_config: - lines: set system host-name {{ inventory_hostname_short }} - match: none - -- debug: msg="END cli/comment.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/incidental_vyos_config/tests/cli/config.cfg b/test/integration/targets/incidental_vyos_config/tests/cli/config.cfg deleted file mode 100644 index 36c98f1..0000000 --- a/test/integration/targets/incidental_vyos_config/tests/cli/config.cfg +++ /dev/null @@ -1,3 +0,0 @@ - set service lldp - set protocols static - diff --git a/test/integration/targets/incidental_vyos_config/tests/cli/save.yaml b/test/integration/targets/incidental_vyos_config/tests/cli/save.yaml deleted file mode 100644 index d8e45e2..0000000 --- a/test/integration/targets/incidental_vyos_config/tests/cli/save.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -- debug: msg="START cli/save.yaml on connection={{ ansible_connection }}" - -- name: setup - vyos.vyos.vyos_config: - lines: set system host-name {{ inventory_hostname_short }} - match: none - -- name: configure hostaname and save - vyos.vyos.vyos_config: - lines: set system host-name foo - save: true - register: result - -- assert: - that: - - "result.changed == true" - - "'set system host-name foo' in result.commands" - -- name: configure hostaname and don't save - vyos.vyos.vyos_config: - lines: set system host-name bar - register: result - -- assert: - that: - - "result.changed == true" - - "'set system host-name bar' in result.commands" - -- name: save config - vyos.vyos.vyos_config: - save: true - register: result - -- assert: - that: - - "result.changed == true" - -- name: save config again - vyos.vyos.vyos_config: - save: true - register: result - -- assert: - that: - - "result.changed == false" - -- name: teardown - vyos.vyos.vyos_config: - lines: set system host-name {{ inventory_hostname_short }} - match: none - save: true - -- debug: msg="END cli/simple.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/incidental_vyos_config/tests/cli/simple.yaml b/test/integration/targets/incidental_vyos_config/tests/cli/simple.yaml deleted file mode 100644 index c082673..0000000 --- a/test/integration/targets/incidental_vyos_config/tests/cli/simple.yaml +++ /dev/null @@ -1,53 +0,0 @@ ---- -- debug: msg="START cli/simple.yaml on connection={{ ansible_connection }}" - -- name: setup - vyos.vyos.vyos_config: - lines: set system host-name {{ inventory_hostname_short }} - match: none - -- name: configure simple config command - vyos.vyos.vyos_config: - lines: set system host-name foo - register: result - -- assert: - that: - - "result.changed == true" - - "'set system host-name foo' in result.commands" - -- name: check simple config command idempontent - vyos.vyos.vyos_config: - lines: set system host-name foo - register: result - -- assert: - that: - - "result.changed == false" - -- name: Delete services - vyos.vyos.vyos_config: &del - lines: - - delete service lldp - - delete protocols static - -- name: Configuring when commands starts with whitespaces - vyos.vyos.vyos_config: - src: "{{ role_path }}/tests/cli/config.cfg" - register: result - -- assert: - that: - - "result.changed == true" - - '"set service lldp" in result.commands' - - '"set protocols static" in result.commands' - -- name: Delete services - vyos.vyos.vyos_config: *del - -- name: teardown - vyos.vyos.vyos_config: - lines: set system host-name {{ inventory_hostname_short }} - match: none - -- debug: msg="END cli/simple.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/incidental_vyos_config/tests/cli_config/cli_backup.yaml b/test/integration/targets/incidental_vyos_config/tests/cli_config/cli_backup.yaml deleted file mode 100644 index 744bb7e..0000000 --- a/test/integration/targets/incidental_vyos_config/tests/cli_config/cli_backup.yaml +++ /dev/null @@ -1,114 +0,0 @@ ---- -- debug: msg="END cli_config/backup.yaml on connection={{ ansible_connection }}" - -- name: delete configurable backup file path - file: - path: "{{ item }}" - state: absent - with_items: - - "{{ role_path }}/backup_test_dir/" - - "{{ role_path }}/backup/backup.cfg" - -- name: collect any backup files - find: - paths: "{{ role_path }}/backup" - pattern: "{{ inventory_hostname_short }}_config*" - register: backup_files - connection: local - -- name: delete backup files - file: - path: "{{ item.path }}" - state: absent - with_items: "{{backup_files.files|default([])}}" - -- name: take config backup - ansible.netcommon.cli_config: - backup: true - become: true - register: result - -- assert: - that: - - "result.changed == true" - -- name: collect any backup files - find: - paths: "{{ role_path }}/backup" - pattern: "{{ inventory_hostname_short }}_config*" - register: backup_files - connection: local - -- assert: - that: - - "backup_files.files is defined" - -- name: take configuration backup in custom filename and directory path - ansible.netcommon.cli_config: - backup: true - backup_options: - filename: backup.cfg - dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - become: true - register: result - -- assert: - that: - - "result.changed == true" - -- name: check if the backup file-1 exist - find: - paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup.cfg" - register: backup_file - connection: local - -- assert: - that: - - "backup_file.files is defined" - -- name: take configuration backup in custom filename - ansible.netcommon.cli_config: - backup: true - backup_options: - filename: backup.cfg - become: true - register: result - -- assert: - that: - - "result.changed == true" - -- name: check if the backup file-2 exist - find: - paths: "{{ role_path }}/backup/backup.cfg" - register: backup_file - connection: local - -- assert: - that: - - "backup_file.files is defined" - -- name: take configuration backup in custom path and default filename - ansible.netcommon.cli_config: - backup: true - backup_options: - dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - become: true - register: result - -- assert: - that: - - "result.changed == true" - -- name: check if the backup file-3 exist - find: - paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - pattern: "{{ inventory_hostname_short }}_config*" - register: backup_file - connection: local - -- assert: - that: - - "backup_file.files is defined" - -- debug: msg="END cli_config/backup.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/incidental_vyos_config/tests/cli_config/cli_basic.yaml b/test/integration/targets/incidental_vyos_config/tests/cli_config/cli_basic.yaml deleted file mode 100644 index c6c4f59..0000000 --- a/test/integration/targets/incidental_vyos_config/tests/cli_config/cli_basic.yaml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- debug: msg="START cli_config/cli_basic.yaml on connection={{ ansible_connection }}" - -- name: setup - remove interface description - ansible.netcommon.cli_config: &rm - config: delete interfaces loopback lo description - -- name: configure device with config - ansible.netcommon.cli_config: &conf - config: set interfaces loopback lo description 'this is a test' - register: result - -- assert: - that: - - "result.changed == true" - -- name: Idempotence - ansible.netcommon.cli_config: *conf - register: result - -- assert: - that: - - "result.changed == false" - -- name: teardown - ansible.netcommon.cli_config: *rm - -- debug: msg="END cli_config/cli_basic.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/incidental_vyos_config/tests/cli_config/cli_comment.yaml b/test/integration/targets/incidental_vyos_config/tests/cli_config/cli_comment.yaml deleted file mode 100644 index 90ee1c8..0000000 --- a/test/integration/targets/incidental_vyos_config/tests/cli_config/cli_comment.yaml +++ /dev/null @@ -1,30 +0,0 @@ ---- -- debug: msg="START cli_config/cli_comment.yaml on connection={{ ansible_connection }}" - -- name: setup - ansible.netcommon.cli_config: &rm - config: set system host-name {{ inventory_hostname_short }} - -- name: configure using comment - ansible.netcommon.cli_config: - config: set system host-name foo - commit_comment: this is a test - register: result - -- assert: - that: - - "result.changed == true" - -- name: collect system commits - vyos.vyos.vyos_command: - commands: show system commit - register: result - -- assert: - that: - - "'this is a test' in result.stdout_lines[0][1]" - -- name: teardown - ansible.netcommon.cli_config: *rm - -- debug: msg="END cli_config/cli_comment.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/aliases b/test/integration/targets/incidental_vyos_lldp_interfaces/aliases deleted file mode 100644 index fae06ba..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/aliases +++ /dev/null @@ -1,2 +0,0 @@ -shippable/vyos/incidental -network/vyos diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/defaults/main.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/defaults/main.yaml deleted file mode 100644 index 164afea..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/defaults/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -testcase: "[^_].*" -test_items: [] diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/meta/main.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/meta/main.yaml deleted file mode 100644 index ee1fa01..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/meta/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -dependencies: - - incidental_vyos_prepare_tests diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/cli.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/cli.yaml deleted file mode 100644 index c6923f3..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/cli.yaml +++ /dev/null @@ -1,19 +0,0 @@ ---- -- 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_tasks: "{{ 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/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/main.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/main.yaml deleted file mode 100644 index a6d418b..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- {import_tasks: cli.yaml, tags: ['cli']} diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/_populate.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/_populate.yaml deleted file mode 100644 index 3acded6..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/_populate.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -- name: Setup - ansible.netcommon.cli_config: - config: "{{ lines }}" - vars: - lines: | - set service lldp interface eth1 - set service lldp interface eth1 location civic-based country-code US - set service lldp interface eth1 location civic-based ca-type 0 ca-value ENGLISH - set service lldp interface eth2 - set service lldp interface eth2 location coordinate-based latitude 33.524449N - set service lldp interface eth2 location coordinate-based altitude 2200 - set service lldp interface eth2 location coordinate-based datum WGS84 - set service lldp interface eth2 location coordinate-based longitude 222.267255W diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/_populate_intf.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/_populate_intf.yaml deleted file mode 100644 index c7ab1ae..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/_populate_intf.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -- name: Setup - ansible.netcommon.cli_config: - config: "{{ lines }}" - vars: - lines: | - set service lldp interface eth2 - set service lldp interface eth2 location civic-based country-code US - set service lldp interface eth2 location civic-based ca-type 0 ca-value ENGLISH - set service lldp interface eth2 disable diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/_remove_config.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/_remove_config.yaml deleted file mode 100644 index 1b1a3b3..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/_remove_config.yaml +++ /dev/null @@ -1,8 +0,0 @@ ---- -- name: Remove Config - ansible.netcommon.cli_config: - config: "{{ lines }}" - vars: - lines: | - delete service lldp interface - delete service lldp diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/deleted.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/deleted.yaml deleted file mode 100644 index 316e91c..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/deleted.yaml +++ /dev/null @@ -1,46 +0,0 @@ ---- -- debug: - msg: "Start vyos_lldp_interfaces deleted integration tests ansible_connection={{ ansible_connection }}" - -- include_tasks: _populate.yaml - -- block: - - name: Delete attributes of given LLDP interfaces. - vyos.vyos.vyos_lldp_interfaces: &deleted - config: - - name: 'eth1' - - name: 'eth2' - state: deleted - register: result - - - name: Assert that the before dicts were correctly generated - assert: - that: - - "populate | symmetric_difference(result['before']) |length == 0" - - - name: Assert that the correct set of commands were generated - assert: - that: - - "deleted['commands'] | symmetric_difference(result['commands']) |length == 0" - - - name: Assert that the after dicts were correctly generated - assert: - that: - - "deleted['after'] | symmetric_difference(result['after']) |length == 0" - - - name: Delete attributes of given interfaces (IDEMPOTENT) - vyos.vyos.vyos_lldp_interfaces: *deleted - register: result - - - name: Assert that the previous task was idempotent - assert: - that: - - "result.changed == false" - - "result.commands|length == 0" - - - name: Assert that the before dicts were correctly generated - assert: - that: - - "deleted['after'] | symmetric_difference(result['before']) |length == 0" - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/empty_config.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/empty_config.yaml deleted file mode 100644 index 44c0b89..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/empty_config.yaml +++ /dev/null @@ -1,36 +0,0 @@ ---- -- debug: - msg: "START vyos_lldp_interfaces empty_config integration tests on connection={{ ansible_connection }}" - -- name: Merged with empty config should give appropriate error message - vyos.vyos.vyos_lldp_interfaces: - config: - state: merged - register: result - ignore_errors: true - -- 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 - vyos.vyos.vyos_lldp_interfaces: - config: - state: replaced - register: result - ignore_errors: true - -- 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 - vyos.vyos.vyos_lldp_interfaces: - config: - state: overridden - register: result - ignore_errors: true - -- assert: - that: - - result.msg == 'value of config parameter must not be empty for state overridden' diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/merged.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/merged.yaml deleted file mode 100644 index 7e0bb53..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/merged.yaml +++ /dev/null @@ -1,58 +0,0 @@ ---- -- debug: - msg: "START vyos_lldp_interfaces merged integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- block: - - name: Merge the provided configuration with the exisiting running configuration - vyos.vyos.vyos_lldp_interfaces: &merged - config: - - name: 'eth1' - location: - civic_based: - country_code: 'US' - ca_info: - - ca_type: 0 - ca_value: 'ENGLISH' - - - name: 'eth2' - location: - coordinate_based: - altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' - state: merged - register: result - - - name: Assert that before dicts were correctly generated - assert: - that: "merged['before'] | symmetric_difference(result['before']) |length == 0" - - - name: Assert that correct set of commands were generated - assert: - that: - - "merged['commands'] | symmetric_difference(result['commands']) |length == 0" - - - name: Assert that after dicts was correctly generated - assert: - that: - - "merged['after'] | symmetric_difference(result['after']) |length == 0" - - - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) - vyos.vyos.vyos_lldp_interfaces: *merged - register: result - - - name: Assert that the previous task was idempotent - assert: - that: - - "result['changed'] == false" - - - name: Assert that before dicts were correctly generated - assert: - that: - - "merged['after'] | symmetric_difference(result['before']) |length == 0" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/overridden.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/overridden.yaml deleted file mode 100644 index ad13f39..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/overridden.yaml +++ /dev/null @@ -1,49 +0,0 @@ ---- -- debug: - msg: "START vyos_lldp_interfaces overridden integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _populate_intf.yaml - -- block: - - name: Overrides all device configuration with provided configuration - vyos.vyos.vyos_lldp_interfaces: &overridden - config: - - name: 'eth2' - location: - elin: '0000000911' - state: overridden - register: result - - - name: Assert that before dicts were correctly generated - assert: - that: - - "populate_intf | symmetric_difference(result['before']) |length == 0" - - - name: Assert that correct commands were generated - assert: - that: - - "overridden['commands'] | symmetric_difference(result['commands']) |length == 0" - - - name: Assert that after dicts were correctly generated - assert: - that: - - "overridden['after'] | symmetric_difference(result['after']) |length == 0" - - - name: Overrides all device configuration with provided configurations (IDEMPOTENT) - vyos.vyos.vyos_lldp_interfaces: *overridden - register: result - - - name: Assert that the previous task was idempotent - assert: - that: - - "result['changed'] == false" - - - name: Assert that before dicts were correctly generated - assert: - that: - - "overridden['after'] | symmetric_difference(result['before']) |length == 0" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/replaced.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/replaced.yaml deleted file mode 100644 index aadc379..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/replaced.yaml +++ /dev/null @@ -1,63 +0,0 @@ ---- -- debug: - msg: "START vyos_lldp_interfaces replaced integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- include_tasks: _populate.yaml - -- block: - - name: Replace device configurations of listed LLDP interfaces with provided configurations - vyos.vyos.vyos_lldp_interfaces: &replaced - config: - - name: 'eth2' - enable: false - location: - civic_based: - country_code: 'US' - ca_info: - - ca_type: 0 - ca_value: 'ENGLISH' - - - name: 'eth1' - enable: false - location: - coordinate_based: - altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' - state: replaced - register: result - - - name: Assert that correct set of commands were generated - assert: - that: - - "replaced['commands'] | symmetric_difference(result['commands']) |length == 0" - - - name: Assert that before dicts are correctly generated - assert: - that: - - "populate | symmetric_difference(result['before']) |length == 0" - - - name: Assert that after dict is correctly generated - assert: - that: - - "replaced['after'] | symmetric_difference(result['after']) |length == 0" - - - name: Replace device configurations of listed LLDP interfaces with provided configurarions (IDEMPOTENT) - vyos.vyos.vyos_lldp_interfaces: *replaced - register: result - - - name: Assert that task was idempotent - assert: - that: - - "result['changed'] == false" - - - name: Assert that before dict is correctly generated - assert: - that: - - "replaced['after'] | symmetric_difference(result['before']) |length == 0" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/rtt.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/rtt.yaml deleted file mode 100644 index 4d4cf82..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/tests/cli/rtt.yaml +++ /dev/null @@ -1,57 +0,0 @@ ---- -- debug: - msg: "START vyos_lldp_interfaces round trip integration tests on connection={{ ansible_connection }}" - -- include_tasks: _remove_config.yaml - -- block: - - name: Apply the provided configuration (base config) - vyos.vyos.vyos_lldp_interfaces: - config: - - name: 'eth1' - location: - civic_based: - country_code: 'US' - ca_info: - - ca_type: 0 - ca_value: 'ENGLISH' - - state: merged - register: base_config - - - name: Gather lldp_interfaces facts - vyos.vyos.vyos_facts: - gather_subset: - - default - gather_network_resources: - - lldp_interfaces - - - name: Apply the provided configuration (config to be reverted) - vyos.vyos.vyos_lldp_interfaces: - config: - - name: 'eth2' - location: - coordinate_based: - altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' - state: merged - register: result - - - name: Assert that changes were applied - assert: - that: "{{ round_trip['after'] | symmetric_difference(result['after']) |length == 0 }}" - - - name: Revert back to base config using facts round trip - vyos.vyos.vyos_lldp_interfaces: - config: "{{ ansible_facts['network_resources']['lldp_interfaces'] }}" - state: overridden - register: revert - - - name: Assert that config was reverted - assert: - that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length == 0 }}" - - always: - - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/incidental_vyos_lldp_interfaces/vars/main.yaml b/test/integration/targets/incidental_vyos_lldp_interfaces/vars/main.yaml deleted file mode 100644 index 169b0d5..0000000 --- a/test/integration/targets/incidental_vyos_lldp_interfaces/vars/main.yaml +++ /dev/null @@ -1,130 +0,0 @@ ---- -merged: - before: [] - - - commands: - - "set service lldp interface eth1 location civic-based country-code 'US'" - - "set service lldp interface eth1 location civic-based ca-type 0 ca-value 'ENGLISH'" - - "set service lldp interface eth1" - - "set service lldp interface eth2 location coordinate-based latitude '33.524449N'" - - "set service lldp interface eth2 location coordinate-based altitude '2200'" - - "set service lldp interface eth2 location coordinate-based datum 'WGS84'" - - "set service lldp interface eth2 location coordinate-based longitude '222.267255W'" - - "set service lldp interface eth2 location coordinate-based latitude '33.524449N'" - - "set service lldp interface eth2 location coordinate-based altitude '2200'" - - "set service lldp interface eth2 location coordinate-based datum 'WGS84'" - - "set service lldp interface eth2 location coordinate-based longitude '222.267255W'" - - "set service lldp interface eth2" - - after: - - name: 'eth1' - location: - civic_based: - country_code: 'US' - ca_info: - - ca_type: 0 - ca_value: 'ENGLISH' - - - name: 'eth2' - location: - coordinate_based: - altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' - -populate: - - name: 'eth1' - location: - civic_based: - country_code: 'US' - ca_info: - - ca_type: 0 - ca_value: 'ENGLISH' - - - name: 'eth2' - location: - coordinate_based: - altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' - -replaced: - commands: - - "delete service lldp interface eth2 location" - - "set service lldp interface eth2 'disable'" - - "set service lldp interface eth2 location civic-based country-code 'US'" - - "set service lldp interface eth2 location civic-based ca-type 0 ca-value 'ENGLISH'" - - "delete service lldp interface eth1 location" - - "set service lldp interface eth1 'disable'" - - "set service lldp interface eth1 location coordinate-based latitude '33.524449N'" - - "set service lldp interface eth1 location coordinate-based altitude '2200'" - - "set service lldp interface eth1 location coordinate-based datum 'WGS84'" - - "set service lldp interface eth1 location coordinate-based longitude '222.267255W'" - - after: - - name: 'eth2' - enable: false - location: - civic_based: - country_code: 'US' - ca_info: - - ca_type: 0 - ca_value: 'ENGLISH' - - - name: 'eth1' - enable: false - location: - coordinate_based: - altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' - -populate_intf: - - name: 'eth2' - enable: false - location: - civic_based: - country_code: 'US' - ca_info: - - ca_type: 0 - ca_value: 'ENGLISH' - -overridden: - commands: - - "delete service lldp interface eth2 location" - - "delete service lldp interface eth2 'disable'" - - "set service lldp interface eth2 location elin '0000000911'" - - after: - - name: 'eth2' - location: - elin: 0000000911 - -deleted: - commands: - - "delete service lldp interface eth1" - - "delete service lldp interface eth2" - - after: [] - -round_trip: - after: - - name: 'eth1' - location: - civic_based: - country_code: 'US' - ca_info: - - ca_type: 0 - ca_value: 'ENGLISH' - - - name: 'eth2' - location: - coordinate_based: - altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' diff --git a/test/integration/targets/incidental_vyos_prepare_tests/aliases b/test/integration/targets/incidental_vyos_prepare_tests/aliases deleted file mode 100644 index 136c05e..0000000 --- a/test/integration/targets/incidental_vyos_prepare_tests/aliases +++ /dev/null @@ -1 +0,0 @@ -hidden diff --git a/test/integration/targets/incidental_vyos_prepare_tests/tasks/main.yaml b/test/integration/targets/incidental_vyos_prepare_tests/tasks/main.yaml deleted file mode 100644 index ac0b492..0000000 --- a/test/integration/targets/incidental_vyos_prepare_tests/tasks/main.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -- name: Ensure required interfaces are present in running-config - ansible.netcommon.cli_config: - config: "{{ lines }}" - vars: - lines: | - set interfaces ethernet eth0 address dhcp - set interfaces ethernet eth0 speed auto - set interfaces ethernet eth0 duplex auto - set interfaces ethernet eth1 - set interfaces ethernet eth2 - delete interfaces loopback lo - ignore_errors: true diff --git a/test/integration/targets/network_cli/aliases b/test/integration/targets/network_cli/aliases deleted file mode 100644 index 6a739c9..0000000 --- a/test/integration/targets/network_cli/aliases +++ /dev/null @@ -1,3 +0,0 @@ -# Keeping incidental for efficiency, to avoid spinning up another VM -shippable/vyos/incidental -network/vyos diff --git a/test/integration/targets/network_cli/passworded_user.yml b/test/integration/targets/network_cli/passworded_user.yml deleted file mode 100644 index 5538684..0000000 --- a/test/integration/targets/network_cli/passworded_user.yml +++ /dev/null @@ -1,14 +0,0 @@ -- hosts: vyos - gather_facts: false - - tasks: - - name: Run whoami - vyos.vyos.vyos_command: - commands: - - whoami - register: whoami - - - assert: - that: - - whoami is successful - - whoami.stdout_lines[0][0] == 'atester' diff --git a/test/integration/targets/network_cli/runme.sh b/test/integration/targets/network_cli/runme.sh deleted file mode 100755 index 156674f..0000000 --- a/test/integration/targets/network_cli/runme.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -set -eux -export ANSIBLE_ROLES_PATH=../ - -function cleanup { - ansible-playbook teardown.yml -i "$INVENTORY_PATH" "$@" -} - -trap cleanup EXIT - -ansible-playbook setup.yml -i "$INVENTORY_PATH" "$@" - -# We need a nonempty file to override key with (empty file gives a -# lovely "list index out of range" error) -foo=$(mktemp) -echo hello > "$foo" - -# We want to ensure that passwords make it to the network connection plugins -# because they follow a different path than the rest of the codebase. -# In setup.yml, we create a passworded user, and now we connect as that user -# to make sure the password we pass here successfully makes it to the plugin. -ansible-playbook \ - -i "$INVENTORY_PATH" \ - -e ansible_user=atester \ - -e ansible_password=testymctest \ - -e ansible_ssh_private_key_file="$foo" \ - passworded_user.yml diff --git a/test/integration/targets/network_cli/setup.yml b/test/integration/targets/network_cli/setup.yml deleted file mode 100644 index d862406..0000000 --- a/test/integration/targets/network_cli/setup.yml +++ /dev/null @@ -1,14 +0,0 @@ -- hosts: vyos - connection: ansible.netcommon.network_cli - become: true - gather_facts: false - - tasks: - - name: Create user with password - register: result - vyos.vyos.vyos_config: - lines: - - set system login user atester full-name "Ansible Tester" - - set system login user atester authentication plaintext-password testymctest - - set system login user jsmith level admin - - delete service ssh disable-password-authentication diff --git a/test/integration/targets/network_cli/teardown.yml b/test/integration/targets/network_cli/teardown.yml deleted file mode 100644 index c47f3e8..0000000 --- a/test/integration/targets/network_cli/teardown.yml +++ /dev/null @@ -1,14 +0,0 @@ -- hosts: vyos - connection: ansible.netcommon.network_cli - become: true - gather_facts: false - - tasks: - - name: Get rid of user (undo everything from setup.yml) - register: result - vyos.vyos.vyos_config: - lines: - - delete system login user atester full-name "Ansible Tester" - - delete system login user atester authentication plaintext-password testymctest - - delete system login user jsmith level admin - - set service ssh disable-password-authentication diff --git a/test/lib/ansible_test/_data/completion/network.txt b/test/lib/ansible_test/_data/completion/network.txt index 1d6b0c1..cb523d1 100644 --- a/test/lib/ansible_test/_data/completion/network.txt +++ b/test/lib/ansible_test/_data/completion/network.txt @@ -1,2 +1 @@ ios/csr1000v collection=cisco.ios connection=ansible.netcommon.network_cli provider=aws arch=x86_64 -vyos/1.1.8 collection=vyos.vyos connection=ansible.netcommon.network_cli provider=aws arch=x86_64 diff --git a/test/lib/ansible_test/_internal/cli/compat.py b/test/lib/ansible_test/_internal/cli/compat.py index 19996fa..27267f4 100644 --- a/test/lib/ansible_test/_internal/cli/compat.py +++ b/test/lib/ansible_test/_internal/cli/compat.py @@ -93,7 +93,10 @@ class PythonVersionUnspecifiedError(ApplicationError): """A Python version was not specified for a context which is unknown, thus the Python version is unknown.""" def __init__(self, context: str) -> None: - super().__init__(f'A Python version was not specified for environment `{context}`. Use the `--python` option to specify a Python version.') + super().__init__( + f'Environment `{context}` is unknown. Use a predefined environment instead. ' + f'Alternatively, to use an unknown environment, use the `--python` option to specify a Python version.' + ) class ControllerNotSupportedError(ApplicationError): diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt index 89fcd02..2df3769 100644 --- a/test/sanity/ignore.txt +++ b/test/sanity/ignore.txt @@ -137,7 +137,6 @@ test/integration/targets/win_script/files/test_script_with_args.ps1 pslint:PSAvo test/integration/targets/win_script/files/test_script_with_splatting.ps1 pslint:PSAvoidUsingWriteHost # Keep test/lib/ansible_test/_data/requirements/sanity.pslint.ps1 pslint:PSCustomUseLiteralPath # Uses wildcards on purpose test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/cliconf/ios.py pylint:arguments-renamed -test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/cliconf/vyos.py pylint:arguments-renamed test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/module_utils/WebRequest.psm1 pslint!skip test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_uri.ps1 pslint!skip test/support/windows-integration/plugins/modules/async_status.ps1 pslint!skip diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/action/vyos.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/action/vyos.py deleted file mode 100644 index 7865916..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/action/vyos.py +++ /dev/null @@ -1,128 +0,0 @@ -# -# (c) 2016 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/>. -# -from __future__ import annotations - - -import sys -import copy - -from ansible_collections.ansible.netcommon.plugins.action.network import ( - ActionModule as ActionNetworkModule, -) -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( - load_provider, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( - vyos_provider_spec, -) -from ansible.utils.display import Display - -display = Display() - - -class ActionModule(ActionNetworkModule): - def run(self, tmp=None, task_vars=None): - del tmp # tmp no longer has any effect - - module_name = self._task.action.split(".")[-1] - self._config_module = True if module_name == "vyos_config" else False - persistent_connection = self._play_context.connection.split(".")[-1] - warnings = [] - - if persistent_connection == "network_cli": - provider = self._task.args.get("provider", {}) - if any(provider.values()): - display.warning( - "provider is unnecessary when using network_cli and will be ignored" - ) - del self._task.args["provider"] - elif self._play_context.connection == "local": - provider = load_provider(vyos_provider_spec, self._task.args) - pc = copy.deepcopy(self._play_context) - pc.connection = "ansible.netcommon.network_cli" - pc.network_os = "vyos.vyos.vyos" - pc.remote_addr = provider["host"] or self._play_context.remote_addr - pc.port = int(provider["port"] or self._play_context.port or 22) - pc.remote_user = ( - provider["username"] or self._play_context.connection_user - ) - pc.password = provider["password"] or self._play_context.password - pc.private_key_file = ( - provider["ssh_keyfile"] or self._play_context.private_key_file - ) - - connection = self._shared_loader_obj.connection_loader.get( - "ansible.netcommon.persistent", - pc, - sys.stdin, - task_uuid=self._task._uuid, - ) - - # TODO: Remove below code after ansible minimal is cut out - if connection is None: - pc.connection = "network_cli" - pc.network_os = "vyos" - connection = self._shared_loader_obj.connection_loader.get( - "persistent", pc, sys.stdin, task_uuid=self._task._uuid - ) - - display.vvv( - "using connection plugin %s (was local)" % pc.connection, - pc.remote_addr, - ) - - command_timeout = ( - int(provider["timeout"]) - if provider["timeout"] - else connection.get_option("persistent_command_timeout") - ) - connection.set_options( - direct={"persistent_command_timeout": command_timeout} - ) - - socket_path = connection.run() - display.vvvv("socket_path: %s" % socket_path, pc.remote_addr) - if not socket_path: - return { - "failed": True, - "msg": "unable to open shell. Please see: " - + "https://docs.ansible.com/ansible/latest/network/user_guide/network_debug_troubleshooting.html#category-unable-to-open-shell", - } - - task_vars["ansible_socket"] = socket_path - warnings.append( - [ - "connection local support for this module is deprecated and will be removed in version 2.14, use connection %s" - % pc.connection - ] - ) - else: - return { - "failed": True, - "msg": "Connection type %s is not valid for this module" - % self._play_context.connection, - } - - result = super(ActionModule, self).run(task_vars=task_vars) - if warnings: - if "warnings" in result: - result["warnings"].extend(warnings) - else: - result["warnings"] = warnings - return result diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/cliconf/vyos.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/cliconf/vyos.py deleted file mode 100644 index ca54c91..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/cliconf/vyos.py +++ /dev/null @@ -1,342 +0,0 @@ -# -# (c) 2017 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/>. -# -from __future__ import annotations - - -DOCUMENTATION = """ ---- -author: Ansible Networking Team -cliconf: vyos -short_description: Use vyos cliconf to run command on VyOS platform -description: - - This vyos plugin provides low level abstraction apis for - sending and receiving CLI commands from VyOS network devices. -version_added: "2.4" -""" - -import re -import json - -from collections.abc import Mapping - -from ansible.errors import AnsibleConnectionFailure -from ansible.module_utils.common.text.converters import to_text -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config import ( - NetworkConfig, -) -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( - to_list, -) -from ansible.plugins.cliconf import CliconfBase - - -class Cliconf(CliconfBase): - def get_device_info(self): - device_info = {} - - 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"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() - - return device_info - - def get_config(self, flags=None, format=None): - if format: - option_values = self.get_option_values() - if format not in option_values["format"]: - raise ValueError( - "'format' value %s is invalid. Valid values of format are %s" - % (format, ", ".join(option_values["format"])) - ) - - if not flags: - flags = [] - - if format == "text": - command = "show configuration" - else: - command = "show configuration commands" - - command += " ".join(to_list(flags)) - command = command.strip() - - out = self.send_command(command) - return out - - def edit_config( - self, candidate=None, commit=True, replace=None, comment=None - ): - resp = {} - operations = self.get_device_operations() - self.check_edit_config_capability( - operations, candidate, commit, replace, comment - ) - - results = [] - requests = [] - self.send_command("configure") - for cmd in to_list(candidate): - if not isinstance(cmd, Mapping): - cmd = {"command": cmd} - - results.append(self.send_command(**cmd)) - requests.append(cmd["command"]) - out = self.get("compare") - out = to_text(out, errors="surrogate_or_strict") - diff_config = out if not out.startswith("No changes") else None - - if diff_config: - if commit: - try: - self.commit(comment) - except AnsibleConnectionFailure as e: - msg = "commit failed: %s" % e.message - self.discard_changes() - raise AnsibleConnectionFailure(msg) - else: - self.send_command("exit") - else: - self.discard_changes() - else: - self.send_command("exit") - if ( - to_text( - self._connection.get_prompt(), errors="surrogate_or_strict" - ) - .strip() - .endswith("#") - ): - self.discard_changes() - - if diff_config: - resp["diff"] = diff_config - resp["response"] = results - resp["request"] = requests - return resp - - def get( - self, - command=None, - prompt=None, - answer=None, - sendonly=False, - output=None, - newline=True, - check_all=False, - ): - if not command: - raise ValueError("must provide value of command to execute") - if output: - raise ValueError( - "'output' value %s is not supported for get" % output - ) - - return self.send_command( - command=command, - prompt=prompt, - answer=answer, - sendonly=sendonly, - newline=newline, - check_all=check_all, - ) - - def commit(self, comment=None): - if comment: - command = 'commit comment "{0}"'.format(comment) - else: - command = "commit" - self.send_command(command) - - def discard_changes(self): - self.send_command("exit discard") - - def get_diff( - self, - candidate=None, - running=None, - diff_match="line", - diff_ignore_lines=None, - path=None, - diff_replace=None, - ): - diff = {} - device_operations = self.get_device_operations() - option_values = self.get_option_values() - - if candidate is None and device_operations["supports_generate_diff"]: - raise ValueError( - "candidate configuration is required to generate diff" - ) - - if diff_match not in option_values["diff_match"]: - raise ValueError( - "'match' value %s in invalid, valid values are %s" - % (diff_match, ", ".join(option_values["diff_match"])) - ) - - if diff_replace: - raise ValueError("'replace' in diff is not supported") - - if diff_ignore_lines: - raise ValueError("'diff_ignore_lines' in diff is not supported") - - if path: - raise ValueError("'path' in diff is not supported") - - set_format = candidate.startswith("set") or candidate.startswith( - "delete" - ) - candidate_obj = NetworkConfig(indent=4, contents=candidate) - if not set_format: - config = [c.line for c in candidate_obj.items] - commands = list() - # this filters out less specific lines - for item in config: - for index, entry in enumerate(commands): - if item.startswith(entry): - del commands[index] - break - commands.append(item) - - candidate_commands = [ - "set %s" % cmd.replace(" {", "") for cmd in commands - ] - - else: - candidate_commands = str(candidate).strip().split("\n") - - if diff_match == "none": - diff["config_diff"] = list(candidate_commands) - return diff - - running_commands = [ - str(c).replace("'", "") for c in running.splitlines() - ] - - updates = list() - visited = set() - - for line in candidate_commands: - item = str(line).replace("'", "") - - if not item.startswith("set") and not item.startswith("delete"): - raise ValueError( - "line must start with either `set` or `delete`" - ) - - elif item.startswith("set") and item not in running_commands: - updates.append(line) - - elif item.startswith("delete"): - if not running_commands: - updates.append(line) - else: - item = re.sub(r"delete", "set", item) - for entry in running_commands: - if entry.startswith(item) and line not in visited: - updates.append(line) - visited.add(line) - - diff["config_diff"] = list(updates) - return diff - - def run_commands(self, commands=None, check_rc=True): - if commands is None: - raise ValueError("'commands' value is required") - - responses = list() - for cmd in to_list(commands): - if not isinstance(cmd, Mapping): - cmd = {"command": cmd} - - output = cmd.pop("output", None) - if output: - raise ValueError( - "'output' value %s is not supported for run_commands" - % output - ) - - try: - out = self.send_command(**cmd) - except AnsibleConnectionFailure as e: - if check_rc: - raise - out = getattr(e, "err", e) - - responses.append(out) - - return responses - - def get_device_operations(self): - return { - "supports_diff_replace": False, - "supports_commit": True, - "supports_rollback": False, - "supports_defaults": False, - "supports_onbox_diff": True, - "supports_commit_comment": True, - "supports_multiline_delimiter": False, - "supports_diff_match": True, - "supports_diff_ignore_lines": False, - "supports_generate_diff": False, - "supports_replace": False, - } - - def get_option_values(self): - return { - "format": ["text", "set"], - "diff_match": ["line", "none"], - "diff_replace": [], - "output": [], - } - - def get_capabilities(self): - result = super(Cliconf, self).get_capabilities() - result["rpc"] += [ - "commit", - "discard_changes", - "get_diff", - "run_commands", - ] - result["device_operations"] = self.get_device_operations() - result.update(self.get_option_values()) - return json.dumps(result) - - def set_cli_prompt_context(self): - """ - Make sure we are in the operational cli mode - :return: None - """ - if self._connection.connected: - self._update_cli_prompt_context( - config_context="#", exit_command="exit discard" - ) diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/doc_fragments/vyos.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/doc_fragments/vyos.py deleted file mode 100644 index a7f8c12..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/doc_fragments/vyos.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright: (c) 2015, Peter Sprygada <psprygada@ansible.com> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -from __future__ import annotations - - -class ModuleDocFragment(object): - - # Standard files documentation fragment - DOCUMENTATION = r"""options: - provider: - description: - - B(Deprecated) - - 'Starting with Ansible 2.5 we recommend using C(connection: network_cli).' - - For more information please see the L(Network Guide, ../network/getting_started/network_differences.html#multiple-communication-protocols). - - HORIZONTALLINE - - A dict object containing connection details. - type: dict - suboptions: - host: - description: - - Specifies the DNS host name or address for connecting to the remote device - over the specified transport. The value of host is used as the destination - address for the transport. - type: str - required: true - port: - description: - - Specifies the port to use when building the connection to the remote device. - type: int - default: 22 - username: - description: - - Configures the username to use to authenticate the connection to the remote - device. This value is used to authenticate the SSH session. If the value - is not specified in the task, the value of environment variable C(ANSIBLE_NET_USERNAME) - will be used instead. - type: str - password: - description: - - Specifies the password to use to authenticate the connection to the remote - device. This value is used to authenticate the SSH session. If the value - is not specified in the task, the value of environment variable C(ANSIBLE_NET_PASSWORD) - will be used instead. - type: str - timeout: - description: - - Specifies the timeout in seconds for communicating with the network device - for either connecting or sending commands. If the timeout is exceeded before - the operation is completed, the module will error. - type: int - default: 10 - ssh_keyfile: - description: - - Specifies the SSH key to use to authenticate the connection to the remote - device. This value is the path to the key used to authenticate the SSH - session. If the value is not specified in the task, the value of environment - variable C(ANSIBLE_NET_SSH_KEYFILE) will be used instead. - type: path -notes: -- For more information on using Ansible to manage network devices see the :ref:`Ansible - Network Guide <network_guide>` -""" diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/facts/facts.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/facts/facts.py deleted file mode 100644 index afe04ba..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/facts/facts.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The arg spec for the vyos facts module. -""" -from __future__ import annotations - - -class FactsArgs(object): # pylint: disable=R0903 - """ The arg spec for the vyos facts module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = { - "gather_subset": dict(default=["!config"], type="list"), - "gather_network_resources": dict(type="list"), - } diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/firewall_rules/firewall_rules.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/firewall_rules/firewall_rules.py deleted file mode 100644 index 51822ac..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/firewall_rules/firewall_rules.py +++ /dev/null @@ -1,261 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# -""" -The arg spec for the vyos_firewall_rules module -""" - -from __future__ import annotations - - -class Firewall_rulesArgs(object): # pylint: disable=R0903 - """The arg spec for the vyos_firewall_rules module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = { - "config": { - "elements": "dict", - "options": { - "afi": { - "choices": ["ipv4", "ipv6"], - "required": True, - "type": "str", - }, - "rule_sets": { - "elements": "dict", - "options": { - "default_action": { - "choices": ["drop", "reject", "accept"], - "type": "str", - }, - "description": {"type": "str"}, - "enable_default_log": {"type": "bool"}, - "name": {"type": "str"}, - "rules": { - "elements": "dict", - "options": { - "action": { - "choices": [ - "drop", - "reject", - "accept", - "inspect", - ], - "type": "str", - }, - "description": {"type": "str"}, - "destination": { - "options": { - "address": {"type": "str"}, - "group": { - "options": { - "address_group": { - "type": "str" - }, - "network_group": { - "type": "str" - }, - "port_group": {"type": "str"}, - }, - "type": "dict", - }, - "port": {"type": "str"}, - }, - "type": "dict", - }, - "disabled": {"type": "bool"}, - "fragment": { - "choices": [ - "match-frag", - "match-non-frag", - ], - "type": "str", - }, - "icmp": { - "options": { - "code": {"type": "int"}, - "type": {"type": "int"}, - "type_name": { - "choices": [ - "any", - "echo-reply", - "destination-unreachable", - "network-unreachable", - "host-unreachable", - "protocol-unreachable", - "port-unreachable", - "fragmentation-needed", - "source-route-failed", - "network-unknown", - "host-unknown", - "network-prohibited", - "host-prohibited", - "TOS-network-unreachable", - "TOS-host-unreachable", - "communication-prohibited", - "host-precedence-violation", - "precedence-cutoff", - "source-quench", - "redirect", - "network-redirect", - "host-redirect", - "TOS-network-redirect", - "TOS-host-redirect", - "echo-request", - "router-advertisement", - "router-solicitation", - "time-exceeded", - "ttl-zero-during-transit", - "ttl-zero-during-reassembly", - "parameter-problem", - "ip-header-bad", - "required-option-missing", - "timestamp-request", - "timestamp-reply", - "address-mask-request", - "address-mask-reply", - "ping", - "pong", - "ttl-exceeded", - ], - "type": "str", - }, - }, - "type": "dict", - }, - "ipsec": { - "choices": ["match-ipsec", "match-none"], - "type": "str", - }, - "limit": { - "options": { - "burst": {"type": "int"}, - "rate": { - "options": { - "number": {"type": "int"}, - "unit": {"type": "str"}, - }, - "type": "dict", - }, - }, - "type": "dict", - }, - "number": {"required": True, "type": "int"}, - "p2p": { - "elements": "dict", - "options": { - "application": { - "choices": [ - "all", - "applejuice", - "bittorrent", - "directconnect", - "edonkey", - "gnutella", - "kazaa", - ], - "type": "str", - } - }, - "type": "list", - }, - "protocol": {"type": "str"}, - "recent": { - "options": { - "count": {"type": "int"}, - "time": {"type": "int"}, - }, - "type": "dict", - }, - "source": { - "options": { - "address": {"type": "str"}, - "group": { - "options": { - "address_group": { - "type": "str" - }, - "network_group": { - "type": "str" - }, - "port_group": {"type": "str"}, - }, - "type": "dict", - }, - "mac_address": {"type": "str"}, - "port": {"type": "str"}, - }, - "type": "dict", - }, - "state": { - "options": { - "established": {"type": "bool"}, - "invalid": {"type": "bool"}, - "new": {"type": "bool"}, - "related": {"type": "bool"}, - }, - "type": "dict", - }, - "tcp": { - "options": {"flags": {"type": "str"}}, - "type": "dict", - }, - "time": { - "options": { - "monthdays": {"type": "str"}, - "startdate": {"type": "str"}, - "starttime": {"type": "str"}, - "stopdate": {"type": "str"}, - "stoptime": {"type": "str"}, - "utc": {"type": "bool"}, - "weekdays": {"type": "str"}, - }, - "type": "dict", - }, - }, - "type": "list", - }, - }, - "type": "list", - }, - }, - "type": "list", - }, - "running_config": {"type": "str"}, - "state": { - "choices": [ - "merged", - "replaced", - "overridden", - "deleted", - "gathered", - "rendered", - "parsed", - ], - "default": "merged", - "type": "str", - }, - } # pylint: disable=C0301 diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/interfaces/interfaces.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/interfaces/interfaces.py deleted file mode 100644 index 7bf0c22..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/interfaces/interfaces.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# -""" -The arg spec for the vyos_interfaces module -""" - -from __future__ import annotations - - -class InterfacesArgs(object): # pylint: disable=R0903 - """The arg spec for the vyos_interfaces module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = { - "config": { - "elements": "dict", - "options": { - "description": {"type": "str"}, - "duplex": {"choices": ["full", "half", "auto"]}, - "enabled": {"default": True, "type": "bool"}, - "mtu": {"type": "int"}, - "name": {"required": True, "type": "str"}, - "speed": { - "choices": ["auto", "10", "100", "1000", "2500", "10000"], - "type": "str", - }, - "vifs": { - "elements": "dict", - "options": { - "vlan_id": {"type": "int"}, - "description": {"type": "str"}, - "enabled": {"default": True, "type": "bool"}, - "mtu": {"type": "int"}, - }, - "type": "list", - }, - }, - "type": "list", - }, - "state": { - "choices": ["merged", "replaced", "overridden", "deleted"], - "default": "merged", - "type": "str", - }, - } # pylint: disable=C0301 diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/l3_interfaces/l3_interfaces.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/l3_interfaces/l3_interfaces.py deleted file mode 100644 index 9ce2af5..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/l3_interfaces/l3_interfaces.py +++ /dev/null @@ -1,79 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# -""" -The arg spec for the vyos_l3_interfaces module -""" - - -from __future__ import annotations - - -class L3_interfacesArgs(object): # pylint: disable=R0903 - """The arg spec for the vyos_l3_interfaces module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = { - "config": { - "elements": "dict", - "options": { - "ipv4": { - "elements": "dict", - "options": {"address": {"type": "str"}}, - "type": "list", - }, - "ipv6": { - "elements": "dict", - "options": {"address": {"type": "str"}}, - "type": "list", - }, - "name": {"required": True, "type": "str"}, - "vifs": { - "elements": "dict", - "options": { - "ipv4": { - "elements": "dict", - "options": {"address": {"type": "str"}}, - "type": "list", - }, - "ipv6": { - "elements": "dict", - "options": {"address": {"type": "str"}}, - "type": "list", - }, - "vlan_id": {"type": "int"}, - }, - "type": "list", - }, - }, - "type": "list", - }, - "state": { - "choices": ["merged", "replaced", "overridden", "deleted"], - "default": "merged", - "type": "str", - }, - } # pylint: disable=C0301 diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/lag_interfaces/lag_interfaces.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/lag_interfaces/lag_interfaces.py deleted file mode 100644 index b68513f..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/lag_interfaces/lag_interfaces.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The arg spec for the vyos_lag_interfaces module -""" -from __future__ import annotations - - -class Lag_interfacesArgs(object): # pylint: disable=R0903 - """The arg spec for the vyos_lag_interfaces module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = { - "config": { - "elements": "dict", - "options": { - "arp_monitor": { - "options": { - "interval": {"type": "int"}, - "target": {"type": "list"}, - }, - "type": "dict", - }, - "hash_policy": { - "choices": ["layer2", "layer2+3", "layer3+4"], - "type": "str", - }, - "members": { - "elements": "dict", - "options": {"member": {"type": "str"}}, - "type": "list", - }, - "mode": { - "choices": [ - "802.3ad", - "active-backup", - "broadcast", - "round-robin", - "transmit-load-balance", - "adaptive-load-balance", - "xor-hash", - ], - "type": "str", - }, - "name": {"required": True, "type": "str"}, - "primary": {"type": "str"}, - }, - "type": "list", - }, - "state": { - "choices": ["merged", "replaced", "overridden", "deleted"], - "default": "merged", - "type": "str", - }, - } # pylint: disable=C0301 diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/lldp_global/lldp_global.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/lldp_global/lldp_global.py deleted file mode 100644 index d56ff21..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/lldp_global/lldp_global.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The arg spec for the vyos_lldp_global module -""" -from __future__ import annotations - - -class Lldp_globalArgs(object): # pylint: disable=R0903 - """The arg spec for the vyos_lldp_global module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = { - "config": { - "options": { - "address": {"type": "str"}, - "enable": {"type": "bool"}, - "legacy_protocols": { - "choices": ["cdp", "edp", "fdp", "sonmp"], - "type": "list", - }, - "snmp": {"type": "str"}, - }, - "type": "dict", - }, - "state": { - "choices": ["merged", "replaced", "deleted"], - "default": "merged", - "type": "str", - }, - } # pylint: disable=C0301 diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/lldp_interfaces/lldp_interfaces.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/lldp_interfaces/lldp_interfaces.py deleted file mode 100644 index 7a639fe..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/lldp_interfaces/lldp_interfaces.py +++ /dev/null @@ -1,87 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# -""" -The arg spec for the vyos_lldp_interfaces module -""" - -from __future__ import annotations - - -class Lldp_interfacesArgs(object): # pylint: disable=R0903 - """The arg spec for the vyos_lldp_interfaces module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = { - "config": { - "elements": "dict", - "options": { - "enable": {"default": True, "type": "bool"}, - "location": { - "options": { - "civic_based": { - "options": { - "ca_info": { - "elements": "dict", - "options": { - "ca_type": {"type": "int"}, - "ca_value": {"type": "str"}, - }, - "type": "list", - }, - "country_code": { - "required": True, - "type": "str", - }, - }, - "type": "dict", - }, - "coordinate_based": { - "options": { - "altitude": {"type": "int"}, - "datum": { - "choices": ["WGS84", "NAD83", "MLLW"], - "type": "str", - }, - "latitude": {"required": True, "type": "str"}, - "longitude": {"required": True, "type": "str"}, - }, - "type": "dict", - }, - "elin": {"type": "str"}, - }, - "type": "dict", - }, - "name": {"required": True, "type": "str"}, - }, - "type": "list", - }, - "state": { - "choices": ["merged", "replaced", "overridden", "deleted"], - "default": "merged", - "type": "str", - }, - } # pylint: disable=C0301 diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/static_routes/static_routes.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/static_routes/static_routes.py deleted file mode 100644 index 191dc76..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/argspec/static_routes/static_routes.py +++ /dev/null @@ -1,97 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# -""" -The arg spec for the vyos_static_routes module -""" - -from __future__ import annotations - - -class Static_routesArgs(object): # pylint: disable=R0903 - """The arg spec for the vyos_static_routes module - """ - - def __init__(self, **kwargs): - pass - - argument_spec = { - "config": { - "elements": "dict", - "options": { - "address_families": { - "elements": "dict", - "options": { - "afi": { - "choices": ["ipv4", "ipv6"], - "required": True, - "type": "str", - }, - "routes": { - "elements": "dict", - "options": { - "blackhole_config": { - "options": { - "distance": {"type": "int"}, - "type": {"type": "str"}, - }, - "type": "dict", - }, - "dest": {"required": True, "type": "str"}, - "next_hops": { - "elements": "dict", - "options": { - "admin_distance": {"type": "int"}, - "enabled": {"type": "bool"}, - "forward_router_address": { - "required": True, - "type": "str", - }, - "interface": {"type": "str"}, - }, - "type": "list", - }, - }, - "type": "list", - }, - }, - "type": "list", - } - }, - "type": "list", - }, - "running_config": {"type": "str"}, - "state": { - "choices": [ - "merged", - "replaced", - "overridden", - "deleted", - "gathered", - "rendered", - "parsed", - ], - "default": "merged", - "type": "str", - }, - } # pylint: disable=C0301 diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py deleted file mode 100644 index 5b61427..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py +++ /dev/null @@ -1,436 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The vyos_lldp_interfaces class -It is in this file where the current configuration (as dict) -is compared to the provided configuration (as dict) and the command set -necessary to bring the current configuration to it's desired end-state is -created -""" - -from __future__ import annotations - - -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import ( - ConfigBase, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import ( - Facts, -) -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( - to_list, - dict_diff, -) -from ansible.module_utils.six import iteritems -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import ( - search_obj_in_list, - search_dict_tv_in_list, - key_value_in_dict, - is_dict_element_present, -) - - -class Lldp_interfaces(ConfigBase): - """ - The vyos_lldp_interfaces class - """ - - gather_subset = [ - "!all", - "!min", - ] - - gather_network_resources = [ - "lldp_interfaces", - ] - - params = ["enable", "location", "name"] - - def __init__(self, module): - super(Lldp_interfaces, self).__init__(module) - - def get_lldp_interfaces_facts(self): - """ Get the 'facts' (the current configuration) - - :rtype: A dictionary - :returns: The current configuration as a dictionary - """ - facts, _warnings = Facts(self._module).get_facts( - self.gather_subset, self.gather_network_resources - ) - lldp_interfaces_facts = facts["ansible_network_resources"].get( - "lldp_interfaces" - ) - if not lldp_interfaces_facts: - return [] - return lldp_interfaces_facts - - def execute_module(self): - """ Execute the module - - :rtype: A dictionary - :returns: The result from module execution - """ - result = {"changed": False} - commands = list() - warnings = list() - existing_lldp_interfaces_facts = self.get_lldp_interfaces_facts() - commands.extend(self.set_config(existing_lldp_interfaces_facts)) - if commands: - if self._module.check_mode: - resp = self._connection.edit_config(commands, commit=False) - else: - resp = self._connection.edit_config(commands) - result["changed"] = True - - result["commands"] = commands - - if self._module._diff: - result["diff"] = resp["diff"] if result["changed"] else None - - changed_lldp_interfaces_facts = self.get_lldp_interfaces_facts() - result["before"] = existing_lldp_interfaces_facts - if result["changed"]: - result["after"] = changed_lldp_interfaces_facts - - result["warnings"] = warnings - return result - - def set_config(self, existing_lldp_interfaces_facts): - """ Collect the configuration from the args passed to the module, - collect the current configuration (as a dict from facts) - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - want = self._module.params["config"] - have = existing_lldp_interfaces_facts - resp = self.set_state(want, have) - return to_list(resp) - - def set_state(self, want, have): - """ Select the appropriate function based on the state provided - - :param want: the desired configuration as a dictionary - :param have: the current configuration as a dictionary - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - state = self._module.params["state"] - if state in ("merged", "replaced", "overridden") and not want: - self._module.fail_json( - msg="value of config parameter must not be empty for state {0}".format( - state - ) - ) - if state == "overridden": - commands.extend(self._state_overridden(want=want, have=have)) - elif state == "deleted": - if want: - for item in want: - name = item["name"] - have_item = search_obj_in_list(name, have) - commands.extend( - self._state_deleted(want=None, have=have_item) - ) - else: - for have_item in have: - commands.extend( - self._state_deleted(want=None, have=have_item) - ) - else: - for want_item in want: - name = want_item["name"] - have_item = search_obj_in_list(name, have) - if state == "merged": - commands.extend( - self._state_merged(want=want_item, have=have_item) - ) - else: - commands.extend( - self._state_replaced(want=want_item, have=have_item) - ) - return commands - - def _state_replaced(self, want, have): - """ The command generator when state is replaced - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - if have: - commands.extend(self._state_deleted(want, have)) - commands.extend(self._state_merged(want, have)) - return commands - - def _state_overridden(self, want, have): - """ The command generator when state is overridden - - :rtype: A list - :returns: the commands necessary to migrate the current configuration - to the desired configuration - """ - commands = [] - for have_item in have: - lldp_name = have_item["name"] - lldp_in_want = search_obj_in_list(lldp_name, want) - if not lldp_in_want: - commands.append( - self._compute_command(have_item["name"], remove=True) - ) - - for want_item in want: - name = want_item["name"] - lldp_in_have = search_obj_in_list(name, have) - commands.extend(self._state_replaced(want_item, lldp_in_have)) - return commands - - def _state_merged(self, want, have): - """ The command generator when state is merged - - :rtype: A list - :returns: the commands necessary to merge the provided into - the current configuration - """ - commands = [] - if have: - commands.extend(self._render_updates(want, have)) - else: - commands.extend(self._render_set_commands(want)) - return commands - - def _state_deleted(self, want, have): - """ The command generator when state is deleted - - :rtype: A list - :returns: the commands necessary to remove the current configuration - of the provided objects - """ - commands = [] - if want: - params = Lldp_interfaces.params - for attrib in params: - if attrib == "location": - commands.extend( - self._update_location(have["name"], want, have) - ) - - elif have: - commands.append(self._compute_command(have["name"], remove=True)) - return commands - - def _render_updates(self, want, have): - commands = [] - lldp_name = have["name"] - commands.extend(self._configure_status(lldp_name, want, have)) - commands.extend(self._add_location(lldp_name, want, have)) - - return commands - - def _render_set_commands(self, want): - commands = [] - have = {} - lldp_name = want["name"] - params = Lldp_interfaces.params - - commands.extend(self._add_location(lldp_name, want, have)) - for attrib in params: - value = want[attrib] - if value: - if attrib == "location": - commands.extend(self._add_location(lldp_name, want, have)) - elif attrib == "enable": - if not value: - commands.append( - self._compute_command(lldp_name, value="disable") - ) - else: - commands.append(self._compute_command(lldp_name)) - - return commands - - def _configure_status(self, name, want_item, have_item): - commands = [] - if is_dict_element_present(have_item, "enable"): - temp_have_item = False - else: - temp_have_item = True - if want_item["enable"] != temp_have_item: - if want_item["enable"]: - commands.append( - self._compute_command(name, value="disable", remove=True) - ) - else: - commands.append(self._compute_command(name, value="disable")) - return commands - - def _add_location(self, name, want_item, have_item): - commands = [] - have_dict = {} - have_ca = {} - set_cmd = name + " location " - want_location_type = want_item.get("location") or {} - have_location_type = have_item.get("location") or {} - - if want_location_type["coordinate_based"]: - want_dict = want_location_type.get("coordinate_based") or {} - if is_dict_element_present(have_location_type, "coordinate_based"): - have_dict = have_location_type.get("coordinate_based") or {} - location_type = "coordinate-based" - updates = dict_diff(have_dict, want_dict) - for key, value in iteritems(updates): - if value: - commands.append( - self._compute_command( - set_cmd + location_type, key, str(value) - ) - ) - - elif want_location_type["civic_based"]: - location_type = "civic-based" - want_dict = want_location_type.get("civic_based") or {} - want_ca = want_dict.get("ca_info") or [] - if is_dict_element_present(have_location_type, "civic_based"): - have_dict = have_location_type.get("civic_based") or {} - have_ca = have_dict.get("ca_info") or [] - if want_dict["country_code"] != have_dict["country_code"]: - commands.append( - self._compute_command( - set_cmd + location_type, - "country-code", - str(want_dict["country_code"]), - ) - ) - else: - commands.append( - self._compute_command( - set_cmd + location_type, - "country-code", - str(want_dict["country_code"]), - ) - ) - commands.extend(self._add_civic_address(name, want_ca, have_ca)) - - elif want_location_type["elin"]: - location_type = "elin" - if is_dict_element_present(have_location_type, "elin"): - if want_location_type.get("elin") != have_location_type.get( - "elin" - ): - commands.append( - self._compute_command( - set_cmd + location_type, - value=str(want_location_type["elin"]), - ) - ) - else: - commands.append( - self._compute_command( - set_cmd + location_type, - value=str(want_location_type["elin"]), - ) - ) - return commands - - def _update_location(self, name, want_item, have_item): - commands = [] - del_cmd = name + " location" - want_location_type = want_item.get("location") or {} - have_location_type = have_item.get("location") or {} - - if want_location_type["coordinate_based"]: - want_dict = want_location_type.get("coordinate_based") or {} - if is_dict_element_present(have_location_type, "coordinate_based"): - have_dict = have_location_type.get("coordinate_based") or {} - location_type = "coordinate-based" - for key, value in iteritems(have_dict): - only_in_have = key_value_in_dict(key, value, want_dict) - if not only_in_have: - commands.append( - self._compute_command( - del_cmd + location_type, key, str(value), True - ) - ) - else: - commands.append(self._compute_command(del_cmd, remove=True)) - - elif want_location_type["civic_based"]: - want_dict = want_location_type.get("civic_based") or {} - want_ca = want_dict.get("ca_info") or [] - if is_dict_element_present(have_location_type, "civic_based"): - have_dict = have_location_type.get("civic_based") or {} - have_ca = have_dict.get("ca_info") - commands.extend( - self._update_civic_address(name, want_ca, have_ca) - ) - else: - commands.append(self._compute_command(del_cmd, remove=True)) - - else: - if is_dict_element_present(have_location_type, "elin"): - if want_location_type.get("elin") != have_location_type.get( - "elin" - ): - commands.append( - self._compute_command(del_cmd, remove=True) - ) - else: - commands.append(self._compute_command(del_cmd, remove=True)) - return commands - - def _add_civic_address(self, name, want, have): - commands = [] - for item in want: - ca_type = item["ca_type"] - ca_value = item["ca_value"] - obj_in_have = search_dict_tv_in_list( - ca_type, ca_value, have, "ca_type", "ca_value" - ) - if not obj_in_have: - commands.append( - self._compute_command( - key=name + " location civic-based ca-type", - attrib=str(ca_type) + " ca-value", - value=ca_value, - ) - ) - return commands - - def _update_civic_address(self, name, want, have): - commands = [] - for item in have: - ca_type = item["ca_type"] - ca_value = item["ca_value"] - in_want = search_dict_tv_in_list( - ca_type, ca_value, want, "ca_type", "ca_value" - ) - if not in_want: - commands.append( - self._compute_command( - name, - "location civic-based ca-type", - str(ca_type), - remove=True, - ) - ) - return commands - - def _compute_command(self, key, attrib=None, value=None, remove=False): - if remove: - cmd = "delete service lldp interface " - else: - cmd = "set service lldp interface " - cmd += key - if attrib: - cmd += " " + attrib - if value: - cmd += " '" + value + "'" - return cmd diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/facts.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/facts.py deleted file mode 100644 index f174849..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/facts.py +++ /dev/null @@ -1,82 +0,0 @@ -# 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 annotations - -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.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, -) - - -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/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py deleted file mode 100644 index 6e583f6..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py +++ /dev/null @@ -1,379 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The vyos firewall_rules fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" -from __future__ import annotations - - -from re import findall, search, M -from copy import deepcopy -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( - utils, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.firewall_rules.firewall_rules import ( - Firewall_rulesArgs, -) - - -class Firewall_rulesFacts(object): - """ The vyos firewall_rules fact class - """ - - def __init__(self, module, subspec="config", options="options"): - self._module = module - self.argument_spec = Firewall_rulesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def get_device_data(self, connection): - return connection.get_config() - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for firewall_rules - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - if not data: - # typically data is populated from the current device configuration - # data = connection.get('show running-config | section ^interface') - # using mock data instead - data = self.get_device_data(connection) - # split the config into instances of the resource - objs = [] - v6_rules = findall( - r"^set firewall ipv6-name (?:\'*)(\S+)(?:\'*)", data, M - ) - v4_rules = findall(r"^set firewall name (?:\'*)(\S+)(?:\'*)", data, M) - if v6_rules: - config = self.get_rules(data, v6_rules, type="ipv6") - if config: - config = utils.remove_empties(config) - objs.append(config) - if v4_rules: - config = self.get_rules(data, v4_rules, type="ipv4") - if config: - config = utils.remove_empties(config) - objs.append(config) - - ansible_facts["ansible_network_resources"].pop("firewall_rules", None) - facts = {} - if objs: - facts["firewall_rules"] = [] - params = utils.validate_config( - self.argument_spec, {"config": objs} - ) - for cfg in params["config"]: - facts["firewall_rules"].append(utils.remove_empties(cfg)) - - ansible_facts["ansible_network_resources"].update(facts) - return ansible_facts - - def get_rules(self, data, rules, type): - """ - This function performs following: - - Form regex to fetch 'rule-sets' specific config from data. - - Form the rule-set list based on ip address. - :param data: configuration. - :param rules: list of rule-sets. - :param type: ip address type. - :return: generated rule-sets configuration. - """ - r_v4 = [] - r_v6 = [] - for r in set(rules): - rule_regex = r" %s .+$" % r.strip("'") - cfg = findall(rule_regex, data, M) - fr = self.render_config(cfg, r.strip("'")) - fr["name"] = r.strip("'") - if type == "ipv6": - r_v6.append(fr) - else: - r_v4.append(fr) - if r_v4: - config = {"afi": "ipv4", "rule_sets": r_v4} - if r_v6: - config = {"afi": "ipv6", "rule_sets": r_v6} - return config - - def render_config(self, conf, match): - """ - Render config as dictionary structure and delete keys - from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - conf = "\n".join(filter(lambda x: x, conf)) - a_lst = ["description", "default_action", "enable_default_log"] - config = self.parse_attr(conf, a_lst, match) - if not config: - config = {} - config["rules"] = self.parse_rules_lst(conf) - return config - - def parse_rules_lst(self, conf): - """ - This function forms the regex to fetch the 'rules' with in - 'rule-sets' - :param conf: configuration data. - :return: generated rule list configuration. - """ - r_lst = [] - rules = findall(r"rule (?:\'*)(\d+)(?:\'*)", conf, M) - if rules: - rules_lst = [] - for r in set(rules): - r_regex = r" %s .+$" % r - cfg = "\n".join(findall(r_regex, conf, M)) - obj = self.parse_rules(cfg) - obj["number"] = int(r) - if obj: - rules_lst.append(obj) - r_lst = sorted(rules_lst, key=lambda i: i["number"]) - return r_lst - - def parse_rules(self, conf): - """ - This function triggers the parsing of 'rule' attributes. - a_lst is a list having rule attributes which doesn't - have further sub attributes. - :param conf: configuration - :return: generated rule configuration dictionary. - """ - a_lst = [ - "ipsec", - "action", - "protocol", - "fragment", - "disabled", - "description", - ] - rule = self.parse_attr(conf, a_lst) - r_sub = { - "p2p": self.parse_p2p(conf), - "tcp": self.parse_tcp(conf, "tcp"), - "icmp": self.parse_icmp(conf, "icmp"), - "time": self.parse_time(conf, "time"), - "limit": self.parse_limit(conf, "limit"), - "state": self.parse_state(conf, "state"), - "recent": self.parse_recent(conf, "recent"), - "source": self.parse_src_or_dest(conf, "source"), - "destination": self.parse_src_or_dest(conf, "destination"), - } - rule.update(r_sub) - return rule - - def parse_p2p(self, conf): - """ - This function forms the regex to fetch the 'p2p' with in - 'rules' - :param conf: configuration data. - :return: generated rule list configuration. - """ - a_lst = [] - applications = findall(r"p2p (?:\'*)(\d+)(?:\'*)", conf, M) - if applications: - app_lst = [] - for r in set(applications): - obj = {"application": r.strip("'")} - app_lst.append(obj) - a_lst = sorted(app_lst, key=lambda i: i["application"]) - return a_lst - - def parse_src_or_dest(self, conf, attrib=None): - """ - This function triggers the parsing of 'source or - destination' attributes. - :param conf: configuration. - :param attrib:'source/destination'. - :return:generated source/destination configuration dictionary. - """ - a_lst = ["port", "address", "mac_address"] - cfg_dict = self.parse_attr(conf, a_lst, match=attrib) - cfg_dict["group"] = self.parse_group(conf, attrib + " group") - return cfg_dict - - def parse_recent(self, conf, attrib=None): - """ - This function triggers the parsing of 'recent' attributes - :param conf: configuration. - :param attrib: 'recent'. - :return: generated config dictionary. - """ - a_lst = ["time", "count"] - cfg_dict = self.parse_attr(conf, a_lst, match=attrib) - return cfg_dict - - def parse_tcp(self, conf, attrib=None): - """ - This function triggers the parsing of 'tcp' attributes. - :param conf: configuration. - :param attrib: 'tcp'. - :return: generated config dictionary. - """ - cfg_dict = self.parse_attr(conf, ["flags"], match=attrib) - return cfg_dict - - def parse_time(self, conf, attrib=None): - """ - This function triggers the parsing of 'time' attributes. - :param conf: configuration. - :param attrib: 'time'. - :return: generated config dictionary. - """ - a_lst = [ - "stopdate", - "stoptime", - "weekdays", - "monthdays", - "startdate", - "starttime", - ] - cfg_dict = self.parse_attr(conf, a_lst, match=attrib) - return cfg_dict - - def parse_state(self, conf, attrib=None): - """ - This function triggers the parsing of 'state' attributes. - :param conf: configuration - :param attrib: 'state'. - :return: generated config dictionary. - """ - a_lst = ["new", "invalid", "related", "established"] - cfg_dict = self.parse_attr(conf, a_lst, match=attrib) - return cfg_dict - - def parse_group(self, conf, attrib=None): - """ - This function triggers the parsing of 'group' attributes. - :param conf: configuration. - :param attrib: 'group'. - :return: generated config dictionary. - """ - a_lst = ["port_group", "address_group", "network_group"] - cfg_dict = self.parse_attr(conf, a_lst, match=attrib) - return cfg_dict - - def parse_icmp(self, conf, attrib=None): - """ - This function triggers the parsing of 'icmp' attributes. - :param conf: configuration to be parsed. - :param attrib: 'icmp'. - :return: generated config dictionary. - """ - a_lst = ["code", "type", "type_name"] - cfg_dict = self.parse_attr(conf, a_lst, match=attrib) - return cfg_dict - - def parse_limit(self, conf, attrib=None): - """ - This function triggers the parsing of 'limit' attributes. - :param conf: configuration to be parsed. - :param attrib: 'limit' - :return: generated config dictionary. - """ - cfg_dict = self.parse_attr(conf, ["burst"], match=attrib) - cfg_dict["rate"] = self.parse_rate(conf, "rate") - return cfg_dict - - def parse_rate(self, conf, attrib=None): - """ - This function triggers the parsing of 'rate' attributes. - :param conf: configuration. - :param attrib: 'rate' - :return: generated config dictionary. - """ - a_lst = ["unit", "number"] - cfg_dict = self.parse_attr(conf, a_lst, match=attrib) - return cfg_dict - - def parse_attr(self, conf, attr_list, match=None): - """ - This function peforms the following: - - Form the regex to fetch the required attribute config. - - Type cast the output in desired format. - :param conf: configuration. - :param attr_list: list of attributes. - :param match: parent node/attribute name. - :return: generated config dictionary. - """ - config = {} - for attrib in attr_list: - regex = self.map_regex(attrib) - if match: - regex = match + " " + regex - if conf: - if self.is_bool(attrib): - out = conf.find(attrib.replace("_", "-")) - - dis = conf.find(attrib.replace("_", "-") + " 'disable'") - if out >= 1: - if dis >= 1: - config[attrib] = False - else: - config[attrib] = True - else: - out = search(r"^.*" + regex + " (.+)", conf, M) - if out: - val = out.group(1).strip("'") - if self.is_num(attrib): - val = int(val) - config[attrib] = val - return config - - def map_regex(self, attrib): - """ - - This function construct the regex string. - - replace the underscore with hyphen. - :param attrib: attribute - :return: regex string - """ - regex = attrib.replace("_", "-") - if attrib == "disabled": - regex = "disable" - return regex - - def is_bool(self, attrib): - """ - This function looks for the attribute in predefined bool type set. - :param attrib: attribute. - :return: True/False - """ - bool_set = ( - "new", - "invalid", - "related", - "disabled", - "established", - "enable_default_log", - ) - return True if attrib in bool_set else False - - def is_num(self, attrib): - """ - This function looks for the attribute in predefined integer type set. - :param attrib: attribute. - :return: True/false. - """ - num_set = ("time", "code", "type", "count", "burst", "number") - return True if attrib in num_set else False diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/interfaces/interfaces.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/interfaces/interfaces.py deleted file mode 100644 index e3bb52c..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/interfaces/interfaces.py +++ /dev/null @@ -1,132 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The vyos interfaces fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import annotations - - -from re import findall, M -from copy import deepcopy -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( - utils, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.interfaces.interfaces import ( - InterfacesArgs, -) - - -class InterfacesFacts(object): - """ The vyos interfaces fact class - """ - - def __init__(self, module, subspec="config", options="options"): - self._module = module - self.argument_spec = InterfacesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for interfaces - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - if not data: - data = connection.get_config(flags=["| grep interfaces"]) - - objs = [] - interface_names = findall( - r"^set interfaces (?:ethernet|bonding|vti|loopback|vxlan) (?:\'*)(\S+)(?:\'*)", - data, - M, - ) - if interface_names: - for interface in set(interface_names): - intf_regex = r" %s .+$" % interface.strip("'") - cfg = findall(intf_regex, data, M) - obj = self.render_config(cfg) - obj["name"] = interface.strip("'") - if obj: - objs.append(obj) - facts = {} - if objs: - facts["interfaces"] = [] - params = utils.validate_config( - self.argument_spec, {"config": objs} - ) - for cfg in params["config"]: - facts["interfaces"].append(utils.remove_empties(cfg)) - - ansible_facts["ansible_network_resources"].update(facts) - return ansible_facts - - def render_config(self, conf): - """ - Render config as dictionary structure and delete keys - from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - vif_conf = "\n".join(filter(lambda x: ("vif" in x), conf)) - eth_conf = "\n".join(filter(lambda x: ("vif" not in x), conf)) - config = self.parse_attribs( - ["description", "speed", "mtu", "duplex"], eth_conf - ) - config["vifs"] = self.parse_vifs(vif_conf) - - return utils.remove_empties(config) - - def parse_vifs(self, conf): - vif_names = findall(r"vif (?:\'*)(\d+)(?:\'*)", conf, M) - vifs_list = None - - if vif_names: - vifs_list = [] - for vif in set(vif_names): - vif_regex = r" %s .+$" % vif - cfg = "\n".join(findall(vif_regex, conf, M)) - obj = self.parse_attribs(["description", "mtu"], cfg) - obj["vlan_id"] = int(vif) - if obj: - vifs_list.append(obj) - vifs_list = sorted(vifs_list, key=lambda i: i["vlan_id"]) - - return vifs_list - - def parse_attribs(self, attribs, conf): - config = {} - for item in attribs: - value = utils.parse_conf_arg(conf, item) - if value and item == "mtu": - config[item] = int(value.strip("'")) - elif value: - config[item] = value.strip("'") - else: - config[item] = None - if "disable" in conf: - config["enabled"] = False - else: - config["enabled"] = True - - return utils.remove_empties(config) diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py deleted file mode 100644 index 944629c..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py +++ /dev/null @@ -1,141 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The vyos l3_interfaces fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import annotations - - -import re -from copy import deepcopy -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( - utils, -) -from ansible.module_utils.six import iteritems -from ansible_collections.ansible.netcommon.plugins.module_utils.compat import ( - ipaddress, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.l3_interfaces.l3_interfaces import ( - L3_interfacesArgs, -) - - -class L3_interfacesFacts(object): - """ The vyos l3_interfaces fact class - """ - - def __init__(self, module, subspec="config", options="options"): - self._module = module - self.argument_spec = L3_interfacesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for l3_interfaces - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - if not data: - data = connection.get_config() - - # operate on a collection of resource x - objs = [] - interface_names = re.findall( - r"set interfaces (?:ethernet|bonding|vti|vxlan) (?:\'*)(\S+)(?:\'*)", - data, - re.M, - ) - if interface_names: - for interface in set(interface_names): - intf_regex = r" %s .+$" % interface - cfg = re.findall(intf_regex, data, re.M) - obj = self.render_config(cfg) - obj["name"] = interface.strip("'") - if obj: - objs.append(obj) - - ansible_facts["ansible_network_resources"].pop("l3_interfaces", None) - facts = {} - if objs: - facts["l3_interfaces"] = [] - params = utils.validate_config( - self.argument_spec, {"config": objs} - ) - for cfg in params["config"]: - facts["l3_interfaces"].append(utils.remove_empties(cfg)) - - ansible_facts["ansible_network_resources"].update(facts) - return ansible_facts - - def render_config(self, conf): - """ - Render config as dictionary structure and delete keys from spec for null values - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - vif_conf = "\n".join(filter(lambda x: ("vif" in x), conf)) - eth_conf = "\n".join(filter(lambda x: ("vif" not in x), conf)) - config = self.parse_attribs(eth_conf) - config["vifs"] = self.parse_vifs(vif_conf) - - return utils.remove_empties(config) - - def parse_vifs(self, conf): - vif_names = re.findall(r"vif (\d+)", conf, re.M) - vifs_list = None - if vif_names: - vifs_list = [] - for vif in set(vif_names): - vif_regex = r" %s .+$" % vif - cfg = "\n".join(re.findall(vif_regex, conf, re.M)) - obj = self.parse_attribs(cfg) - obj["vlan_id"] = vif - if obj: - vifs_list.append(obj) - - return vifs_list - - def parse_attribs(self, conf): - config = {} - ipaddrs = re.findall(r"address (\S+)", conf, re.M) - config["ipv4"] = [] - config["ipv6"] = [] - - for item in ipaddrs: - item = item.strip("'") - if item == "dhcp": - config["ipv4"].append({"address": item}) - elif item == "dhcpv6": - config["ipv6"].append({"address": item}) - else: - ip_version = ipaddress.ip_address(item.split("/")[0]).version - if ip_version == 4: - config["ipv4"].append({"address": item}) - else: - config["ipv6"].append({"address": item}) - - for key, value in iteritems(config): - if value == []: - config[key] = None - - return utils.remove_empties(config) diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/lag_interfaces/lag_interfaces.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/lag_interfaces/lag_interfaces.py deleted file mode 100644 index b26dfd1..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/lag_interfaces/lag_interfaces.py +++ /dev/null @@ -1,151 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The vyos lag_interfaces fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" -from __future__ import annotations - -from re import findall, search, M -from copy import deepcopy - -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( - utils, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.lag_interfaces.lag_interfaces import ( - Lag_interfacesArgs, -) - - -class Lag_interfacesFacts(object): - """ The vyos lag_interfaces fact class - """ - - def __init__(self, module, subspec="config", options="options"): - self._module = module - self.argument_spec = Lag_interfacesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for lag_interfaces - :param module: the module instance - :param connection: the device connection - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - if not data: - data = connection.get_config() - - objs = [] - lag_names = findall(r"^set interfaces bonding (\S+)", data, M) - if lag_names: - for lag in set(lag_names): - lag_regex = r" %s .+$" % lag - cfg = findall(lag_regex, data, M) - obj = self.render_config(cfg) - - output = connection.run_commands( - ["show interfaces bonding " + lag + " slaves"] - ) - lines = output[0].splitlines() - members = [] - member = {} - if len(lines) > 1: - for line in lines[2:]: - splitted_line = line.split() - - if len(splitted_line) > 1: - member["member"] = splitted_line[0] - members.append(member) - else: - members = [] - member = {} - obj["name"] = lag.strip("'") - if members: - obj["members"] = members - - if obj: - objs.append(obj) - - facts = {} - if objs: - facts["lag_interfaces"] = [] - params = utils.validate_config( - self.argument_spec, {"config": objs} - ) - for cfg in params["config"]: - facts["lag_interfaces"].append(utils.remove_empties(cfg)) - - ansible_facts["ansible_network_resources"].update(facts) - return ansible_facts - - def render_config(self, conf): - """ - Render config as dictionary structure and delete keys - from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - arp_monitor_conf = "\n".join( - filter(lambda x: ("arp-monitor" in x), conf) - ) - hash_policy_conf = "\n".join( - filter(lambda x: ("hash-policy" in x), conf) - ) - lag_conf = "\n".join(filter(lambda x: ("bond" in x), conf)) - config = self.parse_attribs(["mode", "primary"], lag_conf) - config["arp_monitor"] = self.parse_arp_monitor(arp_monitor_conf) - config["hash_policy"] = self.parse_hash_policy(hash_policy_conf) - - return utils.remove_empties(config) - - def parse_attribs(self, attribs, conf): - config = {} - for item in attribs: - value = utils.parse_conf_arg(conf, item) - if value: - config[item] = value.strip("'") - else: - config[item] = None - return utils.remove_empties(config) - - def parse_arp_monitor(self, conf): - arp_monitor = None - if conf: - arp_monitor = {} - target_list = [] - interval = search(r"^.*arp-monitor interval (.+)", conf, M) - targets = findall(r"^.*arp-monitor target '(.+)'", conf, M) - if targets: - for target in targets: - target_list.append(target) - arp_monitor["target"] = target_list - if interval: - value = interval.group(1).strip("'") - arp_monitor["interval"] = int(value) - return arp_monitor - - def parse_hash_policy(self, conf): - hash_policy = None - if conf: - hash_policy = search(r"^.*hash-policy (.+)", conf, M) - hash_policy = hash_policy.group(1).strip("'") - return hash_policy diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/legacy/base.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/legacy/base.py deleted file mode 100644 index c5294b5..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/legacy/base.py +++ /dev/null @@ -1,161 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The VyOS interfaces fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import annotations - -import platform -import re -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( - run_commands, - get_capabilities, -) - - -class LegacyFactsBase(object): - - COMMANDS = frozenset() - - def __init__(self, module): - self.module = module - self.facts = dict() - self.warnings = list() - self.responses = None - - def populate(self): - self.responses = run_commands(self.module, list(self.COMMANDS)) - - -class Default(LegacyFactsBase): - - COMMANDS = [ - "show version", - ] - - def populate(self): - super(Default, self).populate() - data = self.responses[0] - self.facts["serialnum"] = self.parse_serialnum(data) - self.facts.update(self.platform_facts()) - - def parse_serialnum(self, data): - match = re.search(r"HW S/N:\s+(\S+)", data) - if match: - return match.group(1) - - def platform_facts(self): - platform_facts = {} - - resp = get_capabilities(self.module) - device_info = resp["device_info"] - - platform_facts["system"] = device_info["network_os"] - - for item in ("model", "image", "version", "platform", "hostname"): - val = device_info.get("network_os_%s" % item) - if val: - platform_facts[item] = val - - platform_facts["api"] = resp["network_api"] - platform_facts["python_version"] = platform.python_version() - - return platform_facts - - -class Config(LegacyFactsBase): - - COMMANDS = [ - "show configuration commands", - "show system commit", - ] - - def populate(self): - super(Config, self).populate() - - self.facts["config"] = self.responses - - commits = self.responses[1] - entries = list() - entry = None - - for line in commits.split("\n"): - match = re.match(r"(\d+)\s+(.+)by(.+)via(.+)", line) - if match: - if entry: - entries.append(entry) - - entry = dict( - revision=match.group(1), - datetime=match.group(2), - by=str(match.group(3)).strip(), - via=str(match.group(4)).strip(), - comment=None, - ) - else: - entry["comment"] = line.strip() - - self.facts["commits"] = entries - - -class Neighbors(LegacyFactsBase): - - COMMANDS = [ - "show lldp neighbors", - "show lldp neighbors detail", - ] - - def populate(self): - super(Neighbors, self).populate() - - all_neighbors = self.responses[0] - if "LLDP not configured" not in all_neighbors: - neighbors = self.parse(self.responses[1]) - self.facts["neighbors"] = self.parse_neighbors(neighbors) - - def parse(self, data): - parsed = list() - values = None - for line in data.split("\n"): - if not line: - continue - elif line[0] == " ": - values += "\n%s" % line - elif line.startswith("Interface"): - if values: - parsed.append(values) - values = line - if values: - parsed.append(values) - return parsed - - def parse_neighbors(self, data): - facts = dict() - for item in data: - interface = self.parse_interface(item) - host = self.parse_host(item) - port = self.parse_port(item) - if interface not in facts: - facts[interface] = list() - facts[interface].append(dict(host=host, port=port)) - return facts - - def parse_interface(self, data): - match = re.search(r"^Interface:\s+(\S+),", data) - return match.group(1) - - def parse_host(self, data): - match = re.search(r"SysName:\s+(.+)$", data, re.M) - if match: - return match.group(1) - - def parse_port(self, data): - match = re.search(r"PortDescr:\s+(.+)$", data, re.M) - if match: - return match.group(1) diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/lldp_global/lldp_global.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/lldp_global/lldp_global.py deleted file mode 100644 index 10f239f..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/lldp_global/lldp_global.py +++ /dev/null @@ -1,115 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The vyos lldp_global fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" -from __future__ import annotations - - -from re import findall, M -from copy import deepcopy - -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( - utils, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.lldp_global.lldp_global import ( - Lldp_globalArgs, -) - - -class Lldp_globalFacts(object): - """ The vyos lldp_global fact class - """ - - def __init__(self, module, subspec="config", options="options"): - self._module = module - self.argument_spec = Lldp_globalArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for lldp_global - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - if not data: - data = connection.get_config() - - objs = {} - lldp_output = findall(r"^set service lldp (\S+)", data, M) - if lldp_output: - for item in set(lldp_output): - lldp_regex = r" %s .+$" % item - cfg = findall(lldp_regex, data, M) - obj = self.render_config(cfg) - if obj: - objs.update(obj) - lldp_service = findall(r"^set service (lldp)?('lldp')", data, M) - if lldp_service or lldp_output: - lldp_obj = {} - lldp_obj["enable"] = True - objs.update(lldp_obj) - - facts = {} - params = utils.validate_config(self.argument_spec, {"config": objs}) - facts["lldp_global"] = utils.remove_empties(params["config"]) - - ansible_facts["ansible_network_resources"].update(facts) - - return ansible_facts - - def render_config(self, conf): - """ - Render config as dictionary structure and delete keys - from spec for null values - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - protocol_conf = "\n".join( - filter(lambda x: ("legacy-protocols" in x), conf) - ) - att_conf = "\n".join( - filter(lambda x: ("legacy-protocols" not in x), conf) - ) - config = self.parse_attribs(["snmp", "address"], att_conf) - config["legacy_protocols"] = self.parse_protocols(protocol_conf) - return utils.remove_empties(config) - - def parse_protocols(self, conf): - protocol_support = None - if conf: - protocols = findall(r"^.*legacy-protocols (.+)", conf, M) - if protocols: - protocol_support = [] - for protocol in protocols: - protocol_support.append(protocol.strip("'")) - return protocol_support - - def parse_attribs(self, attribs, conf): - config = {} - for item in attribs: - value = utils.parse_conf_arg(conf, item) - if value: - config[item] = value.strip("'") - else: - config[item] = None - return utils.remove_empties(config) diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/lldp_interfaces/lldp_interfaces.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/lldp_interfaces/lldp_interfaces.py deleted file mode 100644 index d9d59b1..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/lldp_interfaces/lldp_interfaces.py +++ /dev/null @@ -1,153 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The vyos lldp_interfaces fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import annotations - - -from re import findall, search, M -from copy import deepcopy - -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( - utils, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.lldp_interfaces.lldp_interfaces import ( - Lldp_interfacesArgs, -) - - -class Lldp_interfacesFacts(object): - """ The vyos lldp_interfaces fact class - """ - - def __init__(self, module, subspec="config", options="options"): - self._module = module - self.argument_spec = Lldp_interfacesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for lldp_interfaces - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - if not data: - data = connection.get_config() - - objs = [] - lldp_names = findall(r"^set service lldp interface (\S+)", data, M) - if lldp_names: - for lldp in set(lldp_names): - lldp_regex = r" %s .+$" % lldp - cfg = findall(lldp_regex, data, M) - obj = self.render_config(cfg) - obj["name"] = lldp.strip("'") - if obj: - objs.append(obj) - facts = {} - if objs: - facts["lldp_interfaces"] = objs - ansible_facts["ansible_network_resources"].update(facts) - - ansible_facts["ansible_network_resources"].update(facts) - return ansible_facts - - def render_config(self, conf): - """ - Render config as dictionary structure and delete keys - from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - config = {} - location = {} - - civic_conf = "\n".join(filter(lambda x: ("civic-based" in x), conf)) - elin_conf = "\n".join(filter(lambda x: ("elin" in x), conf)) - coordinate_conf = "\n".join( - filter(lambda x: ("coordinate-based" in x), conf) - ) - disable = "\n".join(filter(lambda x: ("disable" in x), conf)) - - coordinate_based_conf = self.parse_attribs( - ["altitude", "datum", "longitude", "latitude"], coordinate_conf - ) - elin_based_conf = self.parse_lldp_elin_based(elin_conf) - civic_based_conf = self.parse_lldp_civic_based(civic_conf) - if disable: - config["enable"] = False - if coordinate_conf: - location["coordinate_based"] = coordinate_based_conf - config["location"] = location - elif civic_based_conf: - location["civic_based"] = civic_based_conf - config["location"] = location - elif elin_conf: - location["elin"] = elin_based_conf - config["location"] = location - - return utils.remove_empties(config) - - def parse_attribs(self, attribs, conf): - config = {} - for item in attribs: - value = utils.parse_conf_arg(conf, item) - if value: - value = value.strip("'") - if item == "altitude": - value = int(value) - config[item] = value - else: - config[item] = None - return utils.remove_empties(config) - - def parse_lldp_civic_based(self, conf): - civic_based = None - if conf: - civic_info_list = [] - civic_add_list = findall(r"^.*civic-based ca-type (.+)", conf, M) - if civic_add_list: - for civic_add in civic_add_list: - ca = civic_add.split(" ") - c_add = {} - c_add["ca_type"] = int(ca[0].strip("'")) - c_add["ca_value"] = ca[2].strip("'") - civic_info_list.append(c_add) - - country_code = search( - r"^.*civic-based country-code (.+)", conf, M - ) - civic_based = {} - civic_based["ca_info"] = civic_info_list - civic_based["country_code"] = country_code.group(1).strip("'") - return civic_based - - def parse_lldp_elin_based(self, conf): - elin_based = None - if conf: - e_num = search(r"^.* elin (.+)", conf, M) - elin_based = e_num.group(1).strip("'") - - return elin_based diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/static_routes/static_routes.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/static_routes/static_routes.py deleted file mode 100644 index 7ca7f20..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/facts/static_routes/static_routes.py +++ /dev/null @@ -1,180 +0,0 @@ -# -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The vyos static_routes fact class -It is in this file the configuration is collected from the device -for a given resource, parsed, and the facts tree is populated -based on the configuration. -""" - -from __future__ import annotations - -from re import findall, search, M -from copy import deepcopy -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( - utils, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.static_routes.static_routes import ( - Static_routesArgs, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import ( - get_route_type, -) - - -class Static_routesFacts(object): - """ The vyos static_routes fact class - """ - - def __init__(self, module, subspec="config", options="options"): - self._module = module - self.argument_spec = Static_routesArgs.argument_spec - spec = deepcopy(self.argument_spec) - if subspec: - if options: - facts_argument_spec = spec[subspec][options] - else: - facts_argument_spec = spec[subspec] - else: - facts_argument_spec = spec - - self.generated_spec = utils.generate_dict(facts_argument_spec) - - def get_device_data(self, connection): - return connection.get_config() - - def populate_facts(self, connection, ansible_facts, data=None): - """ Populate the facts for static_routes - :param connection: the device connection - :param ansible_facts: Facts dictionary - :param data: previously collected conf - :rtype: dictionary - :returns: facts - """ - if not data: - data = self.get_device_data(connection) - # typically data is populated from the current device configuration - # data = connection.get('show running-config | section ^interface') - # using mock data instead - objs = [] - r_v4 = [] - r_v6 = [] - af = [] - static_routes = findall( - r"set protocols static route(6)? (\S+)", data, M - ) - if static_routes: - for route in set(static_routes): - route_regex = r" %s .+$" % route[1] - cfg = findall(route_regex, data, M) - sr = self.render_config(cfg) - sr["dest"] = route[1].strip("'") - afi = self.get_afi(sr["dest"]) - if afi == "ipv4": - r_v4.append(sr) - else: - r_v6.append(sr) - if r_v4: - afi_v4 = {"afi": "ipv4", "routes": r_v4} - af.append(afi_v4) - if r_v6: - afi_v6 = {"afi": "ipv6", "routes": r_v6} - af.append(afi_v6) - config = {"address_families": af} - if config: - objs.append(config) - - ansible_facts["ansible_network_resources"].pop("static_routes", None) - facts = {} - if objs: - facts["static_routes"] = [] - params = utils.validate_config( - self.argument_spec, {"config": objs} - ) - for cfg in params["config"]: - facts["static_routes"].append(utils.remove_empties(cfg)) - - ansible_facts["ansible_network_resources"].update(facts) - return ansible_facts - - def render_config(self, conf): - """ - Render config as dictionary structure and delete keys - from spec for null values - - :param spec: The facts tree, generated from the argspec - :param conf: The configuration - :rtype: dictionary - :returns: The generated config - """ - next_hops_conf = "\n".join(filter(lambda x: ("next-hop" in x), conf)) - blackhole_conf = "\n".join(filter(lambda x: ("blackhole" in x), conf)) - routes_dict = { - "blackhole_config": self.parse_blackhole(blackhole_conf), - "next_hops": self.parse_next_hop(next_hops_conf), - } - return routes_dict - - def parse_blackhole(self, conf): - blackhole = None - if conf: - distance = search(r"^.*blackhole distance (.\S+)", conf, M) - bh = conf.find("blackhole") - if distance is not None: - blackhole = {} - value = distance.group(1).strip("'") - blackhole["distance"] = int(value) - elif bh: - blackhole = {} - blackhole["type"] = "blackhole" - return blackhole - - def get_afi(self, address): - route_type = get_route_type(address) - if route_type == "route": - return "ipv4" - elif route_type == "route6": - return "ipv6" - - def parse_next_hop(self, conf): - nh_list = None - if conf: - nh_list = [] - hop_list = findall(r"^.*next-hop (.+)", conf, M) - if hop_list: - for hop in hop_list: - distance = search(r"^.*distance (.\S+)", hop, M) - interface = search(r"^.*interface (.\S+)", hop, M) - - dis = hop.find("disable") - hop_info = hop.split(" ") - nh_info = { - "forward_router_address": hop_info[0].strip("'") - } - if interface: - nh_info["interface"] = interface.group(1).strip("'") - if distance: - value = distance.group(1).strip("'") - nh_info["admin_distance"] = int(value) - elif dis >= 1: - nh_info["enabled"] = False - for element in nh_list: - if ( - element["forward_router_address"] - == nh_info["forward_router_address"] - ): - if "interface" in nh_info.keys(): - element["interface"] = nh_info["interface"] - if "admin_distance" in nh_info.keys(): - element["admin_distance"] = nh_info[ - "admin_distance" - ] - if "enabled" in nh_info.keys(): - element["enabled"] = nh_info["enabled"] - nh_info = None - if nh_info is not None: - nh_list.append(nh_info) - return nh_list diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/utils/utils.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/utils/utils.py deleted file mode 100644 index 1a6a724..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/utils/utils.py +++ /dev/null @@ -1,230 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# utils -from __future__ import annotations - -from ansible.module_utils.six import iteritems -from ansible_collections.ansible.netcommon.plugins.module_utils.compat import ( - ipaddress, -) - - -def search_obj_in_list(name, lst, key="name"): - for item in lst: - if item[key] == name: - return item - return None - - -def get_interface_type(interface): - """Gets the type of interface - """ - if interface.startswith("eth"): - return "ethernet" - elif interface.startswith("bond"): - return "bonding" - elif interface.startswith("vti"): - return "vti" - elif interface.startswith("lo"): - return "loopback" - - -def dict_delete(base, comparable): - """ - This function generates a dict containing key, value pairs for keys - that are present in the `base` dict but not present in the `comparable` - dict. - - :param base: dict object to base the diff on - :param comparable: dict object to compare against base - :returns: new dict object with key, value pairs that needs to be deleted. - - """ - to_delete = dict() - - for key in base: - if isinstance(base[key], dict): - sub_diff = dict_delete(base[key], comparable.get(key, {})) - if sub_diff: - to_delete[key] = sub_diff - else: - if key not in comparable: - to_delete[key] = base[key] - - return to_delete - - -def diff_list_of_dicts(want, have): - diff = [] - - set_w = set(tuple(d.items()) for d in want) - set_h = set(tuple(d.items()) for d in have) - difference = set_w.difference(set_h) - - for element in difference: - diff.append(dict((x, y) for x, y in element)) - - return diff - - -def get_lst_diff_for_dicts(want, have, lst): - """ - This function generates a list containing values - that are only in want and not in list in have dict - :param want: dict object to want - :param have: dict object to have - :param lst: list the diff on - :return: new list object with values which are only in want. - """ - if not have: - diff = want.get(lst) or [] - - else: - want_elements = want.get(lst) or {} - have_elements = have.get(lst) or {} - diff = list_diff_want_only(want_elements, have_elements) - return diff - - -def get_lst_same_for_dicts(want, have, lst): - """ - This function generates a list containing values - that are common for list in want and list in have dict - :param want: dict object to want - :param have: dict object to have - :param lst: list the comparison on - :return: new list object with values which are common in want and have. - """ - diff = None - if want and have: - want_list = want.get(lst) or {} - have_list = have.get(lst) or {} - diff = [ - i - for i in want_list and have_list - if i in have_list and i in want_list - ] - return diff - - -def list_diff_have_only(want_list, have_list): - """ - This function generated the list containing values - that are only in have list. - :param want_list: - :param have_list: - :return: new list with values which are only in have list - """ - if have_list and not want_list: - diff = have_list - elif not have_list: - diff = None - else: - diff = [ - i - for i in have_list + want_list - if i in have_list and i not in want_list - ] - return diff - - -def list_diff_want_only(want_list, have_list): - """ - This function generated the list containing values - that are only in want list. - :param want_list: - :param have_list: - :return: new list with values which are only in want list - """ - if have_list and not want_list: - diff = None - elif not have_list: - diff = want_list - else: - diff = [ - i - for i in have_list + want_list - if i in want_list and i not in have_list - ] - return diff - - -def search_dict_tv_in_list(d_val1, d_val2, lst, key1, key2): - """ - This function return the dict object if it exist in list. - :param d_val1: - :param d_val2: - :param lst: - :param key1: - :param key2: - :return: - """ - obj = next( - ( - item - for item in lst - if item[key1] == d_val1 and item[key2] == d_val2 - ), - None, - ) - if obj: - return obj - else: - return None - - -def key_value_in_dict(have_key, have_value, want_dict): - """ - This function checks whether the key and values exist in dict - :param have_key: - :param have_value: - :param want_dict: - :return: - """ - for key, value in iteritems(want_dict): - if key == have_key and value == have_value: - return True - return False - - -def is_dict_element_present(dict, key): - """ - This function checks whether the key is present in dict. - :param dict: - :param key: - :return: - """ - for item in dict: - if item == key: - return True - return False - - -def get_ip_address_version(address): - """ - This function returns the version of IP address - :param address: IP address - :return: - """ - try: - address = unicode(address) - except NameError: - address = str(address) - version = ipaddress.ip_address(address.split("/")[0]).version - return version - - -def get_route_type(address): - """ - This function returns the route type based on IP address - :param address: - :return: - """ - version = get_ip_address_version(address) - if version == 6: - return "route6" - elif version == 4: - return "route" diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/vyos.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/vyos.py deleted file mode 100644 index 274a463..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/module_utils/network/vyos/vyos.py +++ /dev/null @@ -1,126 +0,0 @@ -# This code is part of Ansible, but is an independent component. -# This particular file snippet, and this file snippet only, is BSD licensed. -# Modules you write using this snippet, which is embedded dynamically by Ansible -# still belong to the author of the module, and may assign their own license -# to the complete work. -# -# (c) 2016 Red Hat Inc. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -from __future__ import annotations - -import json - -from ansible.module_utils.common.text.converters import to_text -from ansible.module_utils.basic import env_fallback -from ansible.module_utils.connection import Connection, ConnectionError - -_DEVICE_CONFIGS = {} - -vyos_provider_spec = { - "host": dict(), - "port": dict(type="int"), - "username": dict(fallback=(env_fallback, ["ANSIBLE_NET_USERNAME"])), - "password": dict( - fallback=(env_fallback, ["ANSIBLE_NET_PASSWORD"]), no_log=True - ), - "ssh_keyfile": dict( - fallback=(env_fallback, ["ANSIBLE_NET_SSH_KEYFILE"]), type="path" - ), - "timeout": dict(type="int"), -} -vyos_argument_spec = { - "provider": dict( - type="dict", options=vyos_provider_spec, removed_in_version=2.14 - ), -} - - -def get_provider_argspec(): - return vyos_provider_spec - - -def get_connection(module): - if hasattr(module, "_vyos_connection"): - return module._vyos_connection - - capabilities = get_capabilities(module) - network_api = capabilities.get("network_api") - if network_api == "cliconf": - module._vyos_connection = Connection(module._socket_path) - else: - module.fail_json(msg="Invalid connection type %s" % network_api) - - return module._vyos_connection - - -def get_capabilities(module): - if hasattr(module, "_vyos_capabilities"): - return module._vyos_capabilities - - try: - capabilities = Connection(module._socket_path).get_capabilities() - except ConnectionError as exc: - module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) - - module._vyos_capabilities = json.loads(capabilities) - return module._vyos_capabilities - - -def get_config(module, flags=None, format=None): - flags = [] if flags is None else flags - global _DEVICE_CONFIGS - - if _DEVICE_CONFIGS != {}: - return _DEVICE_CONFIGS - else: - connection = get_connection(module) - try: - out = connection.get_config(flags=flags, format=format) - except ConnectionError as exc: - module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) - cfg = to_text(out, errors="surrogate_then_replace").strip() - _DEVICE_CONFIGS = cfg - return cfg - - -def run_commands(module, commands, check_rc=True): - connection = get_connection(module) - try: - response = connection.run_commands( - commands=commands, check_rc=check_rc - ) - except ConnectionError as exc: - module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) - return response - - -def load_config(module, commands, commit=False, comment=None): - connection = get_connection(module) - - try: - response = connection.edit_config( - candidate=commands, commit=commit, comment=comment - ) - except ConnectionError as exc: - module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) - - return response.get("diff") diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_command.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_command.py deleted file mode 100644 index ed90aea..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_command.py +++ /dev/null @@ -1,224 +0,0 @@ -#!/usr/bin/python -# -# 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/>. -# -from __future__ import annotations - -ANSIBLE_METADATA = { - "metadata_version": "1.1", - "status": ["preview"], - "supported_by": "network", -} - - -DOCUMENTATION = """module: vyos_command -author: Nathaniel Case (@Qalthos) -short_description: Run one or more commands on VyOS devices -description: -- The command module allows running one or more commands on remote devices running - VyOS. This module can also be introspected to validate key parameters before returning - successfully. If the conditional statements are not met in the wait period, the - task fails. -- Certain C(show) commands in VyOS produce many lines of output and use a custom pager - that can cause this module to hang. If the value of the environment variable C(ANSIBLE_VYOS_TERMINAL_LENGTH) - is not set, the default number of 10000 is used. -extends_documentation_fragment: -- vyos.vyos.vyos -options: - commands: - description: - - The ordered set of commands to execute on the remote device running VyOS. The - output from the command execution is returned to the playbook. If the I(wait_for) - argument is provided, the module is not returned until the condition is satisfied - or the number of retries has been exceeded. - required: true - wait_for: - description: - - Specifies what to evaluate from the output of the command and what conditionals - to apply. This argument will cause the task to wait for a particular conditional - to be true before moving forward. If the conditional is not true by the configured - I(retries), the task fails. See examples. - aliases: - - waitfor - match: - description: - - The I(match) argument is used in conjunction with the I(wait_for) argument to - specify the match policy. Valid values are C(all) or C(any). If the value is - set to C(all) then all conditionals in the wait_for must be satisfied. If the - value is set to C(any) then only one of the values must be satisfied. - default: all - choices: - - any - - all - retries: - description: - - Specifies the number of retries a command should be tried before it is considered - failed. The command is run on the target device every retry and evaluated against - the I(wait_for) conditionals. - default: 10 - interval: - description: - - Configures the interval in seconds to wait between I(retries) of the command. - If the command does not pass the specified conditions, the interval indicates - how long to wait before trying the command again. - default: 1 -notes: -- Tested against VyOS 1.1.8 (helium). -- Running C(show system boot-messages all) will cause the module to hang since VyOS - is using a custom pager setting to display the output of that command. -- If a command sent to the device requires answering a prompt, it is possible to pass - a dict containing I(command), I(answer) and I(prompt). See examples. -- This module works with connection C(network_cli). See L(the VyOS OS Platform Options,../network/user_guide/platform_vyos.html). -""" - -EXAMPLES = """ -tasks: - - name: show configuration on ethernet devices eth0 and eth1 - vyos_command: - commands: - - show interfaces ethernet {{ item }} - with_items: - - eth0 - - eth1 - - - name: run multiple commands and check if version output contains specific version string - vyos_command: - commands: - - show version - - show hardware cpu - wait_for: - - "result[0] contains 'VyOS 1.1.7'" - - - name: run command that requires answering a prompt - vyos_command: - commands: - - command: 'rollback 1' - prompt: 'Proceed with reboot? [confirm][y]' - answer: y -""" - -RETURN = """ -stdout: - description: The set of responses from the commands - returned: always apart from low level errors (such as action plugin) - type: list - sample: ['...', '...'] -stdout_lines: - description: The value of stdout split into a list - returned: always - type: list - sample: [['...', '...'], ['...'], ['...']] -failed_conditions: - description: The list of conditionals that have failed - returned: failed - type: list - sample: ['...', '...'] -warnings: - description: The list of warnings (if any) generated by module based on arguments - returned: always - type: list - sample: ['...', '...'] -""" -import time - -from ansible.module_utils.common.text.converters import to_text -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.parsing import ( - Conditional, -) -from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( - transform_commands, - to_lines, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( - run_commands, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( - vyos_argument_spec, -) - - -def parse_commands(module, warnings): - commands = transform_commands(module) - - if module.check_mode: - for item in list(commands): - if not item["command"].startswith("show"): - warnings.append( - "Only show commands are supported when using check mode, not " - "executing %s" % item["command"] - ) - commands.remove(item) - - return commands - - -def main(): - spec = dict( - commands=dict(type="list", required=True), - wait_for=dict(type="list", aliases=["waitfor"]), - match=dict(default="all", choices=["all", "any"]), - retries=dict(default=10, type="int"), - interval=dict(default=1, type="int"), - ) - - spec.update(vyos_argument_spec) - - module = AnsibleModule(argument_spec=spec, supports_check_mode=True) - - warnings = list() - result = {"changed": False, "warnings": warnings} - commands = parse_commands(module, warnings) - wait_for = module.params["wait_for"] or list() - - try: - conditionals = [Conditional(c) for c in wait_for] - except AttributeError as exc: - module.fail_json(msg=to_text(exc)) - - retries = module.params["retries"] - interval = module.params["interval"] - match = module.params["match"] - - for dummy in range(retries): - responses = run_commands(module, commands) - - for item in list(conditionals): - if item(responses): - if match == "any": - conditionals = list() - break - conditionals.remove(item) - - if not conditionals: - break - - time.sleep(interval) - - if conditionals: - failed_conditions = [item.raw for item in conditionals] - msg = "One or more conditional statements have not been satisfied" - module.fail_json(msg=msg, failed_conditions=failed_conditions) - - result.update( - {"stdout": responses, "stdout_lines": list(to_lines(responses)), } - ) - - module.exit_json(**result) - - -if __name__ == "__main__": - main() diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_config.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_config.py deleted file mode 100644 index fdd42f6..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_config.py +++ /dev/null @@ -1,355 +0,0 @@ -#!/usr/bin/python -# -# 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/>. -# -from __future__ import annotations - -ANSIBLE_METADATA = { - "metadata_version": "1.1", - "status": ["preview"], - "supported_by": "network", -} - - -DOCUMENTATION = """module: vyos_config -author: Nathaniel Case (@Qalthos) -short_description: Manage VyOS configuration on remote device -description: -- This module provides configuration file management of VyOS devices. It provides - arguments for managing both the configuration file and state of the active configuration. - All configuration statements are based on `set` and `delete` commands in the device - configuration. -extends_documentation_fragment: -- vyos.vyos.vyos -notes: -- Tested against VyOS 1.1.8 (helium). -- This module works with connection C(network_cli). See L(the VyOS OS Platform Options,../network/user_guide/platform_vyos.html). -options: - lines: - description: - - The ordered set of configuration lines to be managed and compared with the existing - configuration on the remote device. - src: - description: - - The C(src) argument specifies the path to the source config file to load. The - source config file can either be in bracket format or set format. The source - file can include Jinja2 template variables. - match: - description: - - The C(match) argument controls the method used to match against the current - active configuration. By default, the desired config is matched against the - active config and the deltas are loaded. If the C(match) argument is set to - C(none) the active configuration is ignored and the configuration is always - loaded. - default: line - choices: - - line - - none - backup: - description: - - The C(backup) argument will backup the current devices active configuration - to the Ansible control host prior to making any changes. If the C(backup_options) - value is not given, the backup file will be located in the backup folder in - the playbook root directory or role root directory, if playbook is part of an - ansible role. If the directory does not exist, it is created. - type: bool - default: 'no' - comment: - description: - - Allows a commit description to be specified to be included when the configuration - is committed. If the configuration is not changed or committed, this argument - is ignored. - default: configured by vyos_config - config: - description: - - The C(config) argument specifies the base configuration to use to compare against - the desired configuration. If this value is not specified, the module will - automatically retrieve the current active configuration from the remote device. - save: - description: - - The C(save) argument controls whether or not changes made to the active configuration - are saved to disk. This is independent of committing the config. When set - to True, the active configuration is saved. - type: bool - default: 'no' - backup_options: - description: - - This is a dict object containing configurable options related to backup file - path. The value of this option is read only when C(backup) is set to I(yes), - if C(backup) is set to I(no) this option will be silently ignored. - suboptions: - filename: - description: - - The filename to be used to store the backup configuration. If the filename - is not given it will be generated based on the hostname, current time and - date in format defined by <hostname>_config.<current-date>@<current-time> - dir_path: - description: - - This option provides the path ending with directory name in which the backup - configuration file will be stored. If the directory does not exist it will - be first created and the filename is either the value of C(filename) or - default filename as described in C(filename) options description. If the - path value is not given in that case a I(backup) directory will be created - in the current working directory and backup configuration will be copied - in C(filename) within I(backup) directory. - type: path - type: dict -""" - -EXAMPLES = """ -- name: configure the remote device - vyos_config: - lines: - - set system host-name {{ inventory_hostname }} - - set service lldp - - delete service dhcp-server - -- name: backup and load from file - vyos_config: - src: vyos.cfg - backup: yes - -- name: render a Jinja2 template onto the VyOS router - vyos_config: - src: vyos_template.j2 - -- name: for idempotency, use full-form commands - vyos_config: - lines: - # - set int eth eth2 description 'OUTSIDE' - - set interface ethernet eth2 description 'OUTSIDE' - -- name: configurable backup path - vyos_config: - backup: yes - backup_options: - filename: backup.cfg - dir_path: /home/user -""" - -RETURN = """ -commands: - description: The list of configuration commands sent to the device - returned: always - type: list - sample: ['...', '...'] -filtered: - description: The list of configuration commands removed to avoid a load failure - returned: always - type: list - sample: ['...', '...'] -backup_path: - description: The full path to the backup file - returned: when backup is yes - type: str - sample: /playbooks/ansible/backup/vyos_config.2016-07-16@22:28:34 -filename: - description: The name of the backup file - returned: when backup is yes and filename is not specified in backup options - type: str - sample: vyos_config.2016-07-16@22:28:34 -shortname: - description: The full path to the backup file excluding the timestamp - returned: when backup is yes and filename is not specified in backup options - type: str - sample: /playbooks/ansible/backup/vyos_config -date: - description: The date extracted from the backup file name - returned: when backup is yes - type: str - sample: "2016-07-16" -time: - description: The time extracted from the backup file name - returned: when backup is yes - type: str - sample: "22:28:34" -""" -import re - -from ansible.module_utils.common.text.converters import to_text -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.connection import ConnectionError -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( - load_config, - get_config, - run_commands, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( - vyos_argument_spec, - get_connection, -) - - -DEFAULT_COMMENT = "configured by vyos_config" - -CONFIG_FILTERS = [ - re.compile(r"set system login user \S+ authentication encrypted-password") -] - - -def get_candidate(module): - contents = module.params["src"] or module.params["lines"] - - if module.params["src"]: - contents = format_commands(contents.splitlines()) - - contents = "\n".join(contents) - return contents - - -def format_commands(commands): - """ - This function format the input commands and removes the prepend white spaces - for command lines having 'set' or 'delete' and it skips empty lines. - :param commands: - :return: list of commands - """ - return [ - line.strip() if line.split()[0] in ("set", "delete") else line - for line in commands - if len(line.strip()) > 0 - ] - - -def diff_config(commands, config): - config = [str(c).replace("'", "") for c in config.splitlines()] - - updates = list() - visited = set() - - for line in commands: - item = str(line).replace("'", "") - - if not item.startswith("set") and not item.startswith("delete"): - raise ValueError("line must start with either `set` or `delete`") - - elif item.startswith("set") and item not in config: - updates.append(line) - - elif item.startswith("delete"): - if not config: - updates.append(line) - else: - item = re.sub(r"delete", "set", item) - for entry in config: - if entry.startswith(item) and line not in visited: - updates.append(line) - visited.add(line) - - return list(updates) - - -def sanitize_config(config, result): - result["filtered"] = list() - index_to_filter = list() - for regex in CONFIG_FILTERS: - for index, line in enumerate(list(config)): - if regex.search(line): - result["filtered"].append(line) - index_to_filter.append(index) - # Delete all filtered configs - for filter_index in sorted(index_to_filter, reverse=True): - del config[filter_index] - - -def run(module, result): - # get the current active config from the node or passed in via - # the config param - config = module.params["config"] or get_config(module) - - # create the candidate config object from the arguments - candidate = get_candidate(module) - - # create loadable config that includes only the configuration updates - connection = get_connection(module) - try: - response = connection.get_diff( - candidate=candidate, - running=config, - diff_match=module.params["match"], - ) - except ConnectionError as exc: - module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) - - commands = response.get("config_diff") - sanitize_config(commands, result) - - result["commands"] = commands - - commit = not module.check_mode - comment = module.params["comment"] - - diff = None - if commands: - diff = load_config(module, commands, commit=commit, comment=comment) - - if result.get("filtered"): - result["warnings"].append( - "Some configuration commands were " - "removed, please see the filtered key" - ) - - result["changed"] = True - - if module._diff: - result["diff"] = {"prepared": diff} - - -def main(): - backup_spec = dict(filename=dict(), dir_path=dict(type="path")) - argument_spec = dict( - src=dict(type="path"), - lines=dict(type="list"), - match=dict(default="line", choices=["line", "none"]), - comment=dict(default=DEFAULT_COMMENT), - config=dict(), - backup=dict(type="bool", default=False), - backup_options=dict(type="dict", options=backup_spec), - save=dict(type="bool", default=False), - ) - - argument_spec.update(vyos_argument_spec) - - mutually_exclusive = [("lines", "src")] - - module = AnsibleModule( - argument_spec=argument_spec, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True, - ) - - warnings = list() - - result = dict(changed=False, warnings=warnings) - - if module.params["backup"]: - result["__backup__"] = get_config(module=module) - - if any((module.params["src"], module.params["lines"])): - run(module, result) - - if module.params["save"]: - diff = run_commands(module, commands=["configure", "compare saved"])[1] - if diff != "[edit]": - run_commands(module, commands=["save"]) - result["changed"] = True - run_commands(module, commands=["exit"]) - - module.exit_json(**result) - - -if __name__ == "__main__": - main() diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_facts.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_facts.py deleted file mode 100644 index d9fb236..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_facts.py +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -""" -The module file for vyos_facts -""" -from __future__ import annotations - - -ANSIBLE_METADATA = { - "metadata_version": "1.1", - "status": [u"preview"], - "supported_by": "network", -} - - -DOCUMENTATION = """module: vyos_facts -short_description: Get facts about vyos devices. -description: -- Collects facts from network devices running the vyos operating system. This module - places the facts gathered in the fact tree keyed by the respective resource name. The - facts module will always collect a base set of facts from the device and can enable - or disable collection of additional facts. -author: -- Nathaniel Case (@qalthos) -- Nilashish Chakraborty (@Nilashishc) -- Rohit Thakur (@rohitthakur2590) -extends_documentation_fragment: -- vyos.vyos.vyos -notes: -- Tested against VyOS 1.1.8 (helium). -- This module works with connection C(network_cli). See L(the VyOS OS Platform Options,../network/user_guide/platform_vyos.html). -options: - gather_subset: - description: - - When supplied, this argument will restrict the facts collected to a given subset. Possible - values for this argument include all, default, config, and neighbors. Can specify - a list of values to include a larger subset. Values can also be used with an - initial C(M(!)) to specify that a specific subset should not be collected. - required: false - default: '!config' - gather_network_resources: - description: - - When supplied, this argument will restrict the facts collected to a given subset. - Possible values for this argument include all and the resources like interfaces. - Can specify a list of values to include a larger subset. Values can also be - used with an initial C(M(!)) to specify that a specific subset should not be - collected. Valid subsets are 'all', 'interfaces', 'l3_interfaces', 'lag_interfaces', - 'lldp_global', 'lldp_interfaces', 'static_routes', 'firewall_rules'. - required: false -""" - -EXAMPLES = """ -# Gather all facts -- vyos_facts: - gather_subset: all - gather_network_resources: all - -# collect only the config and default facts -- vyos_facts: - gather_subset: config - -# collect everything exception the config -- vyos_facts: - gather_subset: "!config" - -# Collect only the interfaces facts -- vyos_facts: - gather_subset: - - '!all' - - '!min' - gather_network_resources: - - interfaces - -# Do not collect interfaces facts -- vyos_facts: - gather_network_resources: - - "!interfaces" - -# Collect interfaces and minimal default facts -- vyos_facts: - gather_subset: min - gather_network_resources: interfaces -""" - -RETURN = """ -ansible_net_config: - description: The running-config from the device - returned: when config is configured - type: str -ansible_net_commits: - description: The set of available configuration revisions - returned: when present - type: list -ansible_net_hostname: - description: The configured system hostname - returned: always - type: str -ansible_net_model: - description: The device model string - returned: always - type: str -ansible_net_serialnum: - description: The serial number of the device - returned: always - type: str -ansible_net_version: - description: The version of the software running - returned: always - type: str -ansible_net_neighbors: - description: The set of LLDP neighbors - returned: when interface is configured - type: list -ansible_net_gather_subset: - description: The list of subsets gathered by the module - returned: always - type: list -ansible_net_api: - description: The name of the transport - returned: always - type: str -ansible_net_python_version: - description: The Python version Ansible controller is using - returned: always - type: str -ansible_net_gather_network_resources: - description: The list of fact resource subsets collected from the device - returned: always - type: list -""" - -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.facts.facts import ( - FactsArgs, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import ( - Facts, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( - vyos_argument_spec, -) - - -def main(): - """ - Main entry point for module execution - - :returns: ansible_facts - """ - argument_spec = FactsArgs.argument_spec - argument_spec.update(vyos_argument_spec) - - module = AnsibleModule( - argument_spec=argument_spec, supports_check_mode=True - ) - - warnings = [] - if module.params["gather_subset"] == "!config": - warnings.append( - "default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards" - ) - - result = Facts(module).get_facts() - - ansible_facts, additional_warnings = result - warnings.extend(additional_warnings) - - module.exit_json(ansible_facts=ansible_facts, warnings=warnings) - - -if __name__ == "__main__": - main() diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_lldp_interfaces.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_lldp_interfaces.py deleted file mode 100644 index d18f3f7..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_lldp_interfaces.py +++ /dev/null @@ -1,512 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2019 Red Hat -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -############################################# -# WARNING # -############################################# -# -# This file is auto generated by the resource -# module builder playbook. -# -# Do not edit this file manually. -# -# Changes to this file will be over written -# by the resource module builder. -# -# Changes should be made in the model used to -# generate this file or in the resource module -# builder template. -# -############################################# - -""" -The module file for vyos_lldp_interfaces -""" - -from __future__ import annotations - - -ANSIBLE_METADATA = { - "metadata_version": "1.1", - "status": ["preview"], - "supported_by": "network", -} - -DOCUMENTATION = """module: vyos_lldp_interfaces -short_description: Manages attributes of lldp interfaces on VyOS devices. -description: This module manages attributes of lldp interfaces on VyOS network devices. -notes: -- Tested against VyOS 1.1.8 (helium). -- This module works with connection C(network_cli). See L(the VyOS OS Platform Options,../network/user_guide/platform_vyos.html). -author: -- Rohit Thakur (@rohitthakur2590) -options: - config: - description: A list of lldp interfaces configurations. - type: list - suboptions: - name: - description: - - Name of the lldp interface. - type: str - required: true - enable: - description: - - to disable lldp on the interface. - type: bool - default: true - location: - description: - - LLDP-MED location data. - type: dict - suboptions: - civic_based: - description: - - Civic-based location data. - type: dict - suboptions: - ca_info: - description: LLDP-MED address info - type: list - suboptions: - ca_type: - description: LLDP-MED Civic Address type. - type: int - required: true - ca_value: - description: LLDP-MED Civic Address value. - type: str - required: true - country_code: - description: Country Code - type: str - required: true - coordinate_based: - description: - - Coordinate-based location. - type: dict - suboptions: - altitude: - description: Altitude in meters. - type: int - datum: - description: Coordinate datum type. - type: str - choices: - - WGS84 - - NAD83 - - MLLW - latitude: - description: Latitude. - type: str - required: true - longitude: - description: Longitude. - type: str - required: true - elin: - description: Emergency Call Service ELIN number (between 10-25 numbers). - type: str - state: - description: - - The state of the configuration after module completion. - type: str - choices: - - merged - - replaced - - overridden - - deleted - default: merged -""" -EXAMPLES = """ -# Using merged -# -# Before state: -# ------------- -# -# vyos@vyos:~$ show configuration commands | grep lldp -# -- name: Merge provided configuration with device configuration - vyos_lldp_interfaces: - config: - - name: 'eth1' - location: - civic_based: - country_code: 'US' - ca_info: - - ca_type: 0 - ca_value: 'ENGLISH' - - - name: 'eth2' - location: - coordinate_based: - altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' - state: merged -# -# -# ------------------------- -# Module Execution Result -# ------------------------- -# -# before": [] -# -# "commands": [ -# "set service lldp interface eth1 location civic-based country-code 'US'", -# "set service lldp interface eth1 location civic-based ca-type 0 ca-value 'ENGLISH'", -# "set service lldp interface eth1", -# "set service lldp interface eth2 location coordinate-based latitude '33.524449N'", -# "set service lldp interface eth2 location coordinate-based altitude '2200'", -# "set service lldp interface eth2 location coordinate-based datum 'WGS84'", -# "set service lldp interface eth2 location coordinate-based longitude '222.267255W'", -# "set service lldp interface eth2 location coordinate-based latitude '33.524449N'", -# "set service lldp interface eth2 location coordinate-based altitude '2200'", -# "set service lldp interface eth2 location coordinate-based datum 'WGS84'", -# "set service lldp interface eth2 location coordinate-based longitude '222.267255W'", -# "set service lldp interface eth2" -# -# "after": [ -# { -# "location": { -# "coordinate_based": { -# "altitude": 2200, -# "datum": "WGS84", -# "latitude": "33.524449N", -# "longitude": "222.267255W" -# } -# }, -# "name": "eth2" -# }, -# { -# "location": { -# "civic_based": { -# "ca_info": [ -# { -# "ca_type": 0, -# "ca_value": "ENGLISH" -# } -# ], -# "country_code": "US" -# } -# }, -# "name": "eth1" -# } -# ], -# -# After state: -# ------------- -# -# vyos@vyos:~$ show configuration commands | grep lldp -# set service lldp interface eth1 location civic-based ca-type 0 ca-value 'ENGLISH' -# set service lldp interface eth1 location civic-based country-code 'US' -# set service lldp interface eth2 location coordinate-based altitude '2200' -# set service lldp interface eth2 location coordinate-based datum 'WGS84' -# set service lldp interface eth2 location coordinate-based latitude '33.524449N' -# set service lldp interface eth2 location coordinate-based longitude '222.267255W' - - -# Using replaced -# -# Before state: -# ------------- -# -# vyos@vyos:~$ show configuration commands | grep lldp -# set service lldp interface eth1 location civic-based ca-type 0 ca-value 'ENGLISH' -# set service lldp interface eth1 location civic-based country-code 'US' -# set service lldp interface eth2 location coordinate-based altitude '2200' -# set service lldp interface eth2 location coordinate-based datum 'WGS84' -# set service lldp interface eth2 location coordinate-based latitude '33.524449N' -# set service lldp interface eth2 location coordinate-based longitude '222.267255W' -# -- name: Replace device configurations of listed LLDP interfaces with provided configurations - vyos_lldp_interfaces: - config: - - name: 'eth2' - location: - civic_based: - country_code: 'US' - ca_info: - - ca_type: 0 - ca_value: 'ENGLISH' - - - name: 'eth1' - location: - coordinate_based: - altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' - state: replaced -# -# -# ------------------------- -# Module Execution Result -# ------------------------- -# -# "before": [ -# { -# "location": { -# "coordinate_based": { -# "altitude": 2200, -# "datum": "WGS84", -# "latitude": "33.524449N", -# "longitude": "222.267255W" -# } -# }, -# "name": "eth2" -# }, -# { -# "location": { -# "civic_based": { -# "ca_info": [ -# { -# "ca_type": 0, -# "ca_value": "ENGLISH" -# } -# ], -# "country_code": "US" -# } -# }, -# "name": "eth1" -# } -# ] -# -# "commands": [ -# "delete service lldp interface eth2 location", -# "set service lldp interface eth2 'disable'", -# "set service lldp interface eth2 location civic-based country-code 'US'", -# "set service lldp interface eth2 location civic-based ca-type 0 ca-value 'ENGLISH'", -# "delete service lldp interface eth1 location", -# "set service lldp interface eth1 'disable'", -# "set service lldp interface eth1 location coordinate-based latitude '33.524449N'", -# "set service lldp interface eth1 location coordinate-based altitude '2200'", -# "set service lldp interface eth1 location coordinate-based datum 'WGS84'", -# "set service lldp interface eth1 location coordinate-based longitude '222.267255W'" -# ] -# -# "after": [ -# { -# "location": { -# "civic_based": { -# "ca_info": [ -# { -# "ca_type": 0, -# "ca_value": "ENGLISH" -# } -# ], -# "country_code": "US" -# } -# }, -# "name": "eth2" -# }, -# { -# "location": { -# "coordinate_based": { -# "altitude": 2200, -# "datum": "WGS84", -# "latitude": "33.524449N", -# "longitude": "222.267255W" -# } -# }, -# "name": "eth1" -# } -# ] -# -# After state: -# ------------- -# -# vyos@vyos:~$ show configuration commands | grep lldp -# set service lldp interface eth1 'disable' -# set service lldp interface eth1 location coordinate-based altitude '2200' -# set service lldp interface eth1 location coordinate-based datum 'WGS84' -# set service lldp interface eth1 location coordinate-based latitude '33.524449N' -# set service lldp interface eth1 location coordinate-based longitude '222.267255W' -# set service lldp interface eth2 'disable' -# set service lldp interface eth2 location civic-based ca-type 0 ca-value 'ENGLISH' -# set service lldp interface eth2 location civic-based country-code 'US' - - -# Using overridden -# -# Before state -# -------------- -# -# vyos@vyos:~$ show configuration commands | grep lldp -# set service lldp interface eth1 'disable' -# set service lldp interface eth1 location coordinate-based altitude '2200' -# set service lldp interface eth1 location coordinate-based datum 'WGS84' -# set service lldp interface eth1 location coordinate-based latitude '33.524449N' -# set service lldp interface eth1 location coordinate-based longitude '222.267255W' -# set service lldp interface eth2 'disable' -# set service lldp interface eth2 location civic-based ca-type 0 ca-value 'ENGLISH' -# set service lldp interface eth2 location civic-based country-code 'US' -# -- name: Overrides all device configuration with provided configuration - vyos_lag_interfaces: - config: - - name: 'eth2' - location: - elin: 0000000911 - - state: overridden -# -# -# ------------------------- -# Module Execution Result -# ------------------------- -# -# "before": [ -# { -# "enable": false, -# "location": { -# "civic_based": { -# "ca_info": [ -# { -# "ca_type": 0, -# "ca_value": "ENGLISH" -# } -# ], -# "country_code": "US" -# } -# }, -# "name": "eth2" -# }, -# { -# "enable": false, -# "location": { -# "coordinate_based": { -# "altitude": 2200, -# "datum": "WGS84", -# "latitude": "33.524449N", -# "longitude": "222.267255W" -# } -# }, -# "name": "eth1" -# } -# ] -# -# "commands": [ -# "delete service lldp interface eth2 location", -# "delete service lldp interface eth2 disable", -# "set service lldp interface eth2 location elin 0000000911" -# -# -# "after": [ -# { -# "location": { -# "elin": 0000000911 -# }, -# "name": "eth2" -# } -# ] -# -# -# After state -# ------------ -# -# vyos@vyos# run show configuration commands | grep lldp -# set service lldp interface eth2 location elin '0000000911' - - -# Using deleted -# -# Before state -# ------------- -# -# vyos@vyos# run show configuration commands | grep lldp -# set service lldp interface eth2 location elin '0000000911' -# -- name: Delete lldp interface attributes of given interfaces. - vyos_lag_interfaces: - config: - - name: 'eth2' - state: deleted -# -# -# ------------------------ -# Module Execution Results -# ------------------------ -# - "before": [ - { - "location": { - "elin": 0000000911 - }, - "name": "eth2" - } - ] -# "commands": [ -# "commands": [ -# "delete service lldp interface eth2" -# ] -# -# "after": [] -# After state -# ------------ -# vyos@vyos# run show configuration commands | grep lldp -# set service 'lldp' - - -""" -RETURN = """ -before: - description: The configuration as structured data prior to module invocation. - returned: always - type: list - sample: > - The configuration returned will always be in the same format - of the parameters above. -after: - description: The configuration as structured data after module completion. - returned: when changed - type: list - sample: > - The configuration returned will always be in the same format - of the parameters above. -commands: - description: The set of commands pushed to the remote device. - returned: always - type: list - sample: - - "set service lldp interface eth2 'disable'" - - "delete service lldp interface eth1 location" -""" - - -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.lldp_interfaces.lldp_interfaces import ( - Lldp_interfacesArgs, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.lldp_interfaces.lldp_interfaces import ( - Lldp_interfaces, -) - - -def main(): - """ - Main entry point for module execution - - :returns: the result form module invocation - """ - required_if = [ - ("state", "merged", ("config",)), - ("state", "replaced", ("config",)), - ("state", "overridden", ("config",)), - ] - module = AnsibleModule( - argument_spec=Lldp_interfacesArgs.argument_spec, - required_if=required_if, - supports_check_mode=True, - ) - - result = Lldp_interfaces(module).execute_module() - module.exit_json(**result) - - -if __name__ == "__main__": - main() diff --git a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/terminal/vyos.py b/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/terminal/vyos.py deleted file mode 100644 index 77ef3e2..0000000 --- a/test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/terminal/vyos.py +++ /dev/null @@ -1,52 +0,0 @@ -# -# (c) 2016 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/>. -# -from __future__ import annotations - - -import os -import re - -from ansible.plugins.terminal import TerminalBase -from ansible.errors import AnsibleConnectionFailure - - -class TerminalModule(TerminalBase): - - terminal_stdout_re = [ - re.compile(br"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"), - re.compile(br"\@[\w\-\.]+:\S+?[>#\$] ?$"), - ] - - terminal_stderr_re = [ - re.compile(br"\n\s*Invalid command:"), - re.compile(br"\nCommit failed"), - re.compile(br"\n\s+Set failed"), - ] - - terminal_length = os.getenv("ANSIBLE_VYOS_TERMINAL_LENGTH", 10000) - - def on_open_shell(self): - try: - for cmd in (b"set terminal length 0", b"set terminal width 512"): - self._exec_cli_command(cmd) - self._exec_cli_command( - b"set terminal length %d" % self.terminal_length - ) - except AnsibleConnectionFailure: - raise AnsibleConnectionFailure("unable to set terminal parameters") |