diff options
author | danielsdeleo <dan@getchef.com> | 2014-03-25 16:51:03 -0700 |
---|---|---|
committer | danielsdeleo <dan@getchef.com> | 2014-03-25 16:51:03 -0700 |
commit | 6231d5f3faa6d94051c3a7878742b3b9a684e374 (patch) | |
tree | d49aa16f17f5fb47ccf53e17df46861b33abf30a /lib/chef/api_client | |
parent | 6b045b48bb40b0fc912d7077b7de5f7987c6cdc9 (diff) | |
download | chef-6231d5f3faa6d94051c3a7878742b3b9a684e374.tar.gz |
Add optional client-side key generation when registering
Diffstat (limited to 'lib/chef/api_client')
-rw-r--r-- | lib/chef/api_client/registration.rb | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/lib/chef/api_client/registration.rb b/lib/chef/api_client/registration.rb index f44c326d5d..213d0b7f49 100644 --- a/lib/chef/api_client/registration.rb +++ b/lib/chef/api_client/registration.rb @@ -30,14 +30,13 @@ class Chef # a new client/node identity by borrowing the validator client identity # when creating a new client. class Registration - attr_reader :private_key attr_reader :destination attr_reader :name def initialize(name, destination) @name = name @destination = destination - @private_key = nil + @server_generated_private_key = nil end # Runs the client registration process, including creating the client on @@ -90,29 +89,67 @@ class Chef end def create - response = http_api.post("clients", :name => name, :admin => false) - @private_key = response["private_key"] + response = http_api.post("clients", post_data) + @server_generated_private_key = response["private_key"] response end def update - response = http_api.put("clients/#{name}", :name => name, - :admin => false, - :private_key => true) + response = http_api.put("clients/#{name}", put_data) if response.respond_to?(:private_key) # Chef 11 - @private_key = response.private_key + @server_generated_private_key = response.private_key else # Chef 10 - @private_key = response["private_key"] + @server_generated_private_key = response["private_key"] end response end + def put_data + base_put_data = { :name => name, :admin => false } + if self_generate_keys? + base_put_data[:public_key] = generated_public_key + else + base_put_data[:private_key] = true + end + base_put_data + end + + def post_data + post_data = { :name => name, :admin => false } + post_data[:public_key] = generated_public_key if self_generate_keys? + post_data + end + + def http_api @http_api_as_validator ||= Chef::REST.new(Chef::Config[:chef_server_url], Chef::Config[:validation_client_name], Chef::Config[:validation_key]) end + # Whether or not to generate keys locally and post the public key to the + # server. Delegates to `Chef::Config.local_key_generation`. Servers + # before 11.0 do not support this feature. + def self_generate_keys? + Chef::Config.local_key_generation + end + + def private_key + if self_generate_keys? + generated_private_key.to_pem + else + @server_generated_private_key + end + end + + def generated_private_key + @generated_key ||= OpenSSL::PKey::RSA.generate(2048) + end + + def generated_public_key + generated_private_key.public_key.to_pem + end + def file_flags base_flags = File::CREAT|File::TRUNC|File::RDWR # Windows doesn't have symlinks, so it doesn't have NOFOLLOW |