I am working in Chef, trying to create/populate a ruby
hash with networking device information, as populated by nmcli
. I think the code is correct, as VS Code
isn't complaining, and it seems to run just fine in chef-shell -z
but I'm not able to query the Ruby Hash as I would expect, and I'm really starting to lose my mind.
Fresh eyes and any expert help here are appreciated, thank you!
interfaces = Hash.new
#DEVICE,TYPE
dev = Mixlib::ShellOut.new("nmcli -terse -field device,type device").run_command.stdout.split(/\n/)
dev.each do |output|
if "#{output.split(":")[1]}" == 'ethernet'
interfaces["ethernet" => "#{output.split(":")[0]}"]
elsif "#{output.split(":")[1]}" == 'wifi'
interfaces["wifi" => "#{output.split(":")[0]}"]
else
Chef::Log.debug("Interface #{output.split(":")} is not supported")
end
end
chef (17.6.18)>
=> ["wlp61s0:wifi", "enp0s31f6:ethernet", "lo:loopback"]
node[interfaces] #nil
node[:interfaces] #nil
node['interfaces'] #nil
node["interfaces"] #nil
When I attempt to edit the code, as suggested by BroiSatse
This line
interfaces["wifi" => "#{output.split(":")[0]}"]
returns the value stored in the hash under the key{"wifi" => "#>{output.split(":")[0]}"}
. It does not perform any assignment and most > likely returns nil.What you need is:
interfaces["wifi"] ="#{output.split(":")[0]}"
So I tried that, but I still get a nil response from the Hash. Here is the Chef output/error:
chef (17.6.18)> interfaces = Hash.new
chef > #DEVICE,TYPE
chef (17.6.18)> dev = Mixlib::ShellOut.new("nmcli -terse -field device,type device").run_command.stdout.split(/\n/)
=> ["wlp61s0:wifi", "enp0s31f6:ethernet", "lo:loopback"]
chef > dev.each do |output|
chef > if "#{output.split(":")[1]}" == 'ethernet'
chef > interfaces["ethernet"] = "#{output.split(":")[0]}"
chef > elsif "#{output.split(":")[1]}" == 'wifi'
chef > interfaces["wifi"] = "#{output.split(":")[0]}"
chef > else
chef > Chef::Log.debug("Interface #{output.split(":")} is not supported")
chef > end
chef (17.6.18)> end
=> ["wlp61s0:wifi", "enp0s31f6:ethernet", "lo:loopback"]
chef (17.6.18)> node[interfaces] #nil
=> nil
chef (17.6.18)> node[:interfaces][:ethernet] #nil
(irb):95:in `<main>': undefined method `[]' for nil:NilClass (NoMethodError)
from /opt/chef/embedded/lib/ruby/gems/3.0.0/gems/chef-17.6.18/lib/chef/shell.rb:93:in `block in start'
from /opt/chef/embedded/lib/ruby/gems/3.0.0/gems/chef-17.6.18/lib/chef/shell.rb:92:in `catch'
from /opt/chef/embedded/lib/ruby/gems/3.0.0/gems/chef-17.6.18/lib/chef/shell.rb:92:in `start'
from /opt/chef/embedded/lib/ruby/gems/3.0.0/gems/chef-bin-17.6.18/bin/chef-shell:31:in `<top (required)>'
from /usr/bin/chef-shell:158:in `load'
from /usr/bin/chef-shell:158:in `<main>'
chef (17.6.18)> node['interfaces'] #nil
chef (17.6.18)> node["interfaces"] #nil
=> nil
chef (17.6.18)>
UPDATE: Monday May 2, 2022 12:08 PST
When I do this command I can see that there is data in the Hash ... but all attempts to actually query the data fail ... I don't know what I'm doing wrong:
chef (17.6.18)> puts "#{interfaces}"
{"wifi"=>"wlp61s0", "ethernet"=>"enp0s31f6"}
=> nil
chef (17.6.18)>
CodePudding user response:
Just call
interfaces["ethernet"]
or
interfaces["wifi"]
interfaces = {}
dev =
Mixlib::ShellOut.new("nmcli -terse -field device,type device").
run_command.
stdout.
lines(chomp: true)
dev.each do |output|
device, type_device = output.split(":")
case type_device
when "ethernet", "wifi"
interfaces[type_device] = device
else
Chef::Log.debug("Interface #{output} is not supported")
end
end
Note: there will be just one key wifi and ethernet. So if you have more devices, just last value will be used
CodePudding user response:
The following line of code returns the value stored in the hsh under the key {"wifi" => "#{output.split(":")[0]}"}
. It does not perform any assignment and most likely returns nil
.
interfaces["wifi" => "#{output.split(":")[0]}"]
What you need is:
interfaces["wifi"] = "#{output.split(":")[0]}"