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.
This commit is contained in:
Michael Price 2017-09-12 14:52:33 -05:00 committed by ansibot
parent adc533804a
commit 984af98b1e

View file

@ -4,14 +4,13 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # 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 from __future__ import absolute_import, division, print_function
__metaclass__ = type
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1', ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'], 'status': ['preview'],
'supported_by': 'community'} 'supported_by': 'community'}
DOCUMENTATION = ''' DOCUMENTATION = '''
--- ---
module: netapp_e_auth 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._text import to_native
from ansible.module_utils.urls import open_url from ansible.module_utils.urls import open_url
HEADERS = { HEADERS = {
"Content-Type": "application/json", "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 count = 0
all_systems = 'storage-systems' all_systems = 'storage-systems'
systems_url = api_url + all_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: for system in data:
if system['name'] == name: if system['name'] == name:
count += 1 count += 1
@ -160,7 +161,8 @@ def get_pwd_status(module, ssid, api_url, user, pwd):
pwd_status = "storage-systems/%s/passwords" % ssid pwd_status = "storage-systems/%s/passwords" % ssid
url = api_url + pwd_status url = api_url + pwd_status
try: 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'] return data['readOnlyPasswordSet'], data['adminPasswordSet']
except HTTPError as e: except HTTPError as e:
module.fail_json(msg="There was an issue with connecting, please check that your " 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): 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 update_pwd = 'storage-systems/%s' % ssid
url = api_url + update_pwd url = api_url + update_pwd
post_body = json.dumps(dict(storedPassword=pwd)) post_body = json.dumps(dict(storedPassword=pwd))
try: try:
rc, data = request(url, data=post_body, method='POST', headers=HEADERS, url_username=api_usr, 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: except Exception as e:
module.fail_json(msg="Failed to update system password. Id [%s]. Error [%s]" % (ssid, to_native(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): 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 set_pass = "storage-systems/%s/passwords" % ssid
url = api_url + set_pass url = api_url + set_pass
@ -191,23 +195,29 @@ def set_password(module, ssid, api_url, user, pwd, current_password=None, new_pa
try: 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,
ignore_errors=True) ignore_errors=True, validate_certs=module.validate_certs)
except Exception as e: 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: if rc == 422:
post_body = json.dumps(dict(currentAdminPassword='', adminPassword=set_admin, newPassword=new_password)) post_body = json.dumps(dict(currentAdminPassword='', adminPassword=set_admin, newPassword=new_password))
try: 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: except:
# TODO(lorenp): Resolve ignored rc, data
module.fail_json(msg="Wrong or no admin password supplied. Please update your playbook and try again") 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 return update_data
else: else:
module.fail_json(msg="%s:%s" % (rc, data)) module.fail_json(msg="%s:%s" % (rc, update_data))
def main(): def main():
@ -234,6 +244,7 @@ def main():
user = module.params['api_username'] user = module.params['api_username']
pwd = module.params['api_password'] pwd = module.params['api_password']
api_url = module.params['api_url'] api_url = module.params['api_url']
module.validate_certs = module.params['validate_certs']
if not api_url.endswith('/'): if not api_url.endswith('/'):
api_url += '/' api_url += '/'
@ -251,11 +262,12 @@ def main():
if len(new_password) > 30: if len(new_password) > 30:
module.fail_json(msg="Passwords must not be greater than 30 characters in length") 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, result = set_password(module, ssid, api_url, user, pwd, current_password=current_password,
new_password=new_password, new_password=new_password, set_admin=set_admin)
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__': if __name__ == '__main__':