From 5afda6cad69e453bb9aa70b6485ecd59eaecf57d Mon Sep 17 00:00:00 2001 From: Sean Cavanaugh Date: Tue, 12 Jan 2021 15:34:14 -0500 Subject: [PATCH 1/4] syncing module and tests for uptime with tons of help from Yanis, we now have uptime in there --- plugins/modules/ec2_instance_info.py | 39 +++++++++++- .../roles/ec2_instance/tasks/uptime.yml | 61 +++++++++++++++++++ 2 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 tests/integration/targets/ec2_instance/roles/ec2_instance/tasks/uptime.yml diff --git a/plugins/modules/ec2_instance_info.py b/plugins/modules/ec2_instance_info.py index 1c4c1f0df33..309a02aa7a5 100644 --- a/plugins/modules/ec2_instance_info.py +++ b/plugins/modules/ec2_instance_info.py @@ -33,6 +33,11 @@ required: false default: {} type: dict + uptime: + description: + - minimum running uptime in minutes of instances. For example if uptime is 60, it would return all instances that have run more than 60 minutes. + required: false + type: int extends_documentation_fragment: - amazon.aws.aws @@ -66,6 +71,15 @@ filters: instance-state-name: [ "shutting-down", "stopping", "stopped" ] +- name: Gather information about any instance with Name beginning with RHEL and been running at least 60 minutes + community.aws.ec2_instance_info: + region: "{{ ec2_region }}" + uptime: 60 + filters: + "tag:Name": "RHEL-*" + instance-state-name: [ "running"] + register: ec2_node_info + ''' RETURN = r''' @@ -492,6 +506,8 @@ ''' import traceback +import datetime + try: import boto3 @@ -509,18 +525,34 @@ def list_ec2_instances(connection, module): instance_ids = module.params.get("instance_ids") + uptime = module.params.get('uptime') filters = ansible_dict_to_boto3_filter_list(module.params.get("filters")) + # Determine oldest launch_time + if uptime is None: + oldest_launch_time = datetime.datetime.utcnow() + datetime.timedelta(days=30 * 365) + else: + oldest_launch_time = datetime.datetime.utcnow() - datetime.timedelta(minutes=int(uptime)) + try: reservations_paginator = connection.get_paginator('describe_instances') reservations = reservations_paginator.paginate(InstanceIds=instance_ids, Filters=filters).build_full_result() except ClientError as e: module.fail_json_aws(e, msg="Failed to list ec2 instances") - # Get instances from reservations instances = [] - for reservation in reservations['Reservations']: - instances = instances + reservation['Instances'] + + + + if uptime: + timedelta = int(uptime) if uptime else 0 + oldest_launch_time = datetime.datetime.utcnow() - datetime.timedelta(minutes=timedelta) + # Get instances from reservations + for reservation in reservations['Reservations']: + instances += [instance for instance in reservation['Instances'] if instance['LaunchTime'].replace(tzinfo=None) < oldest_launch_time] + else: + for reservation in reservations['Reservations']: + instances = instances + reservation['Instances'] # Turn the boto3 result in to ansible_friendly_snaked_names snaked_instances = [camel_dict_to_snake_dict(instance) for instance in instances] @@ -535,6 +567,7 @@ def list_ec2_instances(connection, module): def main(): argument_spec = dict( + uptime=dict(required=False, type='int', default=None), instance_ids=dict(default=[], type='list', elements='str'), filters=dict(default={}, type='dict') ) diff --git a/tests/integration/targets/ec2_instance/roles/ec2_instance/tasks/uptime.yml b/tests/integration/targets/ec2_instance/roles/ec2_instance/tasks/uptime.yml new file mode 100644 index 00000000000..9fd88dd94e4 --- /dev/null +++ b/tests/integration/targets/ec2_instance/roles/ec2_instance/tasks/uptime.yml @@ -0,0 +1,61 @@ +--- +- block: + - name: "create t3.nano instance" + ec2_instance: + name: "{{ resource_prefix }}-test-t3nano-1" + region: "{{ ec2_region }}" + image_id: "{{ ec2_ami_image }}" + tags: + TestId: "{{ ec2_instance_tag_TestId }}" + vpc_subnet_id: "{{ testing_subnet_a.subnet.id }}" + instance_type: t3.nano + wait: yes + + - name: "check ec2 instance" + ec2_instance_info: + filters: + "tag:Name": "{{ resource_prefix }}-test-t3nano-1" + instance-state-name: [ "running"] + register: instance_facts + + - name: "Confirm existence of instance id." + assert: + that: + - "{{ instance_facts.instances | length }} == 1" + + - name: "check using uptime 100 hours - should fail" + ec2_instance_info: + region: "{{ ec2_region }}" + uptime: 6000 + filters: + instance-state-name: [ "running"] + "tag:Name": "{{ resource_prefix }}-test-t3nano-1" + register: instance_facts + + - name: "Confirm there is no running instance" + assert: + that: + - "{{ instance_facts.instances | length }} == 0" + + - name: "check using uptime 1 minute" + ec2_instance_info: + region: "{{ ec2_region }}" + uptime: 1 + filters: + instance-state-name: [ "running"] + "tag:Name": "{{ resource_prefix }}-test-t3nano-1" + register: instance_facts + + - name: "Confirm there is one running instance" + assert: + that: + - "{{ instance_facts.instances | length }} == 1" + + always: + - name: "Terminate instances" + ec2_instance: + state: absent + filters: + "tag:TestId": "{{ ec2_instance_tag_TestId }}" + wait: yes + ignore_errors: yes From ebe23ca1174a7c5b212e63baabe68df900e085a5 Mon Sep 17 00:00:00 2001 From: Sean Cavanaugh Date: Wed, 13 Jan 2021 10:36:19 -0500 Subject: [PATCH 2/4] updating pr with fixes from suggestions adding to https://github.com/ansible-collections/community.aws/pull/356 with comments from @tremble and @duderamos --- plugins/modules/ec2_instance_info.py | 20 +++++++------------ .../roles/ec2_instance/tasks/uptime.yml | 15 +++++++++----- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/plugins/modules/ec2_instance_info.py b/plugins/modules/ec2_instance_info.py index 309a02aa7a5..e37f2cf9cd1 100644 --- a/plugins/modules/ec2_instance_info.py +++ b/plugins/modules/ec2_instance_info.py @@ -33,12 +33,14 @@ required: false default: {} type: dict - uptime: + minimum_uptime: description: - - minimum running uptime in minutes of instances. For example if uptime is 60, it would return all instances that have run more than 60 minutes. + - Minimum running uptime in minutes of instances. For example if I(uptime) is C(60) return all instances that have run more than 60 minutes. required: false + aliases: ['uptime'] type: int + extends_documentation_fragment: - amazon.aws.aws - amazon.aws.ec2 @@ -71,7 +73,7 @@ filters: instance-state-name: [ "shutting-down", "stopping", "stopped" ] -- name: Gather information about any instance with Name beginning with RHEL and been running at least 60 minutes +- name: Gather information about any instance with Name beginning with RHEL and an uptime of at least 60 minutes community.aws.ec2_instance_info: region: "{{ ec2_region }}" uptime: 60 @@ -525,15 +527,9 @@ def list_ec2_instances(connection, module): instance_ids = module.params.get("instance_ids") - uptime = module.params.get('uptime') + uptime = module.params.get('minimum_uptime') filters = ansible_dict_to_boto3_filter_list(module.params.get("filters")) - # Determine oldest launch_time - if uptime is None: - oldest_launch_time = datetime.datetime.utcnow() + datetime.timedelta(days=30 * 365) - else: - oldest_launch_time = datetime.datetime.utcnow() - datetime.timedelta(minutes=int(uptime)) - try: reservations_paginator = connection.get_paginator('describe_instances') reservations = reservations_paginator.paginate(InstanceIds=instance_ids, Filters=filters).build_full_result() @@ -542,8 +538,6 @@ def list_ec2_instances(connection, module): instances = [] - - if uptime: timedelta = int(uptime) if uptime else 0 oldest_launch_time = datetime.datetime.utcnow() - datetime.timedelta(minutes=timedelta) @@ -567,7 +561,7 @@ def list_ec2_instances(connection, module): def main(): argument_spec = dict( - uptime=dict(required=False, type='int', default=None), + minimum_uptime=dict(required=False, type='int', default=None, aliases=['uptime']), instance_ids=dict(default=[], type='list', elements='str'), filters=dict(default={}, type='dict') ) diff --git a/tests/integration/targets/ec2_instance/roles/ec2_instance/tasks/uptime.yml b/tests/integration/targets/ec2_instance/roles/ec2_instance/tasks/uptime.yml index 9fd88dd94e4..6f6c5fe0d49 100644 --- a/tests/integration/targets/ec2_instance/roles/ec2_instance/tasks/uptime.yml +++ b/tests/integration/targets/ec2_instance/roles/ec2_instance/tasks/uptime.yml @@ -2,7 +2,7 @@ - block: - name: "create t3.nano instance" ec2_instance: - name: "{{ resource_prefix }}-test-t3nano-1" + name: "{{ resource_prefix }}-test-uptime" region: "{{ ec2_region }}" image_id: "{{ ec2_ami_image }}" tags: @@ -14,7 +14,7 @@ - name: "check ec2 instance" ec2_instance_info: filters: - "tag:Name": "{{ resource_prefix }}-test-t3nano-1" + "tag:Name": "{{ resource_prefix }}-test-uptime" instance-state-name: [ "running"] register: instance_facts @@ -23,13 +23,13 @@ that: - "{{ instance_facts.instances | length }} == 1" - - name: "check using uptime 100 hours - should fail" + - name: "check using uptime 100 hours - should find nothing" ec2_instance_info: region: "{{ ec2_region }}" uptime: 6000 filters: instance-state-name: [ "running"] - "tag:Name": "{{ resource_prefix }}-test-t3nano-1" + "tag:Name": "{{ resource_prefix }}-test-uptime" register: instance_facts - name: "Confirm there is no running instance" @@ -37,13 +37,18 @@ that: - "{{ instance_facts.instances | length }} == 0" + - name: Sleep for 61 seconds and continue with play + wait_for: + timeout: 61 + delegate_to: localhost + - name: "check using uptime 1 minute" ec2_instance_info: region: "{{ ec2_region }}" uptime: 1 filters: instance-state-name: [ "running"] - "tag:Name": "{{ resource_prefix }}-test-t3nano-1" + "tag:Name": "{{ resource_prefix }}-test-uptime" register: instance_facts - name: "Confirm there is one running instance" From 21127efa9b9ff68c072316485b98444cff43a104 Mon Sep 17 00:00:00 2001 From: Sean Cavanaugh Date: Wed, 13 Jan 2021 11:24:29 -0500 Subject: [PATCH 3/4] Create 356_add_minimum_uptime_parameter.yaml adding changelog fragment per @gravesm suggestion --- changelogs/fragments/356_add_minimum_uptime_parameter.yaml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelogs/fragments/356_add_minimum_uptime_parameter.yaml diff --git a/changelogs/fragments/356_add_minimum_uptime_parameter.yaml b/changelogs/fragments/356_add_minimum_uptime_parameter.yaml new file mode 100644 index 00000000000..f7c72bc8d28 --- /dev/null +++ b/changelogs/fragments/356_add_minimum_uptime_parameter.yaml @@ -0,0 +1,3 @@ +--- +minor_changes: +- adding minimum_uptime and alias uptime to filter instances that have only been online for certain duration of time in minutes From eec51009f43ae236168dec11681962beee612444 Mon Sep 17 00:00:00 2001 From: Sean Cavanaugh Date: Wed, 13 Jan 2021 12:15:52 -0500 Subject: [PATCH 4/4] Update 356_add_minimum_uptime_parameter.yaml last comment from @tremble --- changelogs/fragments/356_add_minimum_uptime_parameter.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/fragments/356_add_minimum_uptime_parameter.yaml b/changelogs/fragments/356_add_minimum_uptime_parameter.yaml index f7c72bc8d28..c436c96f0ea 100644 --- a/changelogs/fragments/356_add_minimum_uptime_parameter.yaml +++ b/changelogs/fragments/356_add_minimum_uptime_parameter.yaml @@ -1,3 +1,3 @@ --- minor_changes: -- adding minimum_uptime and alias uptime to filter instances that have only been online for certain duration of time in minutes +- ec2_instance_info - added ``minimum_uptime`` option with alias ``uptime`` for filtering instances that have only been online for certain duration of time in minutes (https://github.com/ansible-collections/community.aws/pull/356).