Question #10291
closedproperties file in /var/rudder/share/<node-id>/rules/cfengine-community/properties.d not being picked up by node
Description
The properties file properties.json in /var/rudder/share/<node-id>/rules/cfengine-community/properties.d contains the following contents:
-------------------------------
{
"properties":
{
"datcenter": [{"location": "Andover"}]
}
}
-------------------------------
I have a variable defined in an MOTD directive that does not get translated : ${node.properties[datacenter][location]}
A screenshot of the directive is attached.
My /etc/motd on the client comes out with the following contents:
[root@rclient41-1 ~]# more /etc/motd
aaaaa
${node.properties[datacenter][location]}
What am I doing wrong? I 'm not sure that I understand how this is supposed to work.
Thanks
Files
Updated by François ARMAND almost 8 years ago
The syntaxe [a][b] means "a.b" in a json-y translation. So the the properties file should be:
{ "properties": { "datcenter": {"location": "Andover"} } }
without the []
Hope it helps.
You can also set node properties via the API (http://www.rudder-project.org/rudder-api-doc/#api-Nodes-updateNode) or in the coming 4.1 beta, directly in node property UI.
Updated by Hamlyn Mootoo almost 8 years ago
I changed it:
[root@rserver41 properties.d]# pwd
/var/rudder/share/de2a384b-3650-488c-90b3-1dffd7be6609/rules/cfengine-community/properties.d
[root@rserver41 properties.d]# more properties.json
{
"properties": {
"datacenter": {"location": "Andover"}
}
}
[root@rserver41 properties.d]#
However it still does not translate it, and on the client machine it shows:
[root@rclient41-1 ~]# cd /var/rudder/cfengine-community/inputs/properties.d/
[root@rclient41-1 properties.d]# more properties.json
{
"properties":{}
}
[root@rclient41-1 properties.d]#
It does not seem to be transferring the properties.json for the node.
Updated by Hamlyn Mootoo almost 8 years ago
Sounds good. I sent you some credentials via email.
Updated by François ARMAND almost 8 years ago
I now understand what the problem was. It works as intended but the documentation is clearly misleading and let you think that it was working somehow differently.
So, to sum-up:
You can add "node properties" to a node. These properties are visible in the node details page, on tab "properties". When properties are modified, a policy generation is started, which deletes directory /var/rudder/share/xxx-node-id-yyy/rules/
and then generated it again, with the file /var/rudder/share/xxx-node-id-yyy/rules/cfengine-community/properties.d/properties.json
. A generation also put a time-stamp in files /var/rudder/share/xxx-node-id-yyy/rules/cfengine-community/rudder-promises-generated
(and rudder_promises_generated
- fir compatibility reasons). A node only download rules files during an update if that timestamp is more recent than the one it downloaded the last time.
So, when you run "rudder agent update
", the node look if it should download policies from its policy server based on the timestamp. If so, it copies them.
And then, when you run "rudder agent run
", it executes everything that should be done to matches to rules.
Finally, about node properties expansion. There is two mode, one which is doing expansion during policy generation on the server, one other (when you add ${...|node}) which is doing it on the node during "rudder agent run
". The first will fails a generation if the property can't be expanded, the second won't check anything and let the agent do its business. And the behaviour of the agent is to not change anything if it doesn't find the requested property.
So, now that some context was set, this what I think you were doing: you were changing the property file on the server and not actually setting a property on the node. That either get replaced on the next policy generation, or wasn't downloaded due to the timestamp check done by the node. So you ended with the property not defined on the node, and let unchanged (because not found) in motd.
You can do some tests by changing the file "/var/rudder/cfengine-community/inputs/properties.d/properties.json
" on the node, and only run "rudder agent run
". You get a "repaired" for MOTD and the file is updated. But of course, that modification will be overriden on the next update.
What you should have done if the doc let you understand that is to define a property on the node with the API:
curl -k -H "X-API-Token: xxxxxxxxxxx" -H "Content-Type: application/json" -X POST https://rudder-server/rudder/api/latest/nodes/xxxx-yyyy-node-id-zzzz -d'{"properties":[{"name":"datacenter","value":{"location":"france-datacenter-42"}}]}'
Or, with a "property.json" file containing that:
{ "properties":{ "datacenter":{ "France":"france-datacenter-42" } } }
curl -k -H "X-API-Token: xxxxxxxxxxx" -H "Content-Type: application/json" -X POST https://rudder-server/rudder/api/latest/nodes/xxxx-yyyy-node-id-zzzz -d@property.json
And use it (with or without the ${..|node}) in motd like you did.
Or you could have defined a rule executed before motd one with the goal to build node-local context of properties. Some users are doing that to be able to have a common set of properties for all node, even for proerties that can only be known on the node with scripts.
But it does not seem like a simple way to do things. So, the next natural question is "but why the hell is it so hard to use properties, and what is the purpose of having a ${...|node} parameter if you still need to have it defined on node properties?"
We have for now limited the scope of the functionnality to be sure to build a consistant API. It is not apparant at first sight, but the life cycle of node properties combined with the policy generation one and the updates is an hot knot of functionnalities. You can easily ends-up with uncorrectly synchronized properties, or expected reports (as you saw). We keep it minimalist to be able to add things in it, which is always easier for backward compabilities than to try to remove some.
So, some answers are coming in Rudder 4.1. In Rudder 4.1, you will be able to:
- add and rmeove node properties directly from the node details page. No longer forced to use API!
- add a post-policy-generation hook to add your own properties after generation, and have them correctly dispatched to nodes.
- and you will be able to use, if you want, the "data sources" plugin which allow to gather properties from external REST API: https://github.com/Normation/rudder-plugin-datasources/
Hope it helps!
Updated by François ARMAND almost 8 years ago
- Status changed from New to Discussion
- Assignee set to François ARMAND
Updated by Hamlyn Mootoo almost 8 years ago
Well after several re-readings of what you wrote, and some tests of my own, I think I understand, but let me summarize to make sure I'm correct:
1. There is no way (currently) other than the API to set a property for a node, on the server.
2. Simply editing the properties.json file for the node on the server will have no effect because it will not be copied to the node and actually just get overwritten.
3. I could temporarily modify the properties.json on the node, and it would work, but as soon as a full policy regeneration happens it will get overwritten, and go back to whatever was set with the API (assuming there was an API call previously, to set a node property for the node, on the server)
Are any/all of these statements true?
Updated by François ARMAND almost 8 years ago
All correct!
For 2/, you can force the copy by changing the timestamp in rudder_promises_generated/rudder-promises-generated, for example adding 1. It will make the copy works, but as you understood, it will be overriden afterward.
Updated by François ARMAND almost 8 years ago
- Status changed from Discussion to Resolved
Hamlyn Mootoo, I'm marking the question as resolved, but don't hesitate to reopen it or ask for more information if needed.