From 48ecbb8fb90080b4d1056bbb1dc2bfaddcf2c847 Mon Sep 17 00:00:00 2001 From: Trishna Guha Date: Mon, 15 Jan 2018 13:16:41 +0530 Subject: [PATCH] fix connection gets overridden by network_cli for transport nxapi,eapi net_* modules (#34778) * fix connection gets overridden by network_cli for transport nxapi,eapi net_* modules Signed-off-by: Trishna Guha * Define functions in individual action plugins to avoid code duplication Signed-off-by: Trishna Guha * Add net_* eos tests for eapi Signed-off-by: Trishna Guha * update plugin code --- lib/ansible/plugins/action/eos.py | 48 ++++++++-------- lib/ansible/plugins/action/net_base.py | 15 ++++- lib/ansible/plugins/action/nxos.py | 56 ++++++++++--------- .../eos_banner/tests/eapi/net_banner.yaml | 36 ++++++++++++ .../tests/eapi/net_interface.yaml | 53 ++++++++++++++++++ .../tests/eapi/net_l3_interface.yaml | 42 ++++++++++++++ .../eos_logging/tests/eapi/net_logging.yaml | 39 +++++++++++++ .../eos_system/tests/eapi/net_system.yaml | 37 ++++++++++++ .../nxos_logging/tests/common/basic.yaml | 6 ++ .../tests/common/net_logging.yaml | 7 ++- .../nxos_system/tests/nxapi/net_system.yaml | 38 +++++++++++++ .../targets/nxos_user/tests/common/basic.yaml | 6 ++ .../nxos_user/tests/common/net_user.yaml | 12 ++-- 13 files changed, 338 insertions(+), 57 deletions(-) create mode 100644 test/integration/targets/eos_banner/tests/eapi/net_banner.yaml create mode 100644 test/integration/targets/eos_interface/tests/eapi/net_interface.yaml create mode 100644 test/integration/targets/eos_l3_interface/tests/eapi/net_l3_interface.yaml create mode 100644 test/integration/targets/eos_logging/tests/eapi/net_logging.yaml create mode 100644 test/integration/targets/eos_system/tests/eapi/net_system.yaml create mode 100644 test/integration/targets/nxos_system/tests/nxapi/net_system.yaml diff --git a/lib/ansible/plugins/action/eos.py b/lib/ansible/plugins/action/eos.py index 51bff914a87..4fd309c862f 100644 --- a/lib/ansible/plugins/action/eos.py +++ b/lib/ansible/plugins/action/eos.py @@ -79,28 +79,7 @@ class ActionModule(_ActionModule): task_vars['ansible_socket'] = socket_path else: - provider['transport'] = 'eapi' - - if provider.get('host') is None: - provider['host'] = self._play_context.remote_addr - - if provider.get('port') is None: - default_port = 443 if provider['use_ssl'] else 80 - provider['port'] = int(self._play_context.port or default_port) - - if provider.get('timeout') is None: - provider['timeout'] = C.PERSISTENT_COMMAND_TIMEOUT - - if provider.get('username') is None: - provider['username'] = self._play_context.connection_user - - if provider.get('password') is None: - provider['password'] = self._play_context.password - - if provider.get('authorize') is None: - provider['authorize'] = False - - self._task.args['provider'] = provider + self._task.args['provider'] = ActionModule.eapi_implementation(provider, self._play_context) else: return {'failed': True, 'msg': 'Connection type %s is not valid for this module' % self._play_context.connection} @@ -119,3 +98,28 @@ class ActionModule(_ActionModule): result = super(ActionModule, self).run(tmp, task_vars) return result + + @staticmethod + def eapi_implementation(provider, play_context): + provider['transport'] = 'eapi' + + if provider.get('host') is None: + provider['host'] = play_context.remote_addr + + if provider.get('port') is None: + default_port = 443 if provider['use_ssl'] else 80 + provider['port'] = int(play_context.port or default_port) + + if provider.get('timeout') is None: + provider['timeout'] = C.PERSISTENT_COMMAND_TIMEOUT + + if provider.get('username') is None: + provider['username'] = play_context.connection_user + + if provider.get('password') is None: + provider['password'] = play_context.password + + if provider.get('authorize') is None: + provider['authorize'] = False + + return provider diff --git a/lib/ansible/plugins/action/net_base.py b/lib/ansible/plugins/action/net_base.py index 45c58910761..a87736c46d6 100644 --- a/lib/ansible/plugins/action/net_base.py +++ b/lib/ansible/plugins/action/net_base.py @@ -25,6 +25,8 @@ from ansible.module_utils._text import to_text from ansible.module_utils.connection import Connection from ansible.errors import AnsibleError from ansible.plugins.action import ActionBase +from ansible.plugins.action.nxos import ActionModule as _NxosActionModule +from ansible.plugins.action.eos import ActionModule as _EosActionModule from ansible.module_utils.network.common.utils import load_provider from imp import find_module, load_module @@ -58,6 +60,9 @@ class ActionModule(ActionBase): if play_context.network_os == 'junos': play_context.connection = 'netconf' play_context.port = int(self.provider['port'] or self._play_context.port or 830) + elif self.provider['transport'] in ('nxapi', 'eapi') and play_context.network_os in ('nxos', 'eos'): + play_context.connection = play_context.connection + play_context.port = int(self.provider['port'] or self._play_context.port or 22) else: play_context.connection = 'network_cli' play_context.port = int(self.provider['port'] or self._play_context.port or 22) @@ -73,8 +78,14 @@ class ActionModule(ActionBase): play_context.become_method = 'enable' if self._play_context.connection == 'local': - socket_path = self._start_connection(play_context) - task_vars['ansible_socket'] = socket_path + if self.provider['transport'] == 'nxapi' and play_context.network_os == 'nxos': + self._task.args['provider'] = _NxosActionModule.nxapi_implementation(self.provider, self._play_context) + elif self.provider['transport'] == 'eapi' and play_context.network_os == 'eos': + self._task.args['provider'] = _EosActionModule.eapi_implementation(self.provider, self._play_context) + else: + socket_path = self._start_connection(play_context) + task_vars['ansible_socket'] = socket_path + else: provider = self._task.args.get('provider', {}) if any(provider.values()): diff --git a/lib/ansible/plugins/action/nxos.py b/lib/ansible/plugins/action/nxos.py index cc6d757c2f0..52ceab85fd2 100644 --- a/lib/ansible/plugins/action/nxos.py +++ b/lib/ansible/plugins/action/nxos.py @@ -75,32 +75,7 @@ class ActionModule(_ActionModule): task_vars['ansible_socket'] = socket_path else: - provider['transport'] = 'nxapi' - if provider.get('host') is None: - provider['host'] = self._play_context.remote_addr - - if provider.get('port') is None: - if provider.get('use_ssl'): - provider['port'] = 443 - else: - provider['port'] = 80 - - if provider.get('timeout') is None: - provider['timeout'] = C.PERSISTENT_COMMAND_TIMEOUT - - if provider.get('username') is None: - provider['username'] = self._play_context.connection_user - - if provider.get('password') is None: - provider['password'] = self._play_context.password - - if provider.get('use_ssl') is None: - provider['use_ssl'] = False - - if provider.get('validate_certs') is None: - provider['validate_certs'] = True - - self._task.args['provider'] = provider + self._task.args['provider'] = ActionModule.nxapi_implementation(provider, self._play_context) else: return {'failed': True, 'msg': 'Connection type %s is not valid for this module' % self._play_context.connection} @@ -119,3 +94,32 @@ class ActionModule(_ActionModule): result = super(ActionModule, self).run(tmp, task_vars) return result + + @staticmethod + def nxapi_implementation(provider, play_context): + provider['transport'] = 'nxapi' + if provider.get('host') is None: + provider['host'] = play_context.remote_addr + + if provider.get('port') is None: + if provider.get('use_ssl'): + provider['port'] = 443 + else: + provider['port'] = 80 + + if provider.get('timeout') is None: + provider['timeout'] = C.PERSISTENT_COMMAND_TIMEOUT + + if provider.get('username') is None: + provider['username'] = play_context.connection_user + + if provider.get('password') is None: + provider['password'] = play_context.password + + if provider.get('use_ssl') is None: + provider['use_ssl'] = False + + if provider.get('validate_certs') is None: + provider['validate_certs'] = True + + return provider diff --git a/test/integration/targets/eos_banner/tests/eapi/net_banner.yaml b/test/integration/targets/eos_banner/tests/eapi/net_banner.yaml new file mode 100644 index 00000000000..23681d76afa --- /dev/null +++ b/test/integration/targets/eos_banner/tests/eapi/net_banner.yaml @@ -0,0 +1,36 @@ +--- +- debug: msg="START eos eapi/net_banner.yaml on connection={{ ansible_connection }}" + +# Add minimal testcase to check args are passed correctly to +# implementation module and module run is successful. + +- name: Remove previous motd banner (setup) + eos_config: + lines: no banner motd + authorize: yes + provider: "{{ eapi }}" + +- name: create motd + net_banner: + banner: motd + text: this is my motd banner configure by net_banner + state: present + authorize: yes + provider: "{{ eapi }}" + register: result + +- assert: + that: + - "result.changed == true" + - "result.commands.0.cmd == 'banner motd'" + - "result.commands.0.input == 'this is my motd banner configure by net_banner'" + # Ensure sessions contains epoc. Will fail after 18th May 2033 + - "'ansible_1' in result.session_name" + +- name: Remove previous motd banner (teardown) + eos_config: + lines: no banner motd + authorize: yes + provider: "{{ eapi }}" + +- debug: msg="END eos eapi/net_banner.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/eos_interface/tests/eapi/net_interface.yaml b/test/integration/targets/eos_interface/tests/eapi/net_interface.yaml new file mode 100644 index 00000000000..02a9f6663bd --- /dev/null +++ b/test/integration/targets/eos_interface/tests/eapi/net_interface.yaml @@ -0,0 +1,53 @@ +--- +- debug: msg="START eos eapi/net_interface.yaml on connection={{ ansible_connection }}" + +# Add minimal testcase to check args are passed correctly to +# implementation module and module run is successful. + +- name: Set test interface + set_fact: + test_interface_1: ethernet1 + +- name: Configure interface (setup) + net_interface: + name: "{{ test_interface_1 }}" + description: test-interface-1 + mtu: 1800 + state: present + authorize: yes + provider: "{{ eapi }}" + register: result + +- name: Configure interface description using platform agnostic module + net_interface: + name: "{{ test_interface_1 }}" + description: test-interface-initial + state: present + authorize: yes + provider: "{{ eapi }}" + register: result + +- assert: + that: + - 'result.changed == true' + - '"interface {{ test_interface_1 }}" in result.commands' + - '"description test-interface-initial" in result.commands' + +- name: Confgure interface parameters + net_interface: + name: "{{ test_interface_1 }}" + description: test-interface + mtu: 2000 + state: present + authorize: yes + provider: "{{ eapi }}" + register: result + +- assert: + that: + - 'result.changed == true' + - '"interface {{ test_interface_1 }}" in result.commands' + - '"description test-interface" in result.commands' + - '"mtu 2000" in result.commands' + +- debug: msg="END eos eapi/net_interface.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/eos_l3_interface/tests/eapi/net_l3_interface.yaml b/test/integration/targets/eos_l3_interface/tests/eapi/net_l3_interface.yaml new file mode 100644 index 00000000000..8ab448918ab --- /dev/null +++ b/test/integration/targets/eos_l3_interface/tests/eapi/net_l3_interface.yaml @@ -0,0 +1,42 @@ +--- +- debug: msg="START eos eapi/net_l3_interface.yaml on connection={{ ansible_connection }}" + +# Add minimal testcase to check args are passed correctly to +# implementation module and module run is successful. + +- name: Set test interface + set_fact: + test_interface_1: ethernet1 + +- name: Delete interface ipv4 and ipv6 address(setup) + net_l3_interface: + name: "{{ test_interface_1 }}" + state: absent + authorize: yes + provider: "{{ eapi }}" + register: result + +- name: Configure interface ipv4 address using platform agnostic module + net_l3_interface: + name: "{{ test_interface_1 }}" + ipv4: 192.108.0.1/24 + state: present + authorize: yes + provider: "{{ eapi }}" + register: result + +- assert: + that: + - 'result.changed == true' + - '"interface {{ test_interface_1 }}" in result.commands' + - '"ip address 192.108.0.1/24" in result.commands' + +- name: Delete interface ipv4 and ipv6 address(teardown) + net_l3_interface: + name: "{{ test_interface_1 }}" + state: absent + authorize: yes + provider: "{{ eapi }}" + register: result + +- debug: msg="END eos eapi/net_l3_interface.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/eos_logging/tests/eapi/net_logging.yaml b/test/integration/targets/eos_logging/tests/eapi/net_logging.yaml new file mode 100644 index 00000000000..f60d30b04b8 --- /dev/null +++ b/test/integration/targets/eos_logging/tests/eapi/net_logging.yaml @@ -0,0 +1,39 @@ +--- +- debug: msg="START eos eapi/net_logging.yaml on connection={{ ansible_connection }}" + +# Add minimal testcase to check args are passed correctly to +# implementation module and module run is successful. + +- name: Delete/disable host logging- setup + net_logging: + dest: host + name: 172.16.0.1 + state: absent + authorize: yes + provider: "{{ eapi }}" + register: result + +- name: Set up host logging using platform agnostic module + net_logging: + dest: host + name: 172.16.0.1 + state: present + authorize: yes + provider: "{{ eapi }}" + register: result + +- assert: + that: + - 'result.changed == true' + - '"logging host 172.16.0.1" in result.commands' + +- name: Delete/disable host logging- teardown + net_logging: + dest: host + name: 172.16.0.1 + state: absent + authorize: yes + provider: "{{ eapi }}" + register: result + +- debug: msg="END eos eapi/net_logging.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/eos_system/tests/eapi/net_system.yaml b/test/integration/targets/eos_system/tests/eapi/net_system.yaml new file mode 100644 index 00000000000..b094339b530 --- /dev/null +++ b/test/integration/targets/eos_system/tests/eapi/net_system.yaml @@ -0,0 +1,37 @@ +--- +- debug: msg="START eos eapi/net_system.yaml on connection={{ ansible_connection }}" + +# Add minimal testcase to check args are passed correctly to +# implementation module and module run is successful. + +- name: setup + eos_config: + lines: + - no ip domain-list ansible.com + - no ip domain-list redhat.com + match: none + provider: "{{ eapi }}" + +- name: configure domain_list using platform agnostic module + net_system: + domain_list: + - ansible.com + - redhat.com + provider: "{{ eapi }}" + register: result + +- assert: + that: + - result.changed == true + - "'ip domain-list ansible.com' in result.commands" + - "'ip domain-list redhat.com' in result.commands" + +- name: teardown + eos_config: + lines: + - no ip domain-list ansible.com + - no ip domain-list redhat.com + match: none + provider: "{{ eapi }}" + +- debug: msg="END eos eapi/net_system.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/nxos_logging/tests/common/basic.yaml b/test/integration/targets/nxos_logging/tests/common/basic.yaml index 3556f7251f1..5e4d99eb524 100644 --- a/test/integration/targets/nxos_logging/tests/common/basic.yaml +++ b/test/integration/targets/nxos_logging/tests/common/basic.yaml @@ -1,4 +1,8 @@ --- +- debug: msg="START connection={{ ansible_connection }} nxos_logging basic test" +- debug: msg="Using provider={{ connection.transport }}" + when: ansible_connection == "local" + - name: Set up console logging nxos_logging: dest: console @@ -88,3 +92,5 @@ - 'result.changed == true' - '"no logging logfile" in result.commands' - '"no logging level daemon" in result.commands' + +- debug: msg="END connection={{ ansible_connection }} nxos_logging basic test" diff --git a/test/integration/targets/nxos_logging/tests/common/net_logging.yaml b/test/integration/targets/nxos_logging/tests/common/net_logging.yaml index 5d78f1a8a54..f2ec87d70a2 100644 --- a/test/integration/targets/nxos_logging/tests/common/net_logging.yaml +++ b/test/integration/targets/nxos_logging/tests/common/net_logging.yaml @@ -1,5 +1,7 @@ --- -- debug: msg="START nxos common/net_logging.yaml on connection={{ ansible_connection }}" +- debug: msg="START connection={{ ansible_connection }} nxos common/net_logging.yaml" +- debug: msg="Using provider={{ connection.transport }}" + when: ansible_connection == "local" # Add minimal testcase to check args are passed correctly to # implementation module and module run is successful. @@ -33,4 +35,5 @@ provider: "{{ connection }}" register: result -- debug: msg="END nxos common/net_logging.yaml on connection={{ ansible_connection }}" + +- debug: msg="END connection={{ ansible_connection }} nxos common/net_logging.yaml" diff --git a/test/integration/targets/nxos_system/tests/nxapi/net_system.yaml b/test/integration/targets/nxos_system/tests/nxapi/net_system.yaml new file mode 100644 index 00000000000..8193f809b88 --- /dev/null +++ b/test/integration/targets/nxos_system/tests/nxapi/net_system.yaml @@ -0,0 +1,38 @@ +--- +- debug: msg="START nxos nxapi/net_system.yaml on connection={{ ansible_connection }}" +- debug: msg="Using provider={{ connection.transport }}" + +# Add minimal testcase to check args are passed correctly to +# implementation module and module run is successful. + +- name: setup + nxos_config: + lines: + - no ip domain-list ansible.com + - no ip domain-list redhat.com + match: none + provider: "{{ nxapi }}" + +- name: configure domain_list using platform agnostic module + net_system: + domain_search: + - ansible.com + - redhat.com + provider: "{{ nxapi }}" + register: result + +- assert: + that: + - result.changed == true + - "'ip domain-list ansible.com' in result.commands" + - "'ip domain-list redhat.com' in result.commands" + +- name: setup + nxos_config: + lines: + - no ip domain-list ansible.com + - no ip domain-list redhat.com + match: none + provider: "{{ nxapi }}" + +- debug: msg="END nxos nxapi/net_system.yaml on connection={{ ansible_connection }}" diff --git a/test/integration/targets/nxos_user/tests/common/basic.yaml b/test/integration/targets/nxos_user/tests/common/basic.yaml index 87677889563..59017863173 100644 --- a/test/integration/targets/nxos_user/tests/common/basic.yaml +++ b/test/integration/targets/nxos_user/tests/common/basic.yaml @@ -1,4 +1,8 @@ --- +- debug: msg="START connection={{ ansible_connection }} nxos_user basic test" +- debug: msg="Using provider={{ connection.transport }}" + when: ansible_connection == "local" + - name: Remove old entries of user nxos_user: aggregate: @@ -51,3 +55,5 @@ that: - 'result.changed == true' - '"no username" in result.commands[0]' + +- debug: msg="END connection={{ ansible_connection }} nxos_user basic test" diff --git a/test/integration/targets/nxos_user/tests/common/net_user.yaml b/test/integration/targets/nxos_user/tests/common/net_user.yaml index f46005dbdfa..1952d35e146 100644 --- a/test/integration/targets/nxos_user/tests/common/net_user.yaml +++ b/test/integration/targets/nxos_user/tests/common/net_user.yaml @@ -1,12 +1,14 @@ --- -- debug: msg="START nxos common/net_user.yaml on connection={{ ansible_connection }}" +- debug: msg="START connection={{ ansible_connection }} nxos common/net_user.yaml" +- debug: msg="Using provider={{ connection.transport }}" + when: ansible_connection == "local" # Add minimal testcase to check args are passed correctly to # implementation module and module run is successful. -- name: Remove old entries of user - setup +- name: "Remove old entries of user - setup" net_user: - - name: ansibletest1 + name: ansibletest1 state: absent provider: "{{ connection }}" @@ -27,8 +29,8 @@ - name: teardown net_user: - - name: ansibletest1 + name: ansibletest1 state: absent provider: "{{ connection }}" -- debug: msg="END nxos common/net_user.yaml on connection={{ ansible_connection }}" +- debug: msg="END connection={{ ansible_connection }} nxos common/net_user.yaml"