【问题标题】:How can I edit a chef attribute of an ec2 node using knife如何使用刀编辑 ec2 节点的厨师属性
【发布时间】:2015-02-09 21:44:45
【问题描述】:

我想使用knife node 命令编辑 ec2 节点的 node_data。
我可以使用以下命令手动完成。
knife node edit NODE_NAME
它将生成一个我需要编辑的 json。

"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 }

我想在那个 json 中编辑 node_data
如果我必须编辑 run_list,则有一个命令
knife node run_list add node 'role[ROLE_NAME]'
我需要类似这个命令的东西。

【问题讨论】:

    标签: amazon-web-services amazon-ec2 chef-infra knife


    【解决方案1】:

    听起来您想要一种可编写脚本/非交互式的方式来设置给定节点的属性。您可以为此使用knife exec

    对于您给定的示例,假设您想在“NODE-1”的node_data 中获取并设置source_repo 的值。您可以通过运行来实现:

    knife exec -E "nodes.find(:name => 'NODE-1') { |node| node['node_data']['source_repo'] = '/new/path/softwares/'; node.save; }"

    注意最后的node.save:这将使厨师服务器保存您的更改。如果命令中缺少此项,则说明这是一个临时更改,未保存在 Chef 服务器上。

    要确认厨师服务器上的属性确实发生了变化,您可以像这样获取当前值:

    knife exec -E "nodes.find(:name => 'NODE-1') { |node| puts node['node_data']['source_repo'] }"

    您应该看到:/new/path/softwares/ 作为上述命令的输出。

    顺便提一下,node['node_data']['source_repo'] 等价于(并且可以替换为)node.node_data.source_repo

    【讨论】:

    【解决方案2】:

    我添加了一个刀插件来添加到 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
    

    【讨论】:

    • 这很好用,我修改它以用作通用节点属性更新器,因为出于某种原因,Chef 默认不包含该功能...
    【解决方案3】:

    如果你愿意

    添加新属性

    knife exec -E "nodes.find(:name => 'NODE-1') { |node|   node.normal_attrs[:attribute_name]='Value' ; node.save; }"
    

    需要更新属性

    它取决于节点属性类型

    如果节点属性是 json 则运行此命令

    knife exec -E "nodes.find(:name => 'NODE-1') { |node|   node.normal_attrs['node_data'][:attribute_name]= 'Value' ; node.save; }"
    

    如果节点属性在数组类型中

    knife exec -E "nodes.find(:name => 'NODE-1') { |node|   node.normal.tags << {'attribute_name'=>'Value',''=>}; node.save; }"
    

    【讨论】:

      最近更新 更多