Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ericsson contribute feature and module #57353

Closed
wants to merge 21 commits into from
Closed
Changes from 19 commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -0,0 +1,70 @@
.. _eccli_platform_options:

***************************************
ERIC_ECCLI Platform Options
***************************************

ERIC_ECCLI supports Enable Mode (Privilege Escalation). This page offers details on how to use Enable Mode on ERIC_ECCLI in Ansible.

.. contents:: Topics

Connections Available
================================================================================

+---------------------------+-----------------------------------------------+
|.. | CLI |
+===========================+===============================================+
| **Protocol** | SSH |
+---------------------------+-----------------------------------------------+
| | **Credentials** | | uses SSH keys / SSH-agent if present |
| | | | accepts ``-u myuser -k`` if using password |
+---------------------------+-----------------------------------------------+
| **Indirect Access** | via a bastion (jump host) |
+---------------------------+-----------------------------------------------+
| | **Connection Settings** | | ``ansible_connection: network_cli`` |
| | | | |
| | | | |
+---------------------------+-----------------------------------------------+
| | **Enable Mode** | | supported - use ``ansible_become: yes`` |
| | (Privilege Escalation) | | with ``ansible_become_method: enable`` |
| | | | and ``ansible_become_password:`` |
+---------------------------+-----------------------------------------------+
| **Returned Data Format** | ``stdout[0].`` |
+---------------------------+-----------------------------------------------+

For legacy playbooks, ERIC_ECCLI still supports ``ansible_connection: local``. We recommend modernizing to use ``ansible_connection: network_cli`` as soon as possible.

This comment has been minimized.

Copy link
@Qalthos

Qalthos Jun 11, 2019

Contributor

Your module does not support connection: local

This comment has been minimized.

Copy link
@danielmellado

danielmellado Jun 12, 2019

Contributor

if the module does not support it, please remove the documentation regarding to it


Using CLI in Ansible
====================

Example CLI ``group_vars/eric_eccli.yml``
-----------------------------------------

.. code-block:: yaml
ansible_connection: network_cli
ansible_network_os: eric_eccli
ansible_user: myuser
ansible_password: !vault...
ansible_become: yes
ansible_become_method: enable
ansible_become_password: !vault...
ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q bastion01"'
- If you are using SSH keys (including an ssh-agent) you can remove the ``ansible_password`` configuration.

This comment has been minimized.

Copy link
@danielmellado

danielmellado Jun 12, 2019

Contributor

Aren't those just default ansible options? I do see no need of commenting they also here. Instead, I'd refer to the upstream ansible docs

- If you are accessing your host directly (not through a bastion/jump host) you can remove the ``ansible_ssh_common_args`` configuration.
- If you are accessing your host through a bastion/jump host, you cannot include your SSH password in the ``ProxyCommand`` directive. To prevent secrets from leaking out (for example in ``ps`` output), SSH does not support providing passwords via environment variables.

Example CLI Task
----------------

.. code-block:: yaml
- name: Backup current switch config (eric_eccli)
eric_eccli_config:

This comment has been minimized.

Copy link
@Qalthos

Qalthos Jun 11, 2019

Contributor

This is not the module you have included. Please change to a module that will actually exist.

If you intend to add eric_eccli_config at a later date, you can add another example at that time.

backup: yes
register: backup_eric_eccli_location
when: ansible_network_os == 'eric_eccli'
.. include:: shared_snippets/SSH_warning.txt
@@ -27,6 +27,7 @@ Some Ansible Network platforms support multiple connection types, privilege esca
platform_slxos
platform_voss
platform_netconf_enabled
platform_eric_eccli

This comment has been minimized.

Copy link
@samccann

samccann Jun 11, 2019

Contributor

Please move this new platform up in the list. The list needs to be in alphabetical order.

You also need to add your new platform to the "Settings by Platform" table in this rst file.


.. _settings_by_platform:

@@ -1790,4 +1790,18 @@ VERBOSE_TO_STDERR:
- section: defaults
key: verbose_to_stderr
type: bool
ERIC_ECCLI_ADDITIONAL_RE_FILE:

This comment has been minimized.

Copy link
@Qalthos

Qalthos Jun 11, 2019

Contributor

This absolutely does not belong here. This should probably be moved to an option of the terminal plugin, though I am not sure why you need tunable regexes in the first place.

This comment has been minimized.

Copy link
@ghost

ghost Jun 13, 2019

Author

It will output some prompt information when running command through ECCLI model. In order to capture these custom prompt and we will add matching rule in configuration file instead of writing code in terminal plugin. I think it is more convenient and friendly for user of ansible, what do you think about?

name: Set the prompt and error information configuration file used in network eric eccli module
default: null
description:
- Specify a custom ECCLI prompt and error information configuration file,

This comment has been minimized.

Copy link
@samccann

samccann Jun 11, 2019

Contributor
Suggested change
- Specify a custom ECCLI prompt and error information configuration file,
- Specify a custom ECCLI prompt and error information configuration file.
- For each command run through ECCLI module, performs additional checking,

This comment has been minimized.

Copy link
@samccann

samccann Jun 11, 2019

Contributor
Suggested change
- For each command run through ECCLI module, performs additional checking,
- For each command run through ECCLI module, perform additional checking.
- If command's output matches any error regular expressions
- specified in this configuration file, then command runs fails.

This comment has been minimized.

Copy link
@samccann

samccann Jun 11, 2019

Contributor
Suggested change
- specified in this configuration file, then command runs fails.
- specified in this configuration file, then command run fails.
- If command's output matches any prompt specified in this configuration file,
- the current received command's output is treated as complete.
env: [{name: ANSIBLE_ERIC_ECCLI_ADDITIONAL_RE_FILE}]

This comment has been minimized.

Copy link
@danielmellado

danielmellado Jun 12, 2019

Contributor

Please see Qalthos comment above

ini:
- {key: eric_eccli_additional_re_file, section: defaults}
type: string
...
No changes.
@@ -0,0 +1,173 @@
#
# Copyright (c) 2019 Ericsson AB.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
#

import json

from ansible.module_utils._text import to_text
from ansible.module_utils.basic import env_fallback
from ansible.module_utils.network.common.utils import to_list, ComplexList
from ansible.module_utils.connection import Connection, ConnectionError

_DEVICE_CONFIGS = {}

eric_eccli_provider_spec = {

This comment has been minimized.

Copy link
@Qalthos

Qalthos Jun 11, 2019

Contributor

It doesn't look like you're even using connection: local, why is any of this here?

This comment has been minimized.

Copy link
@ghost

ghost Jun 14, 2019

Author

Thank your advise, I will delete it.

'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'),
'authorize': dict(fallback=(env_fallback, ['ANSIBLE_NET_AUTHORIZE']), type='bool'),
'auth_pass': dict(fallback=(env_fallback, ['ANSIBLE_NET_AUTH_PASS']), no_log=True),
'timeout': dict(type='int')
}
eric_eccli_argument_spec = {
'provider': dict(type='dict', options=eric_eccli_provider_spec),
}

eric_eccli_top_spec = {
'host': dict(removed_in_version=2.9),

This comment has been minimized.

Copy link
@Qalthos

Qalthos Jun 11, 2019

Contributor

This argument is marked as being removed in the same version it is introduced. This makes no sense.

This comment has been minimized.

Copy link
@ghost

ghost Jun 14, 2019

Author

Thank your advise. I will correct it.

'port': dict(removed_in_version=2.9, type='int'),
'username': dict(removed_in_version=2.9),
'password': dict(removed_in_version=2.9, no_log=True),
'ssh_keyfile': dict(removed_in_version=2.9, type='path'),
'authorize': dict(fallback=(env_fallback, ['ANSIBLE_NET_AUTHORIZE']), type='bool'),
'auth_pass': dict(removed_in_version=2.9, no_log=True),
'timeout': dict(removed_in_version=2.9, type='int')
}
eric_eccli_argument_spec.update(eric_eccli_top_spec)


def get_provider_argspec():
return eric_eccli_provider_spec


def get_connection(module):
if hasattr(module, '_eric_eccli_connection'):
return module._eric_eccli_connection

capabilities = get_capabilities(module)
network_api = capabilities.get('network_api')
if network_api == 'cliconf':
module._eric_eccli_connection = Connection(module._socket_path)
else:
module.fail_json(msg='Invalid connection type %s' % network_api)

return module._eric_eccli_connection


def get_capabilities(module):
if hasattr(module, '_eric_eccli_capabilities'):
return module._eric_eccli_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._eric_eccli_capabilities = json.loads(capabilities)
return module._eric_eccli_capabilities


def check_args(module, warnings):

This comment has been minimized.

Copy link
@Qalthos

Qalthos Jun 11, 2019

Contributor

You don't need this function

pass


def get_defaults_flag(module):

This comment has been minimized.

Copy link
@Qalthos

Qalthos Jun 11, 2019

Contributor

This isn't implemented in the cliconf plugin. What are you trying to do here?

connection = get_connection(module)
try:
out = connection.get_defaults_flag()
except ConnectionError as exc:
module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))
return to_text(out, errors='surrogate_then_replace').strip()


def get_config(module, flags=None):

This comment has been minimized.

Copy link
@Qalthos

Qalthos Jun 11, 2019

Contributor

get_config is not implemented in the cliconf plugin. This function is not used and will only ever return "None" if tried.

flag_str = ' '.join(to_list(flags))

try:
return _DEVICE_CONFIGS[flag_str]
except KeyError:
connection = get_connection(module)
try:
out = connection.get_config(flags=flags)
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[flag_str] = cfg
return cfg


def to_commands(module, commands):

This comment has been minimized.

Copy link
@Qalthos

Qalthos Jun 11, 2019

Contributor

This function isn't used, and when you implement the same functionality in eric_eccli_command you probably shouldn't be doing it yourself anyway.

spec = {
'command': dict(key=True),
'prompt': dict(),
'answer': dict()
}
transform = ComplexList(spec, module)
return transform(commands)


def run_commands(module, commands, check_rc=True):
connection = get_connection(module)
try:
return connection.run_commands(commands=commands, check_rc=check_rc)
except ConnectionError as exc:
module.fail_json(msg=to_text(exc))


def load_config(module, commands):

This comment has been minimized.

Copy link
@Qalthos

Qalthos Jun 11, 2019

Contributor

This function will only ever throw an AttributeError, as edit_config is not implemented.

connection = get_connection(module)

try:
resp = connection.edit_config(commands)
return resp.get('response')
except ConnectionError as exc:
module.fail_json(msg=to_text(exc))


def normalize_interface(name):

This comment has been minimized.

Copy link
@Qalthos

Qalthos Jun 11, 2019

Contributor

Does this function do anything at all for your platform, or was this just copied from another module_utils file?

"""Return the normalized interface name
"""
if not name:
return

def _get_number(name):
digits = ''
for char in name:
if char.isdigit() or char in '/.':
digits += char
return digits

if name.lower().startswith('gi'):
if_type = 'GigabitEthernet'
elif name.lower().startswith('te'):
if_type = 'TenGigabitEthernet'
elif name.lower().startswith('fa'):
if_type = 'FastEthernet'
elif name.lower().startswith('fo'):
if_type = 'FortyGigabitEthernet'
elif name.lower().startswith('et'):
if_type = 'Ethernet'
elif name.lower().startswith('vl'):
if_type = 'Vlan'
elif name.lower().startswith('lo'):
if_type = 'loopback'
elif name.lower().startswith('po'):
if_type = 'port-channel'
elif name.lower().startswith('nv'):
if_type = 'nve'
else:
if_type = None

number_list = name.split(' ')
if len(number_list) == 2:
if_number = number_list[-1].strip()
else:
if_number = _get_number(name)

if if_type:
proper_interface = if_type + if_number
else:
proper_interface = name

return proper_interface
No changes.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.