summaryrefslogtreecommitdiff
path: root/lib/chef/api_client
diff options
context:
space:
mode:
authordanielsdeleo <dan@getchef.com>2014-03-25 16:51:03 -0700
committerdanielsdeleo <dan@getchef.com>2014-03-25 16:51:03 -0700
commit6231d5f3faa6d94051c3a7878742b3b9a684e374 (patch)
treed49aa16f17f5fb47ccf53e17df46861b33abf30a /lib/chef/api_client
parent6b045b48bb40b0fc912d7077b7de5f7987c6cdc9 (diff)
downloadchef-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.rb55
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