-
Notifications
You must be signed in to change notification settings - Fork 19
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
Support for squashing and pure entries #71
Comments
+1 |
This comment has been minimized.
This comment has been minimized.
One point of clarification, aggregates (or whatever they end up being called) are significantly more than an optimization. Aggregates allow the task to define the aggregate set of configure and only the aggregate set of configuration that should be present on a target. So if the aggregate is A, B, C and the actual target has A, B, D, then the module should add C and remove D. This is impossible to accomplish using |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
In above example with proposed So the validation of the entries within each dict (option validation) and batch processing of the list needs be handled in the module. In case purge/append option is enabled module needs to handle deleting |
@ganeshrn Please don't delete all, followed by adding, that could have an impact. IMO it's better to selectively delete, update or add. Which obviously requires support by the module (which is something it should advertise). If a module supports this methodology, I don't see why someone would disable this. It should be the only modus operandi. (i.e. 'absent' skipping the add/update and 'present' skipping the delete) In my opinion, the purge-option is in fact a state. I don't know yet what the best name would be, but next to absent and present (which only affects the items listed) that third state would affect the existing config. It wouldn't need an absent-alternative because an empty input would mean cleaning everything. |
@ganeshrn that is one way, we probably need 2 diff modes depending on module support, basically an extension of current squashing but 'explicit' vs 'implicit' behaviour. The other way would be to 'pretemplate' the loop and execute all of this remotely (@dagwieers i believe you proposed this already) , but this has a couple of caveats, mainly that loop items cannot depend on previous items execution (loop forks have similar issues). @dagwieers I'm favoring the additional options because i have not been able to find a 'state' that reflects what you are saying, .. but even |
This comment has been minimized.
This comment has been minimized.
@dagwieers Agreed, sequence of add/delete is important. |
I think we all agree on function ...so we are left with UI .. mostly naming ... one of the hard parts of computing! |
An additional option makes room for 4 different combinations where we only really need 3. On top of that, we then also have to ensure that purge is not used with any other state that people may provide (e.g. query or list). This really is a separate state, next to absent/present (which only affects what is specified). Maybe we have to introduce new terminology altogether from a different field. (Like "idempotence" comes from math) Reading up on idempotence I stumbled on pure If any existing configuration/state would influence the resulting state, it is not considered pure. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
purge/replace are imperative and definitely not states. purged and replaced are states, but not about what was specified, like absent or present. declared is, but doesn't indicate what happens to existing config. pure however is a state both about what is specified, but also what remains. And it matches the definition in computer science. |
Here are the notes from the IRC working group session where we discussed this proposal. https://meetbot.fedoraproject.org/ansible-network/2017-10-11/network_working_group.2017-10-11-16.01.html |
My proposal for what users interface with in Ansible is exactly the same as the new loop syntax in v2.5: - net_vlan:
vlan_id: "{{ item.vlan_id }}"
name: "{{ item.name }}"
description: "{{ item.description }}"
state: pure
loop:
- { vlan_id: 100, name: test_vlan_1, description: test vlan-1 }
- { vlan_id: 200, name: test_vlan_2, description: test vlan-2 }
- { vlan_id: 300, name: test_vlan_3, description: test vlan-3 } So So this clearly is something we have to support in Ansible core, and add to modules over time. The argument spec would add something like: Obviously, this only works if the module supports such declarations in a single transaction and Ansible understands that if the module supports this, it no longer needs to run actions for individual items, but can send the whole list in a single call to the module. This would equally works for |
@dagwieers i fail to see how you support squashing with this proposal. Each iteration of |
@privateip No, if the module advertises The main advantage is that existing playbooks will start doing it more efficiently as soon as a module (and Ansible) supports this. Updated to use the new terminology squashing over aggregation. I agree it's better. |
I'm still not clear what the receiver is in this scenario. Obviously it has to be the module but what in the module. A new argument? Also, this would require that all modules are loaded (imported) on the controller side (I'm assuming in the action plugin) prior to passing the arguments. Just trying to clarify my understanding, please correct any assumption here that is wrong |
Obviously it is the module, and yes, it would be some new internal argument. Those details are part of the implementation. And yes, the module would have to be loaded/inspected to understand what it supports, which it already does for But it wouldn't need a specific action plugin, the default action_plugin would do this out of the box. (Modules that require its own action plugin would have to support this too if they want to support squashing, so yes it would need some supporting call for this, or if possible, part of the existing interface). |
No, Basically this proposal moves the functionality of the current |
Check Update: Alright, I misinterpreted what was going on there. It seems the individual modules are run remotely and return skipped. The |
Or, instead of |
Also, something like
|
I wanted to refrain from using words that could be used to indicate which host is doing the looping (looping happens in the module, not on the host, i.e. |
@dag We are no longer actively developing this feature in core and will move any implementation herein into roles on as-needed basis. Any objections to closing this proposal? |
I don't see how roles can solve this. |
Roles solve this by their implementation. If I pass a set of values into a role, the implementation of the role can perform the necessary adds and removes to normalize the desired data set with the configured data set on the device. So you are correct in the sense that roles do not inherently solve this but the implementation of tasks of a role do. Since we are no longer developing modules with an |
@privateip Yes, I would like to keep this open, as a role-based implementation does not offer performance/efficiency improvements. Looping over a task for hundreds of items is in most cases hard to impossible unless it is core/module-based implementation. I have several customers/users asking for this to make Ansible usable in large setups. |
Here's a variation of an earlier example. Here I swapped
A loop In the case of So, I think this is easy enough to explain in user facing documentation as I attempted to do above. What does everyone think? |
@cognifloyd do you have any opinions on what "This only works if the action or module has documented in their DOCUMENTATION string that they support task layer looping." would look like? |
The documentation is already parsed for options, so it shouldn't be a big deal to also put some more metadata in the documentation.
or another option:
or even:
or maybe, if a
I like a list/dict because it makes it feels cleaner (less verbose, but more clear) and is more extensible for future features without a lot of Note that I also included an |
I suppose we could call the two layers
|
@cognifloyd I think that syntax is too verbose and complex. If we expect a lot of modules over time would support squashing and pure, having to specify all that is a drag. Another issue I have with loop: now is the fact the the playbook nor the task is looping, so it adds to the confusion. To the user we simply hand off a dataset to the module, so I would even refrain from using the loop keyword here. Bolting this on top of the loop-mechanism is wrong. (Major change of opinion since last year) So rather than use loop or with_items my new proposal is this: - net_vlan:
description: Production VLAN
state: pure
dataset:
- { vlan_id: 100, name: prod_vlan_1 }
- { vlan_id: 200, name: test_vlan_2, description: Test VLAN }
- { vlan_id: 300, name: test_vlan_3, description: Test VLAN } So the fact that dataset is provided, means we are sending this as a whole to the module. (How exactly is not relevant now, I would do this internally and not expose it as a parameter). At this point Ansible will know what it needs to do, there's no need here to check if the module actually supports it. (If it doesn't, we'll have to make catch that and make it clear to the user though) This would also work with |
First, what does it take to move this proposal to an "accepted" state? An alternative to the As for More thoughts on
In the action/module that I'm writing (that triggered looking this proposal up last week to see if anything changed), I ended up creating something like an Here are some questions that might have to be answered once we get to implementation (I hope asking now will not delay accepting this proposal).
For my action/module, I had my primary identifier arg So, I would imagine that the ansible-core-provided dataset handling would handle merging the top-level task args with the dataset as well as handling basic validation. If it just merged them, and I had to add my extra 'uniqueness' constraint, that would probably be fine. Also, for my use-case I think it makes more sense for the dataset entries to have precedence over the top-level args. Does that also make sense for the network appliance use case? Or do the network modules need to have top-level args override entries in the |
@cognifloyd The official decision was that this functionality is implemented using roles: #71 (comment) But to me that is no solution for the needs I have, so that's why I'd like to first look at a representation in the playbook, then see if it could cover the different needs and look at making a basic implementation. Obviously, this impacts core (a bit), module_utils (mostly) and modules. There's no simple solution, especially for implementing I am not going into details of your questions, because that's going to add to bikeshedding mostly :-) But I do have some opinions. Most of the heavy lifting will be in module_utils and be as transparant to the module writer, as it is today. So parameter handling will just happen, and you'll get an object that's easy and transparant to iterate over so you can basically reuse as much of the existing logic as possible. That will be the goal. |
It would be nice to have something like this for our Bitbucket modules:
The rationale here is that these modules use API calls to manipulate individual entries, and can be significantly sped up, if the proposal by @dagwieers is accepted. |
Proposal: Redesign Aggregates
Author: Dag Wieers <@dagwieers> IRC: dag
Date: 2017/09/15
Motivation
During AnsibleFest SF 2017 some issues came to light regarding the Aggregates functionality that was designed as part of the ansible-network roadmap.
This proposal does not question the merit of this needed functionality, but some design decisions require improvements before this is ready for wider consumption.
Various participants questioned the naming of this functionality, as the name does not seem to adequately describe the purpose of the functionality.
The interface was questioned as well, especially the following aspects of the functionality:
Some believe that rather than a parameter to the module, it should be a new state.
Some believe that this functionality should not be part of the modules, but instead be an integral part of Ansible core instead. There is no need to require a whole new interface, it could fit right into with_items, as long as the module indicate it can handle more than one item in a single run (e.g. supports_aggregation). This would then also replace the existing special cases related to yum, apt and others that already offer similar functionality.
Purging would be optional, you could add/remove multiple items in a single run without purging existing items. This would also be something that the module would need to indicate (e.g. supports_purging).
Handling failures is also something that should be considered better. If processing an item fails, should it continue with subsequent items (as with_item does). Should it also perform the purge when adding/modifying an item fails (probably not). So this requires we understand the various use-cases and problem-causes.
This functionality is useful in a wider context than just networking, so this should have been discussed with use-cases outside of networking only.
Participants wondered whether this functionality would have been acceptable when coming from the community and being reviewed by Ansible core developers. The conclusion was: probably not.
Problems
What problems exist that this proposal will solve?
Solution proposal
Documentation (optional)
Hold off with documenting and promoting this as part of v2.4, so we don't have to support this going forward in light of a user-breaking redesign.
Anything else?
The above feedback was provided during the AnsibleFest SF 2017 Network Working Group and was largely unanimous by participants.
This proposal was made to collect feedback from other participants in order to design a better user interface for this functionality before it becomes a wider standard.
The text was updated successfully, but these errors were encountered: