Problem:
There is no easy way to lookup all hosts that have a smart class parameter with a specific value.
A host can have overrides for a specific smart class parameter in multiple places:
Puppet class level
Host Group level
Host level
Matchers level (This level is truly different than the other levels as it allows you to specify matchers based of puppet environments, classes, facts …). See this.
What value a host gets in the end depends on the “Prioritize attribute order” field found in “Configure > Classes > (Specific Puppet Class) > Smart Class Parameter Tab > (Specific smart class Parameter)”.
Overrides on the “Host Level” (fqdn) do not seem to respect this order and they are always prioritized first.
Example: Configure > Classes > user > Smart Class Parameter Tab > ulimit_value:
**Prioritize attribute order**
fqdn
hostgroup
environment
os
domain
I have made a custom script that searches / tries to search through all of the override values by getting the override_value_order list and then going one by one.
Example: First check if the host has an override, then check if its host group has an override, then check if all the parent host groups of this hostgroup have an override (one by one), …
This blog post / Priority Lookups section / explains how Hiera searches for a correct parameter value, respecting the ordering in the hierarchy. I presume this should be easy to do for Foreman as well.
Does anyone have any information on whether this is proposed as a feature?
Yes, as @Andrew_Schofield mentioned you can search using params.<param> = <value>.
This above search option will no longer exist if you see my pull-request where I introduced parameter-type column for global parameters. In this pull-request, I have removed and replaced above option with 'name' property of parameters. In short user will able to search parameters using ‘name’ not by ‘value’.
@Ji1990, I would like to know about what is the real use case?
Please let us know above option works for you or not for now.
Thank you for taking the time to comment on my thread
Sorry for responding so late. I wanted to do some testing before responding.
It seems that Foreman treats “Global Parameters” differently from “Smart Class Parameters” (which are parameters related to puppet classes).
Personally, I haven’t used Global Parameters that much. I am more concerned with Smart Class Parameters.
From my tests it seems:
facts.<fact_name> = <value> search seems to work as intended in my eyes. It returns all hosts that have that specific fact with a name equal to <fact_name> and a value equal to <value>.
Additionally, a fact value for a specific host can be acquired by using the API: /usr/bin/curl -sS -u <admin_username>:<admin_password> "https://<foreman_server>/api/v2/hosts/<host_ID>/facts?per_page=10000?per_page=10000" | /opt/jq-linux64 ".results[].<fact_name>"
params.<param_name> = <value> search seems to only consider Global Parameters and not consider the Smart Class Parameters from the puppet classes. Maybe this behaviour changed in newer Foreman releases. I am not sure since I am on v1.15.2. I feel that this search should work like the fact search above - It should be able to retrieve all hosts that have a Smart Class Parameter with a name equal to <param_name> and a value equal to <value>.
I am not exactly sure where Global Parameters should come into the equation. Maybe have 2 search options: one for searching through Global Parameters and one for searching through Smart Class Parameters.
@kgaikwad
I am also not sure why we shouldn’t be able to search for hosts based on the value of a parameter they have, global or smart class. It’s a nice feature to have in my opinion.
Example use cases:
environment=testing and class=java and params.java_version=181. Export all these hosts to a CSV, or generate a Report Template.
For a set of hosts get the value of their java_version parameter. Maybe in a Report Template.
Currently, both of these scenarios need to be scripted.
I guess the answer to my original question, for any future reader is: /usr/bin/curl -sS -u <admin_username>:<admin_password> "https://<foreman_server>/api/v2/hosts/<host_ID>/enc?per_page=10000" | /opt/jq-linux64 ".data.classes.<puppet_class_name>.<smart_class_parameter_name>"
This should capture the enc output that Foreman sends to Puppet. Regardless of the level at which the override happened, the final value of the Smart Class Parameter for that specific host will always be in that enc output.
In order to find all hosts that have a parameter with a specific value you need to script it. Basically, you need to run the above curl for all the hosts that concern you and see if that value matches your desired value.
The reason the search isn’t possible is that smart class parameters are dynamic - their value for each host can change depending on the host’s facts and other attributes, and the override resolution order likewise (for example, if a host’s location changes, and the class parameter value has an override for a specific location). Because of this, the value is not stored in the database, but rather calculated when the enc output is generated.
Calculating the value for each host takes a certain amount of time (dependent on several factors, such as the number of overrides for the parameter), so calculating all the values for all hosts will also be a time and resource consuming action, and not something we can do on a regular basis to keep an updated searchable index.
Report templates can be a good tool for generating such reports, that can be done in a faster way than collecting all of the ENC outputs - you might need to play around with it a bit, and possibly disable safe mode, but if done correctly you could generate the values just for the parameters you care about and not all of them. Perhaps @Marek_Hulan can provide further guidance on the best way to do it. If you make such report template, and maybe make it customizable so you can select which parameter you care about using template inputs - that could be a useful contribution for community templates that get shipped to all of our users and tested regularly.
Report templates are good for many things, but does not solve the issue that final parameter values are only known when ENC is rendered. Most likely the report template would use the same search capability or ENC rendering. If we limit the scope to e.g. searching for parameters set via Domain, that might be easier, but it would still be achievable via plain search.
Another thing is, parameters can have complex values such as arrays, hashes or jsons. Then the search is even more complicated. We chat with @kgaikwad about that recently, it seems viable solution would be to store the value in second column in full text representation and perform search on this column.