diff --git a/lib/ansible/module_utils/ibm_sa_utils.py b/lib/ansible/module_utils/ibm_sa_utils.py new file mode 100644 index 0000000000..4e349be23e --- /dev/null +++ b/lib/ansible/module_utils/ibm_sa_utils.py @@ -0,0 +1,85 @@ +# Copyright (C) 2018 IBM CORPORATION +# Author(s): Tzur Eliyahu +# +# 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 + +from functools import wraps +from ansible.module_utils._text import to_native + +PYXCLI_INSTALLED = True +try: + from pyxcli import client, errors +except ImportError: + PYXCLI_INSTALLED = False + +AVAILABLE_PYXCLI_FIELDS = ['pool', 'size', 'snapshot_size', + 'domain', 'perf_class', 'vol', + 'iscsi_chap_name', 'iscsi_chap_secret', + 'cluster', 'host', 'lun', 'override', + 'fcaddress', 'iscsi_name'] + + +def xcli_wrapper(func): + """ Catch xcli errors and return a proper message""" + @wraps(func) + def wrapper(module, *args, **kwargs): + try: + return func(module, *args, **kwargs) + except errors.CommandExecutionError as e: + module.fail_json(msg=to_native(e)) + return wrapper + + +@xcli_wrapper +def connect_ssl(module): + endpoints = module.params['endpoints'] + username = module.params['username'] + password = module.params['password'] + if not (username and password and endpoints): + module.fail_json( + msg="Username, password or endpoints arguments " + "are missing from the module arguments") + + try: + return client.XCLIClient.connect_multiendpoint_ssl(username, + password, + endpoints) + except errors.CommandFailedConnectionError as e: + module.fail_json( + msg="Connection with Spectrum Accelerate system has " + "failed: {[0]}.".format(to_native(e))) + + +def spectrum_accelerate_spec(): + """ Return arguments spec for AnsibleModule """ + return dict( + endpoints=dict(required=True), + username=dict(required=True), + password=dict(no_log=True, required=True), + ) + + +@xcli_wrapper +def execute_pyxcli_command(module, xcli_command, xcli_client): + pyxcli_args = build_pyxcli_command(module.params) + getattr(xcli_client.cmd, xcli_command)(**(pyxcli_args)) + return True + + +def build_pyxcli_command(fields): + """ Builds the args for pyxcli using the exact args from ansible""" + pyxcli_args = {} + for field in fields: + if field in AVAILABLE_PYXCLI_FIELDS and fields[field]: + pyxcli_args[field] = fields[field] + return pyxcli_args + + +def is_pyxcli_installed(module): + if not PYXCLI_INSTALLED: + module.fail_json( + msg='pyxcli is required, use \'pip install pyxcli\' ' + 'in order to install it.') diff --git a/lib/ansible/modules/storage/ibm/__init__.py b/lib/ansible/modules/storage/ibm/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/ansible/modules/storage/ibm/ibm_sa_vol.py b/lib/ansible/modules/storage/ibm/ibm_sa_vol.py new file mode 100644 index 0000000000..3e02275cf0 --- /dev/null +++ b/lib/ansible/modules/storage/ibm/ibm_sa_vol.py @@ -0,0 +1,112 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (C) 2018 IBM CORPORATION +# Author(s): Tzur Eliyahu +# +# 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 = {'status': ['preview'], + 'supported_by': 'community', + 'metadata_version': '1.1'} + +DOCUMENTATION = ''' +--- +module: ibm_sa_vol +short_description: Handle volumes on an IBM Spectrum Accelerate storage array +version_added: "2.7" + +description: + - "This module creates or deletes volumes to be used on IBM Spectrum Accelerate storage systems." + +options: + vol: + description: + - Volume name. + required: true + pool: + description: + - Volume pool. + required: false + state: + description: + - Volume state. + required: true + default: "present" + choices: [ "present", "absent" ] + size: + description: + - Volume size. + required: false + +extends_documentation_fragment: + - ibm_storage + +author: + - Tzur Eliyahu (tzure@il.ibm.com) +''' + +EXAMPLES = ''' +- name: Create a new volume. + ibm_sa_vol: + vol: volume_name + pool: pool_name + size: 17 + state: present + username: admin + password: secret + endpoints: hostdev-system + +- name: Delete an existing volume. + ibm_sa_vol: + vol: volume_name + state: absent + username: admin + password: secret + endpoints: hostdev-system +''' +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ibm_sa_utils import execute_pyxcli_command, \ + connect_ssl, spectrum_accelerate_spec, is_pyxcli_installed + + +def main(): + argument_spec = spectrum_accelerate_spec() + argument_spec.update( + dict( + state=dict(default='present', choices=['present', 'absent']), + vol=dict(required=True), + pool=dict(), + size=dict() + ) + ) + + module = AnsibleModule(argument_spec) + + is_pyxcli_installed(module) + + xcli_client = connect_ssl(module) + # required args + volume = xcli_client.cmd.vol_list( + vol=module.params.get('vol')).as_single_element + state = module.params['state'] + + state_changed = False + if state == 'present' and not volume: + state_changed = execute_pyxcli_command( + module, 'vol_create', xcli_client) + elif state == 'absent' and volume: + state_changed = execute_pyxcli_command( + module, 'vol_delete', xcli_client) + + module.exit_json(changed=state_changed) + + +if __name__ == '__main__': + main() diff --git a/lib/ansible/utils/module_docs_fragments/ibm_storage.py b/lib/ansible/utils/module_docs_fragments/ibm_storage.py new file mode 100644 index 0000000000..371ef91376 --- /dev/null +++ b/lib/ansible/utils/module_docs_fragments/ibm_storage.py @@ -0,0 +1,33 @@ +# +# Copyright (C) 2018 IBM CORPORATION +# Author(s): Tzur Eliyahu +# 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 + + +class ModuleDocFragment(object): + + # ibm_storage documentation fragment + DOCUMENTATION = ''' +options: + username: + description: + - Management user on the spectrum accelerate storage system. + required: True + password: + description: + - Password for username on the spectrum accelerate storage system. + required: True + endpoints: + description: + - The hostname or management IP of Spectrum Accelerate storage system. + required: True +notes: + - This module requires pyxcli python library. + Use 'pip install pyxcli' in order to get pyxcli. +requirements: + - "python >= 2.7" + - pyxcli +'''