diff options
author | Jordan Running <jr@getchef.com> | 2016-02-04 13:53:27 -0600 |
---|---|---|
committer | Jordan Running <jr@getchef.com> | 2016-02-10 17:06:57 -0600 |
commit | 6916229c6b06c3c428d1e2f33295feebdab1bc29 (patch) | |
tree | 663fb369327d8d1340ff6951070ac34d6d623b12 | |
parent | c8b79e62f628bd7dccc63b04313e044b13600841 (diff) | |
download | chef-zero-jr/pedant-client-keys.tar.gz |
-rw-r--r-- | lib/chef_zero/chef_data/data_normalizer.rb | 17 | ||||
-rw-r--r-- | lib/chef_zero/endpoints/actor_endpoint.rb | 44 | ||||
-rw-r--r-- | lib/chef_zero/endpoints/actor_key_endpoint.rb | 12 | ||||
-rw-r--r-- | lib/chef_zero/endpoints/actor_keys_endpoint.rb | 29 | ||||
-rw-r--r-- | lib/chef_zero/endpoints/actors_endpoint.rb | 14 | ||||
-rw-r--r-- | lib/chef_zero/endpoints/organization_endpoint.rb | 3 | ||||
-rw-r--r-- | lib/chef_zero/endpoints/organizations_endpoint.rb | 11 | ||||
-rw-r--r-- | lib/chef_zero/endpoints/principal_endpoint.rb | 85 | ||||
-rw-r--r-- | lib/chef_zero/rest_base.rb | 2 | ||||
-rw-r--r-- | lib/chef_zero/rspec.rb | 2 | ||||
-rw-r--r-- | spec/run_oc_pedant.rb | 1 |
11 files changed, 131 insertions, 89 deletions
diff --git a/lib/chef_zero/chef_data/data_normalizer.rb b/lib/chef_zero/chef_data/data_normalizer.rb index 3ab20fa..c72feb5 100644 --- a/lib/chef_zero/chef_data/data_normalizer.rb +++ b/lib/chef_zero/chef_data/data_normalizer.rb @@ -17,14 +17,15 @@ module ChefZero end def self.normalize_client(data_store, client, name, orgname = nil) + client['orgname'] ||= orgname + unless client['public_key'] - client['public_key'] = get_default_public_key(data_store, :client, name) + client['public_key'] = get_default_public_key(data_store, :client, name, client['orgname']) end client['name'] ||= name client['clientname'] ||= name client['admin'] = !!client['admin'] if client.has_key?('admin') - client['orgname'] ||= orgname client['validator'] ||= false client['validator'] = !!client['validator'] client['json_class'] ||= "Chef::ApiClient" @@ -233,8 +234,16 @@ module ChefZero private - def self.get_default_public_key(data_store, user_or_client, user_or_client_name) - key_json = data_store.get([ "#{user_or_client}_keys", user_or_client_name, "keys", DEFAULT_PUBLIC_KEY_NAME ]) + def self.get_default_public_key(data_store, user_or_client, user_or_client_name, orgname=nil) + path = + if user_or_client == :client + [ "organizations", orgname, "client_keys" ] + else + [ "user_keys" ] + end + .push(user_or_client_name, "keys", DEFAULT_PUBLIC_KEY_NAME) + + key_json = data_store.get(path) return unless key_json FFI_Yajl::Parser.parse(key_json, create_additions: false)["public_key"] diff --git a/lib/chef_zero/endpoints/actor_endpoint.rb b/lib/chef_zero/endpoints/actor_endpoint.rb index 46b9082..ffbc571 100644 --- a/lib/chef_zero/endpoints/actor_endpoint.rb +++ b/lib/chef_zero/endpoints/actor_endpoint.rb @@ -24,7 +24,7 @@ module ChefZero end end - delete_actor_keys!(request, client_or_user_name) + delete_actor_keys!(request) result end @@ -131,17 +131,15 @@ module ChefZero # Move key data to new path def rename_keys!(request, new_client_or_user_name) - orig_client_or_user_name = request.rest_path.last - - path_root = "#{client_or_user(request)}_keys" - orig_keys_path = [ path_root, orig_client_or_user_name, "keys" ] - new_keys_path = [ path_root, new_client_or_user_name, "keys" ] + orig_keys_path = keys_path_base(request) + new_keys_path = orig_keys_path.dup + .tap {|path| path[-2] = new_client_or_user_name } key_names = list_data(request, orig_keys_path, :data_store_exceptions) key_names.each do |key_name| # Get old data - orig_path = orig_keys_path + [ key_name ] + orig_path = [ *orig_keys_path, key_name ] data = get_data(request, orig_path, :data_store_exceptions) # Copy data to new path @@ -158,8 +156,7 @@ module ChefZero end def update_default_public_key!(request, client_or_user_name, public_key) - path = [ "#{client_or_user(request)}_keys", client_or_user_name, - "keys", DEFAULT_PUBLIC_KEY_NAME ] + path = [ *keys_path_base(request, client_or_user_name), DEFAULT_PUBLIC_KEY_NAME ] data = FFI_Yajl::Encoder.encode( "name" => DEFAULT_PUBLIC_KEY_NAME, @@ -170,18 +167,35 @@ module ChefZero set_data(request, path, data, :create, :data_store_exceptions) end - def delete_actor_keys!(request, client_or_user_name) - path = [ "#{client_or_user(request)}_keys", client_or_user_name ] + def delete_actor_keys!(request) + path = keys_path_base(request)[0..-2] delete_data_dir(request, path, :recursive, :data_store_exceptions) rescue DataStore::DataNotFoundError end - def client_or_user(request) - request.rest_path[2] == "clients" ? :client : :user + def client?(request, rest_path=nil) + rest_path ||= request.rest_path + request.rest_path[2] == "clients" end - def client?(request) - client_or_user(request) == :client + # Return the data store keys path for the request client or user, e.g. + # + # [ "organizations", <org>, "client_keys", <client>, "keys" ] + # + # Or: + # + # [ "user_keys", <user>, "keys" ] + # + def keys_path_base(request, client_or_user_name=nil) + rest_path = (rest_path || request.rest_path).dup + rest_path[-1] = client_or_user_name if client_or_user_name + + if client?(request, rest_path) + [ *rest_path[0..1], "client_keys" ] + else + [ "user_keys" ] + end + .push(rest_path.last, "keys") end end end diff --git a/lib/chef_zero/endpoints/actor_key_endpoint.rb b/lib/chef_zero/endpoints/actor_key_endpoint.rb index 98229fc..2a20f2d 100644 --- a/lib/chef_zero/endpoints/actor_key_endpoint.rb +++ b/lib/chef_zero/endpoints/actor_key_endpoint.rb @@ -29,9 +29,17 @@ module ChefZero private + # Returns the keys data store path, which is the same as + # `request.rest_path` except with "user_keys" instead of "users" or + # "client_keys" instead of "clients." def data_path(request) - root = request.rest_path[2] == "clients" ? "client_keys" : "user_keys" - [root, *request.rest_path.last(3) ] + request.rest_path.dup.tap do |path| + if request.rest_path[2] == "clients" + path[2] = "client_keys" + else + path[0] = "user_keys" + end + end end end end diff --git a/lib/chef_zero/endpoints/actor_keys_endpoint.rb b/lib/chef_zero/endpoints/actor_keys_endpoint.rb index ed3f828..2b33084 100644 --- a/lib/chef_zero/endpoints/actor_keys_endpoint.rb +++ b/lib/chef_zero/endpoints/actor_keys_endpoint.rb @@ -9,12 +9,7 @@ module ChefZero DATE_FORMAT = "%FT%TZ" # e.g. 2015-12-24T21:00:00Z def get(request) - path = - if client?(request) - [ "client_keys", request.rest_path[3], "keys" ] - else - [ "user_keys", request.rest_path[1], "keys" ] - end + path = data_path(request) result = list_data(request, path).map do |key_name| list_key(request, [ *path, key_name ]) @@ -24,7 +19,6 @@ module ChefZero end def post(request) - client_or_user_name = client?(request) ? request.rest_path[3] : request.rest_path[1] request_body = FFI_Yajl::Parser.parse(request.body) validate_client_or_user!(request) @@ -38,7 +32,7 @@ module ChefZero end key_name = request_body["name"] - path = [ "#{client_or_user(request)}_keys", client_or_user_name, "keys" ] + path = data_path(request) data = FFI_Yajl::Encoder.encode( "name" => key_name, @@ -57,6 +51,19 @@ module ChefZero private + # Returns the keys data store path, which is the same as + # `request.rest_path` except with "user_keys" instead of "users" or + # "client_keys" instead of "clients." + def data_path(request) + request.rest_path.dup.tap do |path| + if client?(request) + path[2] = "client_keys" + else + path[0] = "user_keys" + end + end + end + def list_key(request, data_path) data = FFI_Yajl::Parser.parse(get_data(request, data_path), create_additions: false) key_name = data["name"] @@ -78,12 +85,8 @@ module ChefZero get_data(request, path) end - def client_or_user(request) - request.rest_path[2] == "clients" ? :client : :user - end - def client?(request) - client_or_user(request) == :client + request.rest_path[2] == "clients" end def key_uri(request, key_name) diff --git a/lib/chef_zero/endpoints/actors_endpoint.rb b/lib/chef_zero/endpoints/actors_endpoint.rb index f8d65cb..e3cb283 100644 --- a/lib/chef_zero/endpoints/actors_endpoint.rb +++ b/lib/chef_zero/endpoints/actors_endpoint.rb @@ -73,7 +73,13 @@ module ChefZero # Store the public key in user_keys def store_default_public_key!(request, client_or_user_name, public_key) - path = [ "#{client_or_user(request)}_keys", client_or_user_name, "keys" ] + path = + if client?(request) + [ *request.rest_path[0..1], "client_keys" ] + else + [ "user_keys" ] + end + .push(client_or_user_name, "keys") data = FFI_Yajl::Encoder.encode( "name" => DEFAULT_PUBLIC_KEY_NAME, @@ -84,12 +90,8 @@ module ChefZero create_data(request, path, DEFAULT_PUBLIC_KEY_NAME, data, :create_dir) end - def client_or_user(request) - request.rest_path[2] == "clients" ? :client : :user - end - def client?(request) - client_or_user(request) == :client + request.rest_path[2] == "clients" end end end diff --git a/lib/chef_zero/endpoints/organization_endpoint.rb b/lib/chef_zero/endpoints/organization_endpoint.rb index c600f88..2c85d7e 100644 --- a/lib/chef_zero/endpoints/organization_endpoint.rb +++ b/lib/chef_zero/endpoints/organization_endpoint.rb @@ -64,7 +64,8 @@ module ChefZero end def delete_validator_client_keys!(request, org_name) - keys_path = [ "client_keys", validator_name(org_name) ] + keys_path = [ "organizations", org_name, + "client_keys", validator_name(org_name) ] delete_data_dir(request, keys_path, :recursive, :data_store_exceptions) rescue DataStore::DataNotFoundError end diff --git a/lib/chef_zero/endpoints/organizations_endpoint.rb b/lib/chef_zero/endpoints/organizations_endpoint.rb index 9464ae7..df1ba57 100644 --- a/lib/chef_zero/endpoints/organizations_endpoint.rb +++ b/lib/chef_zero/endpoints/organizations_endpoint.rb @@ -60,7 +60,9 @@ module ChefZero end def create_validator_client!(request, org_path) - name = validator_name(org_path.last) + org_name = org_path.last + name = validator_name(org_name) + validator_path = [ *org_path, 'clients', name ] private_key, public_key = server.gen_key_pair @@ -71,14 +73,15 @@ module ChefZero set_data(request, validator_path, validator) - store_default_public_key!(request, name, public_key) + store_validator_public_key!(request, org_name, name, public_key) private_key end # Store the validator client's public key in client_keys - def store_default_public_key!(request, client_name, public_key) - path = [ "client_keys", client_name, "keys" ] + def store_validator_public_key!(request, org_name, client_name, public_key) + path = [ "organizations", org_name, + "client_keys", client_name, "keys" ] data = FFI_Yajl::Encoder.encode( "name" => DEFAULT_PUBLIC_KEY_NAME, diff --git a/lib/chef_zero/endpoints/principal_endpoint.rb b/lib/chef_zero/endpoints/principal_endpoint.rb index 2dcec1b..90be311 100644 --- a/lib/chef_zero/endpoints/principal_endpoint.rb +++ b/lib/chef_zero/endpoints/principal_endpoint.rb @@ -25,60 +25,61 @@ module ChefZero private def get_principal_data(request, name) - # If /organizations/ORG/users/NAME exists, use this user (only org members have precedence over clients). hey are an org member. - get_org_users_data(request, name) || + # If /organizations/ORG/users/NAME exists, use this user (only org + # members have precedence over clients). + get_org_user_data(request, name) || # If /organizations/ORG/clients/NAME exists, use the client. - get_clients_data(request, name) || - # If there is no client with that name, check for a user (/users/NAME) and return that with - # org_member = false. - get_users_data(request, name) + get_client_data(request, name) || + # If there is no client with that name, check for a user + # (/users/NAME) and return that with org_member = false. + get_user_data(request, name) end - def get_org_users_data(request, name) - path = [ *request.rest_path[0..1], 'users', name ] - return if get_data(request, path, :nil).nil? - - user_keys_json = get_data(request, - [ 'user_keys', name, 'keys', DEFAULT_PUBLIC_KEY_NAME ], - :data_store_exceptions - ) - - public_key = FFI_Yajl::Parser.parse(user_keys_json)['public_key'] + def get_org_user_data(request, name) + user_path = request.rest_path.first(2) + [ 'users', name ] + return if get_data(request, user_path, :nil).nil? + + # In single org. mode assume that we only support one user, "pivotal," + # and there is no user_keys data for that user; use the default + # PUBLIC_KEY. + public_key = + if data_store.real_store.respond_to?(:single_org) && data_store.real_store.single_org + PUBLIC_KEY + else + user_keys_json = get_data(request, + [ 'user_keys', name, 'keys', DEFAULT_PUBLIC_KEY_NAME ], + :data_store_exceptions + ) + + FFI_Yajl::Parser.parse(user_keys_json)['public_key'] + end { "type" => "user", "org_member" => true, - "public_key" => public_key - } + "public_key" => public_key } end - def get_clients_data(request, name) - path = [ *request.rest_path[0..1], 'clients', name ] - json = get_data(request, path, :nil) - return if json.nil? + def get_client_data(request, name) + base_path = request.rest_path.first(2) + client_path = base_path + [ 'clients', name ] + client_key_path = base_path + [ 'client_keys', name, 'keys', DEFAULT_PUBLIC_KEY_NAME ] - public_key = FFI_Yajl::Parser.parse(json)['public_key'] - - { "type" => "client", - "org_member" => true, - "public_key" => public_key || PUBLIC_KEY - } + get_actor_data(request, client_path, client_key_path, + "type" => "client", "org_member" => true) end - def get_users_data(request, name) - path = [ 'users', name ] - return if get_data(request, path, :nil).nil? - - user_keys_json = get_data(request, - [ 'user_keys', name, 'keys', DEFAULT_PUBLIC_KEY_NAME ], - :data_store_exceptions - ) - - public_key = FFI_Yajl::Parser.parse(user_keys_json)['public_key'] + def get_user_data(request, name) + user_path = [ 'users', name ] + user_key_path = [ 'user_keys', name, 'keys', DEFAULT_PUBLIC_KEY_NAME ] + get_actor_data(request, user_path, user_key_path, + "type" => "user", "org_member" => false) + end - { "type" => "user", - "org_member" => false, - "public_key" => public_key - } + def get_actor_data(request, actor_path, actor_key_path, attrs={}) + return if get_data(request, actor_path, :nil).nil? + actor_key_json = get_data(request, actor_key_path, :data_store_exceptions) + public_key = FFI_Yajl::Parser.parse(actor_key_json)['public_key'] + attrs.merge("public_key" => public_key) end end end diff --git a/lib/chef_zero/rest_base.rb b/lib/chef_zero/rest_base.rb index 6a9bd2e..a0c9633 100644 --- a/lib/chef_zero/rest_base.rb +++ b/lib/chef_zero/rest_base.rb @@ -61,7 +61,7 @@ module ChefZero begin self.send(method, request) rescue RestErrorResponse => e - ChefZero::Log.debug("#{e.inspect}\n#{e.backtrace.join("\n")}") + ChefZero::Log.info("#{e.inspect}\n#{e.backtrace.join("\n")}") error(e.response_code, e.error) end end diff --git a/lib/chef_zero/rspec.rb b/lib/chef_zero/rspec.rb index fe8cf30..8867f37 100644 --- a/lib/chef_zero/rspec.rb +++ b/lib/chef_zero/rspec.rb @@ -67,7 +67,7 @@ module ChefZero if chef_server_options[:server_scope] != self.class.chef_server_options[:server_scope] raise "server_scope: #{chef_server_options[:server_scope]} will not be honored: it can only be set on when_the_chef_server!" end - Log.debug("Starting Chef server with options #{chef_server_options}") + Log.info("Starting Chef server with options #{chef_server_options}") ChefZero::RSpec.set_server_options(chef_server_options) diff --git a/spec/run_oc_pedant.rb b/spec/run_oc_pedant.rb index e4e8475..c3d4e7f 100644 --- a/spec/run_oc_pedant.rb +++ b/spec/run_oc_pedant.rb @@ -124,6 +124,7 @@ begin '--skip-users', '--skip-organizations', '--skip-multiuser', + '--skip-user-keys', # chef-zero has some non-removable quirks, such as the fact that files # with 255-character names cannot be stored in local mode. This is |