feat: publish a group the target does not have yet - #220
Merged
Conversation
A source declares what a group MEANS; who is in it is often not its to know. Device42 settles membership on its next sync, and Ansible's group_by settles it at play time -- it puts a host into an existing group of the same name and picks up the vars it finds there. The enricher skipped any group the target did not already have, which lost every variable declared for one whose members are decided elsewhere. For an inventory whose groups come from a different system that is most of them: 24 files of OS-specific vars reached nothing at all. The render side is the other half. A group with vars and no hosts was dropped as empty, so even a created group would have been thrown away between the enricher writing it and the endpoint answering -- silently, with the enricher reporting success. Emptiness is now read two ways, because the two cases are opposites. A group that named hosts and lost them all to a filter is still pruned: the filter's answer for it is nothing. A group that never named any is a declaration for members settled elsewhere, and survives. No host is added by any of it. An enricher still moves variables only.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First of two for 0.28.0.
The problem
A source declares what a group means. Who is in it is frequently not that source's to know — Device42 settles membership on its next sync, and Ansible's
group_bysettles it at play time, putting a host into an existing group of the same name and picking up whatever vars it finds there.The enricher skipped any group the target did not already have:
For an inventory whose group membership comes from a different system, that is most groups. In our estate it meant 24 files of OS-specific variables —
repositories_repos, packages, sshd, sssd, pamd — reached nothing at all, becauseoraclelinux_9exists in the declaring source and not in the Device42 one.The change, in two halves
Create the group rather than skipping it: vars, no hosts.
Render it too. A group with vars and no hosts was pruned as empty, so even a created group would have been thrown away between the enricher writing it and the endpoint answering — silently, with the enricher reporting success. Neither half is useful without the other.
The subtlety, found by an existing test
builtin_json_output_filters_via_query_paramswent red on the first attempt, and it was right to. Two empty groups are opposite cases:So emptiness is read against whether the group ever listed a member, not just against the list being empty now. Pinned by
an_emptied_group_is_pruned_but_one_that_never_had_hosts_is_kept.Verified beforehand, not assumed
AWX imports a named group carrying variables and zero hosts, and attaches the vars — probed on a throwaway DEV inventory before any of this was written:
Measured cost: 42 KB per target, against a pod sitting at 796 MiB of a 2 GiB limit. Group vars are stored once, not per member — that is the 0.26.0 design paying off.
Gates
cargo fmt --checkclean,clippy --all-targets -- -D warningsclean, 587 tests. Three new, each red before the change; one existing test inverted, because it pinned the behaviour being replaced.No host moves
An enricher still copies variables only. A shared group name cannot pull one source's hosts into another.