繁体   English   中英

在 Chef 自定义资源的 for 循环中获取哈希数组中的最后一项

[英]Getting the last item in an array of hashes in my for loop in a Chef custom resource

我有点被这个难住了......我很清楚 Chef 运行阶段和编译阶段之间的概念,但我似乎仍然无法弄清楚我需要完成什么。

我认为在How to store array in node object chef? 中列出的解决方案? 可能对普通配方有所帮助,但我正在尝试创建一个自定义资源,该资源基本上读取具有以下结构的数据包:

  {                                                                                                                                                                    
  "id": "local_files",                                                                                                                                               
  "development":                                                                                                                                                     
    [                                                                                                                                                                
      {                                                                                                                                                              
        "source": "https://sourcecode.mydomain.com/projects/ASX-NBJG/repos/sapops/raw/config/lama/Z_LVM_CheckBackup.conf?at=refs%2Fheads%2Ffeature%2FADVR-575-as-a-basis- 
user-i-want-to-be-able-to-use-chef-to-copy-files-locally-to-servers",                                                                                                
        "target": "/tmp/some_folder/Z_LVM_CheckBackup.conf",                                                                                                         
        "owner": "root",                                                                                                                                             
        "group": "root",                                                                                                                                             
        "mode": "0777",                                                                                                                                              
        "action": "create",                                                                                                                                          
        "run_command" : "echo 'hello my beautiful world' > /tmp/helloworld.txt"                                                                                      
      },                                                                                                                                                             
      {                                                                                                                                                              
        "source": "https://sourcecode.mydomain.com/projects/ABCD/repos/build/raw/copylocal/sudoerspolicy?at=refs%2Fheads%2Ffeature%2FADVR575CopyLocal",   
        "target": "/etc/sudoers.d/mysudoers",                                                                                                                       
        "owner": "root",                                                                                                                                             
        "group": "root",                                                                                                                                             
        "mode": "0440",                                                                                                                                              
        "action": "create",                                                                                                                                          
        "run_command" : "echo \"sudoers file updated on `date`\" |tee -a /tmp/sudoers_updated.log"                                                                   
      },                                                                                                                                                             
      {                                                                                                                                                              
        "source": "file:///erpsoftware/auto/copylocal/testtar.tar",                                                                                               
        "target": "/tmp/testtar.tar",                                                                                                                                
        "owner": "root",                                                                                                                                             
        "group": "root",                                                                                                                                             
        "mode": "0440",                                                                                                                                              
        "action": "create",                                                                                                                                          
        "run_command" : "mkdir -p /tmp/letsSeeHowItGoes && tar -xvf /tmp/testtar.tar -C /tmp/letsSeeHowItGoes"                                                       
      },   
 ],       
"qa":                                                                                                                                                     
    [                                                                                                                                                                
      {                                                                                                                                                              
        "source": "https://sourcecode.mydomain.com/projects/ASX/repos/ops/raw/config/stuff/Z_LVM_CheckBackup.conf?at=refs%2Fheads%2Ffeature%2FADVR-575-as-a-basis- 
user-i-want-to-be-able-to-use-chef-to-copy-files-locally-to-servers",                                                                                                
        "target": "/tmp/some_folder/Z_LVM_CheckBackup.conf",                                                                                                         
        "owner": "root",                                                                                                                                             
        "group": "root",                                                                                                                                             
        "mode": "0777",                                                                                                                                              
        "action": "create",                                                                                                                                          
        "run_command" : "echo 'hello my beautiful world' > /tmp/helloworld.txt"                                                                                      
      }
   ]

资源调用:

copy_local 'Ensure all files that need to be copied locally are handled...' do
  databag_itemid node['srv']['copylocal_databag_id']
  action :from_databag
end

我遇到的问题是,即使我删除了第一个文件,我的代码选择的“run_command”始终是哈希数组中的最后一项。

我有一个像这样的简单循环:

resource_name :copy_local

property :databag_itemid, String
property :databag_auth_required, [true, false], default: true
property :databag_name, String, default: node['srv']['databag_name']
property :databag_env, String, default: node['scm_appbranch'].downcase
property :secret_databag_itemid, String, default: 'sa'
property :secret_keysrc, String, default: node['srv']['sa_sec_key_src']
property :secret_key, String, default: node['srv']['sa_secret_key']
property :service_acctname, String, default: 'service_account'
property :service_acctpwname, String, default: 'service_account_pw'
property :files, Hash
property :files_env, String, default: node['scm_appbranch'].downcase
property :debug, [true, false], default: false

  action :from_databag do
  
  # load variables
  skey      = new_resource.secret_key
  skeysrc   = new_resource.secret_keysrc
  sdbid     = new_resource.secret_databag_itemid
  dbenv     = new_resource.databag_env
  dbid      = new_resource.databag_itemid
  dbname    = new_resource.databag_name
  dbauthreq = new_resource.databag_auth_required
  saname    = new_resource.service_acctname
  sapwname  = new_resource.service_acctpwname
  dbg       = new_resource.debug

  # DL the secret
  remote_file skey do
    source skeysrc
    action :nothing
    sensitive true
  end.run_action(:create)

  # Load the secret and try to decrypt
  secret = Chef::EncryptedDataBagItem.load_secret(skey)
  begin
    credentials = data_bag_item(dbname, sdbid, secret)
    user        = credentials[saname]
    password    = credentials[sapwname]
  rescue StandardError => msg
    puts 'ERROR :: Could not get credentials from encrypted databag!!!'
    raise msg
  end

  # load the data bag item for copy local functionality
  all_local_files = data_bag_item(dbname, dbid)

  # load the hash
  my_files = missing?(all_local_files[dbenv]) ? all_local_files : all_local_files[dbenv]

  # now loop through files and begin local copy via the remote_file resource
  # This loop does not work, need to find a way to loop through and not only get the last item of the array
  auth = "Basic #{Base64.encode64("#{user}:#{password}")}"
  my_files.each do |file_obj|
    Array.wrap(file_obj).each do |file|
      # check all flavors for each file object
      checks = check_all_flavors(file)
      unless checks.has_value?(false)
        
        # Debug
        puts " :: D E B U G :: ==> file source     : #{file['source']}" if dbg
        puts " :: D E B U G :: ==> file target     : #{file['target']}" if dbg
        puts " :: D E B U G :: ==> file mode       : #{file['mode']}" if dbg
        puts " :: D E B U G :: ==> file owner      : #{file['owner']}" if dbg
        puts " :: D E B U G :: ==> file group      : #{file['group']}" if dbg
        puts " :: D E B U G :: ==> file action     : #{file['action']}" if dbg
        puts " :: D E B U G :: ==> file run_command: #{file['run_command']}" if dbg

        # Create the directory for the parent folder of the file['target'] if it doesn't exist
        directory dir_name(file['target']) do
          recursive true
          mode   file['mode']
          owner  file['owner']
          group  file['group']
          action :create
          not_if { dir_exists?(dir_name(file['target'])) }
        end

        # use remote_file resource to copy the file locally
        remote_file file['target'] do
          source file['source']
          mode   file['mode']
          owner  file['owner']
          group  file['group']
          headers('Authorization' => auth) if dbauthreq
          action file['action']
          notifies :run, 'execute[run-command-for-copy-local-databag]', :immediately unless missing?(file['run_command'])
        end

        # resource to execute any command specified in copy local attributes
        # allows us to "copy local and execute a command"
        execute 'run-command-for-copy-local-databag' do
          command     file['run_command']
          environment file['run_env']
          creates     file['run_creates']
          cwd         file['run_cwd']
          group       file['run_group']
          user        file['run_user']
          action      :nothing
        end
      end
    end
  end

  # # delete secret file once data bag is decrypted successfully
  # file skey do
  #   action :delete
  # end

end

但正如我所提到的,执行的不是附属的“run_command”,而是列表中的最后一个“run_command”。 对我来说,这似乎是一个非常直接的循环,并且对所有者、组和权限都有效,但我的“run_command”执行资源块似乎总是在获取数据包中的最后一项。 意思是,即使我故意删除/tmp/some_folder/Z_LVM_CheckBackup.conf文件,当它应该触发附属的echo "hello my beautiful world"命令时,它正在运行 rum_command 键列表中的最后一个命令: "run_command": "mkdir -p /tmp/letsSeeHowItGoes && tar -xvf /tmp/testtar.tar -C /tmp/letsSeeHowItGoes"

我尝试实施How to store array in node object chef? 中列出的策略? 使用 node.run_state 但这也没有给我任何运气。 在这一点上非常难过,非常感谢任何帮助。

谢谢! 史蒂夫

所以我能够通过使我的执行块“独一无二”来解决这个问题。 我这样做了:

  my_files.each_with_index do |file_obj, index|                   
    Array.wrap(file_obj).each do |file|                           
      # check all flavors for each file object                    
      checks = check_all_flavors(file)                            
      unless checks.has_value?(false)                             
                                                                  
        # set cmd file for correct execution of commands          
        cmd_filename = "file #{index}: \"#{file['target']}\"".to_s

然后像这样调用我的执行资源:

    # use remote_file resource to copy the file locally                                                                                  
    remote_file file['target'] do                                                                                                        
      source file['source']                                                                                                              
      mode   file['mode']                                                                                                                
      owner  file['owner']                                                                                                               
      group  file['group']                                                                                                               
      headers('Authorization' => auth) if dbauthreq                                                                                      
      action file['action']                                                                                                              
      notifies :run, "execute[run-command-for-copy-local-databag for #{cmd_filename}]", :immediately unless missing?(file['run_command'])
    end          

    # resource to execute any command specified in copy local attributes
    # allows us to "copy local and execute a command"                   
    execute "run-command-for-copy-local-databag for #{cmd_filename}" do 
      command     file['run_command']                                   
      environment file['run_env']                                       
      creates     file['run_creates']                                   
      cwd         file['run_cwd']                                       
      group       file['run_group']                                     
      user        file['run_user']                                      
      action      :nothing                                              
    end                                                                                                                                                                                         

问题现已解决。 执行块运行数组中最后一项的原因是因为执行资源的名称是 static。一旦我添加了一个“each_with_index”,然后将其与文件名连接,并以相同的方式重命名执行块,它解决了我的问题,现在一直在工作。 我希望这可以帮助别人!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM