Calling Chef::Knife::Ssh directly(?)

Folks,

I am investigating switching some of our Ruby scripts from using the
’system’ function to calling the Chef libraries directly and am not
having much success. My latest error is:

/usr/lib/ruby/gems/1.8/gems/chef-0.9.8/lib/chef/rest/auth_credentials.rb:41:
in `signature_headers’: Cannot sign the request without a client name,
check that :node_name is assigned (ArgumentError)

Below is a code snippet.

query = "role:#{role}"
knife_ssh = Chef::knife::Ssh.new()
knife_ssh.config[:config_file] = conf_file
knife_ssh.config[:identity_file] = params[“private_key”]
knife_ssh.config[:node_name] = ENV[‘HOSTNAME’]
knife_ssh.config[:client_name] = ENV[‘HOSTNAME’]
cmd_line = "hostname -f"
knife_ssh.name_args = [query, cmd_line]
sys_status = knife_ssh.run

What am I doing wrong here?

Thanks,

Ken Miles
ken.miles@infogroup.com

You might want to look in to Fabric+PyChef for this, it is actually
made for the task :slight_smile:

--Noah

On Jun 1, 2011, at 10:29 AM, Miles, Ken wrote:

Folks,

I am investigating switching some of our Ruby scripts from using the
'system' function to calling the Chef libraries directly and am not
having much success. My latest error is:

/usr/lib/ruby/gems/1.8/gems/chef-0.9.8/lib/chef/rest/
auth_credentials.rb:41:
in `signature_headers': Cannot sign the request without a client name,
check that :node_name is assigned (ArgumentError)

Below is a code snippet.

query = "role:#{role}"
knife_ssh = Chef::knife::Ssh.new()
knife_ssh.config[:config_file] = conf_file
knife_ssh.config[:identity_file] = params["private_key"]
knife_ssh.config[:node_name] = ENV['HOSTNAME']
knife_ssh.config[:client_name] = ENV['HOSTNAME']
cmd_line = "hostname -f"
knife_ssh.name_args = [query, cmd_line]
sys_status = knife_ssh.run

What am I doing wrong here?

Thanks,

Ken Miles
ken.miles@infogroup.com

It appears you have a conflict between the node_name associated with your client_key and the one you are setting with:

knife_ssh.config[:node_name]

The client key is most likely being picked up in the config file passed in with:

knife_ssh.config[:config_file]

You should make a choice to either set all values in the config file...or punt and set all values manually (ie node_name, client_key, chef_server_url etc.) in the knfe_ssh.config hash.

Seth

--
Opscode, Inc.
Seth Chisamore, Senior Technical Evangelist
IRC, Skype, Twitter, Github: schisamo

On Wednesday, June 1, 2011 at 1:42 PM, Noah Kantrowitz wrote:

You might want to look in to Fabric+PyChef for this, it is actually
made for the task :slight_smile:

--Noah

On Jun 1, 2011, at 10:29 AM, Miles, Ken wrote:

Folks,

I am investigating switching some of our Ruby scripts from using the
'system' function to calling the Chef libraries directly and am not
having much success. My latest error is:

/usr/lib/ruby/gems/1.8/gems/chef-0.9.8/lib/chef/rest/
auth_credentials.rb:41:
in `signature_headers': Cannot sign the request without a client name,
check that :node_name is assigned (ArgumentError)

Below is a code snippet.

query = "role:#{role}"
knife_ssh = Chef::knife::Ssh.new()
knife_ssh.config[:config_file] = conf_file
knife_ssh.config[:identity_file] = params["private_key"]
knife_ssh.config[:node_name] = ENV['HOSTNAME']
knife_ssh.config[:client_name] = ENV['HOSTNAME']
cmd_line = "hostname -f"
knife_ssh.name_args = [query, cmd_line]
sys_status = knife_ssh.run

What am I doing wrong here?

Thanks,

Ken Miles
ken.miles@infogroup.com (mailto:ken.miles@infogroup.com)

On Wed, Jun 1, 2011 at 10:29 AM, Miles, Ken Ken.Miles@infogroup.com wrote:

I am investigating switching some of our Ruby scripts from using the
'system' function to calling the Chef libraries directly and am not
having much success. My latest error is:

http://blog.loftninjas.org/2011/01/12/knife-reporting-apt-updates/

This may help if you haven't seen it yet.

Bryan

On Wednesday, June 1, 2011 at 10:29 AM, Miles, Ken wrote:

Folks,

I am investigating switching some of our Ruby scripts from using the
'system' function to calling the Chef libraries directly and am not
having much success. My latest error is:

/usr/lib/ruby/gems/1.8/gems/chef-0.9.8/lib/chef/rest/auth_credentials.rb:41:
in `signature_headers': Cannot sign the request without a client name,
check that :node_name is assigned (ArgumentError)

Below is a code snippet.

query = "role:#{role}"
knife_ssh = Chef::knife::Ssh.new()
knife_ssh.config[:config_file] = conf_file
knife_ssh.config[:identity_file] = params["private_key"]
knife_ssh.config[:node_name] = ENV['HOSTNAME']
knife_ssh.config[:client_name] = ENV['HOSTNAME']
cmd_line = "hostname -f"
knife_ssh.name_args = [query, cmd_line]
sys_status = knife_ssh.run

The Chef::REST class that interacts with the API expects you to have configured Chef::Config[:node_name] and Chef::Config[:client_key]. The easiest way to accomplish this is to reuse the knife code to load your configuration. After setting Knife#config[:config_file] you can call Knife#configure_chef to load it.

As Bryan mentioned, you can skip a lot of boilerplate if you write your code as knife exec scripts, or as a knife plugin. Take a look at this for more info on knife plugins: Chef 0.10 Preview: Knife Plugins and UI - Chef Blog | Chef

--
Dan DeLeo

What am I doing wrong here?

Thanks,

Ken Miles
ken.miles@infogroup.com (mailto:ken.miles@infogroup.com)

Thanks for the help with this guys. For the longer term I am planning on digging into plugins. Shorter term, this is working for me:

conf_file = File.expand_path('~') + '/.chef/' + 'knife.rb'
knife_ssh = Chef::knife::Ssh.new()
knife_ssh.config[:config_file] = conf_file
knife_ssh.configure_chef
cmd_line = "hostname -f"
knife_ssh.name_args = [query, cmd_line]
knife_ssh.run

BTW, at one point I was getting a stack trace from:

/usr/lib/ruby/gems/1.8/gems/json-1.4.6/lib/json/common.rb:44:in deep_const_get': can't find const Chef::Node (ArgumentError) from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in inject'

Which I resolved by adding a
require 'chef/node'

Regards,

Ken Miles

-----Original Message-----
From: Daniel DeLeo [mailto:ddeleo@kallistec.com] On Behalf Of Daniel DeLeo
Sent: Wednesday, June 01, 2011 11:31 AM
To: chef@lists.opscode.com
Subject: [chef] Re: Calling Chef::knife::Ssh directly(?)

On Wednesday, June 1, 2011 at 10:29 AM, Miles, Ken wrote:

Folks,

I am investigating switching some of our Ruby scripts from using the
'system' function to calling the Chef libraries directly and am not
having much success. My latest error is:

/usr/lib/ruby/gems/1.8/gems/chef-0.9.8/lib/chef/rest/auth_credentials.rb:41:
in `signature_headers': Cannot sign the request without a client name,
check that :node_name is assigned (ArgumentError)

Below is a code snippet.

query = "role:#{role}"
knife_ssh = Chef::knife::Ssh.new()
knife_ssh.config[:config_file] = conf_file
knife_ssh.config[:identity_file] = params["private_key"]
knife_ssh.config[:node_name] = ENV['HOSTNAME']
knife_ssh.config[:client_name] = ENV['HOSTNAME']
cmd_line = "hostname -f"
knife_ssh.name_args = [query, cmd_line]
sys_status = knife_ssh.run

The Chef::REST class that interacts with the API expects you to have configured Chef::Config[:node_name] and Chef::Config[:client_key]. The easiest way to accomplish this is to reuse the knife code to load your configuration. After setting Knife#config[:config_file] you can call Knife#configure_chef to load it.

As Bryan mentioned, you can skip a lot of boilerplate if you write your code as knife exec scripts, or as a knife plugin. Take a look at this for more info on knife plugins: Chef 0.10 Preview: Knife Plugins and UI - Chef Blog | Chef

--
Dan DeLeo

What am I doing wrong here?

Thanks,

Ken Miles
ken.miles@infogroup.com (mailto:ken.miles@infogroup.com)