chef-zero 15.0.17 → 15.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +36 -31
- data/LICENSE +201 -201
- data/Rakefile +73 -68
- data/bin/chef-zero +111 -111
- data/chef-zero.gemspec +34 -33
- data/lib/chef_zero/chef_data/acl_path.rb +140 -140
- data/lib/chef_zero/chef_data/cookbook_data.rb +237 -237
- data/lib/chef_zero/chef_data/data_normalizer.rb +276 -276
- data/lib/chef_zero/chef_data/default_creator.rb +476 -476
- data/lib/chef_zero/data_store/data_already_exists_error.rb +29 -29
- data/lib/chef_zero/data_store/data_error.rb +32 -32
- data/lib/chef_zero/data_store/data_not_found_error.rb +29 -29
- data/lib/chef_zero/data_store/default_facade.rb +143 -147
- data/lib/chef_zero/data_store/interface_v1.rb +67 -67
- data/lib/chef_zero/data_store/interface_v2.rb +18 -18
- data/lib/chef_zero/data_store/memory_store.rb +33 -33
- data/lib/chef_zero/data_store/memory_store_v2.rb +159 -159
- data/lib/chef_zero/data_store/raw_file_store.rb +143 -143
- data/lib/chef_zero/data_store/v1_to_v2_adapter.rb +150 -150
- data/lib/chef_zero/data_store/v2_to_v1_adapter.rb +105 -105
- data/lib/chef_zero/dist.rb +9 -9
- data/lib/chef_zero/endpoints/acl_endpoint.rb +39 -39
- data/lib/chef_zero/endpoints/acls_endpoint.rb +41 -41
- data/lib/chef_zero/endpoints/actor_default_key_endpoint.rb +78 -78
- data/lib/chef_zero/endpoints/actor_endpoint.rb +184 -184
- data/lib/chef_zero/endpoints/actor_key_endpoint.rb +62 -62
- data/lib/chef_zero/endpoints/actor_keys_endpoint.rb +129 -129
- data/lib/chef_zero/endpoints/actors_endpoint.rb +104 -104
- data/lib/chef_zero/endpoints/authenticate_user_endpoint.rb +32 -32
- data/lib/chef_zero/endpoints/container_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/containers_endpoint.rb +25 -25
- data/lib/chef_zero/endpoints/controls_endpoint.rb +16 -16
- data/lib/chef_zero/endpoints/cookbook_artifact_endpoint.rb +24 -24
- data/lib/chef_zero/endpoints/cookbook_artifact_identifier_endpoint.rb +68 -68
- data/lib/chef_zero/endpoints/cookbook_artifacts_endpoint.rb +34 -34
- data/lib/chef_zero/endpoints/cookbook_endpoint.rb +39 -39
- data/lib/chef_zero/endpoints/cookbook_version_endpoint.rb +136 -136
- data/lib/chef_zero/endpoints/cookbooks_base.rb +80 -80
- data/lib/chef_zero/endpoints/cookbooks_endpoint.rb +19 -19
- data/lib/chef_zero/endpoints/data_bag_endpoint.rb +45 -45
- data/lib/chef_zero/endpoints/data_bag_item_endpoint.rb +25 -25
- data/lib/chef_zero/endpoints/data_bags_endpoint.rb +23 -23
- data/lib/chef_zero/endpoints/dummy_endpoint.rb +29 -29
- data/lib/chef_zero/endpoints/environment_cookbook_endpoint.rb +24 -24
- data/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb +126 -126
- data/lib/chef_zero/endpoints/environment_cookbooks_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/environment_endpoint.rb +33 -33
- data/lib/chef_zero/endpoints/environment_nodes_endpoint.rb +23 -23
- data/lib/chef_zero/endpoints/environment_recipes_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/environment_role_endpoint.rb +36 -36
- data/lib/chef_zero/endpoints/file_store_file_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/group_endpoint.rb +20 -20
- data/lib/chef_zero/endpoints/groups_endpoint.rb +13 -13
- data/lib/chef_zero/endpoints/license_endpoint.rb +25 -25
- data/lib/chef_zero/endpoints/node_endpoint.rb +34 -34
- data/lib/chef_zero/endpoints/node_identifiers_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/nodes_endpoint.rb +34 -34
- data/lib/chef_zero/endpoints/not_found_endpoint.rb +11 -11
- data/lib/chef_zero/endpoints/organization_association_request_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/organization_association_requests_endpoint.rb +30 -30
- data/lib/chef_zero/endpoints/organization_authenticate_user_endpoint.rb +26 -26
- data/lib/chef_zero/endpoints/organization_endpoint.rb +47 -47
- data/lib/chef_zero/endpoints/organization_user_base.rb +15 -15
- data/lib/chef_zero/endpoints/organization_user_default_key_endpoint.rb +16 -16
- data/lib/chef_zero/endpoints/organization_user_endpoint.rb +26 -26
- data/lib/chef_zero/endpoints/organization_user_key_endpoint.rb +17 -17
- data/lib/chef_zero/endpoints/organization_user_keys_endpoint.rb +17 -17
- data/lib/chef_zero/endpoints/organization_users_endpoint.rb +43 -43
- data/lib/chef_zero/endpoints/organization_validator_key_endpoint.rb +20 -20
- data/lib/chef_zero/endpoints/organizations_endpoint.rb +61 -61
- data/lib/chef_zero/endpoints/policies_endpoint.rb +26 -26
- data/lib/chef_zero/endpoints/policy_endpoint.rb +24 -24
- data/lib/chef_zero/endpoints/policy_group_endpoint.rb +46 -46
- data/lib/chef_zero/endpoints/policy_group_policy_endpoint.rb +83 -83
- data/lib/chef_zero/endpoints/policy_groups_endpoint.rb +38 -38
- data/lib/chef_zero/endpoints/policy_revision_endpoint.rb +66 -66
- data/lib/chef_zero/endpoints/policy_revisions_endpoint.rb +15 -15
- data/lib/chef_zero/endpoints/principal_endpoint.rb +55 -55
- data/lib/chef_zero/endpoints/rest_list_endpoint.rb +42 -42
- data/lib/chef_zero/endpoints/rest_object_endpoint.rb +78 -78
- data/lib/chef_zero/endpoints/role_endpoint.rb +16 -16
- data/lib/chef_zero/endpoints/role_environments_endpoint.rb +14 -14
- data/lib/chef_zero/endpoints/sandbox_endpoint.rb +27 -27
- data/lib/chef_zero/endpoints/sandboxes_endpoint.rb +51 -51
- data/lib/chef_zero/endpoints/search_endpoint.rb +208 -208
- data/lib/chef_zero/endpoints/searches_endpoint.rb +18 -18
- data/lib/chef_zero/endpoints/server_api_version_endpoint.rb +14 -14
- data/lib/chef_zero/endpoints/system_recovery_endpoint.rb +30 -30
- data/lib/chef_zero/endpoints/universe_endpoint.rb +15 -15
- data/lib/chef_zero/endpoints/user_association_request_endpoint.rb +41 -41
- data/lib/chef_zero/endpoints/user_association_requests_count_endpoint.rb +19 -19
- data/lib/chef_zero/endpoints/user_association_requests_endpoint.rb +19 -19
- data/lib/chef_zero/endpoints/user_organizations_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/version_endpoint.rb +13 -13
- data/lib/chef_zero/log.rb +7 -7
- data/lib/chef_zero/rest_base.rb +332 -332
- data/lib/chef_zero/rest_error_response.rb +11 -11
- data/lib/chef_zero/rest_request.rb +84 -88
- data/lib/chef_zero/rest_router.rb +72 -72
- data/lib/chef_zero/rspec.rb +355 -355
- data/lib/chef_zero/server.rb +730 -730
- data/lib/chef_zero/socketless_server_map.rb +92 -93
- data/lib/chef_zero/solr/query/binary_operator.rb +52 -52
- data/lib/chef_zero/solr/query/phrase.rb +23 -23
- data/lib/chef_zero/solr/query/range_query.rb +46 -46
- data/lib/chef_zero/solr/query/regexpable_query.rb +30 -30
- data/lib/chef_zero/solr/query/subquery.rb +37 -37
- data/lib/chef_zero/solr/query/term.rb +45 -45
- data/lib/chef_zero/solr/query/unary_operator.rb +41 -41
- data/lib/chef_zero/solr/solr_doc.rb +53 -53
- data/lib/chef_zero/solr/solr_parser.rb +208 -208
- data/lib/chef_zero/version.rb +3 -3
- data/lib/chef_zero.rb +10 -10
- data/spec/run_oc_pedant.rb +226 -226
- data/spec/search_spec.rb +36 -36
- data/spec/server_spec.rb +96 -96
- data/spec/socketless_server_map_spec.rb +74 -74
- data/spec/support/oc_pedant.rb +149 -149
- data/spec/support/secrets.json +6 -6
- data/spec/support/stickywicket.pem +27 -27
- metadata +35 -18
@@ -1,41 +1,41 @@
|
|
1
|
-
require "ffi_yajl" unless defined?(FFI_Yajl)
|
2
|
-
require_relative "../rest_base"
|
3
|
-
require_relative "../chef_data/data_normalizer"
|
4
|
-
require_relative "../chef_data/acl_path"
|
5
|
-
|
6
|
-
module ChefZero
|
7
|
-
module Endpoints
|
8
|
-
# /organizations/ORG/THING/NAME/_acl
|
9
|
-
# Where THING is:
|
10
|
-
# - clients, data, containers, cookbooks, environments
|
11
|
-
# groups, roles, nodes, users
|
12
|
-
# or
|
13
|
-
# /organizations/ORG/organization/_acl
|
14
|
-
# /users/NAME/_acl
|
15
|
-
class AclsEndpoint < RestBase
|
16
|
-
def get(request)
|
17
|
-
path = request.rest_path[0..-2] # Strip off _acl
|
18
|
-
path = path[0..1] if path.size == 3 && path[0] == "organizations" && %w{organization organizations}.include?(path[2])
|
19
|
-
acl_path = ChefData::AclPath.get_acl_data_path(path)
|
20
|
-
unless acl_path
|
21
|
-
raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}")
|
22
|
-
end
|
23
|
-
|
24
|
-
acls = FFI_Yajl::Parser.parse(get_data(request, acl_path))
|
25
|
-
acls = ChefData::DataNormalizer.normalize_acls(acls)
|
26
|
-
if request.query_params["detail"] == "granular"
|
27
|
-
acls.each do |perm, ace|
|
28
|
-
acls[perm]["actors"] = []
|
29
|
-
end
|
30
|
-
else
|
31
|
-
acls.each do |perm, ace|
|
32
|
-
acls[perm].delete("clients")
|
33
|
-
acls[perm].delete("users")
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
json_response(200, acls)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
1
|
+
require "ffi_yajl" unless defined?(FFI_Yajl)
|
2
|
+
require_relative "../rest_base"
|
3
|
+
require_relative "../chef_data/data_normalizer"
|
4
|
+
require_relative "../chef_data/acl_path"
|
5
|
+
|
6
|
+
module ChefZero
|
7
|
+
module Endpoints
|
8
|
+
# /organizations/ORG/THING/NAME/_acl
|
9
|
+
# Where THING is:
|
10
|
+
# - clients, data, containers, cookbooks, environments
|
11
|
+
# groups, roles, nodes, users
|
12
|
+
# or
|
13
|
+
# /organizations/ORG/organization/_acl
|
14
|
+
# /users/NAME/_acl
|
15
|
+
class AclsEndpoint < RestBase
|
16
|
+
def get(request)
|
17
|
+
path = request.rest_path[0..-2] # Strip off _acl
|
18
|
+
path = path[0..1] if path.size == 3 && path[0] == "organizations" && %w{organization organizations}.include?(path[2])
|
19
|
+
acl_path = ChefData::AclPath.get_acl_data_path(path)
|
20
|
+
unless acl_path
|
21
|
+
raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}")
|
22
|
+
end
|
23
|
+
|
24
|
+
acls = FFI_Yajl::Parser.parse(get_data(request, acl_path))
|
25
|
+
acls = ChefData::DataNormalizer.normalize_acls(acls)
|
26
|
+
if request.query_params["detail"] == "granular"
|
27
|
+
acls.each do |perm, ace|
|
28
|
+
acls[perm]["actors"] = []
|
29
|
+
end
|
30
|
+
else
|
31
|
+
acls.each do |perm, ace|
|
32
|
+
acls[perm].delete("clients")
|
33
|
+
acls[perm].delete("users")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
json_response(200, acls)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -1,78 +1,78 @@
|
|
1
|
-
require_relative "../rest_base"
|
2
|
-
|
3
|
-
module ChefZero
|
4
|
-
module Endpoints
|
5
|
-
# ActorDefaultKeyEndpoint
|
6
|
-
#
|
7
|
-
# This class handles DELETE/GET/PUT requests for client/user default public
|
8
|
-
# keys, i.e. requests with identity key "default". All others are handled
|
9
|
-
# by ActorKeyEndpoint.
|
10
|
-
#
|
11
|
-
# Default public keys are stored with the actor (client or user) instead of
|
12
|
-
# under user/client_keys. Handling those in a separate endpoint offloads
|
13
|
-
# the branching logic onto the router rather than branching in every
|
14
|
-
# endpoint method (`if request.rest_path[-1] == "default" ...`).
|
15
|
-
#
|
16
|
-
# /users/USER/keys/default
|
17
|
-
# /organizations/ORG/clients/CLIENT/keys/default
|
18
|
-
class ActorDefaultKeyEndpoint < RestBase
|
19
|
-
DEFAULT_PUBLIC_KEY_NAME = "default".freeze
|
20
|
-
|
21
|
-
def get(request)
|
22
|
-
# 404 if actor doesn't exist
|
23
|
-
actor_data = get_actor_data(request)
|
24
|
-
key_data = default_public_key_from_actor(actor_data)
|
25
|
-
|
26
|
-
# 404 if the actor doesn't have a default key
|
27
|
-
if key_data["public_key"].nil?
|
28
|
-
raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}")
|
29
|
-
end
|
30
|
-
|
31
|
-
json_response(200, default_public_key_from_actor(actor_data))
|
32
|
-
end
|
33
|
-
|
34
|
-
def delete(request)
|
35
|
-
path = actor_path(request)
|
36
|
-
actor_data = get_actor_data(request) # 404 if actor doesn't exist
|
37
|
-
|
38
|
-
default_public_key = delete_actor_default_public_key!(request, path, actor_data)
|
39
|
-
json_response(200, default_public_key)
|
40
|
-
end
|
41
|
-
|
42
|
-
def put(request)
|
43
|
-
# 404 if actor doesn't exist
|
44
|
-
actor_data = get_actor_data(request)
|
45
|
-
|
46
|
-
new_public_key = parse_json(request.body)["public_key"]
|
47
|
-
actor_data["public_key"] = new_public_key
|
48
|
-
|
49
|
-
set_data(request, actor_path(request), to_json(actor_data))
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
def actor_path(request)
|
55
|
-
return request.rest_path[0..3] if request.rest_path[2] == "clients"
|
56
|
-
|
57
|
-
request.rest_path[0..1]
|
58
|
-
end
|
59
|
-
|
60
|
-
def get_actor_data(request)
|
61
|
-
path = actor_path(request)
|
62
|
-
parse_json(get_data(request, path))
|
63
|
-
end
|
64
|
-
|
65
|
-
def default_public_key_from_actor(actor_data)
|
66
|
-
{ "name" => DEFAULT_PUBLIC_KEY_NAME,
|
67
|
-
"public_key" => actor_data["public_key"],
|
68
|
-
"expiration_date" => "infinity" }
|
69
|
-
end
|
70
|
-
|
71
|
-
def delete_actor_default_public_key!(request, path, actor_data)
|
72
|
-
new_actor_data = actor_data.merge("public_key" => nil)
|
73
|
-
set_data(request, path, to_json(new_actor_data))
|
74
|
-
default_public_key_from_actor(actor_data)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
1
|
+
require_relative "../rest_base"
|
2
|
+
|
3
|
+
module ChefZero
|
4
|
+
module Endpoints
|
5
|
+
# ActorDefaultKeyEndpoint
|
6
|
+
#
|
7
|
+
# This class handles DELETE/GET/PUT requests for client/user default public
|
8
|
+
# keys, i.e. requests with identity key "default". All others are handled
|
9
|
+
# by ActorKeyEndpoint.
|
10
|
+
#
|
11
|
+
# Default public keys are stored with the actor (client or user) instead of
|
12
|
+
# under user/client_keys. Handling those in a separate endpoint offloads
|
13
|
+
# the branching logic onto the router rather than branching in every
|
14
|
+
# endpoint method (`if request.rest_path[-1] == "default" ...`).
|
15
|
+
#
|
16
|
+
# /users/USER/keys/default
|
17
|
+
# /organizations/ORG/clients/CLIENT/keys/default
|
18
|
+
class ActorDefaultKeyEndpoint < RestBase
|
19
|
+
DEFAULT_PUBLIC_KEY_NAME = "default".freeze
|
20
|
+
|
21
|
+
def get(request)
|
22
|
+
# 404 if actor doesn't exist
|
23
|
+
actor_data = get_actor_data(request)
|
24
|
+
key_data = default_public_key_from_actor(actor_data)
|
25
|
+
|
26
|
+
# 404 if the actor doesn't have a default key
|
27
|
+
if key_data["public_key"].nil?
|
28
|
+
raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}")
|
29
|
+
end
|
30
|
+
|
31
|
+
json_response(200, default_public_key_from_actor(actor_data))
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete(request)
|
35
|
+
path = actor_path(request)
|
36
|
+
actor_data = get_actor_data(request) # 404 if actor doesn't exist
|
37
|
+
|
38
|
+
default_public_key = delete_actor_default_public_key!(request, path, actor_data)
|
39
|
+
json_response(200, default_public_key)
|
40
|
+
end
|
41
|
+
|
42
|
+
def put(request)
|
43
|
+
# 404 if actor doesn't exist
|
44
|
+
actor_data = get_actor_data(request)
|
45
|
+
|
46
|
+
new_public_key = parse_json(request.body)["public_key"]
|
47
|
+
actor_data["public_key"] = new_public_key
|
48
|
+
|
49
|
+
set_data(request, actor_path(request), to_json(actor_data))
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def actor_path(request)
|
55
|
+
return request.rest_path[0..3] if request.rest_path[2] == "clients"
|
56
|
+
|
57
|
+
request.rest_path[0..1]
|
58
|
+
end
|
59
|
+
|
60
|
+
def get_actor_data(request)
|
61
|
+
path = actor_path(request)
|
62
|
+
parse_json(get_data(request, path))
|
63
|
+
end
|
64
|
+
|
65
|
+
def default_public_key_from_actor(actor_data)
|
66
|
+
{ "name" => DEFAULT_PUBLIC_KEY_NAME,
|
67
|
+
"public_key" => actor_data["public_key"],
|
68
|
+
"expiration_date" => "infinity" }
|
69
|
+
end
|
70
|
+
|
71
|
+
def delete_actor_default_public_key!(request, path, actor_data)
|
72
|
+
new_actor_data = actor_data.merge("public_key" => nil)
|
73
|
+
set_data(request, path, to_json(new_actor_data))
|
74
|
+
default_public_key_from_actor(actor_data)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -1,184 +1,184 @@
|
|
1
|
-
require "ffi_yajl" unless defined?(FFI_Yajl)
|
2
|
-
require_relative "rest_object_endpoint"
|
3
|
-
require_relative "../chef_data/data_normalizer"
|
4
|
-
|
5
|
-
module ChefZero
|
6
|
-
module Endpoints
|
7
|
-
# /organizations/ORG/clients/NAME
|
8
|
-
# /organizations/ORG/users/NAME
|
9
|
-
# /users/NAME
|
10
|
-
class ActorEndpoint < RestObjectEndpoint
|
11
|
-
|
12
|
-
def get(request)
|
13
|
-
result = super
|
14
|
-
user_data = parse_json(result[2])
|
15
|
-
|
16
|
-
user_data.delete("public_key") unless request.api_v0?
|
17
|
-
|
18
|
-
json_response(200, user_data)
|
19
|
-
end
|
20
|
-
|
21
|
-
def delete(request)
|
22
|
-
result = super
|
23
|
-
|
24
|
-
if request.rest_path[0] == "users"
|
25
|
-
list_data(request, [ "organizations" ]).each do |org|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
delete_actor_keys!(request)
|
34
|
-
result
|
35
|
-
end
|
36
|
-
|
37
|
-
def put(request)
|
38
|
-
# Find out if we're updating the public key.
|
39
|
-
request_body = FFI_Yajl::Parser.parse(request.body)
|
40
|
-
|
41
|
-
if request_body["public_key"].nil?
|
42
|
-
# If public_key is null, then don't overwrite it. Weird patchiness.
|
43
|
-
body_modified = true
|
44
|
-
request_body.delete("public_key")
|
45
|
-
else
|
46
|
-
updating_public_key = true
|
47
|
-
end
|
48
|
-
|
49
|
-
# Generate private_key if requested.
|
50
|
-
if request_body.key?("private_key")
|
51
|
-
body_modified = true
|
52
|
-
|
53
|
-
if request_body.delete("private_key")
|
54
|
-
private_key, public_key = server.gen_key_pair
|
55
|
-
updating_public_key = true
|
56
|
-
request_body["public_key"] = public_key
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# Put modified body back in `request.body`
|
61
|
-
request.body = to_json(request_body) if body_modified
|
62
|
-
|
63
|
-
# PUT /clients is patchy
|
64
|
-
request.body = patch_request_body(request)
|
65
|
-
|
66
|
-
result = super(request)
|
67
|
-
|
68
|
-
# Inject private_key into response, delete public_key/password if applicable
|
69
|
-
if result[0] == 200 || result[0] == 201
|
70
|
-
client_or_user_name = identity_key_value(request) || request.rest_path[-1]
|
71
|
-
|
72
|
-
if is_rename?(request)
|
73
|
-
rename_keys!(request, client_or_user_name)
|
74
|
-
end
|
75
|
-
|
76
|
-
if request.rest_path[0] == "users"
|
77
|
-
response = {
|
78
|
-
"uri" => build_uri(request.base_uri, [ "users", client_or_user_name ]),
|
79
|
-
}
|
80
|
-
else
|
81
|
-
response = parse_json(result[2])
|
82
|
-
end
|
83
|
-
|
84
|
-
if client?(request)
|
85
|
-
response["private_key"] = private_key
|
86
|
-
else
|
87
|
-
response["private_key"] = private_key if private_key
|
88
|
-
response.delete("public_key") unless updating_public_key
|
89
|
-
end
|
90
|
-
|
91
|
-
response.delete("password")
|
92
|
-
|
93
|
-
json_response(result[0], response)
|
94
|
-
else
|
95
|
-
result
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def populate_defaults(request, response_json)
|
100
|
-
response = parse_json(response_json)
|
101
|
-
|
102
|
-
populated_response =
|
103
|
-
if client?(request)
|
104
|
-
ChefData::DataNormalizer.normalize_client(
|
105
|
-
response,
|
106
|
-
response["name"] || request.rest_path[-1],
|
107
|
-
request.rest_path[1]
|
108
|
-
)
|
109
|
-
else
|
110
|
-
ChefData::DataNormalizer.normalize_user(
|
111
|
-
response,
|
112
|
-
response["username"] || request.rest_path[-1],
|
113
|
-
identity_keys,
|
114
|
-
server.options[:osc_compat],
|
115
|
-
request.method
|
116
|
-
)
|
117
|
-
end
|
118
|
-
|
119
|
-
to_json(populated_response)
|
120
|
-
end
|
121
|
-
|
122
|
-
private
|
123
|
-
|
124
|
-
# Move key data to new path
|
125
|
-
def rename_keys!(request, new_client_or_user_name)
|
126
|
-
orig_keys_path = keys_path_base(request)
|
127
|
-
new_keys_path = orig_keys_path.dup
|
128
|
-
.tap { |path| path[-2] = new_client_or_user_name }
|
129
|
-
|
130
|
-
key_names = list_data_or_else(request, orig_keys_path, nil)
|
131
|
-
return unless key_names # No keys to move
|
132
|
-
|
133
|
-
key_names.each do |key_name|
|
134
|
-
# Get old data
|
135
|
-
orig_path = [ *orig_keys_path, key_name ]
|
136
|
-
data = get_data(request, orig_path, :data_store_exceptions)
|
137
|
-
|
138
|
-
# Copy data to new path
|
139
|
-
create_data(
|
140
|
-
request,
|
141
|
-
new_keys_path, key_name,
|
142
|
-
data,
|
143
|
-
:create_dir
|
144
|
-
)
|
145
|
-
end
|
146
|
-
|
147
|
-
# Delete original data
|
148
|
-
delete_data_dir(request, orig_keys_path, :recursive, :data_store_exceptions)
|
149
|
-
end
|
150
|
-
|
151
|
-
def delete_actor_keys!(request)
|
152
|
-
path = keys_path_base(request)[0..-2]
|
153
|
-
delete_data_dir(request, path, :recursive, :data_store_exceptions)
|
154
|
-
rescue DataStore::DataNotFoundError
|
155
|
-
end
|
156
|
-
|
157
|
-
def client?(request, rest_path = nil)
|
158
|
-
rest_path ||= request.rest_path
|
159
|
-
rest_path[2] == "clients"
|
160
|
-
end
|
161
|
-
|
162
|
-
# Return the data store keys path for the request client or user, e.g.
|
163
|
-
#
|
164
|
-
# /organizations/ORG/clients/CLIENT -> /organizations/ORG/client_keys/CLIENT/keys
|
165
|
-
# /organizations/ORG/users/USER -> /organizations/ORG/user_keys/USER/keys
|
166
|
-
# /users/USER -> /user_keys/USER
|
167
|
-
#
|
168
|
-
def keys_path_base(request, client_or_user_name = nil)
|
169
|
-
rest_path = (rest_path || request.rest_path).dup
|
170
|
-
rest_path = rest_path.dup
|
171
|
-
case rest_path[-2]
|
172
|
-
when "users"
|
173
|
-
rest_path[-2] = "user_keys"
|
174
|
-
when "clients"
|
175
|
-
rest_path[-2] = "client_keys"
|
176
|
-
else
|
177
|
-
raise "Unexpected URL #{rest_path.join("/")}: cannot determine key path"
|
178
|
-
end
|
179
|
-
rest_path << "keys"
|
180
|
-
rest_path
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
1
|
+
require "ffi_yajl" unless defined?(FFI_Yajl)
|
2
|
+
require_relative "rest_object_endpoint"
|
3
|
+
require_relative "../chef_data/data_normalizer"
|
4
|
+
|
5
|
+
module ChefZero
|
6
|
+
module Endpoints
|
7
|
+
# /organizations/ORG/clients/NAME
|
8
|
+
# /organizations/ORG/users/NAME
|
9
|
+
# /users/NAME
|
10
|
+
class ActorEndpoint < RestObjectEndpoint
|
11
|
+
|
12
|
+
def get(request)
|
13
|
+
result = super
|
14
|
+
user_data = parse_json(result[2])
|
15
|
+
|
16
|
+
user_data.delete("public_key") unless request.api_v0?
|
17
|
+
|
18
|
+
json_response(200, user_data)
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete(request)
|
22
|
+
result = super
|
23
|
+
|
24
|
+
if request.rest_path[0] == "users"
|
25
|
+
list_data(request, [ "organizations" ]).each do |org|
|
26
|
+
|
27
|
+
delete_data(request, [ "organizations", org, "users", request.rest_path[1] ], :data_store_exceptions)
|
28
|
+
rescue DataStore::DataNotFoundError
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
delete_actor_keys!(request)
|
34
|
+
result
|
35
|
+
end
|
36
|
+
|
37
|
+
def put(request)
|
38
|
+
# Find out if we're updating the public key.
|
39
|
+
request_body = FFI_Yajl::Parser.parse(request.body)
|
40
|
+
|
41
|
+
if request_body["public_key"].nil?
|
42
|
+
# If public_key is null, then don't overwrite it. Weird patchiness.
|
43
|
+
body_modified = true
|
44
|
+
request_body.delete("public_key")
|
45
|
+
else
|
46
|
+
updating_public_key = true
|
47
|
+
end
|
48
|
+
|
49
|
+
# Generate private_key if requested.
|
50
|
+
if request_body.key?("private_key")
|
51
|
+
body_modified = true
|
52
|
+
|
53
|
+
if request_body.delete("private_key")
|
54
|
+
private_key, public_key = server.gen_key_pair
|
55
|
+
updating_public_key = true
|
56
|
+
request_body["public_key"] = public_key
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Put modified body back in `request.body`
|
61
|
+
request.body = to_json(request_body) if body_modified
|
62
|
+
|
63
|
+
# PUT /clients is patchy
|
64
|
+
request.body = patch_request_body(request)
|
65
|
+
|
66
|
+
result = super(request)
|
67
|
+
|
68
|
+
# Inject private_key into response, delete public_key/password if applicable
|
69
|
+
if result[0] == 200 || result[0] == 201
|
70
|
+
client_or_user_name = identity_key_value(request) || request.rest_path[-1]
|
71
|
+
|
72
|
+
if is_rename?(request)
|
73
|
+
rename_keys!(request, client_or_user_name)
|
74
|
+
end
|
75
|
+
|
76
|
+
if request.rest_path[0] == "users"
|
77
|
+
response = {
|
78
|
+
"uri" => build_uri(request.base_uri, [ "users", client_or_user_name ]),
|
79
|
+
}
|
80
|
+
else
|
81
|
+
response = parse_json(result[2])
|
82
|
+
end
|
83
|
+
|
84
|
+
if client?(request)
|
85
|
+
response["private_key"] = private_key || false
|
86
|
+
else
|
87
|
+
response["private_key"] = private_key if private_key
|
88
|
+
response.delete("public_key") unless updating_public_key
|
89
|
+
end
|
90
|
+
|
91
|
+
response.delete("password")
|
92
|
+
|
93
|
+
json_response(result[0], response)
|
94
|
+
else
|
95
|
+
result
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def populate_defaults(request, response_json)
|
100
|
+
response = parse_json(response_json)
|
101
|
+
|
102
|
+
populated_response =
|
103
|
+
if client?(request)
|
104
|
+
ChefData::DataNormalizer.normalize_client(
|
105
|
+
response,
|
106
|
+
response["name"] || request.rest_path[-1],
|
107
|
+
request.rest_path[1]
|
108
|
+
)
|
109
|
+
else
|
110
|
+
ChefData::DataNormalizer.normalize_user(
|
111
|
+
response,
|
112
|
+
response["username"] || request.rest_path[-1],
|
113
|
+
identity_keys,
|
114
|
+
server.options[:osc_compat],
|
115
|
+
request.method
|
116
|
+
)
|
117
|
+
end
|
118
|
+
|
119
|
+
to_json(populated_response)
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
# Move key data to new path
|
125
|
+
def rename_keys!(request, new_client_or_user_name)
|
126
|
+
orig_keys_path = keys_path_base(request)
|
127
|
+
new_keys_path = orig_keys_path.dup
|
128
|
+
.tap { |path| path[-2] = new_client_or_user_name }
|
129
|
+
|
130
|
+
key_names = list_data_or_else(request, orig_keys_path, nil)
|
131
|
+
return unless key_names # No keys to move
|
132
|
+
|
133
|
+
key_names.each do |key_name|
|
134
|
+
# Get old data
|
135
|
+
orig_path = [ *orig_keys_path, key_name ]
|
136
|
+
data = get_data(request, orig_path, :data_store_exceptions)
|
137
|
+
|
138
|
+
# Copy data to new path
|
139
|
+
create_data(
|
140
|
+
request,
|
141
|
+
new_keys_path, key_name,
|
142
|
+
data,
|
143
|
+
:create_dir
|
144
|
+
)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Delete original data
|
148
|
+
delete_data_dir(request, orig_keys_path, :recursive, :data_store_exceptions)
|
149
|
+
end
|
150
|
+
|
151
|
+
def delete_actor_keys!(request)
|
152
|
+
path = keys_path_base(request)[0..-2]
|
153
|
+
delete_data_dir(request, path, :recursive, :data_store_exceptions)
|
154
|
+
rescue DataStore::DataNotFoundError
|
155
|
+
end
|
156
|
+
|
157
|
+
def client?(request, rest_path = nil)
|
158
|
+
rest_path ||= request.rest_path
|
159
|
+
rest_path[2] == "clients"
|
160
|
+
end
|
161
|
+
|
162
|
+
# Return the data store keys path for the request client or user, e.g.
|
163
|
+
#
|
164
|
+
# /organizations/ORG/clients/CLIENT -> /organizations/ORG/client_keys/CLIENT/keys
|
165
|
+
# /organizations/ORG/users/USER -> /organizations/ORG/user_keys/USER/keys
|
166
|
+
# /users/USER -> /user_keys/USER
|
167
|
+
#
|
168
|
+
def keys_path_base(request, client_or_user_name = nil)
|
169
|
+
rest_path = (rest_path || request.rest_path).dup
|
170
|
+
rest_path = rest_path.dup
|
171
|
+
case rest_path[-2]
|
172
|
+
when "users"
|
173
|
+
rest_path[-2] = "user_keys"
|
174
|
+
when "clients"
|
175
|
+
rest_path[-2] = "client_keys"
|
176
|
+
else
|
177
|
+
raise "Unexpected URL #{rest_path.join("/")}: cannot determine key path"
|
178
|
+
end
|
179
|
+
rest_path << "keys"
|
180
|
+
rest_path
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|