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

Cobbler Inventory: allow users to specify extra groups #9420

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

Ty9000
Copy link

@Ty9000 Ty9000 commented Dec 26, 2024

SUMMARY

Fix for #9419

Adds all rolled up Cobbler variables for a system to the Ansible inventory

Allows a user to specify multiple extra groups to add to the inventory

Fixed a few typos, simplify imports for required libraries

ISSUE TYPE
  • Feature Pull Request
COMPONENT NAME

inventory/cobbler.py

ADDITIONAL INFORMATION

Tested on Cobbler 3.4.0

@ansibullbot
Copy link
Collaborator

@ansibullbot ansibullbot added feature This issue/PR relates to a feature request inventory inventory plugin new_contributor Help guide this first time contributor plugins plugin (any type) labels Dec 26, 2024
@Ty9000 Ty9000 changed the title Updated to include extra groups Cobbler Inventory: Pull request to merge changes to allow users to specify extra groups Dec 26, 2024
@felixfontein felixfontein added check-before-release PR will be looked at again shortly before release and merged if possible. backport-10 Automatically create a backport for the stable-10 branch labels Dec 27, 2024
@opoplawski
Copy link
Contributor

Thanks for the contribution. I'm not sure though from first glance how extra_groups is meant to be used. Could you give a specific example? Also, it seems to be tied to want_facts also being set, which isn't mentioned in the doc string.

I also think adding the get_system_as_rendered() call is going to add significant overhead - so I think we will want to add a second want_full_facts or some other mechanism (make want_facts accept full?) to turn it on separately. My timing of ansible-inventory --list without a cache went from 2.9s to 16.5s.

Finally, as implemented the full system info is not cached (doubly important with the added overhead) and in facts breaks the second time it is run with a local cache:

'InventoryModule' object has no attribute 'token'

I think you'll want to move the calls to get_system_as_rendered() into _get_systems so you can cache everything there.

I see how it could be useful for some people though, so it definitely is worth adding.

@felixfontein
Copy link
Collaborator

so I think we will want to add a second want_full_facts or some other mechanism (make want_facts accept full?) to turn it on separately.

want_facts is currently a boolean parameter, changing it to a string with choices is dangerous since it's not fully backwards compatible. (Ansible has some magic that will make it mostly backwards compatible, but probably not fully.)

How about adding a new option that determines the level of facts (maybe facts_level with choices minimal, normal, and as_rendered or something like that?) and that will eventually replace want_facts (whose values would map to two specific choices for the new option)? That would also allow to later add even more levels.

@Ty9000
Copy link
Author

Ty9000 commented Dec 28, 2024

For extra_groups, the environment I'm in using Cobbler to declare autoinstall_meta key:value pairs in the distros, profiles, and systems for things like branch, environment (test/ops/etc), system_role, profile_role. Declaring the extra_groups allows ansible-inventory to pull those values of as group membership. We have so many systems (like 10,000+) and independent Cobbler installations that using branch, environment, profile_role really helps organize machines into groups, especially since we truly have no other way to categorize machines

Yeah, adding a new option like facts_level would work! Sorry about that! It's my first foray into this kind of thing.

As for the massive increase in timing, just curious how many systems did you have in the inventory and what version of Cobbler? We're kinda tied down a specific version of Cobbler for now and was curious if updates are increasing/decreasing overhead on API calls

Yeah, that's my bad - I didn't test the caching. The environment I'm in doesn't really work with caching of anything. We have so many systems, profiles, and distros that may change in between ansible-inventory runs...

I'll test some stuff out at work on Monday/Tuesday with the caching, fixes, et cetera and bring those home to merge in

@russoz russoz changed the title Cobbler Inventory: Pull request to merge changes to allow users to specify extra groups Cobbler Inventory: allow users to specify extra groups Dec 28, 2024
Copy link
Collaborator

@russoz russoz left a comment

Choose a reason for hiding this comment

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

hi @Ty9000 thanks for your contribution.

The new feature seems to be fine, but I left some comments on some of the other changes made.

data = c.get_profiles()
except (socket.gaierror, socket.error, xmlrpc_client.ProtocolError):
data = self.c.get_profiles()
except (gaierror, error, xmlrpc_client.ProtocolError):
Copy link
Collaborator

Choose a reason for hiding this comment

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

As a personal preference, I think it is clearer what those errors are about when prefixed with socket.. One year from now if I read this code, I would have to go back and forth to the imports to understand what's going on. In this case they are close and it would be very quick, but I think it would be a good practice to be more explicit about it. Just my $0.02

@@ -0,0 +1,2 @@
minor_changes:
- inventory/cobbler.py - fix a few typos, simplify required library imports, request full rendered variables for Cobbler system, allow end user to specify extra groups to add systems to in Ansible inventory, should not change currently expected behavior (https://github.com/ansible-collections/community.general/issues/9419)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Some required formatting changes, but also a bit of a style suggestion - we could/should be more concise in here.

Suggested change
- inventory/cobbler.py - fix a few typos, simplify required library imports, request full rendered variables for Cobbler system, allow end user to specify extra groups to add systems to in Ansible inventory, should not change currently expected behavior (https://github.com/ansible-collections/community.general/issues/9419)
- cobbler inventory plugin - fix typos, simplify required library imports, request full rendered variables for Cobbler system, allow end user to specify extra groups, should not change currently expected behavior (https://github.com/ansible-collections/community.general/issues/9419).

Please refer to the standard formatting for the changelog fragments' entries:
https://docs.ansible.com/ansible/devel/community/development_process.html#changelogs-how-to-format

The outcome of this changelog fragment can be seen in the collection changelog:
https://docs.ansible.com/ansible/latest/collections/community/general/changelog.html

@@ -180,13 +185,13 @@ def _reload_cache(self):

def _get_profiles(self):
if not self.use_cache or 'profiles' not in self._cache.get(self.cache_key, {}):
c = self._get_connection()
self.c = self._get_connection()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure I like calling the attribute c. I am fine using these shortcuts in very localised contexts, specially for short-lived vars or comprehensions, but when it comes to actual attributes it is a good practice to have meaningful names.

Someone not familiar with the code, one year from now, should be able to read one of the methods below without having to go back and forth within the code to understand what c means. connection? cache? cobbler? compute?

@ansibullbot ansibullbot added the stale_ci CI is older than 7 days, rerun before merging label Jan 6, 2025
@felixfontein
Copy link
Collaborator

Ping @Ty9000

needs_info

@ansibullbot ansibullbot added the needs_info This issue requires further information. Please answer any outstanding questions label Jan 25, 2025
@Ty9000
Copy link
Author

Ty9000 commented Jan 26, 2025

Ping @Ty9000

needs_info

Sorry! I'm on a work trip and won't be back home for a couple more weeks... This is still on my radar and I'll get some updates pushed out mid-February, if that's okay

@ansibullbot ansibullbot removed the needs_info This issue requires further information. Please answer any outstanding questions label Jan 26, 2025
@felixfontein
Copy link
Collaborator

No worries, it's mainly to make sure that PRs aren't completely abandoned :) (The bot will auto-close if nobody reacts in 2-3 months if the needs_info label is there.)

@ansibullbot ansibullbot added the needs_info This issue requires further information. Please answer any outstanding questions label Jan 26, 2025
@ansibullbot
Copy link
Collaborator

@Ty9000 This pullrequest is waiting for your response. Please respond or the pullrequest will be closed.

click here for bot help

@ansibullbot ansibullbot removed the stale_ci CI is older than 7 days, rerun before merging label Mar 8, 2025
@ansibullbot

This comment was marked as outdated.

@ansibullbot ansibullbot added the needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR label Mar 8, 2025
@ansibullbot ansibullbot removed the needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR label Mar 8, 2025
@ansibullbot ansibullbot added needs_ci This PR requires CI testing to be performed. Please close and re-open this PR to trigger CI needs_rebase https://docs.ansible.com/ansible/devel/dev_guide/developing_rebasing.html needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR labels Mar 13, 2025
Copy link
Contributor

@opoplawski opoplawski left a comment

Choose a reason for hiding this comment

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

There is still more that I don't understand and have questions about but will have to wait until later.

interface DNS names to IP addresses.
type: boolean
default: true
version_added: 7.1.0
facts_level:
Copy link
Contributor

Choose a reason for hiding this comment

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

We will want version_added for these as well.

Copy link
Author

Choose a reason for hiding this comment

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

Okay, I can do that - what version number should I put?

default: normal
extra_groups:
description:
- Comma or space-separated string containing extra groups to be added to the Cobbler inventory
Copy link
Contributor

Choose a reason for hiding this comment

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

Why a comma or space-separated string? Why not a list of strings?

Copy link
Author

@Ty9000 Ty9000 Mar 13, 2025

Choose a reason for hiding this comment

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

I guess it can be a list of strings, I'm not tied to anything specific and that portion of the code would need to be modified to read over the list

@@ -144,7 +158,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
def __init__(self):
super(InventoryModule, self).__init__()
self.cache_key = None
self.connection = None
self.cobbler_connection = None
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't get what's going on with cobbler_connection vs local_connection.

Copy link
Author

Choose a reason for hiding this comment

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

That was because @russoz wanted the self.c variable renamed to something more sensible, and that is just what I came up with. It can always be changed

@@ -326,8 +341,9 @@ def parse(self, inventory, loader, path, cache=True):
else:
groups = [host[group_by]] if isinstance(host[group_by], str) else host[group_by]
for group in groups:
group_name = self._add_safe_group_name(group, child=hostname)
self.display.vvvv(f'Added host {hostname} to group_by {group_by} group {group_name}\n')
if group:
Copy link
Contributor

Choose a reason for hiding this comment

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

Can group really be false here?

Copy link
Author

Choose a reason for hiding this comment

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

I'll have to check on that one at work tomorrow - not sure why I put that in there originally

Copy link
Author

Choose a reason for hiding this comment

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

Okay, I fixed this up - it was because host[group_by] could return a blank/null value or it can return the blank string ''. I added in another check against '' instead of if group

@felixfontein
Copy link
Collaborator

Plesae note that the PR has a conflict with the latest main brnach.

@ansibullbot
Copy link
Collaborator

@Ty9000 this PR contains the following merge commits:

Please rebase your branch to remove these commits.

click here for bot help

@ansibullbot
Copy link
Collaborator

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

plugins/inventory/cobbler.py:418:80: undefined-variable: Undefined variable 'to_text'

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

plugins/inventory/cobbler.py:418:80: undefined-variable: Undefined variable 'to_text'

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

plugins/inventory/cobbler.py:418:80: undefined-variable: Undefined variable 'to_text'

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

plugins/inventory/cobbler.py:418:80: undefined-variable: Undefined variable 'to_text'

click here for bot help

@ansibullbot ansibullbot added ci_verified Push fixes to PR branch to re-run CI merge_commit This PR contains at least one merge commit. Please resolve! and removed needs_ci This PR requires CI testing to be performed. Please close and re-open this PR to trigger CI ci_verified Push fixes to PR branch to re-run CI needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR labels Mar 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport-10 Automatically create a backport for the stable-10 branch check-before-release PR will be looked at again shortly before release and merged if possible. feature This issue/PR relates to a feature request inventory inventory plugin merge_commit This PR contains at least one merge commit. Please resolve! needs_info This issue requires further information. Please answer any outstanding questions needs_rebase https://docs.ansible.com/ansible/devel/dev_guide/developing_rebasing.html new_contributor Help guide this first time contributor plugins plugin (any type)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants