Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ec2_vol_facts: moved to boto3 #43348

Merged
merged 13 commits into from
Aug 31, 2018
Merged

Conversation

hryamzik
Copy link
Contributor

SUMMARY

Moved to boto3 to support role-based profiles.

ISSUE TYPE
  • Bugfix Pull Request
COMPONENT NAME

ec2_vol_facts

ANSIBLE VERSION
2.6.1

@ansibot
Copy link
Contributor

ansibot commented Jul 27, 2018

cc @wimnat
click here for bot help

@ansibot
Copy link
Contributor

ansibot commented Jul 27, 2018

Hi @hryamzik,

Thank you for the pullrequest, just so you are aware we have a dedicated Working Group for aws.
You can find other people interested in this in #ansible-aws on Freenode IRC
For more information about communities, meetings and agendas see https://github.com/ansible/community

click here for bot help

@ansibot ansibot added affects_2.7 This issue/PR affects Ansible v2.7 aws bug This issue/PR relates to a bug. cloud community_review In order to be merged, this PR must follow the community review workflow. module This issue/PR relates to a module. needs_triage Needs a first human triage before being processed. support:community This issue/PR relates to code supported by the Ansible community. labels Jul 27, 2018
@ansibot
Copy link
Contributor

ansibot commented Jul 27, 2018

The test ansible-test sanity --test pylint [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:148:16: undefined-variable Undefined variable 'botocore'

The test ansible-test sanity --test pep8 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:68:161: E501 line too long (211 > 160 characters)

click here for bot help

@ansibot ansibot added ci_verified Changes made in this PR are causing tests to fail. needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. and removed community_review In order to be merged, this PR must follow the community review workflow. ci_verified Changes made in this PR are causing tests to fail. labels Jul 27, 2018
@ansibot
Copy link
Contributor

ansibot commented Jul 27, 2018

The test ansible-test sanity --test pylint [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:70:0: syntax-error unexpected indent (<string>, line 70)

The test ansible-test sanity --test ansible-doc --python 2.6 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:0:0: has a documentation error formatting or is missing documentation.

The test ansible-test sanity --test ansible-doc --python 2.7 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:0:0: has a documentation error formatting or is missing documentation.

The test ansible-test sanity --test ansible-doc --python 3.5 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:0:0: has a documentation error formatting or is missing documentation.

The test ansible-test sanity --test ansible-doc --python 3.6 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:0:0: has a documentation error formatting or is missing documentation.

The test ansible-test sanity --test ansible-doc --python 3.7 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:0:0: has a documentation error formatting or is missing documentation.

The test ansible-test sanity --test compile --python 2.6 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:70:4: SyntaxError: ansible_dict_to_boto3_filter_list, camel_dict_to_snake_dict

The test ansible-test sanity --test compile --python 2.7 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:70:4: SyntaxError: ansible_dict_to_boto3_filter_list, camel_dict_to_snake_dict

The test ansible-test sanity --test compile --python 3.5 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:70:4: SyntaxError: ansible_dict_to_boto3_filter_list, camel_dict_to_snake_dict

The test ansible-test sanity --test compile --python 3.6 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:70:4: SyntaxError: ansible_dict_to_boto3_filter_list, camel_dict_to_snake_dict

The test ansible-test sanity --test compile --python 3.7 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:70:4: SyntaxError: ansible_dict_to_boto3_filter_list, camel_dict_to_snake_dict

The test ansible-test sanity --test docs-build [explain] failed with the error:

Command "/usr/bin/python test/sanity/code-smell/docs-build.py" returned exit status 1.
>>> Standard Error
Traceback (most recent call last):
  File "test/sanity/code-smell/docs-build.py", line 101, in <module>
    main()
  File "test/sanity/code-smell/docs-build.py", line 17, in main
    raise subprocess.CalledProcessError(sphinx.returncode, cmd, output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['make', 'singlehtmldocs']' returned non-zero exit status 2.

The test ansible-test sanity --test import --python 2.6 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:70:4: IndentationError: unexpected indent

The test ansible-test sanity --test import --python 2.7 [explain] failed with 2 errors:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:0:0: IndentationError: unexpected indent (ec2_vol_facts.py, line 70) (in /root/ansible/test/runner/.tox/minimal-py27/bin/importer.py:82)
lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:70:4: IndentationError: unexpected indent

The test ansible-test sanity --test import --python 3.5 [explain] failed with 2 errors:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:0:0: IndentationError: unexpected indent (ec2_vol_facts.py, line 70) (in /root/ansible/test/runner/.tox/minimal-py35/bin/importer.py:82)
lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:70:4: IndentationError: unexpected indent

The test ansible-test sanity --test import --python 3.7 [explain] failed with 2 errors:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:0:0: IndentationError: unexpected indent (ec2_vol_facts.py, line 70) (in /root/ansible/test/runner/.tox/minimal-py37/bin/importer.py:82)
lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:70:4: IndentationError: unexpected indent

The test ansible-test sanity --test import --python 3.6 [explain] failed with 2 errors:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:0:0: IndentationError: unexpected indent (ec2_vol_facts.py, line 70) (in /root/ansible/test/runner/.tox/minimal-py36/bin/importer.py:82)
lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:70:4: IndentationError: unexpected indent

The test ansible-test sanity --test pep8 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:70:5: E113 unexpected indentation

The test ansible-test sanity --test validate-modules [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:0:0: E401 Python SyntaxError while parsing module

The test ansible-test sanity --test yamllint [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:70:4: python-syntax-error unexpected indent (<unknown>, line 70)

click here for bot help

@hryamzik
Copy link
Contributor Author

Love these formatting requirements, 2 imports instead of a single multiline one.

from ansible.module_utils.ec2 import connect_to_aws, ec2_argument_spec, get_aws_connection_info, boto3_conn, HAS_BOTO3, boto3_tag_list_to_ansible_dict
from ansible.module_utils.ec2 import ansible_dict_to_boto3_filter_list, camel_dict_to_snake_dict

@ansibot ansibot added community_review In order to be merged, this PR must follow the community review workflow. and removed needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. labels Jul 27, 2018
@mkrizek mkrizek removed the needs_triage Needs a first human triage before being processed. label Jul 27, 2018
@ansibot ansibot added the stale_ci This PR has been tested by CI more than one week ago. Close and re-open this PR to get it retested. label Aug 4, 2018
@hryamzik
Copy link
Contributor Author

hryamzik commented Aug 9, 2018

@s-hertel is there anything preventing this from being merged?

@hryamzik
Copy link
Contributor Author

cc @mattclay

Is there any way to avoid stuck PRs like this?

@mattclay
Copy link
Member

@hryamzik Since this is a community module, the best thing to do is try pinging the maintainer of the module for a review. If the maintainer is unavailable, you may be able to find others in the community to review and test. Since this is an AWS module you may want to check in the #ansible-aws IRC channel on Freenode.

@hryamzik
Copy link
Contributor Author

Hey @wimnat, can you take a look at this PR, please?


if region:
try:
connection = connect_to_aws(boto.ec2, region, **aws_connect_params)
except (boto.exception.NoAuthHandlerFound, Exception) as e:
connection = boto3_conn(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

boto3_conn is calling module.fail_json for exceptions and the lack of region, so you can remove the exception handling and unnest this and remove the ProfileNotFound import

import boto.ec2
from boto.exception import BotoServerError
HAS_BOTO = True
from botocore.exceptions import ClientError
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module should handle BotoCoreError and ClientError. ProfileNotFound should be handled by boto3_conn and doesn't need to be imported by the module.


from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ec2 import connect_to_aws, ec2_argument_spec, get_aws_connection_info
from ansible.module_utils.ec2 import connect_to_aws, ec2_argument_spec, get_aws_connection_info, boto3_conn, HAS_BOTO3, boto3_tag_list_to_ansible_dict
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could update this module to AnsibleAWSModule if you wanted. That would simplify correcting the exception handling and eliminate the need to use/import all of:
connect_to_aws, ec2_argument_spec, get_aws_connection_info, boto3_conn, and HAS_BOTO3

Doing this would end up looking something like:

from ansible.module_utils.aws.core import AnsibleAWSModule
...
module = AnsibleAWSModule(argument_spec=argument_spec)
connection = module.client('ec2')

And your exception handling would look like:

try:
    connection.describe_volumes(Filters=ansible_dict_to_boto3_filter_list(sanitized_filters))
except (BotoCoreError, ClientError) as e:
    module.fail_json_aws(e, msg="Unable to describe volumes with filters {0}".format(sanitized_filters))

Otherwise you end up having a mess handling the different cases of what attributes exist for what exception because they don't inherit the same properties (such as, you should include e.message and e.response if they exist, but e.message does not exist on Python 3 and BotoCoreErrors never have a response attribute).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't manage to get value for region in this case and it has to be presented in module output.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, no problem either way. You could still get region via get_aws_connection_info, which is how AnsibleAWSModule gets it too.

attachment = volume.attach_data
attachment = volume["attachments"]
tags = {}
for tag in volume["tags"]:
Copy link
Contributor

@s-hertel s-hertel Aug 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've imported boto3_tag_list_to_ansible_dict so you could use that.
line 99: 'tags': boto3_tag_list_to_ansible_dict(volume['tags'])


for volume in all_volumes["Volumes"]:
volume = camel_dict_to_snake_dict(volume)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need camel_dict_to_snake_dict(volume, ignore_list=['Tags'])? If 'Tags' is a key in volumes it will snake_dict the tags too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I didn't manage find any tags issues but going to give this change a try.


filters = module.params.get("filters")
# Replace filter key underscores with dashes, for compatibility, except if we're dealing with tags
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to have integration tests to make sure this module stays backward compatible. It's not a blocker, but there should be tests for features even for preview modules. https://github.com/ansible/community/blob/master/group-aws/integration.md#policy

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm working on an integration test but it's hard to compare everything so let me post results here:

current version:

    "volumes": [
        {
            "attachment_set": {
                "attach_time": "2018-02-12T12:43:22.000Z",
                "device": "/dev/sda1",
                "instance_id": "i-88888888888888885",
                "status": "attached"
            },
            "create_time": "2018-02-12T12:43:22.461Z",
            "encrypted": false,
            "id": "vol-88888888888888888",
            "iops": 100,
            "region": "us-west-2",
            "size": 8,
            "snapshot_id": "snap-88888888888888887",
            "status": "in-use",
            "tags": {
                "Name": "test",
            },
            "type": "gp2",
            "zone": "us-west-2c"
        }
]

new version:

    "volumes": [
        {
            "attachment_set": {
                "attach_time": "2018-02-12T12:43:22+00:00", 
                "delete_on_termination": true, 
                "device": "/dev/sda1", 
                "instance_id": "i-88888888888888885", 
                "status": "attached"
            }, 
            "create_time": "2018-02-12T12:43:22.461000+00:00", 
            "encrypted": false, 
            "id": "vol-88888888888888888", 
            "iops": 100, 
            "region": "us-west-2", 
            "size": 8, 
            "snapshot_id": "snap-88888888888888887", 
            "status": "in-use", 
            "tags": {
                "Name": "test", 
            }, 
            "type": "gp2", 
            "zone": "us-west-2c"
        },
]

So as you can see date format is a bit different, is it something that should be checked/fixed?


for volume in all_volumes:
volume_dict_array.append(get_volume_info(volume))
all_volumes = connection.describe_volumes(Filters=ansible_dict_to_boto3_filter_list(sanitized_filters))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any pagination support in the original code, is it something different in boto3 approach?

volume_dict_array.append(get_volume_info(volume))
all_volumes = connection.describe_volumes(Filters=ansible_dict_to_boto3_filter_list(sanitized_filters))
except ClientError as e:
module.fail_json(msg=e.message, exception=traceback.format_exc())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.message does not exist on Python 3. e.response does exist for ClientErrors and should be included if so.

@hryamzik
Copy link
Contributor Author

ClientError: An error occurred (UnauthorizedOperation) when calling the RunInstances operation: You are not authorized to perform this operation

This is wired as I've copied setup from other module test. Any ideas how to fix this?

@ansibot
Copy link
Contributor

ansibot commented Aug 21, 2018

The test ansible-test sanity --test pep8 [explain] failed with 1 error:

lib/ansible/modules/cloud/amazon/ec2_vol_facts.py:105:1: E302 expected 2 blank lines, found 1

click here for bot help

@s-hertel s-hertel added the needs_ci_update This PR is blocked as it requires an update to CI infrastructure before tests can pass in CI. label Aug 21, 2018
@s-hertel s-hertel self-assigned this Aug 21, 2018
Copy link
Contributor

@ryansb ryansb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM


- name: Create test instance
ec2_instance:
name: "ansible_ec2_vol_facts_test"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (and any other resources) need to be using {{ resource_prefix }} on resource names, it's part of the requirements for the CI IAM policy.

ec2_vol:
instance: "{{ instance.instance_ids[0] }}"
volume_size: 4
name: ansible_ec2_vol_facts_test.db
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here - make sure to use {{ resource_prefix }}

@@ -0,0 +1,2 @@
---
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer not to include effectively empty defaults and vars files

- "v.snapshot_id is defined and v.snapshot_id == ''"
- "v.status is defined and v.status == 'in-use'"
- "v.tags.Name is defined and v.tags.Name == resource_prefix + '_ansible_ec2_vol_facts_test.db'"
- "v.tags['Tag Name with Space-and-dash'] == 'Tag Value with Space-and-dash'"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test fails - this is the only reference to this tag.

@ansibot
Copy link
Contributor

ansibot commented Aug 31, 2018

The test ansible-test sanity --test integration-aliases [explain] failed with 1 error:

test/integration/targets/ec2_vol_facts/aliases:0:0: conflicting alias `shippable/aws/group[1-2]` and `unsupported`

click here for bot help

@ansibot ansibot added the ci_verified Changes made in this PR are causing tests to fail. label Aug 31, 2018
@@ -0,0 +1,2 @@
cloud/aws
unsupported
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like testing this PR is blocked on CI updates that @s-hertel is working on.

We should wait for those updates rather than disabling the tests.

@ansibot ansibot removed the ci_verified Changes made in this PR are causing tests to fail. label Aug 31, 2018
@s-hertel
Copy link
Contributor

+1 to merge from me, and I will update CI for these when I have time. The tests look good and pass locally for me with Python 2 and 3. And it's pretty low risk since it's a preview community facts module.

@willthames willthames merged commit 4f70eb3 into ansible:devel Aug 31, 2018
@willthames
Copy link
Contributor

Merged, thanks @hryamzik

@willthames
Copy link
Contributor

Thanks to @s-hertel for the secondary testing too

@hryamzik
Copy link
Contributor Author

Thanks guys!

@s-hertel s-hertel removed the needs_ci_update This PR is blocked as it requires an update to CI infrastructure before tests can pass in CI. label Nov 15, 2018
@hryamzik hryamzik deleted the vol_facts_boto3 branch May 15, 2019 23:20
@ansible ansible locked and limited conversation to collaborators Jul 22, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.7 This issue/PR affects Ansible v2.7 aws bug This issue/PR relates to a bug. cloud module This issue/PR relates to a module. needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. support:community This issue/PR relates to code supported by the Ansible community. test This PR relates to tests.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants