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



我有点被这个难住了…我很清楚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"

我试图实现在如何在节点对象厨师存储数组布局的策略?使用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

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

# 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                                                                                                                                                                                         

问题已解决。执行块运行数组中最后一项的原因是执行资源的名称是静态的。有一次我添加了"each_with_index"然后将其与文件名连接起来,并以相同的方式重新命名执行块,它解决了我的问题,现在工作一致。我希望这能帮助到其他人!!

相关内容

  • 没有找到相关文章