From 984af98b1e96d0b7082625bbe2c944a2d237025f Mon Sep 17 00:00:00 2001 From: Michael Price Date: Tue, 12 Sep 2017 14:52:33 -0500 Subject: [PATCH] NetApp E-Series Auth - Resolve issues with validate_certs and error handling (#30167) * Cleanup password error handling for E-Series auth The E-Series auth module was using some erronous behavior on handling the status codes when updating the system password. This patch resolves some of these issues. * Fix validate_certs param in E-Series auth module The auth module was ignoring the validate_certs parameter for making HTTPS calls to the back-end API. This patch resolves the ignored parameter. --- .../modules/storage/netapp/netapp_e_auth.py | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/lib/ansible/modules/storage/netapp/netapp_e_auth.py b/lib/ansible/modules/storage/netapp/netapp_e_auth.py index 40a7f86535..1c8534fe99 100644 --- a/lib/ansible/modules/storage/netapp/netapp_e_auth.py +++ b/lib/ansible/modules/storage/netapp/netapp_e_auth.py @@ -4,14 +4,13 @@ # 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 +__metaclass__ = type ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} - DOCUMENTATION = ''' --- module: netapp_e_auth @@ -94,10 +93,11 @@ from ansible.module_utils.six.moves.urllib.error import HTTPError from ansible.module_utils._text import to_native from ansible.module_utils.urls import open_url - HEADERS = { "Content-Type": "application/json", - "Accept": "application/json" + "Accept": "application/json", + "x-netapp-password-validate-method": "none" + } @@ -136,7 +136,8 @@ def get_ssid(module, name, api_url, user, pwd): count = 0 all_systems = 'storage-systems' systems_url = api_url + all_systems - rc, data = request(systems_url, headers=HEADERS, url_username=user, url_password=pwd) + rc, data = request(systems_url, headers=HEADERS, url_username=user, url_password=pwd, + validate_certs=module.validate_certs) for system in data: if system['name'] == name: count += 1 @@ -160,7 +161,8 @@ def get_pwd_status(module, ssid, api_url, user, pwd): pwd_status = "storage-systems/%s/passwords" % ssid url = api_url + pwd_status try: - rc, data = request(url, headers=HEADERS, url_username=user, url_password=pwd) + rc, data = request(url, headers=HEADERS, url_username=user, url_password=pwd, + validate_certs=module.validate_certs) return data['readOnlyPasswordSet'], data['adminPasswordSet'] except HTTPError as e: module.fail_json(msg="There was an issue with connecting, please check that your " @@ -168,18 +170,20 @@ def get_pwd_status(module, ssid, api_url, user, pwd): def update_storage_system_pwd(module, ssid, pwd, api_url, api_usr, api_pwd): + """Update the stored storage-system password""" update_pwd = 'storage-systems/%s' % ssid url = api_url + update_pwd post_body = json.dumps(dict(storedPassword=pwd)) try: rc, data = request(url, data=post_body, method='POST', headers=HEADERS, url_username=api_usr, - url_password=api_pwd) + url_password=api_pwd, validate_certs=module.validate_certs) + return rc, data except Exception as e: module.fail_json(msg="Failed to update system password. Id [%s]. Error [%s]" % (ssid, to_native(e))) - return data def set_password(module, ssid, api_url, user, pwd, current_password=None, new_password=None, set_admin=False): + """Set the storage-system password""" set_pass = "storage-systems/%s/passwords" % ssid url = api_url + set_pass @@ -191,23 +195,29 @@ def set_password(module, ssid, api_url, user, pwd, current_password=None, new_pa try: rc, data = request(url, method='POST', data=post_body, headers=HEADERS, url_username=user, url_password=pwd, - ignore_errors=True) + ignore_errors=True, validate_certs=module.validate_certs) except Exception as e: - module.fail_json(msg="Failed to set system password. Id [%s]. Error [%s]" % (ssid, to_native(e)), exception=traceback.format_exc()) + module.fail_json(msg="Failed to set system password. Id [%s]. Error [%s]" % (ssid, to_native(e)), + exception=traceback.format_exc()) if rc == 422: post_body = json.dumps(dict(currentAdminPassword='', adminPassword=set_admin, newPassword=new_password)) try: - rc, data = request(url, method='POST', data=post_body, headers=HEADERS, url_username=user, url_password=pwd) + rc, data = request(url, method='POST', data=post_body, headers=HEADERS, url_username=user, url_password=pwd, + validate_certs=module.validate_certs) except: + # TODO(lorenp): Resolve ignored rc, data module.fail_json(msg="Wrong or no admin password supplied. Please update your playbook and try again") - update_data = update_storage_system_pwd(module, ssid, new_password, api_url, user, pwd) + if int(rc) >= 300: + module.fail_json(msg="Failed to set system password. Id [%s] Code [%s]. Error [%s]" % (ssid, rc, data)) - if int(rc) == 204: + rc, update_data = update_storage_system_pwd(module, ssid, new_password, api_url, user, pwd) + + if int(rc) < 300: return update_data else: - module.fail_json(msg="%s:%s" % (rc, data)) + module.fail_json(msg="%s:%s" % (rc, update_data)) def main(): @@ -234,6 +244,7 @@ def main(): user = module.params['api_username'] pwd = module.params['api_password'] api_url = module.params['api_url'] + module.validate_certs = module.params['validate_certs'] if not api_url.endswith('/'): api_url += '/' @@ -251,11 +262,12 @@ def main(): if len(new_password) > 30: module.fail_json(msg="Passwords must not be greater than 30 characters in length") - success = set_password(module, ssid, api_url, user, pwd, current_password=current_password, - new_password=new_password, - set_admin=set_admin) + result = set_password(module, ssid, api_url, user, pwd, current_password=current_password, + new_password=new_password, set_admin=set_admin) - module.exit_json(changed=True, msg="Password Updated Successfully", **success) + module.exit_json(changed=True, msg="Password Updated Successfully", + password_set=result['passwordSet'], + password_status=result['passwordStatus']) if __name__ == '__main__':