Allow httpapi for EOS resource modules (#66871)

* Redo tests to be transport agnostic

cli -> eos config

* Redirect connection for httpapi

* Fix tests

* Handle missing platform imports
This commit is contained in:
Nathaniel Case 2020-02-03 08:04:08 -05:00 committed by GitHub
parent 0ee28c14c2
commit 53c7f8cbde
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
70 changed files with 359 additions and 159 deletions

View file

@ -30,12 +30,23 @@ import json
from ansible.module_utils._text import to_text, to_native
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.basic import env_fallback
from ansible.module_utils.basic import env_fallback, missing_required_lib
from ansible.module_utils.connection import Connection, ConnectionError
from ansible.module_utils.network.common.netconf import NetconfConnection
from ansible.module_utils.network.common.parsing import Cli
from ansible.module_utils.six import iteritems
try:
from ansible.module_utils.network.eos import eos
HAS_EOS = True
except ImportError:
HAS_EOS = False
try:
from ansible.module_utils.network.nxos import nxos
HAS_NXOS = True
except ImportError:
HAS_NXOS = False
NET_TRANSPORT_ARGS = dict(
host=dict(required=True),
@ -212,7 +223,17 @@ def get_resource_connection(module):
capabilities = get_capabilities(module)
network_api = capabilities.get('network_api')
if network_api in ('cliconf', 'nxapi', 'eapi', 'exosapi'):
if network_api == 'eapi':
if HAS_EOS:
module._connection = eos.get_connection(module)
else:
module.fail_json(msg=missing_required_lib("collection arista.eos"))
elif network_api == 'nxapi':
if HAS_NXOS:
module._connection = nxos.get_connection(module)
else:
module.fail_json(msg=missing_required_lib("collection cisco.nxos"))
elif network_api in ('cliconf', 'exosapi'):
module._connection = Connection(module._socket_path)
elif network_api == 'netconf':
module._connection = NetconfConnection(module._socket_path)

View file

@ -418,6 +418,9 @@ class HttpApi:
self._session_support = self._connection.supports_sessions()
return self._session_support
def get(self, command, **kwargs):
return self._connection.send_request(command)
def run_commands(self, commands, check_rc=True):
"""Runs list of commands on remote device and returns results
"""
@ -511,7 +514,7 @@ class HttpApi:
"""
return self.edit_config(config, commit, replace)
def edit_config(self, config, commit=False, replace=False):
def edit_config(self, config, commit=True, replace=False):
"""Loads the configuration onto the remote devices
If the device doesn't support configuration sessions, this will

View file

@ -130,6 +130,13 @@ class Interfaces(FactsBase):
self.facts['all_ipv6_addresses'] = list()
data = self.responses[0]
if not isinstance(data, dict):
# EAPI kills the whole request on an error.
self.COMMANDS.pop()
super(Interfaces, self).populate()
self.responses.append(None)
data = self.responses[0]
self.facts['interfaces'] = self.populate_interfaces(data)
data = self.responses[1]

View file

@ -63,8 +63,7 @@ class VlansFacts(object):
if obj:
objs.extend(obj)
ansible_facts['ansible_network_resources'].pop('vlans', None)
facts = {}
facts = {'vlans': []}
if objs:
params = utils.validate_config(self.argument_spec, {'config': objs})
facts['vlans'] = [utils.remove_empties(cfg) for cfg in params['config']]

View file

@ -39,7 +39,7 @@ class JsonRpcServer(object):
break
if not rpc_method:
error = self.method_not_found()
error = self.method_not_found(rpc_method)
response = json.dumps(error)
else:
try:

View file

@ -0,0 +1,17 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli

View file

@ -0,0 +1,17 @@
---
- name: collect all eapi test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=httpapi)
include: "{{ test_case_to_run }} ansible_connection=httpapi"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_httpapi

View file

@ -1,17 +1,3 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/cli"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli
- { include: cli.yaml, tags: ['cli'] }
- { include: eapi.yaml, tags: ['eapi'] }

View file

@ -1,7 +1,7 @@
---
- name: Reset initial config
cli_config:
config: |
eos_config:
lines: |
interface Ethernet1
description "Interface 1"
no shutdown

View file

@ -0,0 +1,22 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- block:
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli
always:
- name: Clean up test state
include: "{{ role_path }}/tests/common/cleanup.yml ansible_connection=network_cli"

View file

@ -0,0 +1,22 @@
---
- name: collect all eapi test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- block:
- name: run test cases (connection=httpapi)
include: "{{ test_case_to_run }} ansible_connection=httpapi"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_httpapi
always:
- name: Clean up test state
include: "{{ role_path }}/tests/common/cleanup.yml ansible_connection=httpapi"

View file

@ -1,22 +1,3 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/cli"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- block:
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli
always:
- name: Clean up test state
include: "{{ role_path }}/tests/cli/cleanup.yml ansible_connection=network_cli"
- { include: cli.yaml, tags: ['cli'] }
- { include: eapi.yaml, tags: ['eapi'] }

View file

@ -1,12 +1,12 @@
---
- name: Remove all vlans
cli_config:
config: no vlan 1-4094
eos_config:
lines: no vlan 1-4094
become: yes
- name: Completely remove vlans from interfaces
cli_config:
config: |
eos_config:
lines: |
interface {{ item }}
no switchport mode
no switchport access vlan

View file

@ -1,7 +1,7 @@
---
- name: Reset state
cli_config:
config: |
eos_config:
lines: |
interface Ethernet1
switchport access vlan 20
no switchport trunk native vlan

View file

@ -0,0 +1,17 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli

View file

@ -0,0 +1,17 @@
---
- name: collect all eapi test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=httpapi)
include: "{{ test_case_to_run }} ansible_connection=httpapi"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli

View file

@ -1,17 +1,3 @@
---
- 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 cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli
- { include: cli.yaml, tags: ['cli'] }
- { include: eapi.yaml, tags: ['eapi'] }

View file

@ -1,7 +1,7 @@
---
- name: Reset state
cli_config:
config: |
eos_config:
lines: |
interface Ethernet1
ip address 192.0.2.12/24
ip address 203.0.113.27/31 secondary

View file

@ -0,0 +1,17 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli

View file

@ -0,0 +1,17 @@
---
- name: collect all eapi test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=httpapi)
include: "{{ test_case_to_run }} ansible_connection=httpapi"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_httpapi

View file

@ -1,17 +1,3 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/cli"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli
- { include: cli.yaml, tags: ['cli'] }
- { include: eapi.yaml, tags: ['eapi'] }

View file

@ -1,7 +1,7 @@
---
- name: Reset initial config
cli_config:
config: |
eos_config:
lines: |
interface Ethernet1
lacp port-priority 30
lacp rate normal

View file

@ -0,0 +1,17 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli

View file

@ -0,0 +1,17 @@
---
- name: collect all eapi test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=httpapi)
include: "{{ test_case_to_run }} ansible_connection=httpapi"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_httpapi

View file

@ -1,17 +1,3 @@
---
- 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 cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli
- { include: cli.yaml, tags: ['cli'] }
- { include: eapi.yaml, tags: ['eapi'] }

View file

@ -1,7 +1,7 @@
---
- name: Reset state
cli_config:
config: |
eos_config:
lines: |
interface Ethernet1
channel-group 5 mode on
interface Ethernet2

View file

@ -0,0 +1,17 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli

View file

@ -0,0 +1,17 @@
---
- name: collect all eapi test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=httpapi)
include: "{{ test_case_to_run }} ansible_connection=httpapi"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_httpapi

View file

@ -1,17 +1,3 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/cli"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli
- { include: cli.yaml, tags: ['cli'] }
- { include: eapi.yaml, tags: ['eapi'] }

View file

@ -1,7 +1,7 @@
---
- name: Reset initial config
cli_config:
config: |
eos_config:
lines: |
lldp timer 3000
lldp holdtime 100
lldp reinit 5

View file

@ -0,0 +1,17 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli

View file

@ -0,0 +1,17 @@
---
- name: collect all eapi test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=httpapi)
include: "{{ test_case_to_run }} ansible_connection=httpapi"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_httpapi

View file

@ -1,17 +1,3 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/cli"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli
- { include: cli.yaml, tags: ['cli'] }
- { include: eapi.yaml, tags: ['eapi'] }

View file

@ -1,7 +1,7 @@
---
- name: Reset initial config
cli_config:
config: |
eos_config:
lines: |
interface Ethernet1
no lldp receive
lldp transmit

View file

@ -0,0 +1,17 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli

View file

@ -0,0 +1,17 @@
---
- name: collect all eapi test cases
find:
paths: "{{ role_path }}/tests/common"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=httpapi)
include: "{{ test_case_to_run }} ansible_connection=httpapi"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_httpapi

View file

@ -1,17 +1,3 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/cli"
patterns: "{{ testcase }}.yaml"
delegate_to: localhost
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test cases (connection=network_cli)
include: "{{ test_case_to_run }} ansible_connection=network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
tags: connection_network_cli
- { include: cli.yaml, tags: ['cli'] }
- { include: eapi.yaml, tags: ['eapi'] }

View file

@ -1,12 +1,17 @@
---
- name: Reset initial config
cli_config:
config: |
eos_config:
before:
no vlan 1-4094
defaults: yes
match: exact
lines: |
vlan 10
name ten
state active
vlan 20
name twenty
state active
become: yes
- eos_facts: