The "node" concept in Chef right now suffers from a conflation problem between desired node state, and actual node state. This causes a couple of problems:
- Users configure nodes (run lists, tags, attributes) and it sometimes gets overwritten by chef-client
- When editing and viewing node configuration, the data in some views are heavily confused because it is overrun by ohai attributes
Solution: split node configuration (stuff the user passes as input for the node) from runtime data (stuff detected by ohai and spit out at the end of a run) in the Chef server to avoid the config data getting overwritten when data is output (and vice versa). config and runtime are merged during GET /nodes/NAME so that things work seamlessly with Chef 10 and 11 clients.
Add a new endpoint for user-editable node configuration, called /nodes/NODE_NAME/configuration. This endpoint accepts POST, PUT, and GET. POST will create a node and update only configuration data. PUT and GET act only on this configuration data, which looks like:
{ "name": "node_name", "chef_environment": "_default", "run_list": [ "recipe[recipe_name]" ], "normal": { "tags": [ ] } }
The /nodes/NAME/runtime endpoint will have the attributes that are generated by a Chef run, and accept POST, PUT and GET. POST will create a node and update only runtime data.
{ "name": "node_name", "default": { }, "override": { }, "automatic": { } }
The /nodes/NAME endpoint will accept GET, POST, PUT and DELETE and work exactly like it currently does.
In vNext, chef-client will GET runtime and configuration data separately, and at the end will PUT either /nodes/NAME/runtime (if configuration data has not changed, the normal case) or PUT /nodes/NAME (if configuration data has changed).
knife upload, download, etc. (essentials) in vNext will put node configuration data in /nodes/NAME.json, and will relegate runtime data to /nodes/runtime/NAME.json. There will be no combined view.
knife node edit, show, and friends will work with configuration data. knife node edit, show, etc. with --runtime will work as it does now (on all data).
knife run_list commands will work with configuration data.
knife tag commands will work with configuration data.
People currently do things like mutate the run_list in a client run, as well. Maybe the client should track if it dirties any of its component data (i.e., attributes in the OO sense)?