Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
Signed-off-by: Alina Buzachis <[email protected]>
  • Loading branch information
alinabuzachis committed Dec 5, 2024
1 parent 01aaf1e commit a94bf6d
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 67 deletions.
136 changes: 73 additions & 63 deletions plugins/modules/route53_ksk.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@
- amazon.aws.common.modules
- amazon.aws.region.modules
- amazon.aws.boto3
notes:
- This module does not support check_mode.
author:
- Alina Buzachis (@alinabuzachis)
"""
Expand Down Expand Up @@ -99,8 +97,8 @@

RETURN = r"""
change_info:
description: A dictionary that escribes change information about changes made to your hosted zone.
returned: when the Key Signing Request to be deleted exists
description: A dictionary that describes change information about changes made to the hosted zone.
returned: when the Key Signing Request is created or updated
type: dict
contains:
id:
Expand All @@ -122,12 +120,12 @@
}
location:
description: The unique URL representing the new key-signing key (KSK).
returned: when O(state=present)
returned: when only a new Key Signing Key is created
type: str
sample: "https://route53.amazonaws.com/2013-04-01/keysigningkey/xxx/ansible-test-ksk"
key_signing_key:
description: The key-signing key (KSK) that the request creates.
returned: only when a new Key Signing Request is created
returned: always
type: dict
contains:
name:
Expand Down Expand Up @@ -224,6 +222,23 @@ def get_change(client, change_id):
return client.get_change(Id=change_id)


def get_hosted_zone(client, hosted_zone_id):
return client.get_hosted_zone(Id=hosted_zone_id)


def get_dnssec(client, hosted_zone_id):
return client.get_dnssec(HostedZoneId=hosted_zone_id)


def find_ksk(client, module):
hosted_zone_dnssec = get_dnssec(client, module.params.get("hosted_zone_id"))
if hosted_zone_dnssec["KeySigningKeys"] != []:
for ksk in hosted_zone_dnssec["KeySigningKeys"]:
if ksk["Name"] == module.params.get("name"):
return ksk
return None


def wait(client, module, change_id):
try:
waiter = get_waiter(client, "resource_record_sets_changed")
Expand All @@ -238,73 +253,63 @@ def wait(client, module, change_id):
module.fail_json_aws(e, msg="Timeout waiting for changes to be applied")


def create(client, module: AnsibleAWSModule):
# The API does not raise KeySigningKeyAlreadyExists when a request with the same name and
# KMS arn already exist. It will always try to create a new KSK request.
changed: bool = True
def create_or_update(client, module: AnsibleAWSModule, ksk):
changed: bool = False
zone_id = module.params.get("hosted_zone_id")
name = module.params.get("name")
status = module.params.get("status")
request_time = datetime.datetime.utcnow()

response = client.create_key_signing_key(
CallerReference=module.params.get("caller_reference"),
KeyManagementServiceArn=module.params.get("key_management_service_arn"),
HostedZoneId=zone_id,
Name=name,
Status=status,
)

if response and response.get("ChangeInfo", {}):
submitted_at = response["ChangeInfo"].get("SubmittedAt").replace(tzinfo=None)
if submitted_at < request_time:
# A KSK request already exists.
if response["KeySigningKey"]["Status"] != status:
# Wait before activating or deactivating to reach INSYNC state
change_id = response["ChangeInfo"]["Id"]
wait(client, module, change_id)

if module.params.get("status") == "ACTIVE":
response = activate(client, zone_id, name)
elif module.params.get("status") == "INACTIVE":
response = deactivate(client, zone_id, name)
else:
changed = False

if module.params.get("wait"):
change_id = response["ChangeInfo"]["Id"]
wait(client, module, change_id)
response["ChangeInfo"] = get_change(client, change_id)
else:
changed = False
if ksk is not None:
response = {"KeySigningKey": ksk}
if ksk["Status"] != status:
changed = True

if module.check_mode:
module.exit_json(
changed=changed,
msg=f"Would have updated the Key Signing Key status to {status} if not in check_mode.",
)

if status == "ACTIVE":
response.update(activate(client, zone_id, name))
elif status == "INACTIVE":
response.update(deactivate(client, zone_id, name))
else:
changed = True
if module.check_mode:
module.exit_json(changed=changed, msg=f"Would have created the Key Signing Key if not in check_mode.")

response = client.create_key_signing_key(
CallerReference=module.params.get("caller_reference"),
KeyManagementServiceArn=module.params.get("key_management_service_arn"),
HostedZoneId=zone_id,
Name=name,
Status=status,
)

del response["ResponseMetadata"]

return changed, response


def delete(client, module: AnsibleAWSModule):
def delete(client, module: AnsibleAWSModule, ksk):
changed: bool = False
zone_id = module.params.get("hosted_zone_id")
name = module.params.get("name")
response = {"KeySigningRequest": {}}

if module.params.get("status") == "INACTIVE":
try:
# Deactivate the Key Signing Request before deleting
result = deactivate(client, zone_id, name)
except is_boto3_error_code("NoSuchKeySigningKey"):
return changed, {}

change_id = result["ChangeInfo"]["Id"]
wait(client, module, change_id)
try:
response = client.delete_key_signing_key(HostedZoneId=zone_id, Name=name)
if ksk is not None:
changed = True
response["KeySigningRequest"] = ksk
if module.check_mode:
module.exit_json(changed=changed, msg=f"Would have deleted the Key Signing Key if not in check_mode.")

if module.params.get("wait"):
change_id = response["ChangeInfo"]["Id"]
if module.params.get("status") == "INACTIVE":
result = deactivate(client, zone_id, name)
change_id = result["ChangeInfo"]["Id"]
wait(client, module, change_id)
response["ChangeInfo"] = get_change(client, change_id)
except is_boto3_error_code("NoSuchKeySigningKey"):
return changed, {}

response = client.delete_key_signing_key(HostedZoneId=zone_id, Name=name)

return changed, response

Expand All @@ -323,6 +328,7 @@ def main() -> None:

module = AnsibleAWSModule(
argument_spec=argument_spec,
supports_check_mode=True,
required_if=[["state", "present", ["caller_reference", "key_management_service_arn"]]],
)

Expand All @@ -335,16 +341,20 @@ def main() -> None:
state = module.params.get("state")

try:
ksk = find_ksk(client, module)
if state == "present":
changed, result = create(client, module)
changed, result = create_or_update(client, module, ksk)
else:
changed, result = delete(client, module)
changed, result = delete(client, module, ksk)

if module.params.get("wait") and result.get("ChangeInfo"):
change_id = result["ChangeInfo"]["Id"]
wait(client, module, change_id)
result["ChangeInfo"] = get_change(client, change_id)

except AnsibleAWSError as e:
module.fail_json_aws_error(e)

if "ResponseMetadata" in result:
del result["ResponseMetadata"]

module.exit_json(changed=changed, **camel_dict_to_snake_dict(result))


Expand Down
67 changes: 63 additions & 4 deletions tests/integration/targets/route53_ksk/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,25 @@
state: present
register: _hosted_zone

- name: Create a Key Signing Key request (check_mode)
amazon.aws.route53_ksk:
name: "{{ resource_prefix }}-ksk"
hosted_zone_id: "{{ _hosted_zone.zone_id }}"
key_management_service_arn: "{{ kms_key.key_arn }}"
caller_reference: "{{ aws_caller_info.arn }}"
status: "INACTIVE"
state: present
check_mode: true
register: _ksk_request

- name: Assert success
ansible.builtin.assert:
that:
- _ksk_request is successful
- _ksk_request.changed
- '"msg" in _ksk_request'
- '"Would have created the Key Signing Key if not in check_mode." in _ksk_request.msg'

- name: Create a Key Signing Key request
amazon.aws.route53_ksk:
name: "{{ resource_prefix }}-ksk"
Expand Down Expand Up @@ -60,10 +79,28 @@
ansible.builtin.assert:
that:
- _ksk_request is successful
- '"change_info" in _ksk_request'
- not _ksk_request.changed
- '"key_signing_key" in _ksk_request'

- name: Activate the Key Signing Key request (check_mode)
amazon.aws.route53_ksk:
name: "{{ resource_prefix }}-ksk"
hosted_zone_id: "{{ _hosted_zone.zone_id }}"
key_management_service_arn: "{{ kms_key.key_arn }}"
caller_reference: "{{ aws_caller_info.arn }}"
status: "ACTIVE"
state: present
check_mode: true
register: _ksk_request

- name: Assert success
ansible.builtin.assert:
that:
- _ksk_request is successful
- _ksk_request.changed
- '"msg" in _ksk_request'
- '"Would have updated the Key Signing Key status to ACTIVE if not in check_mode." in _ksk_request.msg'

- name: Activate the Key Signing Key request
amazon.aws.route53_ksk:
name: "{{ resource_prefix }}-ksk"
Expand All @@ -82,7 +119,7 @@
- '"change_info" in _ksk_request'
- _ksk_request.changed

- name: Activate KSK (idempotency)
- name: Activate the Key Signing Key request (idempotency)
amazon.aws.route53_ksk:
name: "{{ resource_prefix }}-ksk"
hosted_zone_id: "{{ _hosted_zone.zone_id }}"
Expand All @@ -96,7 +133,6 @@
ansible.builtin.assert:
that:
- _ksk_request is successful
- '"change_info" in _ksk_request'
- not _ksk_request.changed

- name: Enable DNSSEC for Route53 public zone (check_mode)
Expand Down Expand Up @@ -198,9 +234,23 @@
ansible.builtin.assert:
that:
- _ksk_request is successful
- '"change_info" in _ksk_request'
- not _ksk_request.changed

- name: Delete the Key Signing Key request (check_mode)
amazon.aws.route53_ksk:
name: "{{ resource_prefix }}-ksk"
hosted_zone_id: "{{ _hosted_zone.zone_id }}"
status: "INACTIVE"
state: absent
check_mode: true
register: _ksk_request

- name: Assert success
ansible.builtin.assert:
that:
- _ksk_request is successful
- _ksk_request.changed

- name: Delete the Key Signing Key request
amazon.aws.route53_ksk:
name: "{{ resource_prefix }}-ksk"
Expand All @@ -215,6 +265,8 @@
- _ksk_request is successful
- '"change_info" in _ksk_request'
- _ksk_request.changed
- '"msg" in _ksk_request'
- '"Would have deteled the Key Signing Key if not in check_mode." in _ksk_request.msg'

- name: Delete the Key Signing Key request (idempotency)
amazon.aws.route53_ksk:
Expand Down Expand Up @@ -245,6 +297,13 @@
- not _ksk_request.changed

always:
- name: Disable DNSSEC for Route53 public zone
amazon.aws.route53_zone:
zone: "{{ resource_prefix }}.public"
state: present
dnssec: false
ignore_errors: true

- name: Delete the Key Signing Key Request
amazon.aws.route53_ksk:
name: "{{ resource_prefix }}-ksk"
Expand Down

0 comments on commit a94bf6d

Please sign in to comment.