ctdk / goiardi

A Chef server written in Go, able to run entirely in memory, with optional persistence with saving the in-memory data to disk or using MySQL or Postgres as the data storage backend. Docs: http://goiardi.readthedocs.io/en/latest/index.html
http://goiardi.gl
Apache License 2.0
280 stars 39 forks source link

Unexpected Search Index merge precedence #82

Open hynd opened 4 years ago

hynd commented 4 years ago

Describe the bug Searching by a node attribute set at different precedence levels gives unexpected results. For example, if attribute "x" is false at the default level but true at the normal level, a search for x:true returns no results.

The Node data is saved correctly (at different levels) in the node table, and a knife node show my.host shows prometheus.enabled as true in Attributes, but false in default attributes. However, after indexing, only a single entry in the search_items table for "x" is stored as false:

goiardi=> select * from search_items where path ~ 'prometheus.enabled' and item_name = 'my.host';
    id    |    item_name    | value |       path
----------+-----------------+-------+-------------------------
 25599967 | my.host         | false | prometheus.enabled

I think this is because walking/merging down through the Field()s returned from reflection of the Node object is performed in the order they are defined in the Node struct - "Automatic", "Normal", "Default", "Override".

I think the order should probably be "Default", "Normal", "Override", "Automatic"? Reordering the Node struct fields then gives me the expected results for searches (after reindexing). It's a small fix, but i wanted to check the existing ordering wasn't intentional?

(the stability/predictability of the struct field ordering was confirmed by Ian Lance-Taylor here: https://groups.google.com/g/golang-nuts/c/_he7g1TL0K8/m/8BBCFB0tCgAJ)

To Reproduce Converge a node with attributes set differently at the different precedence levels, search.

Expected behavior Searching for attribute values set differently at the "automatic" or "normal" level should take precedence over those set at the "default" level.