diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 20:03:01 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 20:03:01 +0000 |
commit | a453ac31f3428614cceb99027f8efbdb9258a40b (patch) | |
tree | f61f87408f32a8511cbd91799f9cececb53e0374 /collections-debian-merged/ansible_collections/netapp/aws | |
parent | Initial commit. (diff) | |
download | ansible-a453ac31f3428614cceb99027f8efbdb9258a40b.tar.xz ansible-a453ac31f3428614cceb99027f8efbdb9258a40b.zip |
Adding upstream version 2.10.7+merged+base+2.10.8+dfsg.upstream/2.10.7+merged+base+2.10.8+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'collections-debian-merged/ansible_collections/netapp/aws')
19 files changed, 2623 insertions, 0 deletions
diff --git a/collections-debian-merged/ansible_collections/netapp/aws/FILES.json b/collections-debian-merged/ansible_collections/netapp/aws/FILES.json new file mode 100644 index 00000000..74c78d40 --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/FILES.json @@ -0,0 +1,194 @@ +{ + "files": [ + { + "format": 1, + "ftype": "dir", + "chksum_sha256": null, + "name": ".", + "chksum_type": null + }, + { + "ftype": "dir", + "chksum_sha256": null, + "name": "plugins", + "chksum_type": null, + "format": 1 + }, + { + "ftype": "dir", + "chksum_sha256": null, + "name": "plugins/doc_fragments", + "chksum_type": null, + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "a629828b5936404e9822e066dc372b9f36d24f0a4ace73c9b2dbf99c8d2bb56d", + "name": "plugins/doc_fragments/netapp.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "dir", + "chksum_sha256": null, + "name": "plugins/module_utils", + "chksum_type": null, + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "9109380e733e4915f5bd347431c61b0f64489a177fbbaca57baa4b2e018adfbd", + "name": "plugins/module_utils/netapp.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "2d69e77a6e5b76dc8909149c8c364454e80fb42631af7d889dfb6e2ff0438c3e", + "name": "plugins/module_utils/netapp_module.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "dir", + "chksum_sha256": null, + "name": "plugins/modules", + "chksum_type": null, + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "6fd061a1e54ce32dfbdeecd58f40f78e0836ec2c6eb2d10d60bce10d581ef40a", + "name": "plugins/modules/aws_netapp_cvs_filesystems.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "495a911b97e0593f7c7f9b8d225296394bf0e712dee0e0d922d9d0952fd660df", + "name": "plugins/modules/aws_netapp_cvs_active_directory.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "8edfd787384f01ef37a0032e60898b0253472355a32e420b439e1dbb4d385e85", + "name": "plugins/modules/aws_netapp_cvs_snapshots.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "7a4b6fc9d48d61cf80a052455334ffd671dd880e7ec476aff6ccae820b658610", + "name": "plugins/modules/aws_netapp_cvs_pool.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "dir", + "chksum_sha256": null, + "name": "tests", + "chksum_type": null, + "format": 1 + }, + { + "ftype": "dir", + "chksum_sha256": null, + "name": "tests/unit", + "chksum_type": null, + "format": 1 + }, + { + "ftype": "dir", + "chksum_sha256": null, + "name": "tests/unit/compat", + "chksum_type": null, + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "5401a046e5ce71fa19b6d905abd0f9bdf816c0c635f7bdda6730b3ef06e67096", + "name": "tests/unit/compat/unittest.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "0ca4cac919e166b25e601e11acb01f6957dddd574ff0a62569cb994a5ecb63e1", + "name": "tests/unit/compat/builtins.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "name": "tests/unit/compat/__init__.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "0af958450cf6de3fbafe94b1111eae8ba5a8dbe1d785ffbb9df81f26e4946d99", + "name": "tests/unit/compat/mock.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "bae23898d2424f99afdc207e2598c8cb827f78f86cd1880c5e92947a2750d988", + "name": "tests/unit/requirements.txt", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "dir", + "chksum_sha256": null, + "name": "tests/unit/plugins", + "chksum_type": null, + "format": 1 + }, + { + "ftype": "dir", + "chksum_sha256": null, + "name": "tests/unit/plugins/modules", + "chksum_type": null, + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "1832d488ba9e6378f74e39d04606b3f0cf9d5fc35e7777caf7eec9ab12a6cc77", + "name": "tests/unit/plugins/modules/test_aws_netapp_cvs_snapshots.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "90605d26722db28c00b7f430723043a94adfc8490bc7e5055f8fae530886c51a", + "name": "tests/unit/plugins/modules/test_aws_netapp_cvs_active_directory.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "5f5ad7dfe4fcad1f781209e5f3524eeabc47f75f6a15b3660f7d918de670b026", + "name": "tests/unit/plugins/modules/test_aws_netapp_cvs_filesystems.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "4d368fda4b642933c3b14ecbbec6b20c5cf397fc1e1adb0c9797286da9b6db56", + "name": "tests/unit/plugins/modules/test_aws_netapp_cvs_pool.py", + "chksum_type": "sha256", + "format": 1 + }, + { + "ftype": "file", + "chksum_sha256": "73bbfeb60d4f06f66dc2ef058eded510eb8eab2eb1f1bbc6ba2324742e118911", + "name": "README.md", + "chksum_type": "sha256", + "format": 1 + } + ], + "format": 1 +}
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/netapp/aws/MANIFEST.json b/collections-debian-merged/ansible_collections/netapp/aws/MANIFEST.json new file mode 100644 index 00000000..eb531c42 --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/MANIFEST.json @@ -0,0 +1,33 @@ +{ + "collection_info": { + "description": "Cloud Volumes Service (CVS) for AWS", + "repository": "https://github.com/ansible-collections/netapp", + "tags": [ + "storage", + "cloud" + ], + "dependencies": {}, + "authors": [ + "NetApp Ansible Team <ng-ansibleteam@netapp.com>" + ], + "issues": null, + "name": "aws", + "license": [ + "GPL-2.0-or-later" + ], + "documentation": null, + "namespace": "netapp", + "version": "20.9.0", + "readme": "README.md", + "license_file": null, + "homepage": "https://netapp.io/configuration-management-and-automation/" + }, + "file_manifest_file": { + "format": 1, + "ftype": "file", + "chksum_sha256": "6d32959d548c4eeb9fc2f62a94868ce46604ea71acafdd0bd50ed765012df889", + "name": "FILES.json", + "chksum_type": "sha256" + }, + "format": 1 +}
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/netapp/aws/README.md b/collections-debian-merged/ansible_collections/netapp/aws/README.md new file mode 100644 index 00000000..3faa0ee9 --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/README.md @@ -0,0 +1,56 @@ +============================================================= + +netapp.aws + +NetApp AWS CVS Collection + +Copyright (c) 2019 NetApp, Inc. All rights reserved. +Specifications subject to change without notice. + +============================================================= + +# Installation +```bash +ansible-galaxy collection install netapp.aws +``` +To use Collection add the following to the top of your playbook, with out this you will be using Ansible 2.9 version of the module +``` +collections: + - netapp.aws +``` +# Need help +Join our Slack Channel at [Netapp.io](http://netapp.io/slack) + +# Notes + +These Ansible modules are supporting NetApp Cloud Volumes Service for AWS. + +They require a subscription to the service and your API access keys. + +The modules currently support Active Directory, Pool, FileSystem (Volume), and Snapshot services. + +# Release Notes + + +## 20.9.0 + +Fix pylint or flake8 warnings reported by galaxy importer. + +## 20.8.0 + +### Module documentation changes +- use a three group format for `version_added`. So 2.7 becomes 2.7.0. Same thing for 2.8 and 2.9. +- add `elements:` and update `required:` to match module requirements. + +## 20.6.0 + +### Bug Fixes +- galaxy.xml: fix repository and homepage links. + +## 20.2.0 + +### Bug Fixes +- galaxy.yml: fix path to github repository. + +## 19.11.0 +- Initial release as a collection. diff --git a/collections-debian-merged/ansible_collections/netapp/aws/plugins/doc_fragments/netapp.py b/collections-debian-merged/ansible_collections/netapp/aws/plugins/doc_fragments/netapp.py new file mode 100644 index 00000000..a2e7335a --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/plugins/doc_fragments/netapp.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- + +# Copyright: (c) 2019, NetApp Ansible Team <ng-ansibleteam@netapp.com> +# 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): + + DOCUMENTATION = r''' +options: + - See respective platform section for more details +requirements: + - See respective platform section for more details +notes: + - This is documentation for NetApp's AWS CVS modules. +''' + + # Documentation fragment for AWSCVS + AWSCVS = """ +options: + api_key: + required: true + type: str + description: + - The access key to authenticate with the AWSCVS Web Services Proxy or Embedded Web Services API. + secret_key: + required: true + type: str + description: + - The secret_key to authenticate with the AWSCVS Web Services Proxy or Embedded Web Services API. + api_url: + required: true + type: str + description: + - The url to the AWSCVS Web Services Proxy or Embedded Web Services API. + validate_certs: + required: false + default: true + description: + - Should https certificates be validated? + type: bool +notes: + - The modules prefixed with aws\\_cvs\\_netapp are built to Manage AWS Cloud Volumes Service . +""" diff --git a/collections-debian-merged/ansible_collections/netapp/aws/plugins/module_utils/netapp.py b/collections-debian-merged/ansible_collections/netapp/aws/plugins/module_utils/netapp.py new file mode 100644 index 00000000..38e0e351 --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/plugins/module_utils/netapp.py @@ -0,0 +1,159 @@ +# This code is part of Ansible, but is an independent component. +# This particular file snippet, and this file snippet only, is BSD licensed. +# Modules you write using this snippet, which is embedded dynamically by Ansible +# still belong to the author of the module, and may assign their own license +# to the complete work. +# +# Copyright (c) 2019, NetApp Ansible Team <ng-ansibleteam@netapp.com> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.module_utils.basic import missing_required_lib + +try: + from ansible.module_utils.ansible_release import __version__ as ansible_version +except ImportError: + ansible_version = 'unknown' + +COLLECTION_VERSION = "20.9.0" + +try: + import requests + HAS_REQUESTS = True +except ImportError: + HAS_REQUESTS = False + + +POW2_BYTE_MAP = dict( + # Here, 1 kb = 1024 + bytes=1, + b=1, + kb=1024, + mb=1024 ** 2, + gb=1024 ** 3, + tb=1024 ** 4, + pb=1024 ** 5, + eb=1024 ** 6, + zb=1024 ** 7, + yb=1024 ** 8 +) + + +def aws_cvs_host_argument_spec(): + + return dict( + api_url=dict(required=True, type='str'), + validate_certs=dict(required=False, type='bool', default=True), + api_key=dict(required=True, type='str'), + secret_key=dict(required=True, type='str') + ) + + +class AwsCvsRestAPI(object): + def __init__(self, module, timeout=60): + self.module = module + self.api_key = self.module.params['api_key'] + self.secret_key = self.module.params['secret_key'] + self.api_url = self.module.params['api_url'] + self.verify = self.module.params['validate_certs'] + self.timeout = timeout + self.url = 'https://' + self.api_url + '/v1/' + self.check_required_library() + + def check_required_library(self): + if not HAS_REQUESTS: + self.module.fail_json(msg=missing_required_lib('requests')) + + def send_request(self, method, api, params, json=None): + ''' send http request and process reponse, including error conditions ''' + if params is not None: + self.module.fail_json(msg='params is not implemented. api=%s, params=%s' % (api, repr(params))) + url = self.url + api + json_dict = None + json_error = None + error_details = None + headers = { + 'Content-type': "application/json", + 'api-key': self.api_key, + 'secret-key': self.secret_key, + 'Cache-Control': "no-cache", + } + + def get_json(response): + ''' extract json, and error message if present ''' + try: + json = response.json() + + except ValueError: + return None, None + success_code = [200, 201, 202] + if response.status_code not in success_code: + error = json.get('message') + else: + error = None + return json, error + try: + response = requests.request(method, url, headers=headers, timeout=self.timeout, json=json) + # If the response was successful, no Exception will be raised + json_dict, json_error = get_json(response) + except requests.exceptions.HTTPError as err: + __, json_error = get_json(response) + if json_error is None: + error_details = str(err) + except requests.exceptions.ConnectionError as err: + error_details = str(err) + except Exception as err: + error_details = str(err) + if json_error is not None: + error_details = json_error + + return json_dict, error_details + + # If an error was reported in the json payload, it is handled below + def get(self, api, params=None): + method = 'GET' + return self.send_request(method, api, params) + + def post(self, api, data, params=None): + method = 'POST' + return self.send_request(method, api, params, json=data) + + def patch(self, api, data, params=None): + method = 'PATCH' + return self.send_request(method, api, params, json=data) + + def put(self, api, data, params=None): + method = 'PUT' + return self.send_request(method, api, params, json=data) + + def delete(self, api, data, params=None): + method = 'DELETE' + return self.send_request(method, api, params, json=data) + + def get_state(self, job_id): + """ Method to get the state of the job """ + response, dummy = self.get('Jobs/%s' % job_id) + while str(response['state']) not in 'done': + response, dummy = self.get('Jobs/%s' % job_id) + return 'done' diff --git a/collections-debian-merged/ansible_collections/netapp/aws/plugins/module_utils/netapp_module.py b/collections-debian-merged/ansible_collections/netapp/aws/plugins/module_utils/netapp_module.py new file mode 100644 index 00000000..3e31ae98 --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/plugins/module_utils/netapp_module.py @@ -0,0 +1,142 @@ +# This code is part of Ansible, but is an independent component. +# This particular file snippet, and this file snippet only, is BSD licensed. +# Modules you write using this snippet, which is embedded dynamically by Ansible +# still belong to the author of the module, and may assign their own license +# to the complete work. +# +# Copyright (c) 2018, Laurent Nicolas <laurentn@netapp.com> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +''' Support class for NetApp ansible modules ''' + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +def cmp(a, b): + """ + Python 3 does not have a cmp function, this will do the cmp. + :param a: first object to check + :param b: second object to check + :return: + """ + # convert to lower case for string comparison. + if a is None: + return -1 + if isinstance(a, str) and isinstance(b, str): + a = a.lower() + b = b.lower() + # if list has string element, convert string to lower case. + if isinstance(a, list) and isinstance(b, list): + a = [x.lower() if isinstance(x, str) else x for x in a] + b = [x.lower() if isinstance(x, str) else x for x in b] + a.sort() + b.sort() + return (a > b) - (a < b) + + +class NetAppModule(object): + ''' + Common class for NetApp modules + set of support functions to derive actions based + on the current state of the system, and a desired state + ''' + + def __init__(self): + self.log = list() + self.changed = False + self.parameters = {'name': 'not intialized'} + + def set_parameters(self, ansible_params): + self.parameters = dict() + for param in ansible_params: + if ansible_params[param] is not None: + self.parameters[param] = ansible_params[param] + return self.parameters + + def get_cd_action(self, current, desired): + ''' takes a desired state and a current state, and return an action: + create, delete, None + eg: + is_present = 'absent' + some_object = self.get_object(source) + if some_object is not None: + is_present = 'present' + action = cd_action(current=is_present, desired = self.desired.state()) + ''' + if 'state' in desired: + desired_state = desired['state'] + else: + desired_state = 'present' + + if current is None and desired_state == 'absent': + return None + if current is not None and desired_state == 'present': + return None + # change in state + self.changed = True + if current is not None: + return 'delete' + return 'create' + + def compare_and_update_values(self, current, desired, keys_to_compare): + updated_values = dict() + is_changed = False + for key in keys_to_compare: + if key in current: + if key in desired and desired[key] is not None: + if current[key] != desired[key]: + updated_values[key] = desired[key] + is_changed = True + else: + updated_values[key] = current[key] + else: + updated_values[key] = current[key] + + return updated_values, is_changed + + def is_rename_action(self, source, target): + ''' takes a source and target object, and returns True + if a rename is required + eg: + source = self.get_object(source_name) + target = self.get_object(target_name) + action = is_rename_action(source, target) + :return: None for error, True for rename action, False otherwise + ''' + if source is None and target is None: + # error, do nothing + # cannot rename an non existent resource + # alternatively we could create B + return None + if source is not None and target is not None: + # error, do nothing + # idempotency (or) new_name_is_already_in_use + # alternatively we could delete B and rename A to B + return False + if source is None and target is not None: + # do nothing, maybe the rename was already done + return False + # source is not None and target is None: + # rename is in order + self.changed = True + return True diff --git a/collections-debian-merged/ansible_collections/netapp/aws/plugins/modules/aws_netapp_cvs_active_directory.py b/collections-debian-merged/ansible_collections/netapp/aws/plugins/modules/aws_netapp_cvs_active_directory.py new file mode 100644 index 00000000..68b25c7d --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/plugins/modules/aws_netapp_cvs_active_directory.py @@ -0,0 +1,274 @@ +#!/usr/bin/python + +# (c) 2019, NetApp Inc. +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +"""AWS Cloud Volumes Services - Manage ActiveDirectory""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'certified'} + + +DOCUMENTATION = ''' + +module: aws_netapp_cvs_active_directory + +short_description: NetApp AWS CloudVolumes Service Manage Active Directory. +extends_documentation_fragment: + - netapp.aws.netapp.awscvs +version_added: 2.9.0 +author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com> +description: + - Create, Update, Delete ActiveDirectory on AWS Cloud Volumes Service. + +options: + state: + description: + - Whether the specified ActiveDirectory should exist or not. + choices: ['present', 'absent'] + required: true + type: str + + region: + description: + - The region to which the Active Directory credentials are associated. + required: true + type: str + + domain: + description: + - Name of the Active Directory domain + type: str + + DNS: + description: + - DNS server address for the Active Directory domain + - Required when C(state=present) + - Required when C(state=present), to modify ActiveDirectory properties. + type: str + + netBIOS: + description: + - NetBIOS name of the server. + type: str + + username: + description: + - Username of the Active Directory domain administrator + type: str + + password: + description: + - Password of the Active Directory domain administrator + - Required when C(state=present), to modify ActiveDirectory properties + type: str +''' + +EXAMPLES = """ + - name: Create Active Directory + aws_netapp_cvs_active_directory.py: + state: present + region: us-east-1 + DNS: 101.102.103.123 + domain: mydomain.com + password: netapp1! + netBIOS: testing + username: user1 + api_url : My_CVS_Hostname + api_key: My_API_Key + secret_key : My_Secret_Key + + - name: Update Active Directory + aws_netapp_cvs_active_directory.py: + state: present + region: us-east-1 + DNS: 101.102.103.123 + domain: mydomain.com + password: netapp2! + netBIOS: testingBIOS + username: user2 + api_url : My_CVS_Hostname + api_key: My_API_Key + secret_key : My_Secret_Key + + - name: Delete Active Directory + aws_netapp_cvs_active_directory.py: + state: absent + region: us-east-1 + domain: mydomain.com + api_url : My_CVS_Hostname + api_key: My_API_Key + secret_key : My_Secret_Key +""" + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +import ansible_collections.netapp.aws.plugins.module_utils.netapp as netapp_utils +from ansible_collections.netapp.aws.plugins.module_utils.netapp_module import NetAppModule +from ansible_collections.netapp.aws.plugins.module_utils.netapp import AwsCvsRestAPI + + +class AwsCvsNetappActiveDir(object): + """ + Contains methods to parse arguments, + derive details of AWS_CVS objects + and send requests to AWS CVS via + the restApi + """ + + def __init__(self): + """ + Parse arguments, setup state variables, + check paramenters and ensure request module is installed + """ + self.argument_spec = netapp_utils.aws_cvs_host_argument_spec() + self.argument_spec.update(dict( + state=dict(required=True, choices=['present', 'absent'], type='str'), + region=dict(required=True, type='str'), + DNS=dict(required=False, type='str'), + domain=dict(required=False, type='str'), + password=dict(required=False, type='str', no_log=True), + netBIOS=dict(required=False, type='str'), + username=dict(required=False, type='str') + )) + + self.module = AnsibleModule( + argument_spec=self.argument_spec, + required_if=[ + ('state', 'present', ['domain', 'password']), + ], + supports_check_mode=True + ) + + self.na_helper = NetAppModule() + + # set up state variables + self.parameters = self.na_helper.set_parameters(self.module.params) + # Calling generic AWSCVS restApi class + self.rest_api = AwsCvsRestAPI(self.module) + + def get_activedirectory_id(self): + # Check if ActiveDirectory exists + # Return UUID for ActiveDirectory is found, None otherwise + try: + list_activedirectory, dummy = self.rest_api.get('Storage/ActiveDirectory') + except Exception: + return None + + for activedirectory in list_activedirectory: + if activedirectory['region'] == self.parameters['region']: + return activedirectory['UUID'] + return None + + def get_activedirectory(self, activedirectory_id=None): + if activedirectory_id is None: + return None + else: + activedirectory_info, error = self.rest_api.get('Storage/ActiveDirectory/%s' % activedirectory_id) + if not error: + return activedirectory_info + return None + + def create_activedirectory(self): + # Create ActiveDirectory + api = 'Storage/ActiveDirectory' + data = {"region": self.parameters['region'], "DNS": self.parameters['DNS'], "domain": self.parameters['domain'], + "username": self.parameters['username'], "password": self.parameters['password'], "netBIOS": self.parameters['netBIOS']} + + response, error = self.rest_api.post(api, data) + + if not error: + return response + else: + self.module.fail_json(msg=response['message']) + + def delete_activedirectory(self): + activedirectory_id = self.get_activedirectory_id() + # Delete ActiveDirectory + + if activedirectory_id: + api = 'Storage/ActiveDirectory/' + activedirectory_id + data = None + response, error = self.rest_api.delete(api, data) + if not error: + return response + else: + self.module.fail_json(msg=response['message']) + + else: + self.module.fail_json(msg="Active Directory does not exist") + + def update_activedirectory(self, activedirectory_id, updated_activedirectory): + # Update ActiveDirectory + api = 'Storage/ActiveDirectory/' + activedirectory_id + data = { + "region": self.parameters['region'], + "DNS": updated_activedirectory['DNS'], + "domain": updated_activedirectory['domain'], + "username": updated_activedirectory['username'], + "password": updated_activedirectory['password'], + "netBIOS": updated_activedirectory['netBIOS'] + } + + response, error = self.rest_api.put(api, data) + if not error: + return response + else: + self.module.fail_json(msg=response['message']) + + def apply(self): + """ + Perform pre-checks, call functions and exit + """ + modify = False + activedirectory_id = self.get_activedirectory_id() + current = self.get_activedirectory(activedirectory_id) + cd_action = self.na_helper.get_cd_action(current, self.parameters) + + if current and self.parameters['state'] != 'absent': + keys_to_check = ['DNS', 'domain', 'username', 'netBIOS'] + updated_active_directory, modify = self.na_helper.compare_and_update_values(current, self.parameters, keys_to_check) + + if self.parameters['password']: + modify = True + updated_active_directory['password'] = self.parameters['password'] + + if modify is True: + self.na_helper.changed = True + if 'domain' in self.parameters and self.parameters['domain'] is not None: + ad_exists = self.get_activedirectory(updated_active_directory['domain']) + if ad_exists: + modify = False + self.na_helper.changed = False + + if self.na_helper.changed: + if self.module.check_mode: + pass + else: + if modify is True: + self.update_activedirectory(activedirectory_id, updated_active_directory) + elif cd_action == 'create': + self.create_activedirectory() + elif cd_action == 'delete': + self.delete_activedirectory() + + self.module.exit_json(changed=self.na_helper.changed) + + +def main(): + """ + Main function + """ + aws_netapp_cvs_active_directory = AwsCvsNetappActiveDir() + aws_netapp_cvs_active_directory.apply() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/netapp/aws/plugins/modules/aws_netapp_cvs_filesystems.py b/collections-debian-merged/ansible_collections/netapp/aws/plugins/modules/aws_netapp_cvs_filesystems.py new file mode 100644 index 00000000..037a1d89 --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/plugins/modules/aws_netapp_cvs_filesystems.py @@ -0,0 +1,362 @@ +#!/usr/bin/python + +# (c) 2019, NetApp Inc +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +"""AWS Cloud Volumes Services - Manage fileSystem""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' + +module: aws_netapp_cvs_filesystems + +short_description: NetApp AWS Cloud Volumes Service Manage FileSystem. +extends_documentation_fragment: + - netapp.aws.netapp.awscvs +version_added: 2.9.0 +author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com> +description: +- Create, Update, Delete fileSystem on AWS Cloud Volumes Service. + +options: + state: + description: + - Whether the specified fileSystem should exist or not. + required: true + choices: ['present', 'absent'] + type: str + + region: + description: + - The region to which the filesystem belongs to. + required: true + type: str + + creationToken: + description: + - Name of the filesystem + required: true + type: str + + quotaInBytes: + description: + - Size of the filesystem + - Required for create + type: int + + serviceLevel: + description: + - Service Level of a filesystem. + choices: ['standard', 'premium', 'extreme'] + type: str + + exportPolicy: + description: + - The policy rules to export the filesystem + type: dict + suboptions: + rules: + description: + - Set of rules to export the filesystem + - Requires allowedClients, access and protocol + type: list + elements: dict + suboptions: + allowedClients: + description: + - Comma separated list of ip address blocks of the clients to access the fileSystem + - Each address block contains the starting IP address and size for the block + type: str + + cifs: + description: + - Enable or disable cifs filesystem + type: bool + + nfsv3: + description: + - Enable or disable nfsv3 fileSystem + type: bool + + nfsv4: + description: + - Enable or disable nfsv4 filesystem + type: bool + + ruleIndex: + description: + - Index number of the rule + type: int + + unixReadOnly: + description: + - Should fileSystem have read only permission or not + type: bool + + unixReadWrite: + description: + - Should fileSystem have read write permission or not + type: bool +''' + +EXAMPLES = """ +- name: Create FileSystem + aws_netapp_cvs_filesystems: + state: present + region: us-east-1 + creationToken: newVolume-1 + exportPolicy: + rules: + - allowedClients: 172.16.0.4 + cifs: False + nfsv3: True + nfsv4: True + ruleIndex: 1 + unixReadOnly: True + unixReadWrite: False + quotaInBytes: 100000000000 + api_url : cds-aws-bundles.netapp.com + api_key: Q1ZRR0p0VGNuZ3VhMnJBYk5zczM1RkZ3Z0lCbUE3 + secret_key : U1FwdHdKSGRQQUhIdkIwMktMU1ZCV2x6WUowZWRD + +- name: Update FileSystem + aws_netapp_cvs_filesystems: + state: present + region: us-east-1 + creationToken: newVolume-1 + exportPolicy: + rules: + - allowedClients: 172.16.0.4 + cifs: False + nfsv3: True + nfsv4: True + ruleIndex: 1 + unixReadOnly: True + unixReadWrite: False + quotaInBytes: 200000000000 + api_url : cds-aws-bundles.netapp.com + api_key: Q1ZRR0p0VGNuZ3VhMnJBYk5zczM1RkZ3Z0lCbUE3 + secret_key : U1FwdHdKSGRQQUhIdkIwMktMU1ZCV2x6WUowZWRD + +- name: Delete FileSystem + aws_netapp_cvs_filesystems: + state: present + region: us-east-1 + creationToken: newVolume-1 + quotaInBytes: 100000000000 + api_url : cds-aws-bundles.netapp.com + api_key: Q1ZRR0p0VGNuZ3VhMnJBYk5zczM1RkZ3Z0lCbUE3 + secret_key : U1FwdHdKSGRQQUhIdkIwMktMU1ZCV2x6WUowZWRD +""" + +RETURN = """ +""" + +from ansible.module_utils.basic import AnsibleModule +import ansible_collections.netapp.aws.plugins.module_utils.netapp as netapp_utils +from ansible_collections.netapp.aws.plugins.module_utils.netapp_module import NetAppModule +from ansible_collections.netapp.aws.plugins.module_utils.netapp import AwsCvsRestAPI + + +class AwsCvsNetappFileSystem(object): + """ + Contains methods to parse arguments, + derive details of AWS_CVS objects + and send requests to AWS CVS via + the restApi + """ + + def __init__(self): + """ + Parse arguments, setup state variables, + check paramenters and ensure request module is installed + """ + self.argument_spec = netapp_utils.aws_cvs_host_argument_spec() + self.argument_spec.update(dict( + state=dict(required=True, choices=['present', 'absent']), + region=dict(required=True, type='str'), + creationToken=dict(required=True, type='str'), + quotaInBytes=dict(required=False, type='int'), + serviceLevel=dict(required=False, choices=['standard', 'premium', 'extreme']), + exportPolicy=dict( + type='dict', + options=dict( + rules=dict( + type='list', + elements='dict', + options=dict( + allowedClients=dict(required=False, type='str'), + cifs=dict(required=False, type='bool'), + nfsv3=dict(required=False, type='bool'), + nfsv4=dict(required=False, type='bool'), + ruleIndex=dict(required=False, type='int'), + unixReadOnly=dict(required=False, type='bool'), + unixReadWrite=dict(required=False, type='bool') + ) + ) + ) + ), + )) + + self.module = AnsibleModule( + argument_spec=self.argument_spec, + required_if=[ + ('state', 'present', ['region', 'creationToken', 'quotaInBytes']), + ], + supports_check_mode=True + ) + + self.na_helper = NetAppModule() + + # set up state variables + self.parameters = self.na_helper.set_parameters(self.module.params) + + # Calling generic AWSCVS restApi class + self.rest_api = AwsCvsRestAPI(self.module) + + self.data = {} + for key in self.parameters.keys(): + self.data[key] = self.parameters[key] + + def get_filesystem_id(self): + # Check given FileSystem is exists + # Return fileSystemId is found, None otherwise + list_filesystem, error = self.rest_api.get('FileSystems') + if error: + self.module.fail_json(msg=error) + + for filesystem in list_filesystem: + if filesystem['creationToken'] == self.parameters['creationToken']: + return filesystem['fileSystemId'] + return None + + def get_filesystem(self, filesystem_id): + # Get FileSystem information by fileSystemId + # Return fileSystem Information + filesystem_info, error = self.rest_api.get('FileSystems/%s' % filesystem_id) + if error: + self.module.fail_json(msg=error) + else: + return filesystem_info + return None + + def is_job_done(self, response): + # check jobId is present and equal to 'done' + # return True on success, False otherwise + try: + job_id = response['jobs'][0]['jobId'] + except TypeError: + job_id = None + + if job_id is not None and self.rest_api.get_state(job_id) == 'done': + return True + return False + + def create_filesystem(self): + # Create fileSystem + api = 'FileSystems' + response, error = self.rest_api.post(api, self.data) + if not error: + if self.is_job_done(response): + return + error = "Error: unexpected response on FileSystems create: %s" % str(response) + self.module.fail_json(msg=error) + + def delete_filesystem(self, filesystem_id): + # Delete FileSystem + api = 'FileSystems/' + filesystem_id + self.data = None + response, error = self.rest_api.delete(api, self.data) + if not error: + if self.is_job_done(response): + return + error = "Error: unexpected response on FileSystems delete: %s" % str(response) + self.module.fail_json(msg=error) + + def update_filesystem(self, filesystem_id): + # Update FileSystem + api = 'FileSystems/' + filesystem_id + response, error = self.rest_api.put(api, self.data) + if not error: + if self.is_job_done(response): + return + error = "Error: unexpected response on FileSystems update: %s" % str(response) + self.module.fail_json(msg=error) + + def apply(self): + """ + Perform pre-checks, call functions and exit + """ + + filesystem = None + filesystem_id = self.get_filesystem_id() + + if filesystem_id: + # Getting the FileSystem details + filesystem = self.get_filesystem(filesystem_id) + + cd_action = self.na_helper.get_cd_action(filesystem, self.parameters) + + if cd_action is None and self.parameters['state'] == 'present': + # Check if we need to update the fileSystem + update_filesystem = False + if filesystem['quotaInBytes'] is not None and 'quotaInBytes' in self.parameters \ + and filesystem['quotaInBytes'] != self.parameters['quotaInBytes']: + update_filesystem = True + elif filesystem['creationToken'] is not None and 'creationToken' in self.parameters \ + and filesystem['creationToken'] != self.parameters['creationToken']: + update_filesystem = True + elif filesystem['serviceLevel'] is not None and 'serviceLevel' in self.parameters \ + and filesystem['serviceLevel'] != self.parameters['serviceLevel']: + update_filesystem = True + elif filesystem['exportPolicy']['rules'] is not None and 'exportPolicy' in self.parameters: + for rule_org in filesystem['exportPolicy']['rules']: + for rule in self.parameters['exportPolicy']['rules']: + if rule_org['allowedClients'] != rule['allowedClients']: + update_filesystem = True + elif rule_org['unixReadOnly'] != rule['unixReadOnly']: + update_filesystem = True + elif rule_org['unixReadWrite'] != rule['unixReadWrite']: + update_filesystem = True + + if update_filesystem: + self.na_helper.changed = True + + result_message = "" + + if self.na_helper.changed: + if self.module.check_mode: + # Skip changes + result_message = "Check mode, skipping changes" + else: + if cd_action == "create": + self.create_filesystem() + result_message = "FileSystem Created" + elif cd_action == "delete": + self.delete_filesystem(filesystem_id) + result_message = "FileSystem Deleted" + else: # modify + self.update_filesystem(filesystem_id) + result_message = "FileSystem Updated" + self.module.exit_json(changed=self.na_helper.changed, msg=result_message) + + +def main(): + """ + Main function + """ + aws_cvs_netapp_filesystem = AwsCvsNetappFileSystem() + aws_cvs_netapp_filesystem.apply() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/netapp/aws/plugins/modules/aws_netapp_cvs_pool.py b/collections-debian-merged/ansible_collections/netapp/aws/plugins/modules/aws_netapp_cvs_pool.py new file mode 100644 index 00000000..fa4818a3 --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/plugins/modules/aws_netapp_cvs_pool.py @@ -0,0 +1,267 @@ +#!/usr/bin/python + +# (c) 2019, NetApp Inc. +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +"""AWS Cloud Volumes Services - Manage Pools""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' + +module: aws_netapp_cvs_pool + +short_description: NetApp AWS Cloud Volumes Service Manage Pools. +extends_documentation_fragment: + - netapp.aws.netapp.awscvs +version_added: 2.9.0 +author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com> +description: + - Create, Update, Delete Pool on AWS Cloud Volumes Service. + +options: + state: + description: + - Whether the specified pool should exist or not. + choices: ['present', 'absent'] + required: true + type: str + region: + description: + - The region to which the Pool is associated. + required: true + type: str + name: + description: + - pool name ( The human readable name of the Pool ) + - name can be used for create, update and delete operations + required: true + type: str + serviceLevel: + description: + - The service level of the Pool + - can be used with pool create, update operations + choices: ['basic', 'standard', 'extreme'] + type: str + sizeInBytes: + description: + - Size of the Pool in bytes + - can be used with pool create, update operations + - minimum value is 4000000000000 bytes + type: int + vendorID: + description: + - A vendor ID for the Pool. E.g. an ID allocated by a vendor service for the Pool. + - can be used with pool create, update operations + - must be unique + type: str + from_name: + description: + - rename the existing pool name ( The human readable name of the Pool ) + - I(from_name) is the existing name, and I(name) the new name + - can be used with update operation + type: str +''' + +EXAMPLES = """ +- name: Create a new Pool + aws_netapp_cvs_pool: + state: present + name: TestPoolBB12 + serviceLevel: extreme + sizeInBytes: 4000000000000 + vendorID: ansiblePoolTestVendorBB12 + region: us-east-1 + api_url: cds-aws-bundles.netapp.com + api_key: MyAPiKey + secret_key: MySecretKey + +- name: Delete a Pool + aws_netapp_cvs_pool: + state: absent + name: TestPoolBB7 + region: us-east-1 + api_url: cds-aws-bundles.netapp.com + api_key: MyAPiKey + secret_key: MySecretKey + +- name: Update a Pool + aws_netapp_cvs_pool: + state: present + from_name: TestPoolBB12 + name: Mynewpool7 + vendorID: ansibleVendorMynewpool15 + serviceLevel: extreme + sizeInBytes: 4000000000000 + region: us-east-1 + api_url: cds-aws-bundles.netapp.com + api_key: MyAPiKey + secret_key: MySecretKey + +""" + +RETURN = ''' +''' + +from ansible.module_utils.basic import AnsibleModule +import ansible_collections.netapp.aws.plugins.module_utils.netapp as netapp_utils +from ansible_collections.netapp.aws.plugins.module_utils.netapp_module import NetAppModule +from ansible_collections.netapp.aws.plugins.module_utils.netapp import AwsCvsRestAPI + + +class NetAppAWSCVS(object): + '''Class for Pool operations ''' + + def __init__(self): + """ + Parse arguments, setup state variables, + """ + self.argument_spec = netapp_utils.aws_cvs_host_argument_spec() + self.argument_spec.update(dict( + state=dict(required=True, choices=['present', 'absent']), + region=dict(required=True, type='str'), + name=dict(required=True, type='str'), + from_name=dict(required=False, type='str'), + serviceLevel=dict(required=False, choices=['basic', 'standard', 'extreme'], type='str'), + sizeInBytes=dict(required=False, type='int'), + vendorID=dict(required=False, type='str'), + )) + self.module = AnsibleModule( + argument_spec=self.argument_spec, + supports_check_mode=True + ) + + self.na_helper = NetAppModule() + self.parameters = self.na_helper.set_parameters(self.module.params) + self.rest_api = AwsCvsRestAPI(self.module) + self.sizeinbytes_min_value = 4000000000000 + + def get_aws_netapp_cvs_pool(self, name=None): + """ + Returns Pool object if exists else Return None + """ + pool_info = None + + if name is None: + name = self.parameters['name'] + + pools, error = self.rest_api.get('Pools') + + if error is None and pools is not None: + for pool in pools: + if 'name' in pool and pool['region'] == self.parameters['region']: + if pool['name'] == name: + pool_info = pool + break + + return pool_info + + def create_aws_netapp_cvs_pool(self): + """ + Create a pool + """ + api = 'Pools' + + for key in ['serviceLevel', 'sizeInBytes', 'vendorID']: + if key not in self.parameters.keys() or self.parameters[key] is None: + self.module.fail_json(changed=False, msg="Mandatory key '%s' required" % (key)) + + pool = { + "name": self.parameters['name'], + "region": self.parameters['region'], + "serviceLevel": self.parameters['serviceLevel'], + "sizeInBytes": self.parameters['sizeInBytes'], + "vendorID": self.parameters['vendorID'] + } + + dummy, error = self.rest_api.post(api, pool) + if error is not None: + self.module.fail_json(changed=False, msg=error) + + def update_aws_netapp_cvs_pool(self, update_pool_info, pool_id): + """ + Update a pool + """ + api = 'Pools/' + pool_id + + pool = { + "name": update_pool_info['name'], + "region": self.parameters['region'], + "serviceLevel": update_pool_info['serviceLevel'], + "sizeInBytes": update_pool_info['sizeInBytes'], + "vendorID": update_pool_info['vendorID'] + } + + dummy, error = self.rest_api.put(api, pool) + if error is not None: + self.module.fail_json(changed=False, msg=error) + + def delete_aws_netapp_cvs_pool(self, pool_id): + """ + Delete a pool + """ + api = 'Pools/' + pool_id + data = None + dummy, error = self.rest_api.delete(api, data) + + if error is not None: + self.module.fail_json(changed=False, msg=error) + + def apply(self): + """ + Perform pre-checks, call functions and exit + """ + update_required = False + cd_action = None + + if 'sizeInBytes' in self.parameters.keys() and self.parameters['sizeInBytes'] < self.sizeinbytes_min_value: + self.module.fail_json(changed=False, msg="sizeInBytes should be greater than or equal to %d" % (self.sizeinbytes_min_value)) + + current = self.get_aws_netapp_cvs_pool() + if self.parameters.get('from_name'): + existing = self.get_aws_netapp_cvs_pool(self.parameters['from_name']) + rename = self.na_helper.is_rename_action(existing, current) + if rename is None: + self.module.fail_json(changed=False, msg="unable to rename pool: '%s' does not exist" % self.parameters['from_name']) + if rename: + current = existing + else: + cd_action = self.na_helper.get_cd_action(current, self.parameters) + + if cd_action is None and self.parameters['state'] == 'present': + keys_to_check = ['name', 'vendorID', 'sizeInBytes', 'serviceLevel'] + update_pool_info, update_required = self.na_helper.compare_and_update_values(current, self.parameters, keys_to_check) + + if update_required is True: + self.na_helper.changed = True + cd_action = 'update' + + if self.na_helper.changed: + if self.module.check_mode: + pass + else: + if cd_action == 'update': + self.update_aws_netapp_cvs_pool(update_pool_info, current['poolId']) + elif cd_action == 'create': + self.create_aws_netapp_cvs_pool() + elif cd_action == 'delete': + self.delete_aws_netapp_cvs_pool(current['poolId']) + + self.module.exit_json(changed=self.na_helper.changed) + + +def main(): + '''Main Function''' + aws_cvs_netapp_pool = NetAppAWSCVS() + aws_cvs_netapp_pool.apply() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/netapp/aws/plugins/modules/aws_netapp_cvs_snapshots.py b/collections-debian-merged/ansible_collections/netapp/aws/plugins/modules/aws_netapp_cvs_snapshots.py new file mode 100644 index 00000000..fa5c5f87 --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/plugins/modules/aws_netapp_cvs_snapshots.py @@ -0,0 +1,245 @@ +#!/usr/bin/python + +# (c) 2019, NetApp Inc +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +"""AWS Cloud Volumes Services - Manage Snapshots""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' + +module: aws_netapp_cvs_snapshots + +short_description: NetApp AWS Cloud Volumes Service Manage Snapshots. +extends_documentation_fragment: + - netapp.aws.netapp.awscvs +version_added: 2.9.0 +author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com> +description: +- Create, Update, Delete Snapshot on AWS Cloud Volumes Service. + +options: + state: + description: + - Whether the specified snapshot should exist or not. + required: true + type: str + choices: ['present', 'absent'] + + region: + description: + - The region to which the snapshot belongs to. + required: true + type: str + + name: + description: + - Name of the snapshot + required: true + type: str + + fileSystemId: + description: + - Name or Id of the filesystem. + - Required for create operation + type: str + + from_name: + description: + - ID or Name of the snapshot to rename. + - Required to create an snapshot called 'name' by renaming 'from_name'. + type: str +''' + +EXAMPLES = """ +- name: Create Snapshot + aws_netapp_cvs_snapshots: + state: present + region: us-east-1 + name: testSnapshot + fileSystemId: testVolume + api_url : cds-aws-bundles.netapp.com + api_key: myApiKey + secret_key : mySecretKey + +- name: Update Snapshot + aws_netapp_cvs_snapshots: + state: present + region: us-east-1 + name: testSnapshot - renamed + from_name: testSnapshot + fileSystemId: testVolume + api_url : cds-aws-bundles.netapp.com + api_key: myApiKey + secret_key : mySecretKey + +- name: Delete Snapshot + aws_netapp_cvs_snapshots: + state: absent + region: us-east-1 + name: testSnapshot + api_url : cds-aws-bundles.netapp.com + api_key: myApiKey + secret_key : mySecretKey +""" + +RETURN = """ +""" + +from ansible.module_utils.basic import AnsibleModule +import ansible_collections.netapp.aws.plugins.module_utils.netapp as netapp_utils +from ansible_collections.netapp.aws.plugins.module_utils.netapp_module import NetAppModule +from ansible_collections.netapp.aws.plugins.module_utils.netapp import AwsCvsRestAPI + + +class AwsCvsNetappSnapshot(object): + """ + Contains methods to parse arguments, + derive details of AWS_CVS objects + and send requests to AWS CVS via + the restApi + """ + + def __init__(self): + """ + Parse arguments, setup state variables, + check paramenters and ensure request module is installed + """ + self.argument_spec = netapp_utils.aws_cvs_host_argument_spec() + self.argument_spec.update(dict( + state=dict(required=True, choices=['present', 'absent']), + region=dict(required=True, type='str'), + name=dict(required=True, type='str'), + from_name=dict(required=False, type='str'), + fileSystemId=dict(required=False, type='str') + )) + + self.module = AnsibleModule( + argument_spec=self.argument_spec, + required_if=[ + ('state', 'present', ['fileSystemId']), + ], + supports_check_mode=True + ) + + self.na_helper = NetAppModule() + + # set up state variables + self.parameters = self.na_helper.set_parameters(self.module.params) + # Calling generic AWSCVS restApi class + self.rest_api = AwsCvsRestAPI(self.module) + + # Checking for the parameters passed and create new parameters list + self.data = {} + for key in self.parameters.keys(): + self.data[key] = self.parameters[key] + + def get_snapshot_id(self, name): + # Check if snapshot exists + # Return snpashot Id If Snapshot is found, None otherwise + list_snapshots, error = self.rest_api.get('Snapshots') + + if error: + self.module.fail_json(msg=error) + + for snapshot in list_snapshots: + if snapshot['name'] == name: + return snapshot['snapshotId'] + return None + + def get_filesystem_id(self): + # Check given FileSystem is exists + # Return fileSystemId is found, None otherwise + list_filesystem, error = self.rest_api.get('FileSystems') + + if error: + self.module.fail_json(msg=error) + for filesystem in list_filesystem: + if filesystem['fileSystemId'] == self.parameters['fileSystemId']: + return filesystem['fileSystemId'] + elif filesystem['creationToken'] == self.parameters['fileSystemId']: + return filesystem['fileSystemId'] + return None + + def create_snapshot(self): + # Create Snapshot + api = 'Snapshots' + dummy, error = self.rest_api.post(api, self.data) + if error: + self.module.fail_json(msg=error) + + def rename_snapshot(self, snapshot_id): + # Rename Snapshot + api = 'Snapshots/' + snapshot_id + dummy, error = self.rest_api.put(api, self.data) + if error: + self.module.fail_json(msg=error) + + def delete_snapshot(self, snapshot_id): + # Delete Snapshot + api = 'Snapshots/' + snapshot_id + dummy, error = self.rest_api.delete(api, self.data) + if error: + self.module.fail_json(msg=error) + + def apply(self): + """ + Perform pre-checks, call functions and exit + """ + self.snapshot_id = self.get_snapshot_id(self.data['name']) + + if self.snapshot_id is None and 'fileSystemId' in self.data: + self.filesystem_id = self.get_filesystem_id() + self.data['fileSystemId'] = self.filesystem_id + if self.filesystem_id is None: + self.module.fail_json(msg='Error: Specified filesystem id %s does not exist ' % self.data['fileSystemId']) + + cd_action = self.na_helper.get_cd_action(self.snapshot_id, self.data) + result_message = "" + if self.na_helper.changed: + if self.module.check_mode: + # Skip changes + result_message = "Check mode, skipping changes" + else: + if cd_action == "delete": + self.delete_snapshot(self.snapshot_id) + result_message = "Snapshot Deleted" + + elif cd_action == "create": + if 'from_name' in self.data: + # If cd_action is craete and from_name is given + snapshot_id = self.get_snapshot_id(self.data['from_name']) + if snapshot_id is not None: + # If resource pointed by from_name exists, rename the snapshot to name + self.rename_snapshot(snapshot_id) + result_message = "Snapshot Updated" + else: + # If resource pointed by from_name does not exists, error out + self.module.fail_json(msg="Resource does not exist : %s" % self.data['from_name']) + else: + self.create_snapshot() + # If from_name is not defined, Create from scratch. + result_message = "Snapshot Created" + + self.module.exit_json(changed=self.na_helper.changed, msg=result_message) + + +def main(): + """ + Main function + """ + aws_netapp_cvs_snapshots = AwsCvsNetappSnapshot() + aws_netapp_cvs_snapshots.apply() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/compat/__init__.py b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/compat/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/compat/__init__.py diff --git a/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/compat/builtins.py b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/compat/builtins.py new file mode 100644 index 00000000..f60ee678 --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/compat/builtins.py @@ -0,0 +1,33 @@ +# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com> +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +# +# Compat for python2.7 +# + +# One unittest needs to import builtins via __import__() so we need to have +# the string that represents it +try: + import __builtin__ +except ImportError: + BUILTINS = 'builtins' +else: + BUILTINS = '__builtin__' diff --git a/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/compat/mock.py b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/compat/mock.py new file mode 100644 index 00000000..0972cd2e --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/compat/mock.py @@ -0,0 +1,122 @@ +# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com> +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +''' +Compat module for Python3.x's unittest.mock module +''' +import sys + +# Python 2.7 + +# Note: Could use the pypi mock library on python3.x as well as python2.x. It +# is the same as the python3 stdlib mock library + +try: + # Allow wildcard import because we really do want to import all of mock's + # symbols into this compat shim + # pylint: disable=wildcard-import,unused-wildcard-import + from unittest.mock import * +except ImportError: + # Python 2 + # pylint: disable=wildcard-import,unused-wildcard-import + try: + from mock import * + except ImportError: + print('You need the mock library installed on python2.x to run tests') + + +# Prior to 3.4.4, mock_open cannot handle binary read_data +if sys.version_info >= (3,) and sys.version_info < (3, 4, 4): + file_spec = None + + def _iterate_read_data(read_data): + # Helper for mock_open: + # Retrieve lines from read_data via a generator so that separate calls to + # readline, read, and readlines are properly interleaved + sep = b'\n' if isinstance(read_data, bytes) else '\n' + data_as_list = [l + sep for l in read_data.split(sep)] + + if data_as_list[-1] == sep: + # If the last line ended in a newline, the list comprehension will have an + # extra entry that's just a newline. Remove this. + data_as_list = data_as_list[:-1] + else: + # If there wasn't an extra newline by itself, then the file being + # emulated doesn't have a newline to end the last line remove the + # newline that our naive format() added + data_as_list[-1] = data_as_list[-1][:-1] + + for line in data_as_list: + yield line + + def mock_open(mock=None, read_data=''): + """ + A helper function to create a mock to replace the use of `open`. It works + for `open` called directly or used as a context manager. + + The `mock` argument is the mock object to configure. If `None` (the + default) then a `MagicMock` will be created for you, with the API limited + to methods or attributes available on standard file handles. + + `read_data` is a string for the `read` methoddline`, and `readlines` of the + file handle to return. This is an empty string by default. + """ + def _readlines_side_effect(*args, **kwargs): + if handle.readlines.return_value is not None: + return handle.readlines.return_value + return list(_data) + + def _read_side_effect(*args, **kwargs): + if handle.read.return_value is not None: + return handle.read.return_value + return type(read_data)().join(_data) + + def _readline_side_effect(): + if handle.readline.return_value is not None: + while True: + yield handle.readline.return_value + for line in _data: + yield line + + global file_spec + if file_spec is None: + import _io + file_spec = list(set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO)))) + + if mock is None: + mock = MagicMock(name='open', spec=open) + + handle = MagicMock(spec=file_spec) + handle.__enter__.return_value = handle + + _data = _iterate_read_data(read_data) + + handle.write.return_value = None + handle.read.return_value = None + handle.readline.return_value = None + handle.readlines.return_value = None + + handle.read.side_effect = _read_side_effect + handle.readline.side_effect = _readline_side_effect() + handle.readlines.side_effect = _readlines_side_effect + + mock.return_value = handle + return mock diff --git a/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/compat/unittest.py b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/compat/unittest.py new file mode 100644 index 00000000..98f08ad6 --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/compat/unittest.py @@ -0,0 +1,38 @@ +# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com> +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +''' +Compat module for Python2.7's unittest module +''' + +import sys + +# Allow wildcard import because we really do want to import all of +# unittests's symbols into this compat shim +# pylint: disable=wildcard-import,unused-wildcard-import +if sys.version_info < (2, 7): + try: + # Need unittest2 on python2.6 + from unittest2 import * + except ImportError: + print('You need unittest2 installed on python2.6.x to run tests') +else: + from unittest import * diff --git a/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/plugins/modules/test_aws_netapp_cvs_active_directory.py b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/plugins/modules/test_aws_netapp_cvs_active_directory.py new file mode 100644 index 00000000..abcc3fbd --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/plugins/modules/test_aws_netapp_cvs_active_directory.py @@ -0,0 +1,111 @@ +# (c) 2019, NetApp, Inc +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +''' unit tests ONTAP Ansible module: ''' + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +import json +import pytest + +from ansible.module_utils import basic +from ansible.module_utils._text import to_bytes +from ansible_collections.netapp.aws.tests.unit.compat import unittest +from ansible_collections.netapp.aws.tests.unit.compat.mock import patch + +from ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_active_directory \ + import AwsCvsNetappActiveDir as ad_module + + +def set_module_args(args): + """prepare arguments so that they will be picked up during module creation""" + args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) + basic._ANSIBLE_ARGS = to_bytes(args) # pylint: disable=protected-access + + +class AnsibleExitJson(Exception): + """Exception class to be raised by module.exit_json and caught by the test case""" + + +class AnsibleFailJson(Exception): + """Exception class to be raised by module.fail_json and caught by the test case""" + + +def exit_json(*args, **kwargs): # pylint: disable=unused-argument + """function to patch over exit_json; package return data into an exception""" + if 'changed' not in kwargs: + kwargs['changed'] = False + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): # pylint: disable=unused-argument + """function to patch over fail_json; package return data into an exception""" + kwargs['failed'] = True + raise AnsibleFailJson(kwargs) + + +class TestMyModule(unittest.TestCase): + ''' a group of related Unit Tests ''' + + def setUp(self): + self.mock_module_helper = patch.multiple(basic.AnsibleModule, + exit_json=exit_json, + fail_json=fail_json) + self.mock_module_helper.start() + self.addCleanup(self.mock_module_helper.stop) + + def set_default_args_fail_check(self): + return dict({ + 'state': 'present', + 'DNS': '101.102.103.123', + 'domain': 'mydomain.com', + 'password': 'netapp1!', + 'username': 'myuser', + 'api_url': 'myapiurl.com', + 'secret_key': 'mysecretkey', + 'api_key': 'myapikey' + }) + + def set_default_args_pass_check(self): + return dict({ + 'state': 'present', + 'DNS': '101.102.103.123', + 'domain': 'mydomain.com', + 'password': 'netapp1!', + 'region': 'us-east-1', + 'netBIOS': 'testing', + 'username': 'myuser', + 'api_url': 'myapiurl.com', + 'secret_key': 'mysecretkey', + 'api_key': 'myapikey' + }) + + def test_module_fail_when_required_args_missing(self): + ''' required arguments are reported as errors ''' + with pytest.raises(AnsibleFailJson) as exc: + set_module_args(self.set_default_args_fail_check()) + ad_module() + print('Info: %s' % exc.value.args[0]['msg']) + + def test_module_fail_when_required_args_present(self): + ''' required arguments are reported as errors ''' + with pytest.raises(AnsibleExitJson) as exc: + set_module_args(self.set_default_args_pass_check()) + ad_module() + exit_json(changed=True, msg="TestCase Fail when required ars are present") + assert exc.value.args[0]['changed'] + + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_active_directory.AwsCvsNetappActiveDir.get_activedirectory_id') + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_active_directory.AwsCvsNetappActiveDir.get_activedirectory') + @patch('ansible_collections.netapp.aws.plugins.module_utils.netapp.AwsCvsRestAPI.post') + def test_create_aws_netapp_cvs_activedir(self, get_post_api, get_aws_api, get_ad_id): + set_module_args(self.set_default_args_pass_check()) + my_obj = ad_module() + + get_aws_api.return_value = None + get_post_api.return_value = None, None + get_ad_id.return_value = "123" + with pytest.raises(AnsibleExitJson) as exc: + my_obj.apply() + print('Info: test_create_aws_netapp_cvs_active_directory: %s' % repr(exc.value)) + assert exc.value.args[0]['changed'] diff --git a/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/plugins/modules/test_aws_netapp_cvs_filesystems.py b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/plugins/modules/test_aws_netapp_cvs_filesystems.py new file mode 100644 index 00000000..9712db10 --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/plugins/modules/test_aws_netapp_cvs_filesystems.py @@ -0,0 +1,148 @@ +# (c) 2019, NetApp, Inc +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +''' unit tests AWS CVS FileSystems Ansible module: aws_netapp_cvs_filesystems''' + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json +import pytest + +from ansible.module_utils import basic +from ansible.module_utils._text import to_bytes +from ansible_collections.netapp.aws.tests.unit.compat import unittest +from ansible_collections.netapp.aws.tests.unit.compat.mock import patch +from ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_filesystems \ + import AwsCvsNetappFileSystem as fileSystem_module + + +def set_module_args(args): + """prepare arguments so that they will be picked up during module creation""" + args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) + basic._ANSIBLE_ARGS = to_bytes(args) # pylint: disable=protected-access + + +class AnsibleExitJson(Exception): + """Exception class to be raised by module.exit_json and caught by the test case""" + + +class AnsibleFailJson(Exception): + """Exception class to be raised by module.fail_json and caught by the test case""" + + +def exit_json(*args, **kwargs): # pylint: disable=unused-argument + """function to patch over exit_json; package return data into an exception""" + if 'changed' not in kwargs: + kwargs['changed'] = False + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): # pylint: disable=unused-argument + """function to patch over fail_json; package return data into an exception""" + kwargs['failed'] = True + raise AnsibleFailJson(kwargs) + + +class TestMyModule(unittest.TestCase): + ''' a group of related Unit Tests ''' + + def setUp(self): + self.mock_module_helper = patch.multiple(basic.AnsibleModule, + exit_json=exit_json, + fail_json=fail_json) + self.mock_module_helper.start() + self.addCleanup(self.mock_module_helper.stop) + + def set_default_args_fail_check(self): + return dict({ + 'creationToken': 'TestFilesystem', + 'region': 'us-east-1', + 'quotaInBytes': 3424, + 'serviceLevel': 'standard', + 'api_url': 'hostname.com', + 'api_key': 'myapikey', + 'secret_key': 'mysecretkey' + }) + + def set_default_args_pass_check(self): + return dict({ + 'state': 'present', + 'creationToken': 'TestFilesystem', + 'region': 'us-east-1', + 'quotaInBytes': 3424, + 'serviceLevel': 'standard', + 'api_url': 'hostname.com', + 'api_key': 'myapikey', + 'secret_key': 'mysecretkey' + }) + + def set_args_create_aws_netapp_cvs_filesystems(self): + return dict({ + 'state': 'present', + 'creationToken': 'TestFilesystem', + 'region': 'us-east-1', + 'quotaInBytes': 3424, + 'serviceLevel': 'standard', + 'api_url': 'hostname.com', + 'api_key': 'myapikey', + 'secret_key': 'mysecretkey' + }) + + def set_args_delete_aws_netapp_cvs_filesystems(self): + return dict({ + 'state': 'absent', + 'creationToken': 'TestFilesystem', + 'region': 'us-east-1', + 'api_url': 'hostname.com', + 'api_key': 'myapikey', + 'secret_key': 'mysecretkey' + }) + + def test_module_fail_when_required_args_missing(self): + ''' required arguments are reported as errors ''' + with pytest.raises(AnsibleFailJson) as exc: + set_module_args(self.set_default_args_fail_check()) + fileSystem_module() + print('Info: test_module_fail_when_required_args_missing: %s' % exc.value.args[0]['msg']) + + def test_module_fail_when_required_args_present(self): + ''' required arguments are reported as errors ''' + with pytest.raises(AnsibleExitJson) as exc: + set_module_args(self.set_default_args_pass_check()) + fileSystem_module() + exit_json(changed=True, msg="Induced arguments check") + print('Info: test_module_fail_when_required_args_present: %s' % exc.value.args[0]['msg']) + assert exc.value.args[0]['changed'] + + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_filesystems.AwsCvsNetappFileSystem.get_filesystem_id') + @patch('ansible_collections.netapp.aws.plugins.module_utils.netapp.AwsCvsRestAPI.get_state') + @patch('ansible_collections.netapp.aws.plugins.module_utils.netapp.AwsCvsRestAPI.post') + def test_create_aws_netapp_cvs_snapshots_pass(self, get_post_api, get_state_api, get_filesystem_id): + set_module_args(self.set_args_create_aws_netapp_cvs_filesystems()) + my_obj = fileSystem_module() + get_filesystem_id.return_value = None + get_state_api.return_value = 'done' + response = {'jobs': [{'jobId': 'dummy'}]} + get_post_api.return_value = response, None + with pytest.raises(AnsibleExitJson) as exc: + my_obj.apply() + print('Info: test_create_aws_netapp_cvs_filesystem_pass: %s' % repr(exc.value.args[0])) + assert exc.value.args[0]['changed'] + + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_filesystems.AwsCvsNetappFileSystem.get_filesystem_id') + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_filesystems.AwsCvsNetappFileSystem.get_filesystem') + @patch('ansible_collections.netapp.aws.plugins.module_utils.netapp.AwsCvsRestAPI.get_state') + @patch('ansible_collections.netapp.aws.plugins.module_utils.netapp.AwsCvsRestAPI.delete') + def test_delete_aws_netapp_cvs_snapshots_pass(self, get_post_api, get_state_api, get_filesystem, get_filesystem_id): + set_module_args(self.set_args_delete_aws_netapp_cvs_filesystems()) + my_obj = fileSystem_module() + get_filesystem_id.return_value = '432-432-532423-4232' + get_filesystem.return_value = 'dummy' + get_state_api.return_value = 'done' + response = {'jobs': [{'jobId': 'dummy'}]} + get_post_api.return_value = response, None + with pytest.raises(AnsibleExitJson) as exc: + my_obj.apply() + print('Info: test_create_aws_netapp_cvs_filesyste_pass: %s' % repr(exc.value.args[0])) + assert exc.value.args[0]['changed'] diff --git a/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/plugins/modules/test_aws_netapp_cvs_pool.py b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/plugins/modules/test_aws_netapp_cvs_pool.py new file mode 100644 index 00000000..68d038db --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/plugins/modules/test_aws_netapp_cvs_pool.py @@ -0,0 +1,251 @@ +# (c) 2019, NetApp, Inc +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +''' Unit tests for AWS Cloud Volumes Services - Manage Pools ''' + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +import json +import pytest + +from ansible.module_utils import basic +from ansible.module_utils._text import to_bytes +from ansible_collections.netapp.aws.tests.unit.compat import unittest +from ansible_collections.netapp.aws.tests.unit.compat.mock import patch +from ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_pool \ + import NetAppAWSCVS as pool_module + + +def set_module_args(args): + """prepare arguments so that they will be picked up during module creation""" + args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) + basic._ANSIBLE_ARGS = to_bytes(args) # pylint: disable=protected-access + + +class AnsibleExitJson(Exception): + """Exception class to be raised by module.exit_json and caught by the test case""" + + +class AnsibleFailJson(Exception): + """Exception class to be raised by module.fail_json and caught by the test case""" + + +def exit_json(*args, **kwargs): # pylint: disable=unused-argument + """function to patch over exit_json; package return data into an exception""" + if 'changed' not in kwargs: + kwargs['changed'] = False + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): # pylint: disable=unused-argument + """function to patch over fail_json; package return data into an exception""" + kwargs['failed'] = True + raise AnsibleFailJson(kwargs) + + +class TestMyModule(unittest.TestCase): + ''' a group of related Unit Tests ''' + + def setUp(self): + self.mock_module_helper = patch.multiple(basic.AnsibleModule, + exit_json=exit_json, + fail_json=fail_json) + self.mock_module_helper.start() + self.addCleanup(self.mock_module_helper.stop) + + def set_default_args_fail_check(self): + return dict({ + 'from_name': 'TestPoolAA', + 'name': 'TestPoolAA_new', + 'serviceLevel': 'standard', + 'sizeInBytes': 4000000000000, + 'vendorID': 'ansiblePoolTestVendorA', + 'region': 'us-east-1', + 'api_url': 'hostname.invalid', + 'api_key': 'myapikey', + 'secret_key': 'mysecretkey' + }) + + def set_default_args_pass_check(self): + return dict({ + 'state': 'present', + 'from_name': 'TestPoolAA', + 'name': 'TestPoolAA_new', + 'serviceLevel': 'standard', + 'sizeInBytes': 4000000000000, + 'vendorID': 'ansiblePoolTestVendorA', + 'region': 'us-east-1', + 'api_url': 'hostname.invalid', + 'api_key': 'myapikey', + 'secret_key': 'mysecretkey' + }) + + def set_args_create_aws_netapp_cvs_pool(self): + return dict({ + 'state': 'present', + 'name': 'TestPoolAA', + 'serviceLevel': 'standard', + 'sizeInBytes': 4000000000000, + 'vendorID': 'ansiblePoolTestVendorA', + 'region': 'us-east-1', + 'api_url': 'hostname.invalid', + 'api_key': 'myapikey', + 'secret_key': 'mysecretkey' + }) + + def set_args_update_aws_netapp_cvs_pool(self): + return dict({ + 'state': 'present', + 'from_name': 'TestPoolAA', + 'name': 'TestPoolAA_new', + 'serviceLevel': 'standard', + 'sizeInBytes': 4000000000000, + 'vendorID': 'ansiblePoolTestVendorA', + 'region': 'us-east-1', + 'api_url': 'hostname.invalid', + 'api_key': 'myapikey', + 'secret_key': 'mysecretkey' + }) + + def set_args_delete_aws_netapp_cvs_pool(self): + return dict({ + 'state': 'absent', + 'name': 'TestPoolAA', + 'region': 'us-east-1', + 'api_url': 'hostname.invalid', + 'api_key': 'myapikey', + 'secret_key': 'mysecretkey' + }) + + def test_module_fail_when_required_args_missing(self): + ''' required arguments are reported as errors ''' + with pytest.raises(AnsibleFailJson) as exc: + set_module_args(self.set_default_args_fail_check()) + pool_module() + print('Info: test_module_fail_when_required_args_missing: %s' % exc.value.args[0]['msg']) + + def test_module_pass_when_required_args_present(self): + ''' required arguments are present ''' + with pytest.raises(AnsibleExitJson) as exc: + set_module_args(self.set_default_args_pass_check()) + pool_module() + exit_json(changed=True, msg="Induced arguments check") + print('Info: test_module_pass_when_required_args_present: %s' % exc.value.args[0]['msg']) + assert exc.value.args[0]['changed'] + + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_pool.NetAppAWSCVS.get_aws_netapp_cvs_pool') + @patch('ansible_collections.netapp.aws.plugins.module_utils.netapp.AwsCvsRestAPI.put') + def test_update_aws_netapp_cvs_pool_pass(self, get_put_api, get_aws_api): + set_module_args(self.set_args_update_aws_netapp_cvs_pool()) + my_obj = pool_module() + my_pool = { + "name": "Dummyname", + "poolId": "1f63b3d0-4fd4-b4fe-1ed6-c62f5f20d975", + "region": "us-east-1", + "serviceLevel": "extreme", + "sizeInBytes": 40000000000000000, + "state": "available", + "vendorID": "Dummy" + } + get_aws_api.return_value = my_pool + get_put_api.return_value = my_pool, None + with pytest.raises(AnsibleExitJson) as exc: + my_obj.apply() + print('Info: test_update_aws_netapp_cvs_pool_pass: %s' % repr(exc.value)) + assert exc.value.args[0]['changed'] + + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_pool.NetAppAWSCVS.get_aws_netapp_cvs_pool') + @patch('ansible_collections.netapp.aws.plugins.module_utils.netapp.AwsCvsRestAPI.put') + def test_update_aws_netapp_cvs_pool_fail(self, get_put_api, get_aws_api): + set_module_args(self.set_args_update_aws_netapp_cvs_pool()) + my_obj = pool_module() + my_pool = { + "name": "Dummyname", + "poolId": "1f63b3d0-4fd4-b4fe-1ed6-c62f5f20d975", + "region": "us-east-1", + "serviceLevel": "extreme", + "sizeInBytes": 40000000000000000, + "state": "available", + "vendorID": "Dummy" + } + get_put_api.return_value = my_pool, "Error" + get_aws_api.return_value = my_pool + with pytest.raises(AnsibleFailJson) as exc: + my_obj.apply() + print('Info: test_update_aws_netapp_cvs_pool_fail: %s' % repr(exc.value)) + assert exc.value.args[0]['msg'] is not None + + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_pool.NetAppAWSCVS.get_aws_netapp_cvs_pool') + @patch('ansible_collections.netapp.aws.plugins.module_utils.netapp.AwsCvsRestAPI.post') + def test_create_aws_netapp_cvs_pool_pass(self, get_post_api, get_aws_api): + set_module_args(self.set_args_create_aws_netapp_cvs_pool()) + my_obj = pool_module() + get_aws_api.return_value = None + get_post_api.return_value = None, None + with pytest.raises(AnsibleExitJson) as exc: + my_obj.apply() + print('Info: test_create_aws_netapp_cvs_pool_pass: %s' % repr(exc.value)) + assert exc.value.args[0]['changed'] + + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_pool.NetAppAWSCVS.get_aws_netapp_cvs_pool') + @patch('ansible_collections.netapp.aws.plugins.module_utils.netapp.AwsCvsRestAPI.post') + def test_create_aws_netapp_cvs_pool_fail(self, get_post_api, get_aws_api): + set_module_args(self.set_args_create_aws_netapp_cvs_pool()) + my_obj = pool_module() + my_pool = { + "name": "Dummyname", + "poolId": "1f63b3d0-4fd4-b4fe-1ed6-c62f5f20d975", + "region": "us-east-1", + "serviceLevel": "extreme", + "sizeInBytes": 40000000000000000, + "state": "available", + "vendorID": "Dummy" + } + get_post_api.return_value = my_pool, "Error" + get_aws_api.return_value = None + with pytest.raises(AnsibleFailJson) as exc: + my_obj.apply() + print('Info: test_create_aws_netapp_cvs_pool_fail: %s' % repr(exc.value)) + assert exc.value.args[0]['msg'] is not None + + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_pool.NetAppAWSCVS.get_aws_netapp_cvs_pool') + @patch('ansible_collections.netapp.aws.plugins.module_utils.netapp.AwsCvsRestAPI.delete') + def test_delete_aws_netapp_cvs_pool_pass(self, get_delete_api, get_aws_api): + set_module_args(self.set_args_delete_aws_netapp_cvs_pool()) + my_obj = pool_module() + my_pool = { + "name": "Dummyname", + "poolId": "1f63b3d0-4fd4-b4fe-1ed6-c62f5f20d975", + "region": "us-east-1", + "serviceLevel": "extreme", + "sizeInBytes": 40000000000000000, + "state": "available", + "vendorID": "Dummy" + } + get_aws_api.return_value = my_pool + get_delete_api.return_value = None, None + with pytest.raises(AnsibleExitJson) as exc: + my_obj.apply() + print('Info: test_delete_aws_netapp_cvs_pool_pass: %s' % repr(exc.value)) + assert exc.value.args[0]['changed'] + + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_pool.NetAppAWSCVS.get_aws_netapp_cvs_pool') + @patch('ansible_collections.netapp.aws.plugins.module_utils.netapp.AwsCvsRestAPI.delete') + def test_delete_aws_netapp_cvs_pool_fail(self, get_delete_api, get_aws_api): + set_module_args(self.set_args_delete_aws_netapp_cvs_pool()) + my_obj = pool_module() + my_pool = { + "name": "Dummyname", + "poolId": "1f63b3d0-4fd4-b4fe-1ed6-c62f5f20d975", + "region": "us-east-1", + "serviceLevel": "extreme", + "sizeInBytes": 40000000000000000, + "state": "available", + "vendorID": "Dummy" + } + get_delete_api.return_value = my_pool, "Error" + get_aws_api.return_value = my_pool + with pytest.raises(AnsibleFailJson) as exc: + my_obj.apply() + print('Info: test_delete_aws_netapp_cvs_pool_fail: %s' % repr(exc.value)) + assert exc.value.args[0]['msg'] is not None diff --git a/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/plugins/modules/test_aws_netapp_cvs_snapshots.py b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/plugins/modules/test_aws_netapp_cvs_snapshots.py new file mode 100644 index 00000000..1f4c4bbe --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/plugins/modules/test_aws_netapp_cvs_snapshots.py @@ -0,0 +1,140 @@ +# (c) 2019, NetApp, Inc +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +''' unit tests NetApp AWS CVS Snapshots Ansible module: aws_netapp_cvs_snapshots''' + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type +import json +import pytest + +from ansible.module_utils import basic +from ansible.module_utils._text import to_bytes +from ansible_collections.netapp.aws.tests.unit.compat import unittest +from ansible_collections.netapp.aws.tests.unit.compat.mock import patch +from ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_snapshots \ + import AwsCvsNetappSnapshot as snapshot_module + + +def set_module_args(args): + """prepare arguments so that they will be picked up during module creation""" + args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) + basic._ANSIBLE_ARGS = to_bytes(args) # pylint: disable=protected-access + + +class AnsibleExitJson(Exception): + """Exception class to be raised by module.exit_json and caught by the test case""" + + +class AnsibleFailJson(Exception): + """Exception class to be raised by module.fail_json and caught by the test case""" + + +def exit_json(*args, **kwargs): # pylint: disable=unused-argument + """function to patch over exit_json; package return data into an exception""" + if 'changed' not in kwargs: + kwargs['changed'] = False + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): # pylint: disable=unused-argument + """function to patch over fail_json; package return data into an exception""" + kwargs['failed'] = True + raise AnsibleFailJson(kwargs) + + +class TestMyModule(unittest.TestCase): + ''' a group of related Unit Tests ''' + + def setUp(self): + self.mock_module_helper = patch.multiple(basic.AnsibleModule, + exit_json=exit_json, + fail_json=fail_json) + self.mock_module_helper.start() + self.addCleanup(self.mock_module_helper.stop) + + def set_default_args_fail_check(self): + return dict({ + 'name': 'TestFilesystem', + 'fileSystemId': 'standard', + 'from_name': 'from_TestFilesystem', + 'region': 'us-east-1', + 'api_url': 'hostname.com', + 'api_key': 'myapikey', + 'secret_key': 'mysecretkey' + }) + + def set_default_args_pass_check(self): + return dict({ + 'state': 'present', + 'name': 'testSnapshot', + 'fileSystemId': 'standard', + 'from_name': 'from_TestFilesystem', + 'region': 'us-east-1', + 'api_url': 'hostname.com', + 'api_key': 'myapikey', + 'secret_key': 'mysecretkey' + }) + + def set_args_create_aws_netapp_cvs_snapshots(self): + return dict({ + 'state': 'present', + 'name': 'testSnapshot', + 'fileSystemId': '123-4213-432-432', + 'region': 'us-east-1', + 'api_url': 'hostname.com', + 'api_key': 'myapikey', + 'secret_key': 'mysecretkey' + }) + + def set_args_delete_aws_netapp_cvs_snapshots(self): + return dict({ + 'state': 'absent', + 'name': 'testSnapshot', + 'region': 'us-east-1', + 'api_url': 'hostname.com', + 'api_key': 'myapikey', + 'secret_key': 'mysecretkey' + }) + + def test_module_fail_when_required_args_missing(self): + ''' required arguments are reported as errors ''' + with pytest.raises(AnsibleFailJson) as exc: + set_module_args(self.set_default_args_fail_check()) + snapshot_module() + print('Info: test_module_fail_when_required_args_missing: %s' % exc.value.args[0]['msg']) + + def test_module_fail_when_required_args_present(self): + ''' required arguments are reported as errors ''' + with pytest.raises(AnsibleExitJson) as exc: + set_module_args(self.set_default_args_pass_check()) + snapshot_module() + exit_json(changed=True, msg="Induced arguments check") + print('Info: test_module_fail_when_required_args_present: %s' % exc.value.args[0]['msg']) + assert exc.value.args[0]['changed'] + + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_snapshots.AwsCvsNetappSnapshot.get_snapshot_id') + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_snapshots.AwsCvsNetappSnapshot.get_filesystem_id') + @patch('ansible_collections.netapp.aws.plugins.module_utils.netapp.AwsCvsRestAPI.post') + def test_create_aws_netapp_cvs_snapshots_pass(self, get_post_api, get_filesystem_id, get_snapshot_id): + set_module_args(self.set_args_create_aws_netapp_cvs_snapshots()) + my_obj = snapshot_module() + get_filesystem_id.return_value = 'fiesystemName' + get_snapshot_id.return_value = None + get_post_api.return_value = None, None + with pytest.raises(AnsibleExitJson) as exc: + my_obj.apply() + print('Info: test_create_aws_netapp_cvs_snapshots_pass: %s' % repr(exc.value.args[0])) + assert exc.value.args[0]['changed'] + + @patch('ansible_collections.netapp.aws.plugins.modules.aws_netapp_cvs_snapshots.AwsCvsNetappSnapshot.get_snapshot_id') + @patch('ansible_collections.netapp.aws.plugins.module_utils.netapp.AwsCvsRestAPI.delete') + def test_delete_aws_netapp_cvs_snapshots_pass(self, get_post_api, get_snapshot_id): + set_module_args(self.set_args_delete_aws_netapp_cvs_snapshots()) + my_obj = snapshot_module() + get_snapshot_id.return_value = "1f63b3d0-4fd4-b4fe-1ed6-c62f5f20d975" + get_post_api.return_value = None, None + with pytest.raises(AnsibleExitJson) as exc: + my_obj.apply() + print('Info: test_create_aws_netapp_cvs_snapshots_pass: %s' % repr(exc.value.args[0])) + assert exc.value.args[0]['changed'] diff --git a/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/requirements.txt b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/requirements.txt new file mode 100644 index 00000000..46fbfa46 --- /dev/null +++ b/collections-debian-merged/ansible_collections/netapp/aws/tests/unit/requirements.txt @@ -0,0 +1 @@ +unittest2 ; python_version < '2.7' |