From 8e35e6c87a292503568e583cba8eea0241d09834 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sun, 26 Sep 2021 11:55:36 +0200 Subject: [PATCH 1/7] Initial boto3 migration --- plugins/modules/route53_health_check.py | 393 ++++++++++-------- .../route53_health_check/tasks/main.yml | 3 +- 2 files changed, 211 insertions(+), 185 deletions(-) diff --git a/plugins/modules/route53_health_check.py b/plugins/modules/route53_health_check.py index 0fc8ea4d698..980cef5fba5 100644 --- a/plugins/modules/route53_health_check.py +++ b/plugins/modules/route53_health_check.py @@ -44,7 +44,7 @@ health checks. The path can be any value for which your endpoint will return an HTTP status code of 2xx or 3xx when the endpoint is healthy, for example the file /docs/route53-health-check.html. - - Required for all checks except TCP. + - Mutually exclusive with I(type='TCP'). - The path must begin with a / - Maximum 255 characters. type: str @@ -74,15 +74,13 @@ - The number of consecutive health checks that an endpoint must pass or fail for Amazon Route 53 to change the current status of the endpoint from unhealthy to healthy or vice versa. - default: 3 + - Will default to C(3) if not specified on creation. choices: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] type: int author: "zimbatm (@zimbatm)" extends_documentation_fragment: - amazon.aws.aws - amazon.aws.ec2 -requirements: -- boto >= 2.49.0 ''' EXAMPLES = ''' @@ -119,162 +117,195 @@ import uuid try: - import boto.ec2 - from boto.route53 import Route53Connection, exception - from boto.route53.healthcheck import HealthCheck + import botocore except ImportError: pass # Handled by HAS_BOTO +from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict + from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import HAS_BOTO -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import get_aws_connection_info +from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry + + +def _list_health_checks(**params): + try: + results = client.list_health_checks(aws_retry=True, **params) + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: + module.fail_json_aws(e, msg='Failed to list health checks') + return results -# Things that can't get changed: -# protocol -# ip_address or domain -# request_interval -# string_match if not previously enabled -def find_health_check(conn, wanted): +def find_health_check(ip_addr, fqdn, hc_type, request_interval, port): """Searches for health checks that have the exact same set of immutable values""" - results = conn.get_list_health_checks() + # In lieu of an Id we perform matches against the following values: + # - ip_addr + # - fqdn + # - type (immutable) + # - request_interval + # - port + + # Because the list and route53 provides no 'filter' mechanism, + # the using a paginator would result in (on average) double the + # number of API calls and can get really slow. + # Additionally, we can't properly wrap the paginator, so retrying means + # starting from scratch with a paginator + results = _list_health_checks() while True: - for check in results.HealthChecks: - config = check.HealthCheckConfig + for check in results.get('HealthChecks'): + config = check.get('HealthCheckConfig') if ( - config.get('IPAddress') == wanted.ip_addr and - config.get('FullyQualifiedDomainName') == wanted.fqdn and - config.get('Type') == wanted.hc_type and - config.get('RequestInterval') == str(wanted.request_interval) and - config.get('Port') == str(wanted.port) + config.get('IPAddress', None) == ip_addr and + config.get('FullyQualifiedDomainName', None) == fqdn and + config.get('Type') == hc_type and + config.get('RequestInterval') == request_interval and + config.get('Port', None) == port and + True ): return check - if (results.IsTruncated == 'true'): - results = conn.get_list_health_checks(marker=results.NextMarker) + if results.get('IsTruncated', False): + results = _list_health_checks(Marker=results.get('NextMarker')) else: return None -def to_health_check(config): - return HealthCheck( - config.get('IPAddress'), - int(config.get('Port')), - config.get('Type'), - config.get('ResourcePath'), - fqdn=config.get('FullyQualifiedDomainName'), - string_match=config.get('SearchString'), - request_interval=int(config.get('RequestInterval')), - failure_threshold=int(config.get('FailureThreshold')), - ) +def delete_health_check(check_id): + if not check_id: + return False, None + if module.check_mode: + return True, 'delete' -def health_check_diff(a, b): - a = a.__dict__ - b = b.__dict__ - if a == b: - return {} - diff = {} - for key in set(a.keys()) | set(b.keys()): - if a.get(key) != b.get(key): - diff[key] = b.get(key) - return diff - - -def to_template_params(health_check): - params = { - 'ip_addr_part': '', - 'port': health_check.port, - 'type': health_check.hc_type, - 'resource_path_part': '', - 'fqdn_part': '', - 'string_match_part': '', - 'request_interval': health_check.request_interval, - 'failure_threshold': health_check.failure_threshold, - } - if health_check.ip_addr: - params['ip_addr_part'] = HealthCheck.XMLIpAddrPart % {'ip_addr': health_check.ip_addr} - if health_check.resource_path: - params['resource_path_part'] = XMLResourcePathPart % {'resource_path': health_check.resource_path} - if health_check.fqdn: - params['fqdn_part'] = HealthCheck.XMLFQDNPart % {'fqdn': health_check.fqdn} - if health_check.string_match: - params['string_match_part'] = HealthCheck.XMLStringMatchPart % {'string_match': health_check.string_match} - return params - - -XMLResourcePathPart = """%(resource_path)s""" - -POSTXMLBody = """ - - %(caller_ref)s - - %(ip_addr_part)s - %(port)s - %(type)s - %(resource_path_part)s - %(fqdn_part)s - %(string_match_part)s - %(request_interval)s - %(failure_threshold)s - - - """ - -UPDATEHCXMLBody = """ - - %(health_check_version)s - %(ip_addr_part)s - %(port)s - %(resource_path_part)s - %(fqdn_part)s - %(string_match_part)s - %(failure_threshold)i - - """ - - -def create_health_check(conn, health_check, caller_ref=None): - if caller_ref is None: - caller_ref = str(uuid.uuid4()) - uri = '/%s/healthcheck' % conn.Version - params = to_template_params(health_check) - params.update(xmlns=conn.XMLNameSpace, caller_ref=caller_ref) - - xml_body = POSTXMLBody % params - response = conn.make_request('POST', uri, {'Content-Type': 'text/xml'}, xml_body) - body = response.read() - boto.log.debug(body) - if response.status == 201: - e = boto.jsonresponse.Element() - h = boto.jsonresponse.XmlHandler(e, None) - h.parse(body) - return e - else: - raise exception.DNSServerError(response.status, response.reason, body) - - -def update_health_check(conn, health_check_id, health_check_version, health_check): - uri = '/%s/healthcheck/%s' % (conn.Version, health_check_id) - params = to_template_params(health_check) - params.update( - xmlns=conn.XMLNameSpace, - health_check_version=health_check_version, + try: + client.delete_health_check( + aws_retry=True, + HealthCheckId=check_id, + ) + except is_boto3_error_code('NoSuchHealthCheck'): + # Handle the deletion race condition as cleanly as possible + return False, None + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: # pylint: disable=duplicate-except + module.fail_json_aws(e, msg='Failed to list health checks') + + return True, 'delete' + + +def create_health_check(ip_addr_in, fqdn_in, type_in, request_interval_in, port_in): + + # In general, if a request is repeated with the same CallerRef it won't + # result in a duplicate check appearing. This means we can safely use our + # retry decorators + caller_ref = str(uuid.uuid4()) + missing_args = [] + + health_check = dict( + Type=type_in, + RequestInterval=request_interval_in, + Port=port_in, ) - xml_body = UPDATEHCXMLBody % params - response = conn.make_request('POST', uri, {'Content-Type': 'text/xml'}, xml_body) - body = response.read() - boto.log.debug(body) - if response.status not in (200, 204): - raise exception.DNSServerError(response.status, - response.reason, - body) - e = boto.jsonresponse.Element() - h = boto.jsonresponse.XmlHandler(e, None) - h.parse(body) - return e + if ip_addr_in: + health_check['IPAddress'] = ip_addr_in + if fqdn_in: + health_check['FullyQualifiedDomainName'] = fqdn_in + + if type_in in ['HTTP', 'HTTPS', 'HTTP_STR_MATCH', 'HTTPS_STR_MATCH']: + resource_path = module.params.get('resource_path') + # if not resource_path: + # missing_args.append('resource_path') + if resource_path: + health_check['ResourcePath'] = resource_path + if type_in in ['HTTP_STR_MATCH', 'HTTPS_STR_MATCH']: + string_match = module.params.get('string_match') + if not string_match: + missing_args.append('string_match') + health_check['SearchString'] = module.params.get('string_match') + + failure_threshold = module.params.get('failure_threshold') + if not failure_threshold: + failure_threshold = 3 + health_check['FailureThreshold'] = failure_threshold + + if missing_args: + module.fail_json(msg='missing required arguments for creation: {0}'.format( + ', '.join(missing_args)), + ) + + if module.check_mode: + return True, 'create', None + + try: + result = client.create_health_check( + aws_retry=True, + CallerReference=caller_ref, + HealthCheckConfig=health_check, + ) + except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e: + module.fail_json_aws(e, msg='Failed to create health check.', health_check=health_check) + + return True, 'create', result.get('HealthCheck').get('Id') + + +def update_health_check(existing_check): + # In theory it's also possible to update the IPAddress, Port and + # FullyQualifiedDomainName, however, because we use these in lieu of a + # 'Name' to uniquely identify the health check this isn't currently + # supported. If we accepted an ID it would be possible to modify them. + + changes = dict() + existing_config = existing_check.get('HealthCheckConfig') + + resource_path = module.params.get('resource_path', None) + if resource_path and resource_path != existing_config.get('ResourcePath'): + changes['ResourcePath'] = resource_path + + search_string = module.params.get('string_match', None) + if search_string and search_string != existing_config.get('SearchString'): + changes['SearchString'] = search_string + + failure_threshold = module.params.get('failure_threshold', None) + if failure_threshold and failure_threshold != existing_config.get('FailureThreshold'): + changes['FailureThreshold'] = failure_threshold + + # No changes... + if not changes: + return False, None + + if module.check_mode: + return True, 'update' + + check_id = existing_check.get('Id') + version_id = existing_check.get('HealthCheckVersion', 1) + version_id += 1 + try: + client.update_health_check( + HealthCheckId=check_id, + HealthCheckVersion=version_id, + **changes, + ) + except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e: + module.fail_json_aws(e, msg='Failed to update health check.', id=check_id) + + return True, 'update' + + +def describe_health_check(id): + if not id: + return dict() + + try: + result = client.get_health_check( + aws_retry=True, + HealthCheckId=id, + ) + except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e: + module.fail_json_aws(e, msg='Failed to get health check.', id=id) + + health_check = result.get('HealthCheck', {}) + health_check = camel_dict_to_snake_dict(health_check) + return health_check def main(): @@ -287,12 +318,26 @@ def main(): fqdn=dict(), string_match=dict(), request_interval=dict(type='int', choices=[10, 30], default=30), - failure_threshold=dict(type='int', choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], default=3), + failure_threshold=dict(type='int', choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), ) - module = AnsibleAWSModule(argument_spec=argument_spec, check_boto3=False) - if not HAS_BOTO: - module.fail_json(msg='boto 2.27.0+ required for this module') + args_one_of = [ + ['ip_address', 'fqdn'], + ] + + args_if = [ + ['type', 'TCP', ('port',)], + ] + + global module + global client + + module = AnsibleAWSModule( + argument_spec=argument_spec, + required_one_of=args_one_of, + required_if=args_if, + supports_check_mode=True, + ) state_in = module.params.get('state') ip_addr_in = module.params.get('ip_address') @@ -304,63 +349,45 @@ def main(): request_interval_in = module.params.get('request_interval') failure_threshold_in = module.params.get('failure_threshold') - if ip_addr_in is None and fqdn_in is None: - module.fail_json(msg="parameter 'ip_address' or 'fqdn' is required") - # Default port if port_in is None: if type_in in ['HTTP', 'HTTP_STR_MATCH']: port_in = 80 elif type_in in ['HTTPS', 'HTTPS_STR_MATCH']: port_in = 443 - else: - module.fail_json(msg="parameter 'port' is required for 'type' TCP") - # string_match in relation with type - if type_in in ['HTTP_STR_MATCH', 'HTTPS_STR_MATCH']: - if string_match_in is None: - module.fail_json(msg="parameter 'string_match' is required for the HTTP(S)_STR_MATCH types") - elif len(string_match_in) > 255: + if string_match_in: + if type_in not in ['HTTP_STR_MATCH', 'HTTPS_STR_MATCH']: + module.fail_json(msg="parameter 'string_match' argument is only for the HTTP(S)_STR_MATCH types") + if len(string_match_in) > 255: module.fail_json(msg="parameter 'string_match' is limited to 255 characters max") - elif string_match_in: - module.fail_json(msg="parameter 'string_match' argument is only for the HTTP(S)_STR_MATCH types") - region, ec2_url, aws_connect_kwargs = get_aws_connection_info(module) - # connect to the route53 endpoint - try: - conn = Route53Connection(**aws_connect_kwargs) - except boto.exception.BotoServerError as e: - module.fail_json(msg=e.error_message) + client = module.client('route53', retry_decorator=AWSRetry.jittered_backoff()) changed = False action = None check_id = None - wanted_config = HealthCheck(ip_addr_in, port_in, type_in, resource_path_in, fqdn_in, string_match_in, request_interval_in, failure_threshold_in) - existing_check = find_health_check(conn, wanted_config) + + existing_check = find_health_check(ip_addr_in, fqdn_in, type_in, request_interval_in, port_in) + if existing_check: - check_id = existing_check.Id - existing_config = to_health_check(existing_check.HealthCheckConfig) + check_id = existing_check.get('Id') - if state_in == 'present': + if state_in == 'absent': + changed, action = delete_health_check(check_id) + check_id = None + elif state_in == 'present': if existing_check is None: - action = "create" - check_id = create_health_check(conn, wanted_config).HealthCheck.Id - changed = True + changed, action, check_id = create_health_check(ip_addr_in, fqdn_in, type_in, request_interval_in, port_in) else: - diff = health_check_diff(existing_config, wanted_config) - if diff: - action = "update" - update_health_check(conn, existing_check.Id, int(existing_check.HealthCheckVersion), wanted_config) - changed = True - elif state_in == 'absent': - if check_id: - action = "delete" - conn.delete_health_check(check_id) - changed = True - else: - module.fail_json(msg="Logic Error: Unknown state") - - module.exit_json(changed=changed, health_check=dict(id=check_id), action=action) + changed, action = update_health_check(existing_check) + + health_check = describe_health_check(id=check_id) + health_check['action'] = action + module.exit_json( + changed=changed, + health_check=health_check, + ) if __name__ == '__main__': diff --git a/tests/integration/targets/route53_health_check/tasks/main.yml b/tests/integration/targets/route53_health_check/tasks/main.yml index 0bacbbc242b..edab46a58ac 100644 --- a/tests/integration/targets/route53_health_check/tasks/main.yml +++ b/tests/integration/targets/route53_health_check/tasks/main.yml @@ -256,8 +256,7 @@ assert: that: - update_string_match is successful - # XXX Bug - # - update_string_match is not changed + - update_string_match is not changed - '"health_check" in update_string_match' - '"id" in update_string_match.health_check' - update_string_match.health_check.id == match_check_id From 2149da15c1fbfcf0cb92ceda0e8834355c14d161 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sun, 26 Sep 2021 13:42:28 +0200 Subject: [PATCH 2/7] version --- plugins/modules/route53_health_check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/route53_health_check.py b/plugins/modules/route53_health_check.py index 980cef5fba5..cd74e61f660 100644 --- a/plugins/modules/route53_health_check.py +++ b/plugins/modules/route53_health_check.py @@ -277,8 +277,8 @@ def update_health_check(existing_check): return True, 'update' check_id = existing_check.get('Id') + # This makes sure we're starting from the version we think we are... version_id = existing_check.get('HealthCheckVersion', 1) - version_id += 1 try: client.update_health_check( HealthCheckId=check_id, From ca6cde179f88bf1d055e2783b2b5dd8cfd19d8e4 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sun, 26 Sep 2021 13:43:24 +0200 Subject: [PATCH 3/7] string_match is no longer mandatory --- .../targets/route53_health_check/tasks/main.yml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/tests/integration/targets/route53_health_check/tasks/main.yml b/tests/integration/targets/route53_health_check/tasks/main.yml index edab46a58ac..0edd41e8cef 100644 --- a/tests/integration/targets/route53_health_check/tasks/main.yml +++ b/tests/integration/targets/route53_health_check/tasks/main.yml @@ -186,8 +186,6 @@ fqdn: '{{ fqdn }}' request_interval: '{{ request_interval }}' resource_path: '{{ resource_path }}' - # Mandatory for HTTPS_STR_MATCH checks - string_match: '{{ string_match }}' register: update_resource_path - name: 'Check result - Update HTTPS health check - set resource_path' @@ -208,8 +206,6 @@ fqdn: '{{ fqdn }}' request_interval: '{{ request_interval }}' resource_path: '{{ resource_path }}' - # Mandatory for HTTPS_STR_MATCH checks - string_match: '{{ string_match }}' register: update_resource_path - name: 'Check result - Update HTTPS health check - set resource_path - idempotency' @@ -270,8 +266,6 @@ type: '{{ type_https_match }}' fqdn: '{{ fqdn }}' request_interval: '{{ request_interval }}' - # Mandatory for HTTPS_STR_MATCH checks - string_match: '' register: delete_match - name: 'Check result - Delete HTTPS health check' @@ -288,8 +282,6 @@ type: '{{ type_https_match }}' fqdn: '{{ fqdn }}' request_interval: '{{ request_interval }}' - # Mandatory for HTTPS_STR_MATCH checks - string_match: '' register: delete_match - name: 'Check result - Delete HTTPS health check - idempotency' @@ -399,8 +391,6 @@ type: '{{ type_http_match }}' fqdn: '{{ fqdn }}' request_interval: '{{ request_interval }}' - # Mandatory for HTTPS_STR_MATCH checks - string_match: '' register: delete_complex - name: 'Check result - Delete Complex health check' @@ -417,8 +407,6 @@ type: '{{ type_http_match }}' fqdn: '{{ fqdn }}' request_interval: '{{ request_interval }}' - # Mandatory for HTTPS_STR_MATCH checks - string_match: '' register: delete_complex - name: 'Check result - Delete Complex health check - idempotency' @@ -449,8 +437,6 @@ type: '{{ type_https_match }}' fqdn: '{{ fqdn }}' request_interval: '{{ request_interval }}' - # Mandatory for HTTPS_STR_MATCH checks - string_match: '' ignore_errors: true - name: 'Delete Complex health check' @@ -461,8 +447,6 @@ type: '{{ type_http_match }}' fqdn: '{{ fqdn }}' request_interval: '{{ request_interval }}' - # Mandatory for HTTPS_STR_MATCH checks - string_match: '' ignore_errors: true - name: release EIP From f9a2c0d9350ead130f3f427e9d6571a4ea4faf6a Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sun, 26 Sep 2021 13:43:39 +0200 Subject: [PATCH 4/7] Add check_mode tests --- .../route53_health_check/tasks/main.yml | 349 ++++++++++++++++++ 1 file changed, 349 insertions(+) diff --git a/tests/integration/targets/route53_health_check/tasks/main.yml b/tests/integration/targets/route53_health_check/tasks/main.yml index 0edd41e8cef..96b9ab849a2 100644 --- a/tests/integration/targets/route53_health_check/tasks/main.yml +++ b/tests/integration/targets/route53_health_check/tasks/main.yml @@ -32,6 +32,21 @@ ip_address: '{{ eip.public_ip }}' # Minimum possible definition + - name: 'Create a TCP health check - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type }}' + register: create_check + check_mode: true + + - name: 'Check result - Create a TCP health check - check_mode' + assert: + that: + - create_check is successful + - create_check is changed + - name: 'Create a TCP health check' route53_health_check: state: present @@ -51,6 +66,21 @@ - set_fact: tcp_check_id: '{{ create_check.health_check.id }}' + - name: 'Create a TCP health check - idempotency - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type }}' + register: create_check + check_mode: true + + - name: 'Check result - Create a TCP health check - idempotency - check_mode' + assert: + that: + - create_check is successful + - create_check is not changed + - name: 'Create a TCP health check - idempotency' route53_health_check: state: present @@ -69,6 +99,22 @@ - create_check.health_check.id == tcp_check_id # Update an attribute (for TCP only failure threshold makes sense) + - name: 'Update TCP health check - set threshold - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type }}' + failure_threshold: '{{ failure_threshold_updated }}' + register: update_threshold + check_mode: true + + - name: 'Check result - Update TCP health check - set threshold - check_mode' + assert: + that: + - update_threshold is successful + - update_threshold is changed + - name: 'Update TCP health check - set threshold' route53_health_check: state: present @@ -87,6 +133,22 @@ - '"id" in update_threshold.health_check' - update_threshold.health_check.id == tcp_check_id + - name: 'Update TCP health check - set threshold - idempotency - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type }}' + failure_threshold: '{{ failure_threshold_updated }}' + register: update_threshold + check_mode: true + + - name: 'Check result - Update TCP health check - set threshold - idempotency - check_mode' + assert: + that: + - update_threshold is successful + - update_threshold is not changed + - name: 'Update TCP health check - set threshold - idempotency' route53_health_check: state: present @@ -105,6 +167,22 @@ - '"id" in update_threshold.health_check' - update_threshold.health_check.id == tcp_check_id + # Delete the check + - name: 'Delete TCP health check - check_mode' + route53_health_check: + state: absent + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type }}' + register: delete_tcp + check_mode: True + + - name: 'Check result - Delete TCP health check - check_mode' + assert: + that: + - delete_tcp is successful + - delete_tcp is changed + - name: 'Delete TCP health check' route53_health_check: state: absent @@ -119,6 +197,21 @@ - delete_tcp is successful - delete_tcp is changed + - name: 'Delete TCP health check - idempotency - check_mode' + route53_health_check: + state: absent + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type }}' + register: delete_tcp + check_mode: True + + - name: 'Check result - Delete TCP health check - idempotency - check_mode' + assert: + that: + - delete_tcp is successful + - delete_tcp is not changed + - name: 'Delete TCP health check - idempotency' route53_health_check: state: absent @@ -134,6 +227,24 @@ - delete_tcp is not changed # Create an HTTPS_STR_MATCH healthcheck so we can try out more settings + - name: 'Create a HTTPS_STR_MATCH health check - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_https_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + string_match: '{{ string_match }}' + register: create_match + check_mode: true + + - name: 'Check result - Create a HTTPS_STR_MATCH health check - check_mode' + assert: + that: + - create_match is successful + - create_match is changed + - name: 'Create a HTTPS_STR_MATCH health check' route53_health_check: state: present @@ -157,6 +268,24 @@ - set_fact: match_check_id: '{{ create_match.health_check.id }}' + - name: 'Create a HTTPS_STR_MATCH health check - idempotency - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_https_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + string_match: '{{ string_match }}' + register: create_match + check_mode: true + + - name: 'Check result - Create a HTTPS_STR_MATCH health check - idempotency - check_mode' + assert: + that: + - create_match is successful + - create_match is not changed + - name: 'Create a HTTPS_STR_MATCH health check - idempotency' route53_health_check: state: present @@ -177,6 +306,24 @@ - '"id" in create_match.health_check' - create_match.health_check.id == match_check_id + - name: 'Update HTTPS health check - set resource_path - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_https_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + resource_path: '{{ resource_path }}' + register: update_resource_path + check_mode: true + + - name: 'Check result - Update HTTPS health check - set resource_path - check_mode' + assert: + that: + - update_resource_path is successful + - update_resource_path is changed + - name: 'Update HTTPS health check - set resource_path' route53_health_check: state: present @@ -197,6 +344,24 @@ - '"id" in update_resource_path.health_check' - update_resource_path.health_check.id == match_check_id + - name: 'Update HTTPS health check - set resource_path - idempotency - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_https_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + resource_path: '{{ resource_path }}' + register: update_resource_path + check_mode: true + + - name: 'Check result - Update HTTPS health check - set resource_path - idempotency - check_mode' + assert: + that: + - update_resource_path is successful + - update_resource_path is not changed + - name: 'Update HTTPS health check - set resource_path - idempotency' route53_health_check: state: present @@ -217,6 +382,24 @@ - '"id" in update_resource_path.health_check' - update_resource_path.health_check.id == match_check_id + - name: 'Update HTTPS health check - set string_match - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_https_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + string_match: '{{ string_match_updated }}' + register: update_string_match + check_mode: true + + - name: 'Check result - Update HTTPS health check - set string_match - check_mode' + assert: + that: + - update_string_match is successful + - update_string_match is changed + - name: 'Update HTTPS health check - set string_match' route53_health_check: state: present @@ -237,6 +420,24 @@ - '"id" in update_string_match.health_check' - update_string_match.health_check.id == match_check_id + - name: 'Update HTTPS health check - set string_match - idempotency - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_https_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + string_match: '{{ string_match_updated }}' + register: update_string_match + check_mode: true + + - name: 'Check result - Update HTTPS health check - set string_match - idempotency - check_mode' + assert: + that: + - update_string_match is successful + - update_string_match is not changed + - name: 'Update HTTPS health check - set string_match - idempotency' route53_health_check: state: present @@ -258,6 +459,23 @@ - update_string_match.health_check.id == match_check_id # Test deletion + - name: 'Delete HTTPS health check - check_mode' + route53_health_check: + state: absent + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_https_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + register: delete_match + check_mode: true + + - name: 'Check result - Delete HTTPS health check - check_mode' + assert: + that: + - delete_match is successful + - delete_match is changed + - name: 'Delete HTTPS health check' route53_health_check: state: absent @@ -274,6 +492,23 @@ - delete_match is successful - delete_match is changed + - name: 'Delete HTTPS health check - idempotency - check_mode' + route53_health_check: + state: absent + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_https_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + register: delete_match + check_mode: true + + - name: 'Check result - Delete HTTPS health check - idempotency - check_mode' + assert: + that: + - delete_match is successful + - delete_match is not changed + - name: 'Delete HTTPS health check - idempotency' route53_health_check: state: absent @@ -291,6 +526,26 @@ - delete_match is not changed # Create an HTTP health check with lots of settings we can update + - name: 'Create Complex health check - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_http_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + string_match: '{{ string_match }}' + resource_path: '{{ resource_path }}' + failure_threshold: '{{ failure_threshold }}' + register: create_complex + check_mode: true + + - name: 'Check result - Create Complex health check - check_mode' + assert: + that: + - create_complex is successful + - create_complex is changed + - name: 'Create Complex health check' route53_health_check: state: present @@ -317,6 +572,26 @@ - set_fact: complex_check_id: '{{ create_complex.health_check.id }}' + - name: 'Create Complex health check - idempotency - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_http_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + string_match: '{{ string_match }}' + resource_path: '{{ resource_path }}' + failure_threshold: '{{ failure_threshold }}' + register: create_complex + check_mode: true + + - name: 'Check result - Create Complex health check - idempotency - check_mode' + assert: + that: + - create_complex is successful + - create_complex is not changed + - name: 'Create Complex health check - idempotency' route53_health_check: state: present @@ -339,6 +614,26 @@ - '"id" in create_complex.health_check' - create_complex.health_check.id == complex_check_id + - name: 'Update Complex health check - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_http_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + string_match: '{{ string_match_updated }}' + resource_path: '{{ resource_path_updated }}' + failure_threshold: '{{ failure_threshold_updated }}' + register: update_complex + check_mode: true + + - name: 'Check result - Update Complex health check - check_mode' + assert: + that: + - update_complex is successful + - update_complex is changed + - name: 'Update Complex health check' route53_health_check: state: present @@ -361,6 +656,26 @@ - '"id" in update_complex.health_check' - update_complex.health_check.id == complex_check_id + - name: 'Update Complex health check - idempotency - check_mode' + route53_health_check: + state: present + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_http_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + string_match: '{{ string_match_updated }}' + resource_path: '{{ resource_path_updated }}' + failure_threshold: '{{ failure_threshold_updated }}' + register: update_complex + check_mode: true + + - name: 'Check result - Update Complex health check - idempotency - check_mode' + assert: + that: + - update_complex is successful + - update_complex is not changed + - name: 'Update Complex health check - idempotency' route53_health_check: state: present @@ -383,6 +698,23 @@ - '"id" in update_complex.health_check' - update_complex.health_check.id == complex_check_id + - name: 'Delete Complex health check - check_mode' + route53_health_check: + state: absent + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_http_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + register: delete_complex + check_mode: true + + - name: 'Check result - Delete Complex health check - check_mode' + assert: + that: + - delete_complex is successful + - delete_complex is changed + - name: 'Delete Complex health check' route53_health_check: state: absent @@ -399,6 +731,23 @@ - delete_complex is successful - delete_complex is changed + - name: 'Delete Complex health check - idempotency - check_mode' + route53_health_check: + state: absent + ip_address: '{{ ip_address }}' + port: '{{ port }}' + type: '{{ type_http_match }}' + fqdn: '{{ fqdn }}' + request_interval: '{{ request_interval }}' + register: delete_complex + check_mode: true + + - name: 'Check result - Delete Complex health check - idempotency - check_mode' + assert: + that: + - delete_complex is successful + - delete_complex is not changed + - name: 'Delete Complex health check - idempotency' route53_health_check: state: absent From f3137d50cd8527dd8d0b911f9cfed8cab98cd905 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sun, 26 Sep 2021 17:19:53 +0200 Subject: [PATCH 5/7] better --- plugins/modules/route53_health_check.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/modules/route53_health_check.py b/plugins/modules/route53_health_check.py index cd74e61f660..b54b7699d83 100644 --- a/plugins/modules/route53_health_check.py +++ b/plugins/modules/route53_health_check.py @@ -161,8 +161,7 @@ def find_health_check(ip_addr, fqdn, hc_type, request_interval, port): config.get('FullyQualifiedDomainName', None) == fqdn and config.get('Type') == hc_type and config.get('RequestInterval') == request_interval and - config.get('Port', None) == port and - True + config.get('Port', None) == port ): return check From f73c0f0f575952d7fe3844199ed288ee41a86189 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sun, 26 Sep 2021 20:20:35 +0200 Subject: [PATCH 6/7] Add docs and tests for return codes --- plugins/modules/route53_health_check.py | 73 ++++ .../route53_health_check/defaults/main.yml | 2 +- .../route53_health_check/tasks/main.yml | 363 ++++++++++++++++-- 3 files changed, 410 insertions(+), 28 deletions(-) diff --git a/plugins/modules/route53_health_check.py b/plugins/modules/route53_health_check.py index b54b7699d83..bcf7357c0ef 100644 --- a/plugins/modules/route53_health_check.py +++ b/plugins/modules/route53_health_check.py @@ -25,6 +25,7 @@ ip_address: description: - IP address of the end-point to check. Either this or I(fqdn) has to be provided. + - IP addresses must be publicly routable. type: str port: description: @@ -111,7 +112,79 @@ community.aws.route53_health_check: state: absent fqdn: host1.example.com +''' +RETURN = r''' +health_check: + description: Information about the health check. + returned: success + type: dict + contains: + action: + description: The action performed by the module. + type: str + returned: When a change is or would be made. + sample: 'updated' + id: + description: The Unique ID assigned by AWS to the health check. + type: str + returned: When the health check exists. + sample: 50ec8a13-9623-4c66-9834-dd8c5aedc9ba + health_check_version: + description: The version number of the health check. + type: int + returned: When the health check exists. + sample: 14 + health_check_config: + description: + - Detailed information about the health check. + - May contain additional values from Route 53 health check + features not yet supported by this module. + type: dict + returned: When the health check exists. + contains: + type: + description: The type of the health check. + type: str + returned: When the health check exists. + sample: 'HTTPS_STR_MATCH' + failure_threshold: + description: + - The number of consecutive health checks that an endpoint must pass or fail for Amazon Route 53 to + change the current status of the endpoint from unhealthy to healthy or vice versa. + type: int + returned: When the health check exists. + sample: 3 + fully_qualified_domain_name: + description: The FQDN configured for the health check to test. + type: str + returned: When the health check exists and an FQDN is configured. + sample: 'updated' + ip_address: + description: The IPv4 or IPv6 IP address of the endpoint to be queried. + type: str + returned: When the health check exists and a specific IP address is configured. + sample: '' + port: + description: The port on the endpoint that the health check will query. + type: str + returned: When the health check exists. + sample: 'updated' + request_interval: + description: The number of seconds between health check queries. + type: int + returned: When the health check exists. + sample: 30 + resource_path: + description: The URI path to query when performing an HTTP/HTTPS based health check. + type: str + returned: When the health check exists and a resource path has been configured. + sample: '/healthz' + search_string: + description: A string that must be present in the response for a health check to be considered successful. + type: str + returned: When the health check exists and a search string has been configured. + sample: 'ALIVE' ''' import uuid diff --git a/tests/integration/targets/route53_health_check/defaults/main.yml b/tests/integration/targets/route53_health_check/defaults/main.yml index aba5abb6c53..3763717e6d0 100644 --- a/tests/integration/targets/route53_health_check/defaults/main.yml +++ b/tests/integration/targets/route53_health_check/defaults/main.yml @@ -11,7 +11,7 @@ #ip_address: We allocate an EIP due to route53 restrictions fqdn: '{{ tiny_prefix }}.route53-health.ansible.test' -port: '8080' +port: 8080 type: 'TCP' request_interval: 30 diff --git a/tests/integration/targets/route53_health_check/tasks/main.yml b/tests/integration/targets/route53_health_check/tasks/main.yml index 96b9ab849a2..8053db80735 100644 --- a/tests/integration/targets/route53_health_check/tasks/main.yml +++ b/tests/integration/targets/route53_health_check/tasks/main.yml @@ -61,7 +61,27 @@ - create_check is successful - create_check is changed - '"health_check" in create_check' - - '"id" in create_check.health_check' + - '"id" in _health_check' + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action == 'create' + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" not in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" not in _check_config' + - '"search_string" not in _check_config' + - _check_config.type == 'TCP' + - _check_config.failure_threshold == 3 + - _check_config.request_interval == 30 + - _check_config.ip_address == ip_address + - _check_config.port == port + vars: + _health_check: '{{ create_check.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' - set_fact: tcp_check_id: '{{ create_check.health_check.id }}' @@ -96,7 +116,28 @@ - create_check is not changed - '"health_check" in create_check' - '"id" in create_check.health_check' - - create_check.health_check.id == tcp_check_id + - _health_check.id == tcp_check_id + - '"id" in _health_check' + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action is none + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" not in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" not in _check_config' + - '"search_string" not in _check_config' + - _check_config.type == 'TCP' + - _check_config.request_interval == 30 + - _check_config.failure_threshold == 3 + - _check_config.ip_address == ip_address + - _check_config.port == port + vars: + _health_check: '{{ create_check.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' # Update an attribute (for TCP only failure threshold makes sense) - name: 'Update TCP health check - set threshold - check_mode' @@ -130,8 +171,28 @@ - update_threshold is successful - update_threshold is changed - '"health_check" in update_threshold' - - '"id" in update_threshold.health_check' - - update_threshold.health_check.id == tcp_check_id + - '"id" in _health_check' + - _health_check.id == tcp_check_id + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action is none + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" not in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" not in _check_config' + - '"search_string" not in _check_config' + - _check_config.type == 'TCP' + - _check_config.request_interval == 30 + - _check_config.failure_threshold == failure_threshold_updated + - _check_config.ip_address == ip_address + - _check_config.port == port + vars: + _health_check: '{{ update_threshold.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' - name: 'Update TCP health check - set threshold - idempotency - check_mode' route53_health_check: @@ -164,8 +225,28 @@ - update_threshold is successful - update_threshold is not changed - '"health_check" in update_threshold' - - '"id" in update_threshold.health_check' - - update_threshold.health_check.id == tcp_check_id + - '"id" in _health_check' + - _health_check.id == tcp_check_id + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action is none + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" not in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" not in _check_config' + - '"search_string" not in _check_config' + - _check_config.type == 'TCP' + - _check_config.request_interval == 30 + - _check_config.failure_threshold == failure_threshold_updated + - _check_config.ip_address == ip_address + - _check_config.port == port + vars: + _health_check: '{{ update_threshold.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' # Delete the check - name: 'Delete TCP health check - check_mode' @@ -262,8 +343,30 @@ - create_match is successful - create_match is changed - '"health_check" in create_match' - - '"id" in create_match.health_check' - - create_match.health_check.id != tcp_check_id + - '"id" in _health_check' + - _health_check.id != tcp_check_id + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action is none + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" not in _check_config' + - '"search_string" in _check_config' + - _check_config.type == 'HTTPS_STR_MATCH' + - _check_config.request_interval == request_interval + - _check_config.failure_threshold == 3 + - _check_config.fully_qualified_domain_name == fqdn + - _check_config.ip_address == ip_address + - _check_config.port == port + - _check_config.search_string == string_match + vars: + _health_check: '{{ create_match.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' - set_fact: match_check_id: '{{ create_match.health_check.id }}' @@ -303,8 +406,30 @@ - create_match is successful - create_match is not changed - '"health_check" in create_match' - - '"id" in create_match.health_check' - - create_match.health_check.id == match_check_id + - '"id" in _health_check' + - _health_check.id == match_check_id + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action is none + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" not in _check_config' + - '"search_string" in _check_config' + - _check_config.type == type_https_match + - _check_config.request_interval == request_interval + - _check_config.failure_threshold == 3 + - _check_config.fully_qualified_domain_name == fqdn + - _check_config.ip_address == ip_address + - _check_config.port == port + - _check_config.search_string == string_match + vars: + _health_check: '{{ create_match.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' - name: 'Update HTTPS health check - set resource_path - check_mode' route53_health_check: @@ -341,8 +466,31 @@ - update_resource_path is successful - update_resource_path is changed - '"health_check" in update_resource_path' - - '"id" in update_resource_path.health_check' - - update_resource_path.health_check.id == match_check_id + - '"id" in _health_check' + - _health_check.id == match_check_id + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action is none + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" in _check_config' + - '"search_string" in _check_config' + - _check_config.type == type_https_match + - _check_config.request_interval == request_interval + - _check_config.failure_threshold == 3 + - _check_config.fully_qualified_domain_name == fqdn + - _check_config.ip_address == ip_address + - _check_config.port == port + - _check_config.resource_path == resource_path + - _check_config.search_string == string_match + vars: + _health_check: '{{ update_resource_path.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' - name: 'Update HTTPS health check - set resource_path - idempotency - check_mode' route53_health_check: @@ -379,8 +527,31 @@ - update_resource_path is successful - update_resource_path is not changed - '"health_check" in update_resource_path' - - '"id" in update_resource_path.health_check' - - update_resource_path.health_check.id == match_check_id + - '"id" in _health_check' + - _health_check.id == match_check_id + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action is none + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" in _check_config' + - '"search_string" in _check_config' + - _check_config.type == type_https_match + - _check_config.request_interval == request_interval + - _check_config.failure_threshold == 3 + - _check_config.fully_qualified_domain_name == fqdn + - _check_config.ip_address == ip_address + - _check_config.port == port + - _check_config.resource_path == resource_path + - _check_config.search_string == string_match + vars: + _health_check: '{{ update_resource_path.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' - name: 'Update HTTPS health check - set string_match - check_mode' route53_health_check: @@ -417,8 +588,31 @@ - update_string_match is successful - update_string_match is changed - '"health_check" in update_string_match' - - '"id" in update_string_match.health_check' - - update_string_match.health_check.id == match_check_id + - '"id" in _health_check' + - _health_check.id == match_check_id + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action is none + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" in _check_config' + - '"search_string" in _check_config' + - _check_config.type == type_https_match + - _check_config.request_interval == request_interval + - _check_config.failure_threshold == 3 + - _check_config.fully_qualified_domain_name == fqdn + - _check_config.ip_address == ip_address + - _check_config.port == port + - _check_config.resource_path == resource_path + - _check_config.search_string == string_match_updated + vars: + _health_check: '{{ update_string_match.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' - name: 'Update HTTPS health check - set string_match - idempotency - check_mode' route53_health_check: @@ -455,8 +649,31 @@ - update_string_match is successful - update_string_match is not changed - '"health_check" in update_string_match' - - '"id" in update_string_match.health_check' - - update_string_match.health_check.id == match_check_id + - '"id" in _health_check' + - _health_check.id == match_check_id + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action is none + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" in _check_config' + - '"search_string" in _check_config' + - _check_config.type == type_https_match + - _check_config.request_interval == request_interval + - _check_config.failure_threshold == 3 + - _check_config.fully_qualified_domain_name == fqdn + - _check_config.ip_address == ip_address + - _check_config.port == port + - _check_config.resource_path == resource_path + - _check_config.search_string == string_match_updated + vars: + _health_check: '{{ update_string_match.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' # Test deletion - name: 'Delete HTTPS health check - check_mode' @@ -565,9 +782,32 @@ - create_complex is successful - create_complex is changed - '"health_check" in create_complex' - - '"id" in create_complex.health_check' - - create_complex.health_check.id != tcp_check_id - - create_complex.health_check.id != match_check_id + - '"id" in _health_check' + - _health_check.id != tcp_check_id + - _health_check.id != match_check_id + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action is none + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" in _check_config' + - '"search_string" in _check_config' + - _check_config.type == type_http_match + - _check_config.request_interval == request_interval + - _check_config.failure_threshold == failure_threshold + - _check_config.fully_qualified_domain_name == fqdn + - _check_config.ip_address == ip_address + - _check_config.port == port + - _check_config.resource_path == resource_path + - _check_config.search_string == string_match + vars: + _health_check: '{{ create_complex.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' - set_fact: complex_check_id: '{{ create_complex.health_check.id }}' @@ -611,8 +851,31 @@ - create_complex is successful - create_complex is not changed - '"health_check" in create_complex' - - '"id" in create_complex.health_check' - - create_complex.health_check.id == complex_check_id + - '"id" in _health_check' + - _health_check.id == complex_check_id + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action is none + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" in _check_config' + - '"search_string" in _check_config' + - _check_config.type == type_http_match + - _check_config.request_interval == request_interval + - _check_config.failure_threshold == failure_threshold + - _check_config.fully_qualified_domain_name == fqdn + - _check_config.ip_address == ip_address + - _check_config.port == port + - _check_config.resource_path == resource_path + - _check_config.search_string == string_match + vars: + _health_check: '{{ create_complex.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' - name: 'Update Complex health check - check_mode' route53_health_check: @@ -653,8 +916,31 @@ - update_complex is successful - update_complex is changed - '"health_check" in update_complex' - - '"id" in update_complex.health_check' - - update_complex.health_check.id == complex_check_id + - '"id" in _health_check' + - _health_check.id == complex_check_id + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action is none + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" in _check_config' + - '"search_string" in _check_config' + - _check_config.type == type_http_match + - _check_config.request_interval == request_interval + - _check_config.failure_threshold == failure_threshold_updated + - _check_config.fully_qualified_domain_name == fqdn + - _check_config.ip_address == ip_address + - _check_config.port == port + - _check_config.resource_path == resource_path_updated + - _check_config.search_string == string_match_updated + vars: + _health_check: '{{ update_complex.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' - name: 'Update Complex health check - idempotency - check_mode' route53_health_check: @@ -695,8 +981,31 @@ - update_complex is successful - update_complex is not changed - '"health_check" in update_complex' - - '"id" in update_complex.health_check' - - update_complex.health_check.id == complex_check_id + - '"id" in _health_check' + - _health_check.id == complex_check_id + - '"action" in _health_check' + - '"health_check_version" in _health_check' + - create_check.health_check.action is none + - '"health_check_config" in create_check.health_check' + - '"type" in _check_config' + - '"failure_threshold" in _check_config' + - '"request_interval" in _check_config' + - '"fully_qualified_domain_name" in _check_config' + - '"ip_address" in _check_config' + - '"port" in _check_config' + - '"resource_path" in _check_config' + - '"search_string" in _check_config' + - _check_config.type == type_http_match + - _check_config.request_interval == request_interval + - _check_config.failure_threshold == failure_threshold_updated + - _check_config.fully_qualified_domain_name == fqdn + - _check_config.ip_address == ip_address + - _check_config.port == port + - _check_config.resource_path == resource_path_updated + - _check_config.search_string == string_match_updated + vars: + _health_check: '{{ update_complex.health_check }}' + _check_config: '{{ _health_check.health_check_config }}' - name: 'Delete Complex health check - check_mode' route53_health_check: From 9d1f44e665a6300b147ccdbdc2b941b5a83cd7b2 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sun, 26 Sep 2021 20:23:14 +0200 Subject: [PATCH 7/7] changelog --- changelogs/fragments/734-route53_health_check.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelogs/fragments/734-route53_health_check.yml diff --git a/changelogs/fragments/734-route53_health_check.yml b/changelogs/fragments/734-route53_health_check.yml new file mode 100644 index 00000000000..338f118c75d --- /dev/null +++ b/changelogs/fragments/734-route53_health_check.yml @@ -0,0 +1,3 @@ +minor_changes: +- route53_health_check - migrated to boto3 SDK (https://github.com/ansible-collections/community.aws/pull/734). +- route53_health_check - added support for check_mode (https://github.com/ansible-collections/community.aws/pull/734).