Project

General

Profile

User story #4670

Updated by François ARMAND almost 7 years ago

 
 h2. Original question 

 I had raised a question on the mailing list about injecting arbitrary items into the inventory, and was asked by Francois Armand to open a ticket.    The subject of that email was "Class definition".    What I was wondering is how much work it would be to add the ability to hook into something like the "addInformationsToInventory" bundle to add user defined information. 

 What I was struggling with was how to define classes like I would in plain cfengine.    There, I can define a class based on pretty much anything, and then use that to conditionally run different promises.    Also, with cf-hub, you also gain the ability to query classes that have been defined.    I like the both the inventory aspect of rudder and the ability to query it, and thought that I could mimic much of what I was doing with plain cfengine classes with your inventory if I could add arbitrary information. 

 I'm not sure what would be required to make the web interface handle this, and it looks like a bit of thought would have to go into the LDAP schema.    Either way, it seemed like it would be a nice feature. 

 h2. Proposed solution 

 When doing an inventory, the agent will run executables (script, binaries, whatever) located in `/var/rudder/hooks.d` sequentially. Each scripts is expected to procuce a JSON object output (not a JSON array).  

 These output are join together in a JSON array and are put into a new "CUSTOMPROPERTIES" element: 

 <pre> 
 <CUSTOMPROPERTIES>[{"hook1": json1},{"hook2_key1":json21, "hook2_key2":json22}]</CUSTOMPROPERTIES> 
 </pre> 


 Each key is added as the name of a node property with the "inventory" provider, so with the example, the node will get *3* properties: `("hook1", json1)`, `("hook2_key1", json21)`, `("hook2_key2", json22)`. 

 Remarques about property name unicity:  

 - if two inventory custom properties have the same name, only one is kept (not specified which one, you should really avoid that) 
 - if a node property and an inventory custom property share the same key name, the *inventory* property overrides the node one 

 Of course, you can use naming convention so that it does not happen, but you also have to possibility to use that mecanism for default value overriding when the inventory knows something more about the node. And you can also use convention + ${node.properties[key1] | default = ${node.properties[inventory-key1]} to get override the other way around.  

 h3. Other possible choices for inventory custom properties merge in node properties 

 h4. Make node properties overrides custom inventory properties 

 With that choice, we keep most of above spec but we reverse the overriding order: if a custom inventory property and a node property have the same name, then the node property is chosen.  

 I prefer the other one because it follows the same semantic as for datasources: the non-user-updatable property is the one used (it has a kind of "state of fact" semantic).  

 In all case, you use you own namespacing convention to avoid overriding.  

 h4. Make what overrides what configurable 

 "When there is no provable good choice in all case, make it configurable".  
 That can be good, but I fear the added complexity: do we want a global parameter? More likelly a by key-name one, because the output of that hook states the reallity, but on that other case, it's just better to keep what the user want. Oh, but in fact, that configuration should be made on a node by node basis... 

 And I'm not even sure of the gain, because I believe all (?) cases can be covered tody with convention, node properties default value syntax, and for exceptionnal cases JS scripting.  

 h4. Put all custom properties under the same "inventry properties" key 

 For now, we took as a given that each key:value pair from inventory custom properties get a corresponding node property. But we could merge all inventory custom properties under only one node property like "inventory property". Then the user will just need to go one layer deeper to get the previous key:value pair.  

 It makes getting to the actual value a little less direct, but at least there is no imposed overriding, and the user choose what he want in all cases.  
 The main problem is that for now, we don't have a nice search UI for JSON (see #9299) 

 ((( further thinking on that point:  
 And in fact, we could even go one step further: have an "inventory" key, with a subkey "properties" with CUSTOMPROPERTIES content, and why not in the future an "os" key, a "networkInterfaces" one, etc.  

 But that would make for some nice duplication in node details information (via REST api espcially) and it would make search etc more cumbersome.  
 ))) 
 h2. Implementation details 

 Inventory custom properties are stored in the the *node inventory* entry, on a "customProperty" multivalued attribute where as node properties are store in the *rudder node* entry, under a serializedNodeProperty attribute. The merge/overriding logic is done in Rudder logic, when we gather "node information".

Back