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

Refactor ec2_vpc_dhcp_option to use boto3 (breaking change) #252

Merged
merged 13 commits into from
Apr 29, 2021

Conversation

jillr
Copy link
Collaborator

@jillr jillr commented Feb 1, 2021

SUMMARY
  • Convert to boto3
  • More consistent use of check_mode
  • Use AwsRetry
  • Catch BotoCoreError, ClientError
ISSUE TYPE
  • Feature Pull Request
COMPONENT NAME

plugins/modules/ec2_vpc_dhcp_option.py

@ansibullbot
Copy link

@ansibullbot ansibullbot added WIP Work in progress feature This issue/PR relates to a feature request module module needs_triage owner_pr PR created by owner/maintainer plugins plugin (any type) labels Feb 1, 2021
@ansibullbot ansibullbot added integration tests/integration tests tests and removed owner_pr PR created by owner/maintainer labels Feb 6, 2021
@jillr
Copy link
Collaborator Author

jillr commented Feb 9, 2021

@tremble What would you think about the boto3 version of this module having occasionally slightly different return data, but substantially more consistent (and documented) returns? Things like, in the boto2 module we sometimes returned all DhcpConfigurations keys, we sometimes only returned the ones that were set, and sometimes (such as the - name: add and remove tags test) returned no keys. I'm thinking about always returning all keys, with None set if there's no value, in the interest of simplifying the internal logic.
ETA: although if I'm not trying to sometimes return all keys, it should be easier to always only return keys that are set.

Whether something is returned as a string or a list should also be more predictable now, though I haven't modified the integration tests to confirm for certain yet.
(All the places where we currently have things like dhcp_options.new_options['domain-name'] in ["{{ aws_domain_name }}", ["{{ aws_domain_name }}"]] right now.)

Basically this has turned into a full rewrite, so I'm considering making it part of a 2.0 of the collection and being a bit freer with making the code long-term easier to maintain over a perfect 1:1 matching of the boto2 module.

@tremble
Copy link
Contributor

tremble commented Feb 10, 2021

I'm generally good with returning keys where we didn't before.

Changing what existing return values return (strings vs lists) makes me less comfortable and might be better handled with a breaking release. It's really hard to communicate this to users and 'deprecate' return values.

In general I'd like to be very deliberate about performing a 2.x release since it becomes the point at which we'll probably get asked to start backporting fixes between branches.

  • Are there other places where we'd like to 'break' return values for consistency?
    • Do we have anywhere other than ec2_vpc_igw_info still returning tags as a list of dicts rather than a simple list?
    • Do we want to remove all the old boto2 compatibility return hacks?
    • De we want to push towards more consistent return values, maybe adding the new return types in 2.x and removing the old ones in a 3.x
  • Would a 2.x release be a good time to nuke all the _facts aliases?
  • Would a 2.x release be a good time to make module names a little more consistent? (aws_ is a little redundant and we have a lot of ec2_ modules people might not realise are tied to the EC2 API)

@jillr
Copy link
Collaborator Author

jillr commented Feb 10, 2021

A 2.0 would definitely be more deliberate, I'd see that as happening at the same time we move the first batch of modules out of community.aws and 2.0 that collection (hopefully later this spring). That would leave this PR WIP until that time, but free me up to simplify the logic quite a bit.

We put the facts aliases deprecation notices as 2021-12-01, so I think we're best off waiting until after then regardless of collection version.

I would be in favor of starting to update any return changes and module names that we can in 2.x.

@jillr
Copy link
Collaborator Author

jillr commented Feb 17, 2021

This is mostly done, minus unit tests. There are some lingering bugs noted in the integration test file but I'm inclined to land this already extensive rewrite and handle those later as they're are for features or functions that the module has never provided anyway.

@ansibullbot
Copy link

Copy link
Contributor

@tremble tremble left a comment

Choose a reason for hiding this comment

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

A couple of niggles, nothing major jumping out at me

plugins/modules/ec2_vpc_dhcp_option.py Outdated Show resolved Hide resolved
- assert:
that:
- dhcp_options.changed
- dhcp_options.new_options
# FIXME extra keys are returned unpredictably
- dhcp_options.new_options.keys() | list | sort is superset(['netbios-name-servers', 'netbios-node-type', 'ntp-servers'])
- dhcp_options.new_options.keys() | list | sort == ['netbios-name-servers', 'netbios-node-type', 'ntp-servers']
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
- dhcp_options.new_options.keys() | list | sort == ['netbios-name-servers', 'netbios-node-type', 'ntp-servers']
- dhcp_options.new_options.keys() | list | sort == ['netbios-name-servers', 'netbios-node-type', 'ntp-servers']

I was thinking that maybe failing if a new option was added is the best option here. However, I think if someone wants to add additional info, we should probably get them to return the boto3 style data alongside the original boto2 data.

Maybe worth a comment here about why we fail if extra return values are passed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sorry, I may just be being dense but I'm not sure what you're asking on this. We should only have these 3 keys here because those should be the only 3 keys that are configured in this option set's DhcpConfiguration at this point.

Are you asking if we should return the normalized_config() (which attempts to preserve new_config from the original module insofar as new_config wasn't even entirely consistent in the first place) as well as just dumping the boto3 response?

Copy link
Contributor

Choose a reason for hiding this comment

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

We should only have these 3 keys here because those should be the only 3 keys that are configured in this option set's DhcpConfiguration at this point.

Ah, ok so it's supposed to have done something approximating purge_none_params

Most of the time we do - '"foo" in bar.baz' to say we only care that the mentioned keys are there, not that it must be only specific keys (it gives us flexibility if Amazon add extra features). I'm worried about non-standard examples knocking about that'll confuse people. I'd be good with just a comment that "this is non-standard behaviour because..."

Are you asking if we should return the normalized_config() (which attempts to preserve new_config from the original module insofar as new_config wasn't even entirely consistent in the first place) as well as just dumping the boto3 response?

In general, Yes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Gotcha. Added a quick take at that, no tests yet (in the current incarnation it would solve the need to return tags at least). I really don't like the whole Key, Values, Value structure that amazon is giving us here but that's what we have to work with.

@jillr
Copy link
Collaborator Author

jillr commented Feb 22, 2021

@tremble Took a swipe at returning both result formats in both modules as discussed.

@ansibullbot ansibullbot added the module_utils module_utils label Feb 22, 2021
@jillr jillr changed the title [WIP] Refactor ec2_vpc_dhcp_option to use boto3 Refactor ec2_vpc_dhcp_option to use boto3 Feb 23, 2021
@jillr jillr removed the WIP Work in progress label Feb 23, 2021
@ansibullbot ansibullbot added the needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR label Feb 23, 2021
{'Key': 'domain-name-servers', 'Values': [{'Value': 'AmazonProvidedDNS'}]},
{'Key': 'netbios-name-servers', 'Values': [{'Value': '1.2.3.4'}, {'Value': '5.6.7.8'}]},
{'Key': 'netbios-node-type', 'Values': [1]},
{'Key': 'ntp-servers', 'Values': [{'Value': '1.2.3.4'}, {'Value': '5.6.7.8'}]}
Copy link
Member

Choose a reason for hiding this comment

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

one whitespace too much , but not worth an extra commit

return config_data

for config_item in option_config:
# # Handle single value keys
Copy link
Member

Choose a reason for hiding this comment

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

one # too much , but not worth an extra commit

if purge_tags and not tags:
tags_to_unset = current_tags

if tags_to_unset:
Copy link
Member

Choose a reason for hiding this comment

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

as fas as I see if tags_to_unset: is not necessary here. The logic can instantly applied after L276 if purge_tags and not tags
but on the other hand, the code logic looks cleaner and more separated.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

My concern is keeping things separated enough for the changed logic to be clear. I'm not sure where I would like to put the changed=True to cover a case where there are no tags_to_set but there are tags_to_unset without potentially setting the wrong changed in other cases. It might be a bit verbose this way but it's consistent with what we do in other modules, my inclination would be to leave it a bit more easy to read.

params = module.params
if params['domain_name'] is not None:
new_config.append({'Key': 'domain-name', 'Values': [{'Value': params['domain_name']}]})
if params['dns_servers'] is not None:
Copy link
Member

@markuman markuman Mar 1, 2021

Choose a reason for hiding this comment

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

what about just params.get('domain_name'): and reduce if and forin single for server in params.get('dns_servers', []):
but yeah, then the extra vars (dns_server_list, ntp_server_list etc are always be initialized, even if not used.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Historically the default value of those options is None, not an empty list, and we can't iterate on None. If I change the default to [] I get cascading effects in the data transformations where null values get set on options that should be unset, which breaks changed status assertions. It should be possible to make this change but it would require changing code in several places unfortunately.

Copy link
Member

@markuman markuman left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@tremble tremble left a comment

Choose a reason for hiding this comment

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

Minor tweaks to changelog and thoughts about what's returned.

plugins/modules/ec2_vpc_dhcp_option.py Outdated Show resolved Hide resolved
@jillr jillr force-pushed the ec2_vpc_dhcp_boto3 branch 3 times, most recently from 75ce5b4 to 48ae8da Compare March 8, 2021 18:27
@tremble tremble changed the title Refactor ec2_vpc_dhcp_option to use boto3 Refactor ec2_vpc_dhcp_option to use boto3 (breaking change) Mar 11, 2021
Copy link
Contributor

@tremble tremble left a comment

Choose a reason for hiding this comment

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

whitespace fixup

plugins/modules/ec2_vpc_dhcp_option_info.py Outdated Show resolved Hide resolved
@ansibullbot ansibullbot added community_review and removed needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR labels Apr 29, 2021
@jillr
Copy link
Collaborator Author

jillr commented Apr 29, 2021

rebased around the git conflict.

@jillr jillr added the gate label Apr 29, 2021
@ansible-zuul ansible-zuul bot merged commit 762674e into ansible-collections:main Apr 29, 2021
@jillr jillr deleted the ec2_vpc_dhcp_boto3 branch July 2, 2021 22:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
community_review feature This issue/PR relates to a feature request integration tests/integration module_utils module_utils module module needs_maintainer new_plugin New plugin plugins plugin (any type) tests tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants