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
Added filters option to openstack inventory plugin. #51401
Conversation
Signed-off-by: Turo Soisenniemi <turo.soisenniemi@outlook.com>
Build failed (third-party-check pipeline) integration testing with
|
Build failed (third-party-check pipeline) integration testing with
|
Okay, it seems that pull request description is evaluated in openstack tests: I'll change the example and retest. |
recheck |
Build succeeded (third-party-check pipeline).
|
ready_for_review |
bot_status |
Componentslib/ansible/plugins/inventory/openstack.py Metadatawaiting_on: maintainer |
Hi @Turmio For example the |
Hi @ITD27M01, "filters" limits actual query done to the OpenStack instance. Actually we are using git commit sha as identifier. Adding it to filters, we can get only virtual machines that pass defined filters and use Ansible as in any static inventory. For example Workflow:
Example openstack.yml:
This provides horizontally scalable environment without editing our playbooks for openstack. All OpenStack magic is done in inventory files. |
Hello @Turmio Firstly, All this stuff already is done by "group/groups" metadata keys and ansible hostpatterns: https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/inventory/openstack.py#L272 https://docs.ansible.com/ansible/latest/user_guide/intro_patterns.html In your case "vm_role" and "ci_stack" is overengineering and can be achieved by setting the "group" metadata key to the following:
In this way you will get the groups for "<vm_role>" and "<ci_stack>" in ansible inventory. Secondly, all metadata keys alredy used for host groups (with "meta-" prefix): https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/inventory/openstack.py#L306 So, these keys can be used for your task. |
Hi @ITD27M01, it does not do the same. Filters are passed to OpenStackSDK which does the filtering before ansible can access any host. I looked up the line you referenced and it gets servers from here: This is line where I added filters. This change also improves performance because filtering is done server side before filtering with groups as you suggested. We have potentially hundreds of VMs up same time and need to access about 5-10. I don't think using openstack sdk filters is overengineering as it is openstack way of filtering hosts. aws_ec2 inventory source also has filters: We cannot (or don't want to) use host patterns. We have product where we have defined groups, add-hoc commands etc. which should work on any environment without modifying host patterns. |
@Turmio https://opendev.org/openstack/openstacksdk/src/branch/master/openstack/cloud/inventory.py#L76 So, all the work run on the client side in any way and performance will not be improved. The nova API has limited filters for GET /servers API request: https://developer.openstack.org/api-ref/compute/?expanded=list-servers-detail#list-servers and metadata hash not in these keys. I thought about improving performance too, but the change made should be more complex. Moving the host grouping deeper into the library (openstacksdk) will cause confusion and won't do any good - host grouping is already implemented in the ansible plugin. The good way to use such filters are tags. They can be used to split large environment inside the project to small environments. But there should be support for acceptable filters on openstacksdk side and after that, the filtering can be implemented in ansible plugin. |
@ITD27M01, I'll admit that I did not check where filters are executed. I assumed it was server side based on my experience that it feels faster. This change is not about grouping, but using openstack filters to limit servers before grouping. If you can limit servers before grouping I think performance gain starts from here: https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/inventory/openstack.py#L223 Also I think openstacksdk "filters" allow more complex scenarios than grouping only. Here is the actual filtering done: I missed your comment about automatic meta groups. That would us to define only filters and use meta groups only. Wouldn't that be what most users want? Use metadata as groups and don't want to see unnecessary servers and write host patterns. |
@Turmio For plays with hostpattern 'all' the best choice is to use the '--limit' during ansible run. This limit support the same patterns:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html |
Hello @ITD27M01 While I agree that server side API is better I disagree using it in this plugin. Inventory plugin has only one requirement and that is to openstacksdk. So I think it is natural to use "filters" from openstacksdk. Also this solution is not illusion. It is generally good practice to filter as early it can be implemented. Filters and groups are implementation to different problem. "Filters" remove completely hosts that does not belong to that inventory and "groups" maps hosts to desired groups. I don't understand how does this make simple things difficult. There is no need to use "filters" as it is optional and it adds capability to filter without creating unnecessary groups. I know how to use host patterns. What I am trying to tell you is that we have product which provides ready to use playbooks. All user need is to select or create is an inventory. We have (currently) dozens of users. I don't want to train each of them (and future) users to use different limits with OpenStack than when using same playbooks and ad-hoc commands in different environment. That kind of destroys one of the reasons using Ansible as configuration management tools. About using Nova API: About performance: |
Hi @Turmio
During inventory processing the "metadata" key should be removed from filters:
As you can see the OpenStackSDK needs a litle change:
What do you think? |
shipit |
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.
shipit
shipit |
Should this have |
@@ -192,9 +210,14 @@ def parse(self, inventory, loader, path, cache=True): | |||
|
|||
expand_hostvars = self._config_data.get('expand_hostvars', False) | |||
fail_on_errors = self._config_data.get('fail_on_errors', False) | |||
filters = self.templar.template(self._config_data.get('filters', 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.
I think instead of templating this particular option here it should be added in a more general way. Have you seen #58288?
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.
Hi!
I haven't seen that PR but I'll agree that is the right way to do this.
This new option doesn't really make sense if templating is not included, In that case some other templating mechanism / scripting must be used to achieve dynamic / environment aware filtering.
How about merging this as it is for now and removing templating after #58288 is merged? There seems to failing tests and I wouldn't want to wait if it makes to 2.9.
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.
👍 this seems like a sensible approach.
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.
I marked this as resolved based on @cloudnull's comment and because of #58288 is still failing in CI.
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.
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.
@s-hertel nice!
I did not notice that, I only looked status of original PR. So I should wait that your PR is merged and revert that change which added templating?
@@ -192,9 +210,14 @@ def parse(self, inventory, loader, path, cache=True): | |||
|
|||
expand_hostvars = self._config_data.get('expand_hostvars', False) | |||
fail_on_errors = self._config_data.get('fail_on_errors', False) | |||
filters = self.templar.template(self._config_data.get('filters', 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.
👍 this seems like a sensible approach.
shipit |
Can you please explain what else should be done to merge this PR (finally)? |
Could anyone explain in simple words, what the problem with this filtering? Does openstack really cannot limit http response by metadata? Does it always return the whole project with thousands of servers for a client and client should process it on his side? If so, this sounds bad. Looks like it is lack of basic API functionality. |
hey @ailjushkin , IDK why this is taking so long to get in... :( @Turmio it looks like its in need of a rebase at this point. Can you resolve the merge conflict so we can try and get this in, again? |
Thanks for submitting patch for Openstack Ansible modules! |
@sshnaidm so someone can close this PR ? |
I think it's on Ansible cores, I don't have permissions to close it. |
Closing as per #51401 (comment) |
SUMMARY
Added support for OpenStack SDK filters option to inventory plugin.
ISSUE TYPE
COMPONENT NAME
OpenStack inventory plugin
ADDITIONAL INFORMATION
I use our case as example:
We want to create automatically environment from pull request (multiple virtual machines, networks etc.). Our and 3rd party software are installed and configured with Ansible. We use Heat templates to describe resources and use unique identifier for each environment.
With filters implementation we can use metadata to get only those virtual machine belonging to one pull request: