diff --git a/lib/ansible/module_utils/network/netvisor/__init__.py b/lib/ansible/module_utils/network/netvisor/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/ansible/module_utils/network/netvisor/pn_nvos.py b/lib/ansible/module_utils/network/netvisor/pn_nvos.py new file mode 100644 index 0000000000..2bca029141 --- /dev/null +++ b/lib/ansible/module_utils/network/netvisor/pn_nvos.py @@ -0,0 +1,72 @@ +# Copyright: (c) 2018, Pluribus Networks +# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) +# + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +import shlex + + +def pn_cli(module, switch=None, username=None, password=None, switch_local=None): + """ + Method to generate the cli portion to launch the Netvisor cli. + :param module: The Ansible module to fetch username and password. + :return: The cli string for further processing. + """ + + cli = '/usr/bin/cli --quiet -e --no-login-prompt ' + + if username and password: + cli += '--user "%s":"%s" ' % (username, password) + if switch: + cli += ' switch ' + switch + if switch_local: + cli += ' switch-local ' + + return cli + + +def booleanArgs(arg, trueString, falseString): + if arg is True: + return " %s " % trueString + elif arg is False: + return " %s " % falseString + else: + return "" + + +def run_cli(module, cli, state_map): + """ + This method executes the cli command on the target node(s) and returns the + output. The module then exits based on the output. + :param cli: the complete cli string to be executed on the target node(s). + :param state_map: Provides state of the command. + :param module: The Ansible module to fetch command + """ + state = module.params['state'] + command = state_map[state] + + cmd = shlex.split(cli) + result, out, err = module.run_command(cmd) + + remove_cmd = '/usr/bin/cli --quiet -e --no-login-prompt' + + results = dict( + command=' '.join(cmd).replace(remove_cmd, ''), + msg="%s operation completed" % command, + changed=True + ) + # Response in JSON format + if result != 0: + module.exit_json( + command=' '.join(cmd).replace(remove_cmd, ''), + stderr=err.strip(), + msg="%s operation failed" % command, + changed=False + ) + + if out: + results['stdout'] = out.strip() + module.exit_json(**results) diff --git a/lib/ansible/modules/network/netvisor/pn_access_list.py b/lib/ansible/modules/network/netvisor/pn_access_list.py new file mode 100644 index 0000000000..dad43a95e4 --- /dev/null +++ b/lib/ansible/modules/network/netvisor/pn_access_list.py @@ -0,0 +1,173 @@ +#!/usr/bin/python +# Copyright: (c) 2018, Pluribus Networks +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = """ +--- +module: pn_access_list +author: "Pluribus Networks (@amitsi)" +version_added: "2.8" +short_description: CLI command to create/delete access-list +description: + - This module can be used to create and delete an access list. +options: + pn_cliswitch: + description: + - Target switch to run the CLI on. + required: False + type: str + state: + description: + - State the action to perform. Use 'present' to create access-list and + 'absent' to delete access-list. + required: True + choices: [ "present", "absent"] + pn_name: + description: + - Access List Name. + required: false + type: str + pn_scope: + description: + - 'scope. Available valid values - local or fabric.' + required: false + choices: ['local', 'fabric'] +""" + +EXAMPLES = """ +- name: access list functionality + pn_access_list: + pn_cliswitch: "sw01" + pn_name: "foo" + pn_scope: "local" + state: "present" + +- name: access list functionality + pn_access_list: + pn_cliswitch: "sw01" + pn_name: "foo" + pn_scope: "local" + state: "absent" + +- name: access list functionality + pn_access_list: + pn_cliswitch: "sw01" + pn_name: "foo" + pn_scope: "fabric" + state: "present" +""" + +RETURN = """ +command: + description: the CLI command run on the target node. + returned: always + type: string +stdout: + description: set of responses from the access-list command. + returned: always + type: list +stderr: + description: set of error responses from the access-list command. + returned: on error + type: list +changed: + description: indicates whether the CLI caused changes on the target. + returned: always + type: bool +""" + +import shlex +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.network.netvisor.pn_nvos import pn_cli, run_cli + + +def check_cli(module, cli): + """ + This method checks for idempotency using the access-list-show command. + If a list with given name exists, return ACC_LIST_EXISTS + as True else False. + :param module: The Ansible module to fetch input parameters + :param cli: The CLI string + :return Global Booleans: ACC_LIST_EXISTS + """ + list_name = module.params['pn_name'] + + show = cli + \ + ' access-list-show format name no-show-headers' + show = shlex.split(show) + out = module.run_command(show)[1] + + out = out.split() + # Global flags + global ACC_LIST_EXISTS + + ACC_LIST_EXISTS = True if list_name in out else False + + +def main(): + """ This section is for arguments parsing """ + + global state_map + state_map = dict( + present='access-list-create', + absent='access-list-delete', + ) + + module = AnsibleModule( + argument_spec=dict( + pn_cliswitch=dict(required=False, type='str'), + state=dict(required=True, type='str', + choices=state_map.keys()), + pn_name=dict(required=False, type='str'), + pn_scope=dict(required=False, type='str', + choices=['local', 'fabric']), + ), + required_if=( + ["state", "present", ["pn_name", "pn_scope"]], + ["state", "absent", ["pn_name"]], + ), + ) + + # Accessing the arguments + cliswitch = module.params['pn_cliswitch'] + state = module.params['state'] + list_name = module.params['pn_name'] + scope = module.params['pn_scope'] + + command = state_map[state] + + # Building the CLI command string + cli = pn_cli(module, cliswitch) + + check_cli(module, cli) + cli += ' %s name %s ' % (command, list_name) + + if command == 'access-list-delete': + if ACC_LIST_EXISTS is False: + module.exit_json( + skipped=True, + msg='access-list with name %s does not exist' % list_name + ) + else: + if command == 'access-list-create': + if ACC_LIST_EXISTS is True: + module.exit_json( + skipped=True, + msg='access list with name %s already exists' % list_name + ) + cli += ' scope %s ' % scope + + run_cli(module, cli, state_map) + + +if __name__ == '__main__': + main()