summaryrefslogtreecommitdiffstats
path: root/ansible_collections/netapp/um_info/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/netapp/um_info/plugins')
-rw-r--r--ansible_collections/netapp/um_info/plugins/doc_fragments/netapp.py74
-rw-r--r--ansible_collections/netapp/um_info/plugins/module_utils/netapp.py246
-rw-r--r--ansible_collections/netapp/um_info/plugins/module_utils/netapp_module.py51
-rw-r--r--ansible_collections/netapp/um_info/plugins/modules/na_um_aggregates_info.py163
-rw-r--r--ansible_collections/netapp/um_info/plugins/modules/na_um_clusters_info.py152
-rw-r--r--ansible_collections/netapp/um_info/plugins/modules/na_um_list_aggregates.py163
-rw-r--r--ansible_collections/netapp/um_info/plugins/modules/na_um_list_clusters.py152
-rw-r--r--ansible_collections/netapp/um_info/plugins/modules/na_um_list_nodes.py145
-rw-r--r--ansible_collections/netapp/um_info/plugins/modules/na_um_list_svms.py174
-rw-r--r--ansible_collections/netapp/um_info/plugins/modules/na_um_list_volumes.py133
-rw-r--r--ansible_collections/netapp/um_info/plugins/modules/na_um_nodes_info.py145
-rw-r--r--ansible_collections/netapp/um_info/plugins/modules/na_um_svms_info.py174
-rw-r--r--ansible_collections/netapp/um_info/plugins/modules/na_um_volumes_info.py133
13 files changed, 1905 insertions, 0 deletions
diff --git a/ansible_collections/netapp/um_info/plugins/doc_fragments/netapp.py b/ansible_collections/netapp/um_info/plugins/doc_fragments/netapp.py
new file mode 100644
index 000000000..0790f109a
--- /dev/null
+++ b/ansible_collections/netapp/um_info/plugins/doc_fragments/netapp.py
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+
+# Copyright: (c) 2020, Suhas Bangalore Shekar <bsuhas@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:
+ - Ansible modules are available for the following NetApp Storage Management Platforms: AIQUM 9.7
+'''
+
+ # Documentation fragment for AIQUM (um)
+ UM = r'''
+options:
+ hostname:
+ description:
+ - The hostname or IP address of the Unified Manager instance.
+ type: str
+ required: true
+ username:
+ description:
+ - username of the Unified Manager instance.
+ type: str
+ required: true
+ password:
+ description:
+ - Password for the specified user.
+ type: str
+ required: true
+ validate_certs:
+ description:
+ - If set to C(False), the SSL certificates will not be validated.
+ - This should only set to C(False) used on personally controlled sites using self-signed certificates.
+ type: bool
+ default: True
+ http_port:
+ description:
+ - Override the default port (443) with this port
+ type: int
+ feature_flags:
+ description:
+ - Enable or disable a new feature.
+ - This can be used to enable an experimental feature or disable a new feature that breaks backward compatibility.
+ - Supported keys and values are subject to change without notice. Unknown keys are ignored.
+ - trace_apis can be set to true to enable tracing, data is written to /tmp/um_apis.log.
+ type: dict
+ version_added: 21.7.0
+ max_records:
+ description:
+ - Maximum number of records retrieved in a single GET request.
+ - This module loops on GET requests until all available records are fetched.
+ - If absent, AIQUM uses 1000.
+ type: int
+ version_added: 21.7.0
+
+
+requirements:
+ - A AIQUM 9.7 system.
+ - Ansible 2.9 or later.
+
+notes:
+ - With the 21.6.0 release, all modules have been renamed to na_um_<module>_info. The old ones will continue to work but will be depecrated in the future.
+ - The modules prefixed with na_um are built to support the AIQUM 9.7 platform.
+ - Supports check_mode.
+'''
diff --git a/ansible_collections/netapp/um_info/plugins/module_utils/netapp.py b/ansible_collections/netapp/um_info/plugins/module_utils/netapp.py
new file mode 100644
index 000000000..ba58f56e8
--- /dev/null
+++ b/ansible_collections/netapp/um_info/plugins/module_utils/netapp.py
@@ -0,0 +1,246 @@
+# 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) 2017, Sumit Kumar <sumit4@netapp.com>
+# Copyright (c) 2017, Michael Price <michael.price@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.
+
+'''
+common routines for um_info
+'''
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import logging
+from ansible.module_utils.basic import missing_required_lib
+from ansible.module_utils._text import to_native
+
+try:
+ from ansible.module_utils.ansible_release import __version__ as ansible_version
+except ImportError:
+ ansible_version = 'unknown'
+
+COLLECTION_VERSION = "21.8.0"
+
+try:
+ import requests
+ HAS_REQUESTS = True
+except ImportError:
+ HAS_REQUESTS = False
+
+ERROR_MSG = dict(
+ no_cserver='This module is expected to run as cluster admin'
+)
+
+LOG = logging.getLogger(__name__)
+LOG_FILE = '/tmp/um_apis.log'
+
+
+def na_um_host_argument_spec():
+
+ return dict(
+ hostname=dict(required=True, type='str'),
+ username=dict(required=True, type='str'),
+ password=dict(required=True, type='str', no_log=True),
+ validate_certs=dict(required=False, type='bool', default=True),
+ http_port=dict(required=False, type='int'),
+ feature_flags=dict(required=False, type='dict', default=dict()),
+ max_records=dict(required=False, type='int')
+ )
+
+
+def has_feature(module, feature_name):
+ feature = get_feature(module, feature_name)
+ if isinstance(feature, bool):
+ return feature
+ module.fail_json(msg="Error: expected bool type for feature flag: %s" % feature_name)
+
+
+def get_feature(module, feature_name):
+ ''' if the user has configured the feature, use it
+ otherwise, use our default
+ '''
+ default_flags = dict(
+ strict_json_check=True, # if true, fail if response.content in not empty and is not valid json
+ trace_apis=False, # if true, append REST requests/responses to LOG_FILE
+
+ )
+
+ if module.params['feature_flags'] is not None and feature_name in module.params['feature_flags']:
+ return module.params['feature_flags'][feature_name]
+ if feature_name in default_flags:
+ return default_flags[feature_name]
+ module.fail_json(msg="Internal error: unexpected feature flag: %s" % feature_name)
+
+
+class UMRestAPI(object):
+ ''' send REST request and process response '''
+ def __init__(self, module, timeout=60):
+ self.module = module
+ self.username = self.module.params['username']
+ self.password = self.module.params['password']
+ self.hostname = self.module.params['hostname']
+ self.verify = self.module.params['validate_certs']
+ self.max_records = self.module.params['max_records']
+ self.timeout = timeout
+ if self.module.params.get('http_port') is not None:
+ self.url = 'https://%s:%d' % (self.hostname, self.module.params['http_port'])
+ else:
+ self.url = 'https://%s' % self.hostname
+ self.errors = list()
+ self.debug_logs = list()
+ self.check_required_library()
+ if has_feature(module, 'trace_apis'):
+ logging.basicConfig(filename=LOG_FILE, level=logging.DEBUG, format='%(asctime)s %(levelname)-8s %(message)s')
+
+ def check_required_library(self):
+ if not HAS_REQUESTS:
+ self.module.fail_json(msg=missing_required_lib('requests'))
+
+ def get_records(self, message, api):
+ records = list()
+ try:
+ if message['total_records'] > 0:
+ records = message['records']
+ if message['total_records'] != len(records):
+ self.module.warn('Mismatch between received: %d and expected: %d records.' % (len(records), message['total_records']))
+ except KeyError as exc:
+ self.module.fail_json(msg='Error: unexpected response from %s: %s - expecting key: %s'
+ % (api, message, to_native(exc)))
+ return records
+
+ def send_request(self, method, api, params, json=None, accept=None):
+ ''' send http request and process response, including error conditions '''
+ url = self.url + api
+ status_code = None
+ content = None
+ json_dict = None
+ json_error = None
+ error_details = None
+ headers = None
+ if accept is not None:
+ headers = dict()
+ # accept is used to turn on/off HAL linking
+ if accept is not None:
+ headers['accept'] = accept
+
+ def check_contents(response):
+ '''json() may fail on an empty value, but it's OK if no response is expected.
+ To avoid false positives, only report an issue when we expect to read a value.
+ The first get will see it.
+ '''
+ if method == 'GET' and has_feature(self.module, 'strict_json_check'):
+ contents = response.content
+ if len(contents) > 0:
+ raise ValueError("Expecting json, got: %s" % contents)
+
+ def get_json(response):
+ ''' extract json, and error message if present '''
+ try:
+ json = response.json()
+ except ValueError:
+ check_contents(response)
+ return None, None
+ error = json.get('error')
+ return json, error
+
+ self.log_debug('sending', repr(dict(method=method, url=url, verify=self.verify, params=params,
+ timeout=self.timeout, json=json, headers=headers)))
+ try:
+ response = requests.request(method, url, verify=self.verify, auth=(self.username, self.password),
+ params=params, timeout=self.timeout, json=json, headers=headers)
+ content = response.content # for debug purposes
+ status_code = response.status_code
+ # If the response was successful, no Exception will be raised
+ response.raise_for_status()
+ json_dict, json_error = get_json(response)
+ except requests.exceptions.HTTPError as err:
+ __, json_error = get_json(response)
+ if json_error is None:
+ self.log_error(status_code, 'HTTP error: %s' % err)
+ error_details = str(err)
+ # If an error was reported in the json payload, it is handled below
+ except requests.exceptions.ConnectionError as err:
+ self.log_error(status_code, 'Connection error: %s' % err)
+ error_details = str(err)
+ except Exception as err:
+ self.log_error(status_code, 'Other error: %s' % err)
+ error_details = str(err)
+ if json_error is not None:
+ self.log_error(status_code, 'Endpoint error: %d: %s' % (status_code, json_error))
+ error_details = json_error
+ self.log_debug(status_code, content)
+ return json_dict, error_details
+
+ def get(self, api, params):
+
+ def get_next_api(message):
+ '''make sure _links is present, and href is present if next is present
+ return api if next is present, None otherwise
+ return error if _links or href are missing
+ '''
+ api, error = None, None
+ if message is None or '_links' not in message:
+ error = 'Expecting _links key in %s' % message
+ elif 'next' in message['_links']:
+ if 'href' in message['_links']['next']:
+ api = message['_links']['next']['href']
+ else:
+ error = 'Expecting href key in %s' % message['_links']['next']
+ return api, error
+
+ method = 'GET'
+ records = list()
+ if self.max_records is not None:
+ if params and 'max_records' not in params:
+ params['max_records'] = self.max_records
+ else:
+ params = dict(max_records=self.max_records)
+ api = '/api/%s' % api
+
+ while api:
+ message, error = self.send_request(method, api, params)
+ if error:
+ return message, error
+ api, error = get_next_api(message)
+ if error:
+ return message, error
+ if 'records' in message:
+ records.extend(message['records'])
+ params = None # already included in the next link
+
+ if records:
+ message['records'] = records
+ return message, error
+
+ def log_error(self, status_code, message):
+ LOG.error("%s: %s", status_code, message)
+ self.errors.append(message)
+ self.debug_logs.append((status_code, message))
+
+ def log_debug(self, status_code, content):
+ LOG.debug("%s: %s", status_code, content)
+ self.debug_logs.append((status_code, content))
diff --git a/ansible_collections/netapp/um_info/plugins/module_utils/netapp_module.py b/ansible_collections/netapp/um_info/plugins/module_utils/netapp_module.py
new file mode 100644
index 000000000..f3b95800e
--- /dev/null
+++ b/ansible_collections/netapp/um_info/plugins/module_utils/netapp_module.py
@@ -0,0 +1,51 @@
+# 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) 2020, 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
+
+
+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.changed = False
+ self.parameters = {}
+
+ 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
diff --git a/ansible_collections/netapp/um_info/plugins/modules/na_um_aggregates_info.py b/ansible_collections/netapp/um_info/plugins/modules/na_um_aggregates_info.py
new file mode 100644
index 000000000..10a34cfdf
--- /dev/null
+++ b/ansible_collections/netapp/um_info/plugins/modules/na_um_aggregates_info.py
@@ -0,0 +1,163 @@
+#!/usr/bin/python
+
+# (c) 2020, NetApp, Inc
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+'''
+na_um_list_aggregates
+'''
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'certified'}
+
+
+DOCUMENTATION = '''
+module: na_um_aggregates_info
+short_description: NetApp Unified Manager list aggregates.
+extends_documentation_fragment:
+ - netapp.um_info.netapp.um
+version_added: '20.5.0'
+author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com>
+
+description:
+- List Aggregates on AIQUM.
+'''
+
+EXAMPLES = """
+- name: List Aggregates
+ netapp.um_info.na_um_aggregates_info:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+"""
+
+RETURN = """
+records:
+ description: Returns list of Aggregates information
+ returned: always
+ type: list
+ sample: [{'node':
+ {'_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'uuid': '...',
+ 'key': '...',
+ 'name': '...'
+ },
+ 'snaplock_type': '...',
+ 'uuid': '...',
+ 'space':
+ {'block_storage':
+ {'available': ...,
+ 'used': ...,
+ 'size': ...
+ },
+ 'efficiency':
+ {'savings': ...,
+ 'logical_used': ...
+ }
+ },
+ 'block_storage':
+ {'hybrid_cache':
+ {'enabled': ...,
+ 'size': ...
+ },
+ 'primary':
+ {'raid_size': ...,
+ 'raid_type': '...'
+ },
+ 'mirror':
+ {'state': '...'
+ }
+ },
+ 'data_encryption':
+ {'software_encryption_enabled': ...
+ },
+ 'cluster':
+ {'_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'uuid': '...',
+ 'key': '...',
+ 'name': '...'
+ },
+ 'state': '...',
+ 'create_time': '...',
+ '_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'key': '...',
+ 'type': '...',
+ 'name': '...'
+ }
+ ]
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+import ansible_collections.netapp.um_info.plugins.module_utils.netapp as netapp_utils
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp_module import NetAppModule
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp import UMRestAPI
+
+
+class NetAppUMAggregate(object):
+ ''' aggregates initialize and class methods '''
+
+ def __init__(self):
+ self.argument_spec = netapp_utils.na_um_host_argument_spec()
+ 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 = UMRestAPI(self.module)
+
+ def get_aggregates(self):
+ """
+ Fetch details of aggregates.
+ :return:
+ Dictionary of current details if aggregates found
+ None if aggregates is not found
+ """
+ data = {}
+ api = "datacenter/storage/aggregates?order_by=performance_capacity.used"
+ message, error = self.rest_api.get(api, data)
+ if error:
+ self.module.fail_json(msg=error)
+ return self.rest_api.get_records(message, api)
+
+ def apply(self):
+ """
+ Apply action to the aggregates listing
+ :return: None
+ """
+ current = self.get_aggregates()
+ if current is not None:
+ self.na_helper.changed = True
+ self.module.exit_json(changed=self.na_helper.changed, msg=current)
+
+
+def main():
+ """
+ Create Aggregate class instance and invoke apply
+ :return: None
+ """
+ list_aggregates_obj = NetAppUMAggregate()
+ list_aggregates_obj.apply()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/netapp/um_info/plugins/modules/na_um_clusters_info.py b/ansible_collections/netapp/um_info/plugins/modules/na_um_clusters_info.py
new file mode 100644
index 000000000..60baa7a48
--- /dev/null
+++ b/ansible_collections/netapp/um_info/plugins/modules/na_um_clusters_info.py
@@ -0,0 +1,152 @@
+#!/usr/bin/python
+
+# (c) 2020, NetApp, Inc
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+'''
+na_um_list_clusters
+'''
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'certified'}
+
+
+DOCUMENTATION = '''
+module: na_um_clusters_info
+short_description: NetApp Unified Manager list cluster.
+extends_documentation_fragment:
+ - netapp.um_info.netapp.um
+version_added: '20.5.0'
+author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com>
+
+description:
+- List Cluster on AIQUM.
+'''
+
+EXAMPLES = """
+- name: List Clusters
+ netapp.um_info.na_um_clusters_info:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+"""
+
+RETURN = """
+records:
+ description: Returns list of Clusters information
+ returned: always
+ type: list
+ sample: [{
+ 'name': '...',
+ 'version':
+ {
+ 'generation': ...,
+ 'major': ...,
+ 'full': '...',
+ 'minor': ...
+ },
+ 'management_ip': '...',
+ 'contact': ...,
+ '_links':
+ {
+ 'self':
+ {
+ 'href': '...'
+ }
+ },
+ 'location': '...',
+ 'key': '',
+ 'nodes':
+ [
+ {
+ 'uptime': ...,
+ 'uuid': '...',
+ 'version':
+ {
+ 'generation': ...,
+ 'major': ...,
+ 'full': '...',
+ 'minor': ...
+ },
+ '_links':
+ {
+ 'self':
+ {
+ 'href': '...'
+ }
+ },
+ 'location': '...',
+ 'key': '...',
+ 'serial_number': '...',
+ 'model': '...',
+ 'name': '...'
+ }
+ ],
+ 'isSanOptimized': ...,
+ 'uuid': '...'
+ }
+ ]
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+import ansible_collections.netapp.um_info.plugins.module_utils.netapp as netapp_utils
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp_module import NetAppModule
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp import UMRestAPI
+
+
+class NetAppUMCluster(object):
+ ''' cluster initialize and class methods '''
+
+ def __init__(self):
+ self.argument_spec = netapp_utils.na_um_host_argument_spec()
+ 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 = UMRestAPI(self.module)
+
+ def get_clusters(self):
+ """
+ Fetch details of clusters.
+ :return:
+ Dictionary of current details if clusters found
+ None if clusters is not found
+ """
+ data = {}
+ api = "datacenter/cluster/clusters"
+ message, error = self.rest_api.get(api, data)
+ if error:
+ self.module.fail_json(msg=error)
+ return self.rest_api.get_records(message, api)
+
+ def apply(self):
+ """
+ Apply action to the cluster listing
+ :return: None
+ """
+ current = self.get_clusters()
+ if current is not None:
+ self.na_helper.changed = True
+ self.module.exit_json(changed=self.na_helper.changed, msg=current)
+
+
+def main():
+ """
+ Create Cluster class instance and invoke apply
+ :return: None
+ """
+ list_cluster_obj = NetAppUMCluster()
+ list_cluster_obj.apply()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/netapp/um_info/plugins/modules/na_um_list_aggregates.py b/ansible_collections/netapp/um_info/plugins/modules/na_um_list_aggregates.py
new file mode 100644
index 000000000..10a34cfdf
--- /dev/null
+++ b/ansible_collections/netapp/um_info/plugins/modules/na_um_list_aggregates.py
@@ -0,0 +1,163 @@
+#!/usr/bin/python
+
+# (c) 2020, NetApp, Inc
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+'''
+na_um_list_aggregates
+'''
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'certified'}
+
+
+DOCUMENTATION = '''
+module: na_um_aggregates_info
+short_description: NetApp Unified Manager list aggregates.
+extends_documentation_fragment:
+ - netapp.um_info.netapp.um
+version_added: '20.5.0'
+author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com>
+
+description:
+- List Aggregates on AIQUM.
+'''
+
+EXAMPLES = """
+- name: List Aggregates
+ netapp.um_info.na_um_aggregates_info:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+"""
+
+RETURN = """
+records:
+ description: Returns list of Aggregates information
+ returned: always
+ type: list
+ sample: [{'node':
+ {'_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'uuid': '...',
+ 'key': '...',
+ 'name': '...'
+ },
+ 'snaplock_type': '...',
+ 'uuid': '...',
+ 'space':
+ {'block_storage':
+ {'available': ...,
+ 'used': ...,
+ 'size': ...
+ },
+ 'efficiency':
+ {'savings': ...,
+ 'logical_used': ...
+ }
+ },
+ 'block_storage':
+ {'hybrid_cache':
+ {'enabled': ...,
+ 'size': ...
+ },
+ 'primary':
+ {'raid_size': ...,
+ 'raid_type': '...'
+ },
+ 'mirror':
+ {'state': '...'
+ }
+ },
+ 'data_encryption':
+ {'software_encryption_enabled': ...
+ },
+ 'cluster':
+ {'_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'uuid': '...',
+ 'key': '...',
+ 'name': '...'
+ },
+ 'state': '...',
+ 'create_time': '...',
+ '_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'key': '...',
+ 'type': '...',
+ 'name': '...'
+ }
+ ]
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+import ansible_collections.netapp.um_info.plugins.module_utils.netapp as netapp_utils
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp_module import NetAppModule
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp import UMRestAPI
+
+
+class NetAppUMAggregate(object):
+ ''' aggregates initialize and class methods '''
+
+ def __init__(self):
+ self.argument_spec = netapp_utils.na_um_host_argument_spec()
+ 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 = UMRestAPI(self.module)
+
+ def get_aggregates(self):
+ """
+ Fetch details of aggregates.
+ :return:
+ Dictionary of current details if aggregates found
+ None if aggregates is not found
+ """
+ data = {}
+ api = "datacenter/storage/aggregates?order_by=performance_capacity.used"
+ message, error = self.rest_api.get(api, data)
+ if error:
+ self.module.fail_json(msg=error)
+ return self.rest_api.get_records(message, api)
+
+ def apply(self):
+ """
+ Apply action to the aggregates listing
+ :return: None
+ """
+ current = self.get_aggregates()
+ if current is not None:
+ self.na_helper.changed = True
+ self.module.exit_json(changed=self.na_helper.changed, msg=current)
+
+
+def main():
+ """
+ Create Aggregate class instance and invoke apply
+ :return: None
+ """
+ list_aggregates_obj = NetAppUMAggregate()
+ list_aggregates_obj.apply()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/netapp/um_info/plugins/modules/na_um_list_clusters.py b/ansible_collections/netapp/um_info/plugins/modules/na_um_list_clusters.py
new file mode 100644
index 000000000..60baa7a48
--- /dev/null
+++ b/ansible_collections/netapp/um_info/plugins/modules/na_um_list_clusters.py
@@ -0,0 +1,152 @@
+#!/usr/bin/python
+
+# (c) 2020, NetApp, Inc
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+'''
+na_um_list_clusters
+'''
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'certified'}
+
+
+DOCUMENTATION = '''
+module: na_um_clusters_info
+short_description: NetApp Unified Manager list cluster.
+extends_documentation_fragment:
+ - netapp.um_info.netapp.um
+version_added: '20.5.0'
+author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com>
+
+description:
+- List Cluster on AIQUM.
+'''
+
+EXAMPLES = """
+- name: List Clusters
+ netapp.um_info.na_um_clusters_info:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+"""
+
+RETURN = """
+records:
+ description: Returns list of Clusters information
+ returned: always
+ type: list
+ sample: [{
+ 'name': '...',
+ 'version':
+ {
+ 'generation': ...,
+ 'major': ...,
+ 'full': '...',
+ 'minor': ...
+ },
+ 'management_ip': '...',
+ 'contact': ...,
+ '_links':
+ {
+ 'self':
+ {
+ 'href': '...'
+ }
+ },
+ 'location': '...',
+ 'key': '',
+ 'nodes':
+ [
+ {
+ 'uptime': ...,
+ 'uuid': '...',
+ 'version':
+ {
+ 'generation': ...,
+ 'major': ...,
+ 'full': '...',
+ 'minor': ...
+ },
+ '_links':
+ {
+ 'self':
+ {
+ 'href': '...'
+ }
+ },
+ 'location': '...',
+ 'key': '...',
+ 'serial_number': '...',
+ 'model': '...',
+ 'name': '...'
+ }
+ ],
+ 'isSanOptimized': ...,
+ 'uuid': '...'
+ }
+ ]
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+import ansible_collections.netapp.um_info.plugins.module_utils.netapp as netapp_utils
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp_module import NetAppModule
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp import UMRestAPI
+
+
+class NetAppUMCluster(object):
+ ''' cluster initialize and class methods '''
+
+ def __init__(self):
+ self.argument_spec = netapp_utils.na_um_host_argument_spec()
+ 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 = UMRestAPI(self.module)
+
+ def get_clusters(self):
+ """
+ Fetch details of clusters.
+ :return:
+ Dictionary of current details if clusters found
+ None if clusters is not found
+ """
+ data = {}
+ api = "datacenter/cluster/clusters"
+ message, error = self.rest_api.get(api, data)
+ if error:
+ self.module.fail_json(msg=error)
+ return self.rest_api.get_records(message, api)
+
+ def apply(self):
+ """
+ Apply action to the cluster listing
+ :return: None
+ """
+ current = self.get_clusters()
+ if current is not None:
+ self.na_helper.changed = True
+ self.module.exit_json(changed=self.na_helper.changed, msg=current)
+
+
+def main():
+ """
+ Create Cluster class instance and invoke apply
+ :return: None
+ """
+ list_cluster_obj = NetAppUMCluster()
+ list_cluster_obj.apply()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/netapp/um_info/plugins/modules/na_um_list_nodes.py b/ansible_collections/netapp/um_info/plugins/modules/na_um_list_nodes.py
new file mode 100644
index 000000000..27e81ec2e
--- /dev/null
+++ b/ansible_collections/netapp/um_info/plugins/modules/na_um_list_nodes.py
@@ -0,0 +1,145 @@
+#!/usr/bin/python
+
+# (c) 2020, NetApp, Inc
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+'''
+na_um_list_nodes
+'''
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'certified'}
+
+
+DOCUMENTATION = '''
+module: na_um_nodes_info
+short_description: NetApp Unified Manager list nodes.
+extends_documentation_fragment:
+ - netapp.um_info.netapp.um
+version_added: '20.5.0'
+author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com>
+
+description:
+- List Nodes on AIQUM.
+'''
+
+EXAMPLES = """
+- name: List Nodes
+ netapp.um_info.na_um_nodes_info:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+"""
+
+RETURN = """
+records:
+ description: Returns list of Nodes information
+ returned: always
+ type: list
+ sample: [{'allFlashOptimized': ...,
+ 'uptime': ...,
+ 'vendor': '...',
+ 'uuid': '...',
+ 'nvramid': '...',
+ '_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'cluster':
+ {'_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'uuid': '...',
+ 'key': '...',
+ 'name': '...'
+ },
+ 'version':
+ {'generation': ...,
+ 'major': ...,
+ 'full': '...',
+ 'minor': ...
+ },
+ 'systemid': '...',
+ 'location': '...',
+ 'key': ...',
+ 'is_all_flash_optimized': ...,
+ 'serial_number': '...',
+ 'model': '...',
+ 'ha':
+ {'partners':
+ [{'_links': {},
+ 'uuid': ...,
+ 'key': ...,
+ 'name': ...
+ }]
+ },
+ 'health': ...,
+ 'name': '...'
+ }]
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+import ansible_collections.netapp.um_info.plugins.module_utils.netapp as netapp_utils
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp_module import NetAppModule
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp import UMRestAPI
+
+
+class NetAppUMNode(object):
+ ''' nodes initialize and class methods '''
+
+ def __init__(self):
+ self.argument_spec = netapp_utils.na_um_host_argument_spec()
+ 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 = UMRestAPI(self.module)
+
+ def get_nodes(self):
+ """
+ Fetch details of nodes.
+ :return:
+ Dictionary of current details if nodes found
+ None if nodes is not found
+ """
+ data = {}
+ api = "datacenter/cluster/nodes?order_by=performance_capacity.used"
+ message, error = self.rest_api.get(api, data)
+ if error:
+ self.module.fail_json(msg=error)
+ return self.rest_api.get_records(message, api)
+
+ def apply(self):
+ """
+ Apply action to the nodes listing
+ :return: None
+ """
+ current = self.get_nodes()
+ if current is not None:
+ self.na_helper.changed = True
+ self.module.exit_json(changed=self.na_helper.changed, msg=current)
+
+
+def main():
+ """
+ Create Node class instance and invoke apply
+ :return: None
+ """
+ list_nodes_obj = NetAppUMNode()
+ list_nodes_obj.apply()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/netapp/um_info/plugins/modules/na_um_list_svms.py b/ansible_collections/netapp/um_info/plugins/modules/na_um_list_svms.py
new file mode 100644
index 000000000..2722e9ef6
--- /dev/null
+++ b/ansible_collections/netapp/um_info/plugins/modules/na_um_list_svms.py
@@ -0,0 +1,174 @@
+#!/usr/bin/python
+
+# (c) 2020, NetApp, Inc
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+'''
+na_um_list_svms
+'''
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'certified'}
+
+
+DOCUMENTATION = '''
+module: na_um_svms_info
+short_description: NetApp Unified Manager list svms.
+extends_documentation_fragment:
+ - netapp.um_info.netapp.um
+version_added: '20.5.0'
+author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com>
+
+description:
+- List SVMs on AIQUM.
+'''
+
+EXAMPLES = """
+- name: List SVMs
+ netapp.um_info.na_um_svms_info:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+"""
+
+RETURN = """
+records:
+ description: Returns list of SVMs information
+ returned: always
+ type: list
+ sample: [{'fcp':
+ {'enabled': ...
+ },
+ 'dns': ...,
+ 'snapshot_policy':
+ {'_links': {},
+ 'uuid': ...,
+ 'key': '...',
+ 'name': '...'
+ },
+ 'language': '...',
+ 'subtype': 'default',
+ 'aggregates':
+ [{'_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'uuid': '...',
+ 'key': '...',
+ 'name': '...'
+ }],
+ 'nvme':
+ {'enabled': ...
+ },
+ 'ipspace':
+ {'_links': {},
+ 'uuid': '...',
+ 'key': '...',
+ 'name': '...'
+ },
+ 'uuid': '...',
+ 'cluster':
+ {'_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'uuid': '...',
+ 'key': '...',
+ 'name': '...'
+ },
+ 'state': '...',
+ '_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'key': '...',
+ 'ldap':
+ {'enabled': ...
+ },
+ 'nis':
+ {'domain': ...,
+ 'enabled': ...,
+ 'servers': ...
+ },
+ 'cifs':
+ {'enabled': ...,
+ 'name': ...,
+ 'ad_domain':
+ {'fqdn': ...
+ }
+ },
+ 'iscsi':
+ {'enabled': ...
+ },
+ 'nfs':
+ {'enabled': ...
+ },
+ 'name': '...'
+ }]
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+import ansible_collections.netapp.um_info.plugins.module_utils.netapp as netapp_utils
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp_module import NetAppModule
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp import UMRestAPI
+
+
+class NetAppUMSVM(object):
+ ''' svms initialize and class methods '''
+
+ def __init__(self):
+ self.argument_spec = netapp_utils.na_um_host_argument_spec()
+ 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 = UMRestAPI(self.module)
+
+ def get_svms(self):
+ """
+ Fetch details of svms.
+ :return:
+ Dictionary of current details if svms found
+ None if svms is not found
+ """
+ data = {}
+ api = "datacenter/svm/svms"
+ message, error = self.rest_api.get(api, data)
+ if error:
+ self.module.fail_json(msg=error)
+ return self.rest_api.get_records(message, api)
+
+ def apply(self):
+ """
+ Apply action to the svms listing
+ :return: None
+ """
+ current = self.get_svms()
+ if current is not None:
+ self.na_helper.changed = True
+ self.module.exit_json(changed=self.na_helper.changed, msg=current)
+
+
+def main():
+ """
+ Create SVM class instance and invoke apply
+ :return: None
+ """
+ list_svms_obj = NetAppUMSVM()
+ list_svms_obj.apply()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/netapp/um_info/plugins/modules/na_um_list_volumes.py b/ansible_collections/netapp/um_info/plugins/modules/na_um_list_volumes.py
new file mode 100644
index 000000000..099213226
--- /dev/null
+++ b/ansible_collections/netapp/um_info/plugins/modules/na_um_list_volumes.py
@@ -0,0 +1,133 @@
+#!/usr/bin/python
+
+# (c) 2020, NetApp, Inc
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+'''
+na_um_list_volumes
+'''
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'certified'}
+
+
+DOCUMENTATION = '''
+module: na_um_volumes_info
+short_description: NetApp Unified Manager list volumes.
+extends_documentation_fragment:
+ - netapp.um_info.netapp.um
+version_added: '20.6.0'
+author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com>
+
+description:
+- List Volumes on AIQUM.
+'''
+
+EXAMPLES = """
+- name: List Volumes
+ netapp.um_info.na_um_volumes_info:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+"""
+
+RETURN = """
+records:
+ description: Returns list of Volumes information
+ returned: always
+ type: list
+ sample: [{'style': '...',
+ 'svm':
+ {'_links':
+ {'self': {...}
+ },
+ '...'
+ },
+ 'qos': {...},
+ 'name': '...',
+ 'language': '...',
+ 'space': {...},
+ 'aggregates':
+ [
+ {...}
+ ],
+ 'tiering': {...},
+ 'autosize': {...},
+ 'cluster': {...},
+ 'state': '...',
+ 'create_time': '...',
+ '_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'key': '...',
+ 'snapmirror': {...},
+ 'snapshot_policy': {...},
+ 'type': '...',
+ 'uuid': '...'
+ }]
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+import ansible_collections.netapp.um_info.plugins.module_utils.netapp as netapp_utils
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp_module import NetAppModule
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp import UMRestAPI
+
+
+class NetAppUMVolume(object):
+ ''' volumes initialize and class methods '''
+
+ def __init__(self):
+ self.argument_spec = netapp_utils.na_um_host_argument_spec()
+ 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 = UMRestAPI(self.module)
+
+ def get_volumes(self):
+ """
+ Fetch details of volumes.
+ :return:
+ Dictionary of current details if volumes found
+ None if volumes is not found
+ """
+ data = {}
+ api = "datacenter/storage/volumes"
+ message, error = self.rest_api.get(api, data)
+ if error:
+ self.module.fail_json(msg=error)
+ return self.rest_api.get_records(message, api)
+
+ def apply(self):
+ """
+ Apply action to the volumes listing
+ :return: None
+ """
+ current = self.get_volumes()
+ if current is not None:
+ self.na_helper.changed = True
+ self.module.exit_json(changed=self.na_helper.changed, msg=current)
+
+
+def main():
+ """
+ Create Volume class instance and invoke apply
+ :return: None
+ """
+ list_volumes_obj = NetAppUMVolume()
+ list_volumes_obj.apply()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/netapp/um_info/plugins/modules/na_um_nodes_info.py b/ansible_collections/netapp/um_info/plugins/modules/na_um_nodes_info.py
new file mode 100644
index 000000000..27e81ec2e
--- /dev/null
+++ b/ansible_collections/netapp/um_info/plugins/modules/na_um_nodes_info.py
@@ -0,0 +1,145 @@
+#!/usr/bin/python
+
+# (c) 2020, NetApp, Inc
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+'''
+na_um_list_nodes
+'''
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'certified'}
+
+
+DOCUMENTATION = '''
+module: na_um_nodes_info
+short_description: NetApp Unified Manager list nodes.
+extends_documentation_fragment:
+ - netapp.um_info.netapp.um
+version_added: '20.5.0'
+author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com>
+
+description:
+- List Nodes on AIQUM.
+'''
+
+EXAMPLES = """
+- name: List Nodes
+ netapp.um_info.na_um_nodes_info:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+"""
+
+RETURN = """
+records:
+ description: Returns list of Nodes information
+ returned: always
+ type: list
+ sample: [{'allFlashOptimized': ...,
+ 'uptime': ...,
+ 'vendor': '...',
+ 'uuid': '...',
+ 'nvramid': '...',
+ '_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'cluster':
+ {'_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'uuid': '...',
+ 'key': '...',
+ 'name': '...'
+ },
+ 'version':
+ {'generation': ...,
+ 'major': ...,
+ 'full': '...',
+ 'minor': ...
+ },
+ 'systemid': '...',
+ 'location': '...',
+ 'key': ...',
+ 'is_all_flash_optimized': ...,
+ 'serial_number': '...',
+ 'model': '...',
+ 'ha':
+ {'partners':
+ [{'_links': {},
+ 'uuid': ...,
+ 'key': ...,
+ 'name': ...
+ }]
+ },
+ 'health': ...,
+ 'name': '...'
+ }]
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+import ansible_collections.netapp.um_info.plugins.module_utils.netapp as netapp_utils
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp_module import NetAppModule
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp import UMRestAPI
+
+
+class NetAppUMNode(object):
+ ''' nodes initialize and class methods '''
+
+ def __init__(self):
+ self.argument_spec = netapp_utils.na_um_host_argument_spec()
+ 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 = UMRestAPI(self.module)
+
+ def get_nodes(self):
+ """
+ Fetch details of nodes.
+ :return:
+ Dictionary of current details if nodes found
+ None if nodes is not found
+ """
+ data = {}
+ api = "datacenter/cluster/nodes?order_by=performance_capacity.used"
+ message, error = self.rest_api.get(api, data)
+ if error:
+ self.module.fail_json(msg=error)
+ return self.rest_api.get_records(message, api)
+
+ def apply(self):
+ """
+ Apply action to the nodes listing
+ :return: None
+ """
+ current = self.get_nodes()
+ if current is not None:
+ self.na_helper.changed = True
+ self.module.exit_json(changed=self.na_helper.changed, msg=current)
+
+
+def main():
+ """
+ Create Node class instance and invoke apply
+ :return: None
+ """
+ list_nodes_obj = NetAppUMNode()
+ list_nodes_obj.apply()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/netapp/um_info/plugins/modules/na_um_svms_info.py b/ansible_collections/netapp/um_info/plugins/modules/na_um_svms_info.py
new file mode 100644
index 000000000..2722e9ef6
--- /dev/null
+++ b/ansible_collections/netapp/um_info/plugins/modules/na_um_svms_info.py
@@ -0,0 +1,174 @@
+#!/usr/bin/python
+
+# (c) 2020, NetApp, Inc
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+'''
+na_um_list_svms
+'''
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'certified'}
+
+
+DOCUMENTATION = '''
+module: na_um_svms_info
+short_description: NetApp Unified Manager list svms.
+extends_documentation_fragment:
+ - netapp.um_info.netapp.um
+version_added: '20.5.0'
+author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com>
+
+description:
+- List SVMs on AIQUM.
+'''
+
+EXAMPLES = """
+- name: List SVMs
+ netapp.um_info.na_um_svms_info:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+"""
+
+RETURN = """
+records:
+ description: Returns list of SVMs information
+ returned: always
+ type: list
+ sample: [{'fcp':
+ {'enabled': ...
+ },
+ 'dns': ...,
+ 'snapshot_policy':
+ {'_links': {},
+ 'uuid': ...,
+ 'key': '...',
+ 'name': '...'
+ },
+ 'language': '...',
+ 'subtype': 'default',
+ 'aggregates':
+ [{'_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'uuid': '...',
+ 'key': '...',
+ 'name': '...'
+ }],
+ 'nvme':
+ {'enabled': ...
+ },
+ 'ipspace':
+ {'_links': {},
+ 'uuid': '...',
+ 'key': '...',
+ 'name': '...'
+ },
+ 'uuid': '...',
+ 'cluster':
+ {'_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'uuid': '...',
+ 'key': '...',
+ 'name': '...'
+ },
+ 'state': '...',
+ '_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'key': '...',
+ 'ldap':
+ {'enabled': ...
+ },
+ 'nis':
+ {'domain': ...,
+ 'enabled': ...,
+ 'servers': ...
+ },
+ 'cifs':
+ {'enabled': ...,
+ 'name': ...,
+ 'ad_domain':
+ {'fqdn': ...
+ }
+ },
+ 'iscsi':
+ {'enabled': ...
+ },
+ 'nfs':
+ {'enabled': ...
+ },
+ 'name': '...'
+ }]
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+import ansible_collections.netapp.um_info.plugins.module_utils.netapp as netapp_utils
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp_module import NetAppModule
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp import UMRestAPI
+
+
+class NetAppUMSVM(object):
+ ''' svms initialize and class methods '''
+
+ def __init__(self):
+ self.argument_spec = netapp_utils.na_um_host_argument_spec()
+ 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 = UMRestAPI(self.module)
+
+ def get_svms(self):
+ """
+ Fetch details of svms.
+ :return:
+ Dictionary of current details if svms found
+ None if svms is not found
+ """
+ data = {}
+ api = "datacenter/svm/svms"
+ message, error = self.rest_api.get(api, data)
+ if error:
+ self.module.fail_json(msg=error)
+ return self.rest_api.get_records(message, api)
+
+ def apply(self):
+ """
+ Apply action to the svms listing
+ :return: None
+ """
+ current = self.get_svms()
+ if current is not None:
+ self.na_helper.changed = True
+ self.module.exit_json(changed=self.na_helper.changed, msg=current)
+
+
+def main():
+ """
+ Create SVM class instance and invoke apply
+ :return: None
+ """
+ list_svms_obj = NetAppUMSVM()
+ list_svms_obj.apply()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/netapp/um_info/plugins/modules/na_um_volumes_info.py b/ansible_collections/netapp/um_info/plugins/modules/na_um_volumes_info.py
new file mode 100644
index 000000000..099213226
--- /dev/null
+++ b/ansible_collections/netapp/um_info/plugins/modules/na_um_volumes_info.py
@@ -0,0 +1,133 @@
+#!/usr/bin/python
+
+# (c) 2020, NetApp, Inc
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+'''
+na_um_list_volumes
+'''
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'certified'}
+
+
+DOCUMENTATION = '''
+module: na_um_volumes_info
+short_description: NetApp Unified Manager list volumes.
+extends_documentation_fragment:
+ - netapp.um_info.netapp.um
+version_added: '20.6.0'
+author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com>
+
+description:
+- List Volumes on AIQUM.
+'''
+
+EXAMPLES = """
+- name: List Volumes
+ netapp.um_info.na_um_volumes_info:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+"""
+
+RETURN = """
+records:
+ description: Returns list of Volumes information
+ returned: always
+ type: list
+ sample: [{'style': '...',
+ 'svm':
+ {'_links':
+ {'self': {...}
+ },
+ '...'
+ },
+ 'qos': {...},
+ 'name': '...',
+ 'language': '...',
+ 'space': {...},
+ 'aggregates':
+ [
+ {...}
+ ],
+ 'tiering': {...},
+ 'autosize': {...},
+ 'cluster': {...},
+ 'state': '...',
+ 'create_time': '...',
+ '_links':
+ {'self':
+ {'href': '...'
+ }
+ },
+ 'key': '...',
+ 'snapmirror': {...},
+ 'snapshot_policy': {...},
+ 'type': '...',
+ 'uuid': '...'
+ }]
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+import ansible_collections.netapp.um_info.plugins.module_utils.netapp as netapp_utils
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp_module import NetAppModule
+from ansible_collections.netapp.um_info.plugins.module_utils.netapp import UMRestAPI
+
+
+class NetAppUMVolume(object):
+ ''' volumes initialize and class methods '''
+
+ def __init__(self):
+ self.argument_spec = netapp_utils.na_um_host_argument_spec()
+ 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 = UMRestAPI(self.module)
+
+ def get_volumes(self):
+ """
+ Fetch details of volumes.
+ :return:
+ Dictionary of current details if volumes found
+ None if volumes is not found
+ """
+ data = {}
+ api = "datacenter/storage/volumes"
+ message, error = self.rest_api.get(api, data)
+ if error:
+ self.module.fail_json(msg=error)
+ return self.rest_api.get_records(message, api)
+
+ def apply(self):
+ """
+ Apply action to the volumes listing
+ :return: None
+ """
+ current = self.get_volumes()
+ if current is not None:
+ self.na_helper.changed = True
+ self.module.exit_json(changed=self.na_helper.changed, msg=current)
+
+
+def main():
+ """
+ Create Volume class instance and invoke apply
+ :return: None
+ """
+ list_volumes_obj = NetAppUMVolume()
+ list_volumes_obj.apply()
+
+
+if __name__ == '__main__':
+ main()