[英]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.