-
Notifications
You must be signed in to change notification settings - Fork 343
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
Refactor ec2_vpc_dhcp_option to use boto3 (breaking change) #252
Conversation
@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 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. 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. |
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.
|
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. |
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. |
There was a problem hiding this 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
- 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'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 preservenew_config
from the original module insofar asnew_config
wasn't even entirely consistent in the first place) as well as just dumping the boto3 response?
In general, Yes.
There was a problem hiding this comment.
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.
b7bcb4c
to
6d1f532
Compare
@tremble Took a swipe at returning both result formats in both modules as discussed. |
plugins/module_utils/ec2.py
Outdated
{'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'}]} |
There was a problem hiding this comment.
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
plugins/module_utils/ec2.py
Outdated
return config_data | ||
|
||
for config_item in option_config: | ||
# # Handle single value keys |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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 for
in 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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this 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.
changelogs/fragments/252_boto3_refactor_ec2_vpc_dhcp_option.yaml
Outdated
Show resolved
Hide resolved
75ce5b4
to
48ae8da
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whitespace fixup
* Convert to boto3 * More consistent use of check_mode * Use AwsRetry * Catch BotoCoreError, ClientError
…g and the user-friendly "normalized" comnfig. Move the normalize_config function to module_utils Enable integration test assertions for new return values, including tags
d1f856d
to
4f49c39
Compare
rebased around the git conflict. |
SUMMARY
ISSUE TYPE
COMPONENT NAME
plugins/modules/ec2_vpc_dhcp_option.py