From ffeab003f5840a34955ce3371262af78905fa56f Mon Sep 17 00:00:00 2001 From: Tyler Schwend Date: Wed, 31 Mar 2021 12:16:16 -0400 Subject: [PATCH] kinesis_stream: Don't mark kstreams `changed` when no encryption actions taken (#27) * fix: Don't mark kstreams `changed` when no encryption actions taken Fixes https://github.com/ansible/ansible/issues/65928 * doc: add changelog fragment * Move disable_stream_encryption test to integration test * Update descriptions/fetch calls to still run on check_mode * use standard helpers to convert tags to/from boto3 format * use camel_dict_to_snake_dict helper * use standard compare_aws_tags helper * Fix tag handling and use standard helpers * Format results and add tags when manipulating encryption settings * Move kinesis_stream tests over to just integration tests * changelog * lint Co-authored-by: Tyler Schwend Co-authored-by: Mark Chappell --- .../fragments/23-kinesis_stream-changed.yml | 5 + ...do-not-mark-as-changed-no-enc-actions.yaml | 2 + plugins/modules/kinesis_stream.py | 371 ++++++------------ .../targets/kinesis_stream/defaults/main.yml | 1 + .../targets/kinesis_stream/tasks/main.yml | 35 +- .../kinesis_stream/tasks/test_encryption.yml | 138 +++---- 6 files changed, 191 insertions(+), 361 deletions(-) create mode 100644 changelogs/fragments/23-kinesis_stream-changed.yml create mode 100644 changelogs/fragments/27-kinesis_stream-do-not-mark-as-changed-no-enc-actions.yaml diff --git a/changelogs/fragments/23-kinesis_stream-changed.yml b/changelogs/fragments/23-kinesis_stream-changed.yml new file mode 100644 index 00000000000..881442e2be0 --- /dev/null +++ b/changelogs/fragments/23-kinesis_stream-changed.yml @@ -0,0 +1,5 @@ +minor_changes: +- kinesis_stream - now returns tags consistently (https://github.com/ansible-collections/community.aws/pull/27). +- kinesis_stream - now returns changed more accurately (https://github.com/ansible-collections/community.aws/pull/27). +- kinesis_stream - return values are now the same format when working with both encrypted and un-encrypted streams (https://github.com/ansible-collections/community.aws/pull/27). +- kinesis_stream - check_mode is now based on the live settings rather than comparisons with a hard coded/fake stream definition (https://github.com/ansible-collections/community.aws/pull/27). diff --git a/changelogs/fragments/27-kinesis_stream-do-not-mark-as-changed-no-enc-actions.yaml b/changelogs/fragments/27-kinesis_stream-do-not-mark-as-changed-no-enc-actions.yaml new file mode 100644 index 00000000000..61143ae88cb --- /dev/null +++ b/changelogs/fragments/27-kinesis_stream-do-not-mark-as-changed-no-enc-actions.yaml @@ -0,0 +1,2 @@ +bugfixes: + - kinesis_stream - fixed issue where streams get marked as changed even if no encryption actions were necessary (https://github.com/ansible/ansible/issues/65928). diff --git a/plugins/modules/kinesis_stream.py b/plugins/modules/kinesis_stream.py index d9b3cc0d938..755cfa096d4 100644 --- a/plugins/modules/kinesis_stream.py +++ b/plugins/modules/kinesis_stream.py @@ -192,112 +192,21 @@ pass # Handled by AnsibleAWSModule from ansible.module_utils._text import to_native +from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict +from ansible.module_utils.common.dict_transformations import snake_dict_to_camel_dict from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_tag_list +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_tag_list_to_ansible_dict +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import compare_aws_tags -def convert_to_lower(data): - """Convert all uppercase keys in dict with lowercase_ - Args: - data (dict): Dictionary with keys that have upper cases in them - Example.. FooBar == foo_bar - if a val is of type datetime.datetime, it will be converted to - the ISO 8601 - - Basic Usage: - >>> test = {'FooBar': []} - >>> test = convert_to_lower(test) - { - 'foo_bar': [] - } - - Returns: - Dictionary - """ - results = dict() - if isinstance(data, dict): - for key, val in data.items(): - key = re.sub(r'(([A-Z]{1,3}){1})', r'_\1', key).lower() - if key[0] == '_': - key = key[1:] - if isinstance(val, datetime.datetime): - results[key] = val.isoformat() - elif isinstance(val, dict): - results[key] = convert_to_lower(val) - elif isinstance(val, list): - converted = list() - for item in val: - converted.append(convert_to_lower(item)) - results[key] = converted - else: - results[key] = val - return results - - -def make_tags_in_proper_format(tags): - """Take a dictionary of tags and convert them into the AWS Tags format. - Args: - tags (list): The tags you want applied. - - Basic Usage: - >>> tags = [{'Key': 'env', 'Value': 'development'}] - >>> make_tags_in_proper_format(tags) - { - "env": "development", - } - - Returns: - Dict - """ - formatted_tags = dict() - for tag in tags: - formatted_tags[tag.get('Key')] = tag.get('Value') - - return formatted_tags - - -def make_tags_in_aws_format(tags): - """Take a dictionary of tags and convert them into the AWS Tags format. - Args: - tags (dict): The tags you want applied. - - Basic Usage: - >>> tags = {'env': 'development', 'service': 'web'} - >>> make_tags_in_proper_format(tags) - [ - { - "Value": "web", - "Key": "service" - }, - { - "Value": "development", - "key": "env" - } - ] - - Returns: - List - """ - formatted_tags = list() - for key, val in tags.items(): - formatted_tags.append({ - 'Key': key, - 'Value': val - }) - - return formatted_tags - - -def get_tags(client, stream_name, check_mode=False): +def get_tags(client, stream_name): """Retrieve the tags for a Kinesis Stream. Args: client (botocore.client.EC2): Boto3 client. stream_name (str): Name of the Kinesis stream. - Kwargs: - check_mode (bool): This will pass DryRun as one of the parameters to the aws api. - default=False - Basic Usage: >>> client = boto3.client('kinesis') >>> stream_name = 'test-stream' @@ -313,34 +222,22 @@ def get_tags(client, stream_name, check_mode=False): } results = dict() try: - if not check_mode: - results = ( - client.list_tags_for_stream(**params)['Tags'] - ) - else: - results = [ - { - 'Key': 'DryRunMode', - 'Value': 'true' - }, - ] + results = ( + client.list_tags_for_stream(**params)['Tags'] + ) success = True except botocore.exceptions.ClientError as e: err_msg = to_native(e) - return success, err_msg, results + return success, err_msg, boto3_tag_list_to_ansible_dict(results) -def find_stream(client, stream_name, check_mode=False): +def find_stream(client, stream_name): """Retrieve a Kinesis Stream. Args: client (botocore.client.EC2): Boto3 client. stream_name (str): Name of the Kinesis stream. - Kwargs: - check_mode (bool): This will pass DryRun as one of the parameters to the aws api. - default=False - Basic Usage: >>> client = boto3.client('kinesis') >>> stream_name = 'test-stream' @@ -357,32 +254,19 @@ def find_stream(client, stream_name, check_mode=False): has_more_shards = True shards = list() try: - if not check_mode: - while has_more_shards: - results = ( - client.describe_stream(**params)['StreamDescription'] - ) - shards.extend(results.pop('Shards')) - has_more_shards = results['HasMoreShards'] - if has_more_shards: - params['ExclusiveStartShardId'] = shards[-1]['ShardId'] - results['Shards'] = shards - num_closed_shards = len([s for s in shards if 'EndingSequenceNumber' in s['SequenceNumberRange']]) - results['OpenShardsCount'] = len(shards) - num_closed_shards - results['ClosedShardsCount'] = num_closed_shards - results['ShardsCount'] = len(shards) - else: - results = { - 'OpenShardsCount': 5, - 'ClosedShardsCount': 0, - 'ShardsCount': 5, - 'HasMoreShards': True, - 'RetentionPeriodHours': 24, - 'StreamName': stream_name, - 'StreamARN': 'arn:aws:kinesis:east-side:123456789:stream/{0}'.format(stream_name), - 'StreamStatus': 'ACTIVE', - 'EncryptionType': 'NONE' - } + while has_more_shards: + results = ( + client.describe_stream(**params)['StreamDescription'] + ) + shards.extend(results.pop('Shards')) + has_more_shards = results['HasMoreShards'] + if has_more_shards: + params['ExclusiveStartShardId'] = shards[-1]['ShardId'] + results['Shards'] = shards + num_closed_shards = len([s for s in shards if 'EndingSequenceNumber' in s['SequenceNumberRange']]) + results['OpenShardsCount'] = len(shards) - num_closed_shards + results['ClosedShardsCount'] = num_closed_shards + results['ShardsCount'] = len(shards) success = True except botocore.exceptions.ClientError as e: err_msg = to_native(e) @@ -421,7 +305,7 @@ def wait_for_status(client, stream_name, status, wait_timeout=300, while wait_timeout > time.time(): try: find_success, find_msg, stream = ( - find_stream(client, stream_name, check_mode=check_mode) + find_stream(client, stream_name) ) if check_mode: status_achieved = True @@ -486,7 +370,7 @@ def tags_action(client, stream_name, tags, action='create', check_mode=False): client.add_tags_to_stream(**params) success = True elif action == 'delete': - params['TagKeys'] = list(tags) + params['TagKeys'] = tags client.remove_tags_from_stream(**params) success = True else: @@ -505,38 +389,6 @@ def tags_action(client, stream_name, tags, action='create', check_mode=False): return success, err_msg -def recreate_tags_from_list(list_of_tags): - """Recreate tags from a list of tuples into the Amazon Tag format. - Args: - list_of_tags (list): List of tuples. - - Basic Usage: - >>> list_of_tags = [('Env', 'Development')] - >>> recreate_tags_from_list(list_of_tags) - [ - { - "Value": "Development", - "Key": "Env" - } - ] - - Returns: - List - """ - tags = list() - i = 0 - for i in range(len(list_of_tags)): - key_name = list_of_tags[i][0] - key_val = list_of_tags[i][1] - tags.append( - { - 'Key': key_name, - 'Value': key_val - } - ) - return tags - - def update_tags(client, stream_name, tags, check_mode=False): """Update tags for an amazon resource. Args: @@ -561,52 +413,28 @@ def update_tags(client, stream_name, tags, check_mode=False): changed = False err_msg = '' tag_success, tag_msg, current_tags = ( - get_tags(client, stream_name, check_mode=check_mode) + get_tags(client, stream_name) ) - if current_tags: - tags = make_tags_in_aws_format(tags) - current_tags_set = ( - set( - reduce( - lambda x, y: x + y, - [make_tags_in_proper_format(current_tags).items()] - ) - ) - ) - new_tags_set = ( - set( - reduce( - lambda x, y: x + y, - [make_tags_in_proper_format(tags).items()] - ) + tags_to_set, tags_to_delete = compare_aws_tags( + current_tags, tags, + purge_tags=True, + ) + if tags_to_delete: + delete_success, delete_msg = ( + tags_action( + client, stream_name, tags_to_delete, action='delete', + check_mode=check_mode ) ) - tags_to_delete = list(current_tags_set.difference(new_tags_set)) - tags_to_update = list(new_tags_set.difference(current_tags_set)) - if tags_to_delete: - tags_to_delete = make_tags_in_proper_format( - recreate_tags_from_list(tags_to_delete) - ) - delete_success, delete_msg = ( - tags_action( - client, stream_name, tags_to_delete, action='delete', - check_mode=check_mode - ) - ) - if not delete_success: - return delete_success, changed, delete_msg - if tags_to_update: - tags = make_tags_in_proper_format( - recreate_tags_from_list(tags_to_update) - ) - else: - return True, changed, 'Tags do not need to be updated' + if not delete_success: + return delete_success, changed, delete_msg + tag_msg = 'Tags removed' - if tags: + if tags_to_set: create_success, create_msg = ( tags_action( - client, stream_name, tags, action='create', + client, stream_name, tags_to_set, action='create', check_mode=check_mode ) ) @@ -926,7 +754,7 @@ def update(client, current_stream, stream_name, number_of_shards=1, retention_pe return wait_success, False, wait_msg elif changed and not wait: stream_found, stream_msg, current_stream = ( - find_stream(client, stream_name, check_mode=check_mode) + find_stream(client, stream_name) ) if stream_found: if current_stream['StreamStatus'] != 'ACTIVE': @@ -963,7 +791,7 @@ def update(client, current_stream, stream_name, number_of_shards=1, retention_pe return wait_success, changed, wait_msg else: stream_found, stream_msg, current_stream = ( - find_stream(client, stream_name, check_mode=check_mode) + find_stream(client, stream_name) ) if stream_found and current_stream['StreamStatus'] != 'ACTIVE': err_msg = ( @@ -976,6 +804,7 @@ def update(client, current_stream, stream_name, number_of_shards=1, retention_pe tag_success, tag_changed, err_msg = ( update_tags(client, stream_name, tags, check_mode=check_mode) ) + changed |= tag_changed if wait: success, err_msg, status_stream = ( wait_for_status( @@ -1028,7 +857,7 @@ def create_stream(client, stream_name, number_of_shards=1, retention_period=None results = dict() stream_found, stream_msg, current_stream = ( - find_stream(client, stream_name, check_mode=check_mode) + find_stream(client, stream_name) ) if stream_found and current_stream.get('StreamStatus') == 'DELETING' and wait: @@ -1089,7 +918,7 @@ def create_stream(client, stream_name, number_of_shards=1, retention_period=None return success, changed, err_msg, results stream_found, stream_msg, current_stream = ( - find_stream(client, stream_name, check_mode=check_mode) + find_stream(client, stream_name) ) if retention_period and current_stream.get('StreamStatus') == 'ACTIVE': changed, err_msg = ( @@ -1112,19 +941,19 @@ def create_stream(client, stream_name, number_of_shards=1, retention_period=None if success: stream_found, stream_msg, results = ( - find_stream(client, stream_name, check_mode=check_mode) + find_stream(client, stream_name) ) tag_success, tag_msg, current_tags = ( - get_tags(client, stream_name, check_mode=check_mode) + get_tags(client, stream_name) ) - if current_tags and not check_mode: - current_tags = make_tags_in_proper_format(current_tags) - results['Tags'] = current_tags - elif check_mode and tags: - results['Tags'] = tags - else: - results['Tags'] = dict() - results = convert_to_lower(results) + if check_mode: + current_tags = tags + + if not current_tags: + current_tags = dict() + + results = camel_dict_to_snake_dict(results) + results['tags'] = current_tags return success, changed, err_msg, results @@ -1157,7 +986,7 @@ def delete_stream(client, stream_name, wait=False, wait_timeout=300, err_msg = '' results = dict() stream_found, stream_msg, current_stream = ( - find_stream(client, stream_name, check_mode=check_mode) + find_stream(client, stream_name) ) if stream_found: success, err_msg = ( @@ -1226,35 +1055,53 @@ def start_stream_encryption(client, stream_name, encryption_type='', key_id='', results = dict() stream_found, stream_msg, current_stream = ( - find_stream(client, stream_name, check_mode=check_mode) + find_stream(client, stream_name) ) if stream_found: - success, err_msg = ( - stream_encryption_action( - client, stream_name, action='start_encryption', encryption_type=encryption_type, key_id=key_id, check_mode=check_mode + if (current_stream.get("EncryptionType") == encryption_type and current_stream.get("KeyId") == key_id): + changed = False + success = True + err_msg = 'Kinesis Stream {0} encryption already configured.'.format(stream_name) + else: + success, err_msg = ( + stream_encryption_action( + client, stream_name, action='start_encryption', encryption_type=encryption_type, key_id=key_id, check_mode=check_mode + ) ) - ) - if success: - changed = True - if wait: - success, err_msg, results = ( - wait_for_status( - client, stream_name, 'ACTIVE', wait_timeout, - check_mode=check_mode + if success: + changed = True + if wait: + success, err_msg, results = ( + wait_for_status( + client, stream_name, 'ACTIVE', wait_timeout, + check_mode=check_mode + ) + ) + err_msg = 'Kinesis Stream {0} encryption started successfully.'.format(stream_name) + if not success: + return success, True, err_msg, results + else: + err_msg = ( + 'Kinesis Stream {0} is in the process of starting encryption.'.format(stream_name) ) - ) - err_msg = 'Kinesis Stream {0} encryption started successfully.'.format(stream_name) - if not success: - return success, True, err_msg, results - else: - err_msg = ( - 'Kinesis Stream {0} is in the process of starting encryption.'.format(stream_name) - ) else: success = True changed = False err_msg = 'Kinesis Stream {0} does not exist'.format(stream_name) + if success: + stream_found, stream_msg, results = ( + find_stream(client, stream_name) + ) + tag_success, tag_msg, current_tags = ( + get_tags(client, stream_name) + ) + if not current_tags: + current_tags = dict() + + results = camel_dict_to_snake_dict(results) + results['tags'] = current_tags + return success, changed, err_msg, results @@ -1278,7 +1125,7 @@ def stop_stream_encryption(client, stream_name, encryption_type='', key_id='', Basic Usage: >>> client = boto3.client('kinesis') >>> stream_name = 'test-stream' - >>> start_stream_encryption(client, stream_name,encryption_type, key_id) + >>> stop_stream_encryption(client, stream_name,encryption_type, key_id) Returns: Tuple (bool, bool, str, dict) @@ -1292,7 +1139,7 @@ def stop_stream_encryption(client, stream_name, encryption_type='', key_id='', results = dict() stream_found, stream_msg, current_stream = ( - find_stream(client, stream_name, check_mode=check_mode) + find_stream(client, stream_name) ) if stream_found: if current_stream.get('EncryptionType') == 'KMS': @@ -1301,11 +1148,7 @@ def stop_stream_encryption(client, stream_name, encryption_type='', key_id='', client, stream_name, action='stop_encryption', key_id=key_id, encryption_type=encryption_type, check_mode=check_mode ) ) - elif current_stream.get('EncryptionType') == 'NONE': - success = True - - if success: - changed = True + changed = success if wait: success, err_msg, results = ( wait_for_status( @@ -1313,18 +1156,34 @@ def stop_stream_encryption(client, stream_name, encryption_type='', key_id='', check_mode=check_mode ) ) - err_msg = 'Kinesis Stream {0} encryption stopped successfully.'.format(stream_name) if not success: return success, True, err_msg, results + err_msg = 'Kinesis Stream {0} encryption stopped successfully.'.format(stream_name) else: err_msg = ( 'Stream {0} is in the process of stopping encryption.'.format(stream_name) ) + elif current_stream.get('EncryptionType') == 'NONE': + success = True + err_msg = 'Kinesis Stream {0} encryption already stopped.'.format(stream_name) else: success = True changed = False err_msg = 'Stream {0} does not exist.'.format(stream_name) + if success: + stream_found, stream_msg, results = ( + find_stream(client, stream_name) + ) + tag_success, tag_msg, current_tags = ( + get_tags(client, stream_name) + ) + if not current_tags: + current_tags = dict() + + results = camel_dict_to_snake_dict(results) + results['tags'] = current_tags + return success, changed, err_msg, results diff --git a/tests/integration/targets/kinesis_stream/defaults/main.yml b/tests/integration/targets/kinesis_stream/defaults/main.yml index bdaddb348e5..fd548e87e27 100644 --- a/tests/integration/targets/kinesis_stream/defaults/main.yml +++ b/tests/integration/targets/kinesis_stream/defaults/main.yml @@ -1,4 +1,5 @@ --- +run_kms_tests: True kinesis_stream_name: '{{ resource_prefix }}' kms_cmk_alias_1: '{{ resource_prefix }}-1' diff --git a/tests/integration/targets/kinesis_stream/tasks/main.yml b/tests/integration/targets/kinesis_stream/tasks/main.yml index c55d16afa8a..b6791fb06d8 100644 --- a/tests/integration/targets/kinesis_stream/tasks/main.yml +++ b/tests/integration/targets/kinesis_stream/tasks/main.yml @@ -1,17 +1,5 @@ --- # ============================================================ -# Known issues: -# -# - (CM) check_mode returns changed (always?) -# - (CM_snake) check_mode returns keys and values that don't directly -# map to those from non-check_mode -# - (Tag_snake) tag keys get snake_cased in return values -# - (Tag_changed) changing tags doesn't return changed -# - (Enc_snake) return values don't get snake_cased when updating encryption -# - (Enc_disable) disabling encryption Requires key and type be set -# - (Enc_idemp) Updating encryption settings isn't idempotent -# -# ============================================================ - name: 'Setup AWS Module Defaults' module_defaults: group/aws: @@ -114,8 +102,6 @@ that: - result is success - result is not changed - # XXX BUG (CM) - ignore_errors: yes - name: 'Create a basic Kinesis stream - Idempotency' kinesis_stream: @@ -178,8 +164,6 @@ that: - result is success - result is not changed - # XXX BUG (CM) - ignore_errors: yes - name: 'Increase the retention period - Idempotency' kinesis_stream: @@ -240,8 +224,6 @@ that: - result is success - result is not changed - # XXX BUG (CM) - ignore_errors: yes - name: 'Decrease the retention period - Idempotency' kinesis_stream: @@ -292,8 +274,6 @@ that: - result is changed - result.tags == kinesis_stream_tags_1 - # XXX BUG (CM) - ignore_errors: yes - name: 'Set some tags - Idempotency (CHECK_MODE)' check_mode: yes @@ -306,8 +286,6 @@ that: - result is success - result is not changed - # XXX BUG (CM) - ignore_errors: yes - name: 'Set some tags - Idempotency' kinesis_stream: @@ -382,8 +360,6 @@ that: - result is success - result is not changed - # XXX BUG (CM) - ignore_errors: yes - name: 'Change some tags - Idempotency' kinesis_stream: @@ -462,8 +438,6 @@ that: - result is success - result is not changed - # XXX BUG (CM) - ignore_errors: yes - name: 'Change the number of shards - Idempotency' kinesis_stream: @@ -535,6 +509,7 @@ kinesis_stream: name: '{{ kinesis_stream_name }}' encryption_state: 'disabled' + register: result - name: 'Assert state is not changed when encryption_state not changed (CHECK_MODE)' ignore_errors: yes assert: @@ -547,13 +522,12 @@ kinesis_stream: name: '{{ kinesis_stream_name }}' encryption_state: 'disabled' + register: result - name: 'Assert state is not changed when encryption_state not changed (CHECK_MODE)' assert: that: - result is success - result is not changed - # XXX BUG (Enc_idemp) - ignore_errors: yes # Merge this into the main assertion when the main return keys are # snake_cased - name: 'Assert expected return values' @@ -583,6 +557,7 @@ encryption_state: 'enabled' encryption_type: 'KMS' key_id: '{{ kms_cmk_id_1 }}' + register: result - name: 'Assert that state is changed when enabling encryption' assert: that: @@ -596,6 +571,7 @@ encryption_state: 'enabled' encryption_type: 'KMS' key_id: '{{ kms_cmk_id_2 }}' + register: result - name: 'Assert state is changed when stream encryption key is changed (CHECK_MODE)' assert: that: @@ -608,6 +584,7 @@ encryption_state: 'enabled' encryption_type: 'KMS' key_id: '{{ kms_cmk_id_2 }}' + register: result - name: 'Assert state is changed when stream encryption key is changed' assert: that: @@ -676,8 +653,6 @@ that: - result is success - result is not changed - # XXX BUG (CM) - ignore_errors: yes - name: 'Delete stream - Idempotency' module_defaults: { kinesis_stream: {} } diff --git a/tests/integration/targets/kinesis_stream/tasks/test_encryption.yml b/tests/integration/targets/kinesis_stream/tasks/test_encryption.yml index 1ce2436930c..23555a94586 100644 --- a/tests/integration/targets/kinesis_stream/tasks/test_encryption.yml +++ b/tests/integration/targets/kinesis_stream/tasks/test_encryption.yml @@ -11,6 +11,9 @@ # Disable (check_mode) # Disable # +# Known issue: +# - key_id needs to be in the same form as is already set to return changed=False +# - name: 'Enable encryption using {{ key_type }} (CHECK_MODE)' check_mode: yes kinesis_stream: @@ -18,6 +21,7 @@ encryption_state: 'enabled' encryption_type: 'KMS' key_id: '{{ kinesis_key }}' + register: result - name: 'Assert state is changed when enabling encryption (CHECK_MODE)' assert: that: @@ -30,16 +34,34 @@ encryption_state: 'enabled' encryption_type: 'KMS' key_id: '{{ kinesis_key }}' + register: result - name: 'Assert that state is changed when enabling encryption' assert: that: - result is success - result is changed -# Merge this into the main assertion when the main return keys are -# snake_cased -- name: 'Assert expected return values' + - result.encryption_type == 'KMS' + - result.key_id in kms_cmk_1 + - result.open_shards_count == 1 + - result.retention_period_hours == 48 + - result.stream_arn == kinesis_stream_arn + - result.stream_name == kinesis_stream_name + - result.stream_status == 'ACTIVE' + - result.tags == kinesis_stream_tags_2 + +- name: 'Re-Enable encryption using {{ key_type }} (CHECK_MODE)' + kinesis_stream: + name: '{{ kinesis_stream_name }}' + encryption_state: 'enabled' + encryption_type: 'KMS' + key_id: '{{ kinesis_key }}' + check_mode: True + register: result +- name: 'Assert that state is not changed when enabling encryption' assert: that: + - result is success + - result is not changed - result.encryption_type == 'KMS' - result.key_id in kms_cmk_1 - result.open_shards_count == 1 @@ -47,17 +69,28 @@ - result.stream_arn == kinesis_stream_arn - result.stream_name == kinesis_stream_name - result.stream_status == 'ACTIVE' - #- result.tags == kinesis_stream_tags_2 - # XXX BUG (Enc_snake) - ignore_errors: yes -# Merge this into the main assertion when the tag keys are no longer -# snake_cased -- name: 'Assert tags return as expected (tags2)' + - result.tags == kinesis_stream_tags_2 + +- name: 'Re-Enable encryption using {{ key_type }}' + kinesis_stream: + name: '{{ kinesis_stream_name }}' + encryption_state: 'enabled' + encryption_type: 'KMS' + key_id: '{{ kinesis_key }}' + register: result +- name: 'Assert that state is not changed when enabling encryption' assert: that: + - result is success + - result is not changed + - result.encryption_type == 'KMS' + - result.key_id in kms_cmk_1 + - result.open_shards_count == 1 + - result.retention_period_hours == 48 + - result.stream_arn == kinesis_stream_arn + - result.stream_name == kinesis_stream_name + - result.stream_status == 'ACTIVE' - result.tags == kinesis_stream_tags_2 - # XXX BUG (Tag_snake) - ignore_errors: yes - name: 'Test encryption idempotency comparing {{ key_type }} and ID (CHECK_MODE)' check_mode: yes @@ -66,12 +99,12 @@ encryption_state: 'enabled' encryption_type: 'KMS' key_id: '{{ kinesis_key_id }}' -- name: 'Assert state is changed when enabling encryption (CHECK_MODE)' + register: result +- name: 'Assert state is not changed when comparing {{ key_id }} and ID (CHECK_MODE)' assert: that: - result is success - result is not changed - # XXX BUG (Enc_Idemp) ignore_errors: yes - name: 'Test encryption idempotency comparing {{ key_type }} and ID' @@ -80,18 +113,16 @@ encryption_state: 'enabled' encryption_type: 'KMS' key_id: '{{ kinesis_key_id }}' -- name: 'Assert that state is changed when enabling encryption' + register: result +- name: 'Assert that state is not changed when comparing {{ key_type }} and ID' assert: that: - - result is success - result is not changed - # XXX BUG (Enc_Idemp) ignore_errors: yes -# Merge this into the main assertion when the main return keys are -# snake_cased - name: 'Assert expected return values' assert: that: + - result is success - result.encryption_type == 'KMS' - result.key_id in kms_cmk_1 - result.open_shards_count == 1 @@ -99,17 +130,7 @@ - result.stream_arn == kinesis_stream_arn - result.stream_name == kinesis_stream_name - result.stream_status == 'ACTIVE' - #- result.tags == kinesis_stream_tags_2 - # XXX BUG (Enc_snake) - ignore_errors: yes -# Merge this into the main assertion when the tag keys are no longer -# snake_cased -- name: 'Assert tags return as expected (tags2)' - assert: - that: - result.tags == kinesis_stream_tags_2 - # XXX BUG (Tag_snake) - ignore_errors: yes - name: 'Test encryption idempotency comparing {{ key_type }} and Alias (CHECK_MODE)' @@ -119,12 +140,12 @@ encryption_state: 'enabled' encryption_type: 'KMS' key_id: '{{ kinesis_key_alias }}' -- name: 'Assert state is changed when enabling encryption (CHECK_MODE)' + register: result +- name: 'Assert state is not changed when comparing {{ key_type }} and Alias (CHECK_MODE)' assert: that: - result is success - result is not changed - # XXX BUG (Enc_Idemp) ignore_errors: yes - name: 'Test encryption idempotency comparing {{ key_type }} and Alias' @@ -133,18 +154,16 @@ encryption_state: 'enabled' encryption_type: 'KMS' key_id: '{{ kinesis_key_alias }}' -- name: 'Assert that state is changed when enabling encryption' + register: result +- name: 'Assert that state is not changed when comparing {{ key_type }} and Alias' assert: that: - - result is success - result is not changed - # XXX BUG (Enc_Idemp) ignore_errors: yes -# Merge this into the main assertion when the main return keys are -# snake_cased - name: 'Assert expected return values' assert: that: + - result is success - result.encryption_type == 'KMS' - result.key_id in kms_cmk_1 - result.open_shards_count == 1 @@ -152,17 +171,7 @@ - result.stream_arn == kinesis_stream_arn - result.stream_name == kinesis_stream_name - result.stream_status == 'ACTIVE' - #- result.tags == kinesis_stream_tags_2 - # XXX BUG (Enc_snake) - ignore_errors: yes -# Merge this into the main assertion when the tag keys are no longer -# snake_cased -- name: 'Assert tags return as expected (tags2)' - assert: - that: - result.tags == kinesis_stream_tags_2 - # XXX BUG (Tag_snake) - ignore_errors: yes - name: 'Test encryption idempotency comparing {{ key_type }} and ARN (CHECK_MODE)' check_mode: yes @@ -171,12 +180,12 @@ encryption_state: 'enabled' encryption_type: 'KMS' key_id: '{{ kinesis_key_arn }}' -- name: 'Assert state is changed when enabling encryption (CHECK_MODE)' + register: result +- name: 'Assert state is not changed when comparing {{ key_type }} and ARN (CHECK_MODE)' assert: that: - result is success - result is not changed - # XXX BUG (Enc_Idemp) ignore_errors: yes - name: 'Test encryption idempotency comparing {{ key_type }} and ARN' @@ -185,18 +194,16 @@ encryption_state: 'enabled' encryption_type: 'KMS' key_id: '{{ kinesis_key_arn }}' -- name: 'Assert that state is changed when enabling encryption' + register: result +- name: 'Assert that state is not changed when comparing {{ key_type }} and ARN' assert: that: - - result is success - result is not changed - # XXX BUG (Enc_Idemp) ignore_errors: yes -# Merge this into the main assertion when the main return keys are -# snake_cased - name: 'Assert expected return values' assert: that: + - result is success - result.encryption_type == 'KMS' - result.key_id in kms_cmk_1 - result.open_shards_count == 1 @@ -204,29 +211,18 @@ - result.stream_arn == kinesis_stream_arn - result.stream_name == kinesis_stream_name - result.stream_status == 'ACTIVE' - #- result.tags == kinesis_stream_tags_2 - # XXX BUG (Enc_snake) - ignore_errors: yes -# Merge this into the main assertion when the tag keys are no longer -# snake_cased -- name: 'Assert tags return as expected (tags2)' - assert: - that: - result.tags == kinesis_stream_tags_2 - # XXX BUG (Tag_snake) - ignore_errors: yes - name: 'Disable encryption (CHECK_MODE)' kinesis_stream: name: '{{ kinesis_stream_name }}' encryption_state: 'disabled' - # XXX BUG (Enc_Disable) encryption_type: 'KMS' # XXX Oddity of Kinesis - This needs to match the existing setting key_id: '{{ kinesis_key_arn }}' + register: result + check_mode: yes - name: 'Assert state is changed when disabling encryption (CHECK_MODE)' - # XXX BUG (CM) - ignore_errors: yes assert: that: - result is success @@ -236,11 +232,11 @@ kinesis_stream: name: '{{ kinesis_stream_name }}' encryption_state: 'disabled' - # XXX BUG (Enc_Disable) encryption_type: 'KMS' # XXX Oddity of Kinesis - This needs to match the existing setting key_id: '{{ kinesis_key_arn }}' -- name: 'Assert state is not changed when disabling encryption (CHECK_MODE)' + register: result +- name: 'Assert state is changed when disabling encryption' assert: that: - result is success @@ -251,12 +247,4 @@ - result.stream_arn == kinesis_stream_arn - result.stream_name == kinesis_stream_name - result.stream_status == 'ACTIVE' - #- result.tags == kinesis_stream_tags_2 -# Merge this into the main assertion when the tag keys are no longer -# snake_cased -- name: 'Assert tags return as expected (tags2)' - assert: - that: - result.tags == kinesis_stream_tags_2 - # XXX BUG (Tag_snake) - ignore_errors: yes