Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement APIv1 behaviors #201

Merged
merged 2 commits into from
Feb 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/chef_zero/endpoints/actor_default_key_endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ class ActorDefaultKeyEndpoint < RestBase
def get(request)
# 404 if actor doesn't exist
actor_data = get_actor_data(request)
key_data = default_public_key_from_actor(actor_data)

# 404 if the actor doesn't have a default key
if key_data["public_key"].nil?
raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}")
end

json_response(200, default_public_key_from_actor(actor_data))
end

Expand Down
14 changes: 12 additions & 2 deletions lib/chef_zero/endpoints/actor_endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ module Endpoints
# /organizations/ORG/users/NAME
# /users/NAME
class ActorEndpoint < RestObjectEndpoint

def get(request)
result = super
user_data = parse_json(result[2])

user_data.delete("public_key") unless request.api_v0?

json_response(200, user_data)
end

def delete(request)
result = super

Expand Down Expand Up @@ -48,7 +58,7 @@ def put(request)
end

# Put modified body back in `request.body`
request.body = FFI_Yajl::Encoder.encode(request_body, :pretty => true) if body_modified
request.body = to_json(request_body) if body_modified

# PUT /clients is patchy
request.body = patch_request_body(request)
Expand All @@ -68,7 +78,7 @@ def put(request)
'uri' => build_uri(request.base_uri, [ 'users', client_or_user_name ])
}
else
response = FFI_Yajl::Parser.parse(result[2], :create_additions => false)
response = parse_json(result[2])
end

if client?(request)
Expand Down
50 changes: 38 additions & 12 deletions lib/chef_zero/endpoints/actors_endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,77 @@ def get(request)
response = super(request)

if request.query_params['email']
results = FFI_Yajl::Parser.parse(response[2], :create_additions => false)
results = parse_json(response[2])
new_results = {}
results.each do |name, url|
record = get_data(request, request.rest_path + [ name ], :nil)
if record
record = FFI_Yajl::Parser.parse(record, :create_additions => false)
record = parse_json(record)
new_results[name] = url if record['email'] == request.query_params['email']
end
end
response[2] = FFI_Yajl::Encoder.encode(new_results, :pretty => true)
response[2] = to_json(new_results)
end

if request.query_params['verbose']
results = FFI_Yajl::Parser.parse(response[2], :create_additions => false)
results = parse_json(response[2])
results.each do |name, url|
record = get_data(request, request.rest_path + [ name ], :nil)
if record
record = FFI_Yajl::Parser.parse(record, :create_additions => false)
record = parse_json(record)
record = ChefData::DataNormalizer.normalize_user(record, name, identity_keys, server.options[:osc_compat])
results[name] = record
end
end
response[2] = FFI_Yajl::Encoder.encode(results, :pretty => true)
response[2] = to_json(results)
end
response
end

def post(request)
# First, find out if the user actually posted a public key. If not, make
# one.
request_body = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
request_body = parse_json(request.body)
public_key = request_body['public_key']
if !public_key

skip_key_create = !request.api_v0? && !request_body["create_key"]

if !public_key && !skip_key_create
private_key, public_key = server.gen_key_pair
request_body['public_key'] = public_key
request.body = FFI_Yajl::Encoder.encode(request_body, :pretty => true)
request.body = to_json(request_body)
elsif skip_key_create
request_body['public_key'] = nil
request.body = to_json(request_body)
end

result = super(request)

if result[0] == 201
# If we generated a key, stuff it in the response.
response = FFI_Yajl::Parser.parse(result[2], :create_additions => false)
response['private_key'] = private_key if private_key
response['public_key'] = public_key unless request.rest_path[0] == 'users'
user_data = parse_json(result[2])

key_data = {}
key_data['private_key'] = private_key if private_key
key_data['public_key'] = public_key unless request.rest_path[0] == 'users'

response =
if request.api_v0?
user_data.merge(key_data)
elsif skip_key_create && !public_key
user_data
else
actor_name = request_body["name"] || request_body["username"] || request_body["clientname"]

relpath_to_default_key = [ actor_name, "keys", "default" ]
key_data["uri"] = build_uri(request.base_uri, request.rest_path + relpath_to_default_key)
key_data["public_key"] = public_key
key_data["name"] = "default"
key_data["expiration_date"] = "infinity"
user_data["chef_key"] = key_data
user_data
end

json_response(201, response)
else
result
Expand Down
13 changes: 11 additions & 2 deletions lib/chef_zero/endpoints/principal_endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,22 @@ def get(request)
end
end
if json
json_response(200, {
principal_data = {
'name' => name,
'type' => type,
'public_key' => FFI_Yajl::Parser.parse(json)['public_key'] || PUBLIC_KEY,
'authz_id' => '0'*32,
'org_member' => org_member
})
}

response_data =
if request.api_v0?
principal_data
else
{ "principals" => [ principal_data ] }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is both a user and a client with the given name, should we return them both?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's correct, according to my reading of the code here: https://github.com/chef/chef-server/blob/218579549024b26b3b97c9958503ff3651e3fb16/src/oc_erchef/apps/oc_chef_wm/src/chef_wm_named_principal.erl#L92-L102

OTOH, there's no pedant test for that, and it's an existing bug, and I probably won't have time to fix all that. So my inclination is to leave it as is until the problem comes up again.

end

json_response(200, response_data)
else
error(404, 'Principal not found')
end
Expand Down
9 changes: 8 additions & 1 deletion lib/chef_zero/rest_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

module ChefZero
class RestRequest

ZERO = "0".freeze

def initialize(env, rest_base_prefix = [])
@env = env
@rest_base_prefix = rest_base_prefix
Expand All @@ -19,7 +22,11 @@ def base_uri=(value)
end

def api_version
@env['HTTP_X_OPS_SERVER_API_VERSION'] || 0
@env['HTTP_X_OPS_SERVER_API_VERSION'] || ZERO
end

def api_v0?
api_version == ZERO
end

def requestor
Expand Down
1 change: 0 additions & 1 deletion spec/run_oc_pedant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ def args_from_env(key)
'--skip-usags',

# Chef 12 features not yet 100% supported by Chef Zero
'--skip-api-v1',

# The universe endpoint is unlikely to ever make sense for Chef Zero
'--skip-universe',
Expand Down