diff --git a/ansible_collections/netapp/ontap/README.md b/ansible_collections/netapp/ontap/README.md index f4aaf9fe..9c3aa262 100644 --- a/ansible_collections/netapp/ontap/README.md +++ b/ansible_collections/netapp/ontap/README.md @@ -27,6 +27,11 @@ Join our Slack Channel at [Netapp.io](http://netapp.io/slack) # Release Notes +## 21.6.0 + +### Minor changes + - na_ontap_rest_info - Added "autosupport_check_info"/"support/autosupport/check" to the attributes that will be collected when gathering info using the module. + ## 21.5.0 ### New Options @@ -43,12 +48,14 @@ Join our Slack Channel at [Netapp.io](http://netapp.io/slack) ### Added REST support to existing modules - na_ontap_autosupport - added REST support for ONTAP autosupport modification. - - na_ontap_info - Added "autosupport_check_info" to the attributes that will be collected when gathering info using the module. ### Bug Fixes - na_ontap_qtree - wait for completion when creating or modifying a qtree with REST. - na_ontap_volume - ignore read error because of insufficient privileges for efficiency options so that the module can be run as vsadmin. +### Minor changes + - na_ontap_info - Added "autosupport_check_info" to the attributes that will be collected when gathering info using the module. + ## 21.4.0 ### New Modules diff --git a/ansible_collections/netapp/ontap/changelogs/fragments/DEVOPS-3900.yaml b/ansible_collections/netapp/ontap/changelogs/fragments/DEVOPS-3900.yaml new file mode 100644 index 00000000..5406b25a --- /dev/null +++ b/ansible_collections/netapp/ontap/changelogs/fragments/DEVOPS-3900.yaml @@ -0,0 +1,2 @@ +minor_changes: + - na_ontap_rest_info - Added "autosupport_check_info"/"support/autosupport/check" to the attributes that will be collected when gathering info using the module. diff --git a/ansible_collections/netapp/ontap/galaxy.yml b/ansible_collections/netapp/ontap/galaxy.yml index e7373f59..d2860ce4 100644 --- a/ansible_collections/netapp/ontap/galaxy.yml +++ b/ansible_collections/netapp/ontap/galaxy.yml @@ -1,6 +1,6 @@ namespace: "netapp" name: "ontap" -version: "21.5.0" +version: "21.6.0" authors: - "NetApp Ansible Team " license: "GPL-2.0-or-later" diff --git a/ansible_collections/netapp/ontap/plugins/module_utils/netapp.py b/ansible_collections/netapp/ontap/plugins/module_utils/netapp.py index a2596cfb..1a7a7b81 100644 --- a/ansible_collections/netapp/ontap/plugins/module_utils/netapp.py +++ b/ansible_collections/netapp/ontap/plugins/module_utils/netapp.py @@ -47,7 +47,7 @@ except ImportError: ansible_version = 'unknown' -COLLECTION_VERSION = "21.5.0" +COLLECTION_VERSION = "21.6.0" CLIENT_APP_VERSION = "%s/" + COLLECTION_VERSION IMPORT_EXCEPTION = None diff --git a/ansible_collections/netapp/ontap/plugins/modules/na_ontap_rest_info.py b/ansible_collections/netapp/ontap/plugins/modules/na_ontap_rest_info.py index a1d69ab8..ae625beb 100644 --- a/ansible_collections/netapp/ontap/plugins/modules/na_ontap_rest_info.py +++ b/ansible_collections/netapp/ontap/plugins/modules/na_ontap_rest_info.py @@ -40,6 +40,7 @@ "aggregate_info" or "storage/aggregates", "application_info" or "application/applications", "application_template_info" or "application/templates", + "autosupport_check_info" or "support/autosupport/check", "autosupport_config_info" or "support/autosupport", "autosupport_messages_history" or "support/autosupport/messages", "broadcast_domains_info" or "network/ethernet/broadcast-domains", @@ -122,7 +123,7 @@ EXAMPLES = ''' - name: run ONTAP gather facts for vserver info - na_ontap_info_rest: + netapp.ontap.na_ontap_rest_info: hostname: "1.2.3.4" username: "testuser" password: "test-password" @@ -132,7 +133,7 @@ gather_subset: - vserver_info - name: run ONTAP gather facts for aggregate info and volume info - na_ontap_info_rest: + netapp.ontap.na_ontap_rest_info: hostname: "1.2.3.4" username: "testuser" password: "test-password" @@ -143,7 +144,7 @@ - aggregate_info - volume_info - name: run ONTAP gather facts for all subsets - na_ontap_info_rest: + netapp.ontap.na_ontap_rest_info: hostname: "1.2.3.4" username: "testuser" password: "test-password" @@ -153,7 +154,7 @@ gather_subset: - all - name: run ONTAP gather facts for aggregate info and volume info with fields section - na_ontap_info_rest: + netapp.ontap.na_ontap_rest_info: hostname: "1.2.3.4" username: "testuser" password: "test-password" @@ -166,7 +167,7 @@ - aggregate_info - volume_info - name: run ONTAP gather facts for aggregate info with specified fields - na_ontap_info_rest: + netapp.ontap.na_ontap_rest_info: hostname: "1.2.3.4" username: "testuser" password: "test-password" @@ -193,7 +194,7 @@ class NetAppONTAPGatherInfo(object): def __init__(self): """ Parse arguments, setup state variables, - check paramenters and ensure request module is installed + check parameters and ensure request module is installed """ self.argument_spec = netapp_utils.na_ontap_host_argument_spec() self.argument_spec.update(dict( @@ -242,6 +243,12 @@ def get_subset_info(self, gather_subset_info): if gather_subset_info.pop('post', False): self.run_post(gather_subset_info) data = {'max_records': self.parameters['max_records'], 'fields': self.fields} + + # Delete the fields record from data if it is a private/cli API call. + # The private_cli_fields method handles the fields for API calls using the private/cli endpoint. + if '/private/cli' in api: + del data['fields'] + # allow for passing in any additional rest api fields if self.parameters.get('parameters'): for each in self.parameters['parameters']: @@ -291,6 +298,21 @@ def get_next_records(self, api): return gather_subset_info + def private_cli_fields(self, api): + ''' + The private cli endpoint does not allow '*' to be an entered. + If fields='*' or fields are not included within the playbook, the API call will be populated to return all possible fields. + If fields is entered into the playbook the fields entered will be parsed into the API. + ''' + if api == 'support/autosupport/check': + url = '/private/cli/system/node/autosupport/check/details' + if 'fields' not in self.parameters or '*' in self.parameters['fields']: + fields = '?fields=node,corrective-action,status,error-detail,check-type,check-category' + else: + fields = '?fields=' + ','.join(self.parameters.get('fields')) + + return str(fields) + def convert_subsets(self): """ Convert an info to the REST API @@ -299,6 +321,7 @@ def convert_subsets(self): "aggregate_info": "storage/aggregates", "application_info": "application/applications", "application_template_info": "application/templates", + "autosupport_check_info": "support/autosupport/check", "autosupport_config_info": "support/autosupport", "autosupport_messages_history": "support/autosupport/messages", "broadcast_domains_info": "network/ethernet/broadcast-domains", @@ -534,6 +557,9 @@ def apply(self): 'support/autosupport': { 'api_call': 'support/autosupport', }, + 'support/autosupport/check': { + 'api_call': '/private/cli/system/node/autosupport/check/details' + self.private_cli_fields('support/autosupport/check'), + }, 'support/autosupport/messages': { 'api_call': 'support/autosupport/messages', }, @@ -586,7 +612,7 @@ def apply(self): result_message[subset] = self.get_subset_info(specified_subset) if result_message[subset] is not None: - if isinstance(result_message[subset], dict): + if isinstance(result_message[subset], dict) and '_links' in result_message[subset]: while result_message[subset]['_links'].get('next'): # Get all the set of records if next link found in subset_info for the specified subset next_api = result_message[subset]['_links']['next']['href'] diff --git a/ansible_collections/netapp/ontap/tests/unit/plugins/modules/test_na_ontap_rest_info.py b/ansible_collections/netapp/ontap/tests/unit/plugins/modules/test_na_ontap_rest_info.py index 1987ce4d..5ca96a46 100644 --- a/ansible_collections/netapp/ontap/tests/unit/plugins/modules/test_na_ontap_rest_info.py +++ b/ansible_collections/netapp/ontap/tests/unit/plugins/modules/test_na_ontap_rest_info.py @@ -75,7 +75,15 @@ "href": "/api/cluster/jobs/cca3d070-58c6-11ea-8c0c-005056826c14" } } - }, None) + }, None), + 'get_private_cli_subset_info': (200, + { + 'records': [ + {'node': 'node1', 'check_type': 'type'}, + {'node': 'node1', 'check_type': 'type'}, + {'node': 'node1', 'check_type': 'type'}], + "num_records": 3}, None) + } @@ -332,7 +340,7 @@ def test_run_ontap_gather_facts_for_all_subsets_pass(self, mock_request): 'storage/ports', 'storage/qos/policies', 'storage/qtrees', 'storage/quota/reports', 'storage/quota/rules', 'storage/shelves', 'storage/snapshot-policies', 'storage/volumes', 'support/autosupport', 'support/autosupport/messages', 'support/ems', 'support/ems/destinations', 'support/ems/events', 'support/ems/filters', 'svm/peers', 'svm/peer-permissions', - 'svm/svms'] + 'svm/svms', 'support/autosupport/check'] mock_request.side_effect = [ SRR['validate_ontap_version_pass'], SRR['get_subset_info'], @@ -396,6 +404,7 @@ def test_run_ontap_gather_facts_for_all_subsets_pass(self, mock_request): SRR['get_subset_info'], SRR['get_subset_info'], SRR['get_subset_info'], + SRR['get_private_cli_subset_info'], ] with pytest.raises(AnsibleExitJson) as exc: @@ -422,7 +431,7 @@ def test_run_ontap_gather_facts_for_all_subsets_with_fields_section_pass(self, m 'storage/ports', 'storage/qos/policies', 'storage/qtrees', 'storage/quota/reports', 'storage/quota/rules', 'storage/shelves', 'storage/snapshot-policies', 'storage/volumes', 'support/autosupport', 'support/autosupport/messages', 'support/ems', 'support/ems/destinations', 'support/ems/events', 'support/ems/filters', 'svm/peers', 'svm/peer-permissions', - 'svm/svms'] + 'svm/svms', 'support/autosupport/check'] mock_request.side_effect = [ SRR['validate_ontap_version_pass'], SRR['get_subset_info'], @@ -486,6 +495,7 @@ def test_run_ontap_gather_facts_for_all_subsets_with_fields_section_pass(self, m SRR['get_subset_info'], SRR['get_subset_info'], SRR['get_subset_info'], + SRR['get_private_cli_subset_info'], ] with pytest.raises(AnsibleExitJson) as exc: