[cloud] iam_cert return arn and allow use with ansible vault (#20787)

* iam_cert.py Fix duplicate certificate detection with included chains.

The iam_cert module would fail to detect certificates as duplicates
if the certificate body included the authority chain directly.

This commit fixes the problem by checking if a given certificate
matches the start of the data returned by AWS, since in all cases
where they would match the certificate will come first.

* iam_cert.py Return certificate ARN in all success cases.

When uploading certificates or interacting with IAM, the certificate ARN
is needed for other operations with AWS such as provisioning elastic load
balancers.

This commit returns the certificate ARN in all success cases, which allows
it to be used to idempotently provision other Amazon services depending on
it (ELBs being an immediate example).
This commit is contained in:
Will Rouesnel 2017-06-20 22:01:56 +10:00 committed by Ryan Brown
parent 947e9aba45
commit 3adf08e10f

View file

@ -138,7 +138,11 @@ def cert_meta(iam, name):
server_certificate.\ server_certificate.\
server_certificate_metadata.\ server_certificate_metadata.\
expiration expiration
return opath, ocert, ocert_id, upload_date, exp arn = iam.get_server_certificate(name).get_server_certificate_result.\
server_certificate.\
server_certificate_metadata.\
arn
return opath, ocert, ocert_id, upload_date, exp, arn
def dup_check(module, iam, name, new_name, cert, orig_cert_names, orig_cert_bodies, dup_ok): def dup_check(module, iam, name, new_name, cert, orig_cert_names, orig_cert_bodies, dup_ok):
update=False update=False
@ -159,6 +163,9 @@ def dup_check(module, iam, name, new_name, cert, orig_cert_names, orig_cert_bodi
if slug_orig_cert_bodies == slug_cert: if slug_orig_cert_bodies == slug_cert:
update=True update=True
break break
elif slug_cert.startswith(slug_orig_cert_bodies):
update=True
break
elif slug_orig_cert_bodies != slug_cert: elif slug_orig_cert_bodies != slug_cert:
module.fail_json(changed=False, msg='A cert with the name %s already exists and' module.fail_json(changed=False, msg='A cert with the name %s already exists and'
' has a different certificate body associated' ' has a different certificate body associated'
@ -181,34 +188,34 @@ def cert_action(module, iam, name, cpath, new_name, new_path, state,
update = dup_check(module, iam, name, new_name, cert, orig_cert_names, update = dup_check(module, iam, name, new_name, cert, orig_cert_names,
orig_cert_bodies, dup_ok) orig_cert_bodies, dup_ok)
if update: if update:
opath, ocert, ocert_id, upload_date, exp = cert_meta(iam, name) opath, ocert, ocert_id, upload_date, exp, arn = cert_meta(iam, name)
changed=True changed=True
if new_name and new_path: if new_name and new_path:
iam.update_server_cert(name, new_cert_name=new_name, new_path=new_path) iam.update_server_cert(name, new_cert_name=new_name, new_path=new_path)
module.exit_json(changed=changed, original_name=name, new_name=new_name, module.exit_json(changed=changed, original_name=name, new_name=new_name,
original_path=opath, new_path=new_path, cert_body=ocert, original_path=opath, new_path=new_path, cert_body=ocert,
upload_date=upload_date, expiration_date=exp) upload_date=upload_date, expiration_date=exp, arn=arn)
elif new_name and not new_path: elif new_name and not new_path:
iam.update_server_cert(name, new_cert_name=new_name) iam.update_server_cert(name, new_cert_name=new_name)
module.exit_json(changed=changed, original_name=name, new_name=new_name, module.exit_json(changed=changed, original_name=name, new_name=new_name,
cert_path=opath, cert_body=ocert, cert_path=opath, cert_body=ocert,
upload_date=upload_date, expiration_date=exp) upload_date=upload_date, expiration_date=exp, arn=arn)
elif not new_name and new_path: elif not new_name and new_path:
iam.update_server_cert(name, new_path=new_path) iam.update_server_cert(name, new_path=new_path)
module.exit_json(changed=changed, name=new_name, module.exit_json(changed=changed, name=new_name,
original_path=opath, new_path=new_path, cert_body=ocert, original_path=opath, new_path=new_path, cert_body=ocert,
upload_date=upload_date, expiration_date=exp) upload_date=upload_date, expiration_date=exp, arn=arn)
else: else:
changed=False changed=False
module.exit_json(changed=changed, name=name, cert_path=opath, cert_body=ocert, module.exit_json(changed=changed, name=name, cert_path=opath, cert_body=ocert,
upload_date=upload_date, expiration_date=exp, upload_date=upload_date, expiration_date=exp, arn=arn,
msg='No new path or name specified. No changes made') msg='No new path or name specified. No changes made')
else: else:
changed=True changed=True
iam.upload_server_cert(name, cert, key, cert_chain=chain, path=cpath) iam.upload_server_cert(name, cert, key, cert_chain=chain, path=cpath)
opath, ocert, ocert_id, upload_date, exp = cert_meta(iam, name) opath, ocert, ocert_id, upload_date, exp, arn = cert_meta(iam, name)
module.exit_json(changed=changed, name=name, cert_path=opath, cert_body=ocert, module.exit_json(changed=changed, name=name, cert_path=opath, cert_body=ocert,
upload_date=upload_date, expiration_date=exp) upload_date=upload_date, expiration_date=exp, arn=arn)
elif state == 'absent': elif state == 'absent':
if name in orig_cert_names: if name in orig_cert_names:
changed=True changed=True