# class Chef::ApiClient::Registration

## Chef::ApiClient::Registration¶ ↑

Manages the process of creating or updating a Chef::ApiClient on the server and writing the resulting private key to disk. Registration uses the validator credentials for its API calls. This allows it to bootstrap a new client/node identity by borrowing the validator client identity when creating a new client.

### Attributes

destination[R]
name[R]

### Public Class Methods

new(name, destination) click to toggle source

    # File lib/chef/api_client/registration.rb, line 36
    def initialize(name, destination)
      @name = name
      @destination = destination
      @server_generated_private_key = nil
    end

### Public Instance Methods

assert_destination_writable!() click to toggle source

    # File lib/chef/api_client/registration.rb, line 68
    def assert_destination_writable!
      if (File.exists?(destination) && !File.writable?(destination)) or !File.writable?(File.dirname(destination))
        raise Chef::Exceptions::CannotWritePrivateKey, "I cannot write your private key to #{destination} - check permissions?"
      end
    end

create() click to toggle source

    # File lib/chef/api_client/registration.rb, line 91
    def create
      response = http_api.post("clients", post_data)
      @server_generated_private_key = response["private_key"]
      response
    end

create_or_update() click to toggle source

    # File lib/chef/api_client/registration.rb, line 82
    def create_or_update
      create
    rescue Net::HTTPServerException => e
      # If create fails because the client exists, attempt to update. This
      # requires admin privileges.
      raise unless e.response.code == "409"
      update
    end

file_flags() click to toggle source

    # File lib/chef/api_client/registration.rb, line 153
    def file_flags
      base_flags = File::CREAT|File::TRUNC|File::RDWR
      # Windows doesn't have symlinks, so it doesn't have NOFOLLOW
      base_flags |= File::NOFOLLOW if defined?(File::NOFOLLOW)
      base_flags
    end

generated_private_key() click to toggle source

    # File lib/chef/api_client/registration.rb, line 145
    def generated_private_key
      @generated_key ||= OpenSSL::PKey::RSA.generate(2048)
    end

generated_public_key() click to toggle source

    # File lib/chef/api_client/registration.rb, line 149
    def generated_public_key
      generated_private_key.public_key.to_pem
    end

http_api() click to toggle source

    # File lib/chef/api_client/registration.rb, line 124
    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

post_data() click to toggle source

    # File lib/chef/api_client/registration.rb, line 117
    def post_data
      post_data = { :name => name, :admin => false }
      post_data[:public_key] = generated_public_key if self_generate_keys?
      post_data
    end

private_key() click to toggle source

    # File lib/chef/api_client/registration.rb, line 137
    def private_key
      if self_generate_keys?
        generated_private_key.to_pem
      else
        @server_generated_private_key
      end
    end

put_data() click to toggle source

    # File lib/chef/api_client/registration.rb, line 107
    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

run() click to toggle source

Runs the client registration process, including creating the client on the chef-server and writing its private key to disk.

    # File lib/chef/api_client/registration.rb, line 52
    def run
      assert_destination_writable!
      retries = Config[:client_registration_retries] || 5
      begin
        create_or_update
      rescue Net::HTTPFatalError => e
        # HTTPFatalError implies 5xx.
        raise if retries <= 0
        retries -= 1
        Chef::Log.warn("Failed to register new client, #{retries} tries remaining")
        Chef::Log.warn("Response: HTTP #{e.response.code} - #{e}")
        retry
      end
      write_key
    end

self_generate_keys?() click to toggle source

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.

    # File lib/chef/api_client/registration.rb, line 133
    def self_generate_keys?
      Chef::Config.local_key_generation
    end

update() click to toggle source

    # File lib/chef/api_client/registration.rb, line 97
    def update
      response = http_api.put("clients/#{name}", put_data)
      if response.respond_to?(:private_key) # Chef 11
        @server_generated_private_key = response.private_key
      else # Chef 10
        @server_generated_private_key = response["private_key"]
      end
      response
    end

write_key() click to toggle source

    # File lib/chef/api_client/registration.rb, line 74
    def write_key
      ::File.open(destination, file_flags, 0600) do |f|
        f.print(private_key)
      end
    rescue IOError => e
      raise Chef::Exceptions::CannotWritePrivateKey, "Error writing private key to #{destination}: #{e}"
    end