I'm trying to create a recipe to deploy Remote Desktop Services to Windows Servers, everything is working as expected apart from the Application deployment resource I created - it's a simple resource but I'm having a lot of issues passing the applications to be deployed as a hash array.
attributes\default.rb
default['app']['app_options'] = [{
app1:{
connection_broker: 'serv-01',
options: {
collectionname: 'Terminal Services', alias: 'Acrobat', displayname: 'Adobe Acrobat', filepath: 'C:\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe', filevirtualpath: 'C:\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe', ommandlinesetting: 'DoNotAllow', iconindex: 0, iconpath: '\\\\serv-01\\C$\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe', usergroups: ['domain\\group'], showinwebaccess: 1
}
},
app2:{
connection_broker: 'serv-01',
options: {
collectionname: 'Terminal Services', alias: 'Accounts', displayname: 'Accounts', foldername: 'Accounts', filepath: 'D:\\Accounts\\Accounts.bat', filevirtualpath: 'D:\\Accounts\\Accounts.bat', commandlinesetting: 'DoNotAllow', iconindex: 0, iconpath: 'C:\\Windows\\System32\\cmd.exe', usergroups: ['domain\\group'], showinwebaccess: 1
}
}
}]
recipes\remote_desktop.rb
rdapps = node.read('app', 'app_options') || []
rdapps.each do |app|
remote_desktop_apps app['options']['alias'] do
action :create
connection_broker app['connection_broker']
app_options app['options']
end
end
resources\remote_desktop_apps.rb
resource_name :remote_desktop_apps
property :connection_broker, String,
desired_state: false
property :app_options, [String, Hash, Array],
desired_state: false
action :create do
app_options.each do |k,v|
script << "New-RDRemoteApp -ConnectionBroker "#{connection_broker}" {-#{k.to_s.capitalize} #{v}}.join(' ')}"
end
end
When running the recipe in Test Kitchen, I get the below error:
================================================================================
Recipe Compile Error in C:/Users/ADMINI~1/AppData/Local/Temp/kitchen/cache/cookbooks/windows_/recipes/remote_desktop.rb
================================================================================
NoMethodError
-------------
undefined method `[]' for nil:NilClass
Edit
Thanks to @seshadri_c for the help past the first hurdle, I've hit another issue which seems related to the attributes.
Here is the output of a kitchen converge
================================================================================
Error executing action `create` on resource 'remote_desktop_apps[Acrobat]'
================================================================================
Chef::Exceptions::ValidationFailed
----------------------------------
name is a required property
Resource Declaration:
---------------------
# In C:/Users/ADMINI~1/AppData/Local/Temp/kitchen/cache/cookbooks/rh_windows/recipes/remote_desktop.rb
76: remote_desktop_apps app['options']['alias'] do
77: action :create
78: connection_broker app['connection_broker']
79: app_options app['options']
80: end
81: end
Compiled Resource:
------------------
# Declared in C:/Users/ADMINI~1/AppData/Local/Temp/kitchen/cache/cookbooks/rh_windows/recipes/remote_desktop.rb:76:in `block in from_file'
remote_desktop_apps("Acrobat") do
action [:create]
default_guard_interpreter :default
declared_type :remote_desktop_apps
cookbook_name "windows_"
recipe_name "remote_desktop"
connection_broker "serv-01"
app_options {"collectionname"=>"Terminal Services", "alias"=>"Acrobat", "displayname"=>"Adobe Acrobat", "filepath"=>"C:\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe", "filevirtualpath"=>"C:\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe", "commandlinesetting"=>"DoNotAllow", "iconindex"=>"0", "iconpath"=>"\\\\serv-01\\C$\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe", "usergroups"=>["domain\\group"], "showinwebaccess"=>"1"}
end
Then there's this message at the end of the run:
FATAL: Chef::Exceptions::ValidationFailed: remote_desktop_apps[Acrobat] (rh_windows::remote_desktop line 76) had an error: Chef::Exceptions::ValidationFailed: name is a required property
$$$$$$ Exception calling "Read" with "3" argument(s): "Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection."
At line:100 char:11
$$$$$$ if ($fs.Read($bytes, 0, $fs.Length) -gt 0) {
$$$$$$ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : ArgumentException
CodePudding user response:
The reason for this error is that the array of hashes has different keys app1
and app2
. So each time we iterate over rdapps
we'll get a different key. This way we won't be able get the sub-elements such as app['options']['alias']
.
So you can adjust the attribute to something like:
default['app']['app_options'] = [
{
connection_broker: 'serv-01',
options: {
collectionname: 'Terminal Services',
alias: 'Acrobat',
displayname: 'Adobe Acrobat',
filepath: 'C:\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe',
filevirtualpath: 'C:\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe',
ommandlinesetting: 'DoNotAllow',
iconindex: 0,
iconpath: '\\\\serv-01\\C$\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe',
usergroups: ['domain\\group'],
showinwebaccess: 1
}
},
{
connection_broker: 'serv-01',
options: {
collectionname: 'Terminal Services',
alias: 'Accounts',
displayname: 'Accounts',
foldername: 'Accounts',
filepath: 'D:\\Accounts\\Accounts.bat',
filevirtualpath: 'D:\\Accounts\\Accounts.bat',
commandlinesetting: 'DoNotAllow',
iconindex: 0,
iconpath: 'C:\\Windows\\System32\\cmd.exe',
usergroups: ['domain\\group'],
showinwebaccess: 1
}
}
]
Then we can get this working as expected:
rdapps = node.read('app', 'app_options') || []
rdapps.each do |app|
remote_desktop_apps app['options']['alias'] do
action :create
connection_broker app['connection_broker']
app_options app['options']
end
end