From 559652a1ebc7b45eb78a9ef28b0d9a55921f3933 Mon Sep 17 00:00:00 2001 From: Berend de Boer Date: Mon, 5 Apr 2021 10:42:20 +1200 Subject: [PATCH 1/6] Add support to specify the number of days to transition to inactive storage --- plugins/modules/efs.py | 49 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/plugins/modules/efs.py b/plugins/modules/efs.py index 0cf4f88c1d7..b83d5797042 100644 --- a/plugins/modules/efs.py +++ b/plugins/modules/efs.py @@ -96,6 +96,12 @@ - How long the module should wait (in seconds) for desired state before returning. Zero means wait as long as necessary. default: 0 type: int + transition_to_ia: + description: + - How many days before objects transition to the lower-cost EFS Infrequent Access (IA) storage class. If set to None, any existing lifecyle policy will be removed, and objects will not transition to an IA storage class. If this parameter is absent or left empty, any existing lifecycle policy will not be affected. + default: not set + choices: ['None', '7', '14', '30', '60', '90'] + extends_documentation_fragment: - amazon.aws.aws @@ -125,6 +131,24 @@ - subnet_id: subnet-7654fdca security_groups: [ "sg-4c5d6f7a" ] +- name: Set a lifecycle policy + community.aws.efs: + state: present + name: myTestEFS + transition_to_ia: 7 + targets: + - subnet_id: subnet-7654fdca + security_groups: [ "sg-4c5d6f7a" ] + +- name: Remove a lifecycle policy + community.aws.efs: + state: present + name: myTestEFS + transition_to_ia: None + targets: + - subnet_id: subnet-7654fdca + security_groups: [ "sg-4c5d6f7a" ] + - name: Deleting EFS community.aws.efs: state: absent @@ -459,6 +483,27 @@ def update_file_system(self, name, throughput_mode, provisioned_throughput_in_mi self.module.fail_json_aws(e, msg="Unable to update file system.") return changed + def update_lifecycle_policy(self, name, transition_to_ia): + """ + Update filesystem with new lifecycle policy. + """ + changed = False + state = self.get_file_system_state(name) + if state in [self.STATE_AVAILABLE, self.STATE_CREATING]: + fs_id = self.get_file_system_id(name) + current_policies = self.connection.describe_lifecycle_configuration(FileSystemId=fs_id) + if transition_to_ia == 'None': + LifecyclePolicies = [] + else: + LifecyclePolicies = [{ 'TransitionToIA': 'AFTER_' + transition_to_ia + '_DAYS' }] + if current_policies.get('LifecyclePolicies') != LifecyclePolicies: + response = self.connection.put_lifecycle_configuration( + FileSystemId=fs_id, + LifecyclePolicies = LifecyclePolicies + ) + changed = True + return changed + def converge_file_system(self, name, tags, purge_tags, targets, throughput_mode, provisioned_throughput_in_mibps): """ Change attributes (mount targets and tags) of filesystem by name @@ -680,6 +725,7 @@ def main(): tags=dict(required=False, type="dict", default={}), targets=dict(required=False, type="list", default=[], elements='dict'), performance_mode=dict(required=False, type='str', choices=["general_purpose", "max_io"], default="general_purpose"), + transition_to_ia=dict(required=False, choices=["", "None", "7", "14", "30", "60", "90"], default=None), throughput_mode=dict(required=False, type='str', choices=["bursting", "provisioned"], default=None), provisioned_throughput_in_mibps=dict(required=False, type='float'), wait=dict(required=False, type="bool", default=False), @@ -707,6 +753,7 @@ def main(): kms_key_id = module.params.get('kms_key_id') performance_mode = performance_mode_translations[module.params.get('performance_mode')] purge_tags = module.params.get('purge_tags') + transition_to_ia = module.params.get('transition_to_ia') throughput_mode = module.params.get('throughput_mode') provisioned_throughput_in_mibps = module.params.get('provisioned_throughput_in_mibps') state = str(module.params.get('state')).lower() @@ -720,6 +767,8 @@ def main(): changed = connection.update_file_system(name, throughput_mode, provisioned_throughput_in_mibps) or changed changed = connection.converge_file_system(name=name, tags=tags, purge_tags=purge_tags, targets=targets, throughput_mode=throughput_mode, provisioned_throughput_in_mibps=provisioned_throughput_in_mibps) or changed + if transition_to_ia: + changed = connection.update_lifecycle_policy(name, transition_to_ia) result = first_or_default(connection.get_file_systems(CreationToken=name)) elif state == 'absent': From ee1dc1eaa3fc750451bc4326a559366962bc36de Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sat, 23 Oct 2021 09:07:12 +0200 Subject: [PATCH 2/6] Sanity test fixups --- plugins/modules/efs.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/modules/efs.py b/plugins/modules/efs.py index b83d5797042..4b5908beee1 100644 --- a/plugins/modules/efs.py +++ b/plugins/modules/efs.py @@ -98,8 +98,10 @@ type: int transition_to_ia: description: - - How many days before objects transition to the lower-cost EFS Infrequent Access (IA) storage class. If set to None, any existing lifecyle policy will be removed, and objects will not transition to an IA storage class. If this parameter is absent or left empty, any existing lifecycle policy will not be affected. - default: not set + - How many days before objects transition to the lower-cost EFS Infrequent Access (IA) storage class. + - If set to the string C(None), any existing lifecyle policy will be removed, and objects will not transition + to an IA storage class. + - If this parameter is absent, any existing lifecycle policy will not be affected. choices: ['None', '7', '14', '30', '60', '90'] @@ -495,11 +497,11 @@ def update_lifecycle_policy(self, name, transition_to_ia): if transition_to_ia == 'None': LifecyclePolicies = [] else: - LifecyclePolicies = [{ 'TransitionToIA': 'AFTER_' + transition_to_ia + '_DAYS' }] + LifecyclePolicies = [{'TransitionToIA': 'AFTER_' + transition_to_ia + '_DAYS'}] if current_policies.get('LifecyclePolicies') != LifecyclePolicies: response = self.connection.put_lifecycle_configuration( FileSystemId=fs_id, - LifecyclePolicies = LifecyclePolicies + LifecyclePolicies=LifecyclePolicies, ) changed = True return changed From 5c478c0126f02d420f32db6b435ffa87c098de4c Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sat, 23 Oct 2021 09:08:19 +0200 Subject: [PATCH 3/6] Avoid update_lifecycle_policy potentially overriding changed=True back to changed=False --- plugins/modules/efs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/efs.py b/plugins/modules/efs.py index 4b5908beee1..c653063a8ab 100644 --- a/plugins/modules/efs.py +++ b/plugins/modules/efs.py @@ -770,7 +770,7 @@ def main(): changed = connection.converge_file_system(name=name, tags=tags, purge_tags=purge_tags, targets=targets, throughput_mode=throughput_mode, provisioned_throughput_in_mibps=provisioned_throughput_in_mibps) or changed if transition_to_ia: - changed = connection.update_lifecycle_policy(name, transition_to_ia) + changed |= connection.update_lifecycle_policy(name, transition_to_ia) result = first_or_default(connection.get_file_systems(CreationToken=name)) elif state == 'absent': From e5a9807c00364b9faa1c9ae2136688c4c075235f Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sat, 23 Oct 2021 09:56:38 +0200 Subject: [PATCH 4/6] changelog / version_added --- changelogs/fragments/522-efs-IA-transition.yml | 2 ++ plugins/modules/efs.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/522-efs-IA-transition.yml diff --git a/changelogs/fragments/522-efs-IA-transition.yml b/changelogs/fragments/522-efs-IA-transition.yml new file mode 100644 index 00000000000..aebba2e4499 --- /dev/null +++ b/changelogs/fragments/522-efs-IA-transition.yml @@ -0,0 +1,2 @@ +minor_changes: +- efs - add ``transition_to_ia`` parameter to support specifying the number of days before transitioning data to inactive storage (https://github.com/ansible-collections/community.aws/pull/522). diff --git a/plugins/modules/efs.py b/plugins/modules/efs.py index c653063a8ab..3086ec47beb 100644 --- a/plugins/modules/efs.py +++ b/plugins/modules/efs.py @@ -103,7 +103,7 @@ to an IA storage class. - If this parameter is absent, any existing lifecycle policy will not be affected. choices: ['None', '7', '14', '30', '60', '90'] - + version_added: 2.1.0 extends_documentation_fragment: - amazon.aws.aws From 314c3282c00a19b964e8fd1f78e4ec14c4f913be Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sun, 24 Oct 2021 12:43:25 +0200 Subject: [PATCH 5/6] integration test --- tests/integration/targets/efs/tasks/main.yml | 70 ++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/tests/integration/targets/efs/tasks/main.yml b/tests/integration/targets/efs/tasks/main.yml index dc8e064dbb2..d2e9d4bee97 100644 --- a/tests/integration/targets/efs/tasks/main.yml +++ b/tests/integration/targets/efs/tasks/main.yml @@ -233,6 +233,76 @@ - assert: that: "{{efs_result_assertions}}" + # ============================================================ + - name: Efs configure IA transition + efs: + state: present + name: "{{ efs_name }}-test-efs" + tags: + Name: "{{ efs_name }}-test-tag" + Purpose: file-storage + targets: + - subnet_id: "{{testing_subnet_a.subnet.id}}" + - subnet_id: "{{testing_subnet_b.subnet.id}}" + transition_to_ia: 60 + register: efs_result + + - assert: + that: + - efs_result is changed + + - name: Efs configure IA transition - idempotency + efs: + state: present + name: "{{ efs_name }}-test-efs" + tags: + Name: "{{ efs_name }}-test-tag" + Purpose: file-storage + targets: + - subnet_id: "{{testing_subnet_a.subnet.id}}" + - subnet_id: "{{testing_subnet_b.subnet.id}}" + transition_to_ia: 60 + register: efs_result + + - assert: + that: + - efs_result is not changed + + # ============================================================ + - name: Efs remove IA transition + efs: + state: present + name: "{{ efs_name }}-test-efs" + tags: + Name: "{{ efs_name }}-test-tag" + Purpose: file-storage + targets: + - subnet_id: "{{testing_subnet_a.subnet.id}}" + - subnet_id: "{{testing_subnet_b.subnet.id}}" + transition_to_ia: None + register: efs_result + + - assert: + that: + - efs_result is changed + + - name: Efs remove IA transition - idempotency + efs: + state: present + name: "{{ efs_name }}-test-efs" + tags: + Name: "{{ efs_name }}-test-tag" + Purpose: file-storage + targets: + - subnet_id: "{{testing_subnet_a.subnet.id}}" + - subnet_id: "{{testing_subnet_b.subnet.id}}" + transition_to_ia: None + register: efs_result + + - assert: + that: + - efs_result is not changed + # ============================================================ - name: Query unknown EFS by tag efs_info: From b061ee67038e795b392045c067aabb0c6e7a47cb Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Wed, 27 Oct 2021 06:50:44 +0200 Subject: [PATCH 6/6] match args_spec/doc --- plugins/modules/efs.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/modules/efs.py b/plugins/modules/efs.py index 3086ec47beb..a67c83be3c7 100644 --- a/plugins/modules/efs.py +++ b/plugins/modules/efs.py @@ -103,6 +103,7 @@ to an IA storage class. - If this parameter is absent, any existing lifecycle policy will not be affected. choices: ['None', '7', '14', '30', '60', '90'] + type: str version_added: 2.1.0 extends_documentation_fragment: @@ -727,7 +728,7 @@ def main(): tags=dict(required=False, type="dict", default={}), targets=dict(required=False, type="list", default=[], elements='dict'), performance_mode=dict(required=False, type='str', choices=["general_purpose", "max_io"], default="general_purpose"), - transition_to_ia=dict(required=False, choices=["", "None", "7", "14", "30", "60", "90"], default=None), + transition_to_ia=dict(required=False, type='str', choices=["None", "7", "14", "30", "60", "90"], default=None), throughput_mode=dict(required=False, type='str', choices=["bursting", "provisioned"], default=None), provisioned_throughput_in_mibps=dict(required=False, type='float'), wait=dict(required=False, type="bool", default=False),