问题
I want to edit ec2 node's node_data using a knife node
command.
I can manually do it by using below command.knife node edit NODE_NAME
It will generate a json which I need to edit.
"name": "NODE-1",
3 "chef_environment": "test",
4 "normal": {
5 "node_data": {
6 "version": "23690ecc9c572e47db242bfad1296388f91da1e9",
7 "depot_path": "https://s3.amazonaws.com/builds/",
8 "source_repo": "softwares/"
9 },
10 "tags": [
11
12 ]
13 },
14 "run_list": [
15 "role[my-role]"
16 ]
17 }
I want to edit node_data
in that json.
If I had to edit run_list the there is a command for thatknife node run_list add node 'role[ROLE_NAME]'
I need something similar to this command.
回答1:
It sounds like you want a scriptable/non-interactive way to set an attribute of a given node. You can use knife exec
for this.
For your given example, suppose you want to get and set the value of source_repo
in node_data
for "NODE-1". You could achieve this by running:
knife exec -E "nodes.find(:name => 'NODE-1') { |node| node['node_data']['source_repo'] = '/new/path/softwares/'; node.save; }"
Note the node.save
at the end: this will make the chef server save your changes. If this is missing in the command, then it's a temporary change that is not saved on the chef server.
To confirm that the attribute has indeed changed on the chef server, you can get the current value like this:
knife exec -E "nodes.find(:name => 'NODE-1') { |node| puts node['node_data']['source_repo'] }"
You should see: /new/path/softwares/
as the output of the above command.
By the way, note that node['node_data']['source_repo']
is equivalent to (and can be replaced with) node.node_data.source_repo
回答2:
I have added a knife plugin to add to node_data.
require 'chef/knife'
require 'chef/knife/core/node_presenter'
class Chef
class Knife
class NodeJson_dataUpdate < Knife
deps do
require 'chef/node'
require 'json'
end
banner "knife node json_data update [NODE] [JSON_NODE_DATA]"
def run
node = Chef::Node.load(@name_args[0])
node_data = @name_args[1]
update_node_data(node, node_data)
node.save
output(node.normal.node_data)
end
def update_node_data(node,node_data)
parsed_node_data = JSON.parse(node_data)
parsed_node_data.each do |key,val|
if key.empty?
print "ERROR: Key is empty for value- "+val+". Not adding this to node_data.\n"
else
node.normal.node_data[key]=val
end
end
end
end
end
end
回答3:
if you want to
add new attribute
knife exec -E "nodes.find(:name => 'NODE-1') { |node| node.normal_attrs[:attribute_name]='Value' ; node.save; }"
Need to update attribute
its depends on node attribute type
if node attribute is json then run this command
knife exec -E "nodes.find(:name => 'NODE-1') { |node| node.normal_attrs['node_data'][:attribute_name]= 'Value' ; node.save; }"
if node attribute in array type
knife exec -E "nodes.find(:name => 'NODE-1') { |node| node.normal.tags << {'attribute_name'=>'Value',''=>}; node.save; }"
来源:https://stackoverflow.com/questions/19021289/how-can-i-edit-a-chef-attribute-of-an-ec2-node-using-knife