chef-zero 4.2.3 → 4.3.0
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/LICENSE +201 -201
- data/README.md +155 -150
- data/Rakefile +31 -31
- data/bin/chef-zero +100 -100
- data/lib/chef_zero.rb +10 -7
- data/lib/chef_zero/chef_data/acl_path.rb +139 -139
- data/lib/chef_zero/chef_data/cookbook_data.rb +240 -240
- data/lib/chef_zero/chef_data/data_normalizer.rb +207 -207
- data/lib/chef_zero/chef_data/default_creator.rb +446 -446
- data/lib/chef_zero/data_store/data_already_exists_error.rb +29 -29
- data/lib/chef_zero/data_store/data_error.rb +31 -31
- data/lib/chef_zero/data_store/data_not_found_error.rb +28 -28
- data/lib/chef_zero/data_store/default_facade.rb +149 -149
- 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 +155 -155
- data/lib/chef_zero/data_store/raw_file_store.rb +147 -147
- data/lib/chef_zero/data_store/v1_to_v2_adapter.rb +142 -142
- data/lib/chef_zero/data_store/v2_to_v1_adapter.rb +107 -107
- data/lib/chef_zero/endpoints/acl_endpoint.rb +38 -38
- data/lib/chef_zero/endpoints/acls_endpoint.rb +29 -29
- data/lib/chef_zero/endpoints/actor_endpoint.rb +94 -88
- data/lib/chef_zero/endpoints/actors_endpoint.rb +64 -64
- data/lib/chef_zero/endpoints/authenticate_user_endpoint.rb +31 -31
- data/lib/chef_zero/endpoints/container_endpoint.rb +22 -22
- data/lib/chef_zero/endpoints/containers_endpoint.rb +13 -13
- data/lib/chef_zero/endpoints/cookbook_endpoint.rb +39 -39
- data/lib/chef_zero/endpoints/cookbook_version_endpoint.rb +119 -119
- data/lib/chef_zero/endpoints/cookbooks_base.rb +65 -65
- 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/environment_cookbook_endpoint.rb +24 -24
- data/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb +123 -123
- 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 +17 -17
- data/lib/chef_zero/endpoints/node_identifiers_endpoint.rb +22 -0
- 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 -29
- data/lib/chef_zero/endpoints/organization_authenticate_user_endpoint.rb +26 -26
- data/lib/chef_zero/endpoints/organization_endpoint.rb +46 -41
- data/lib/chef_zero/endpoints/organization_user_base.rb +15 -0
- data/lib/chef_zero/endpoints/organization_user_endpoint.rb +26 -48
- data/lib/chef_zero/endpoints/organization_users_endpoint.rb +43 -14
- data/lib/chef_zero/endpoints/organization_validator_key_endpoint.rb +20 -20
- data/lib/chef_zero/endpoints/organizations_endpoint.rb +62 -55
- data/lib/chef_zero/endpoints/policies_endpoint.rb +151 -154
- data/lib/chef_zero/endpoints/principal_endpoint.rb +42 -42
- data/lib/chef_zero/endpoints/rest_list_endpoint.rb +42 -42
- data/lib/chef_zero/endpoints/rest_object_endpoint.rb +63 -63
- 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 +50 -50
- data/lib/chef_zero/endpoints/search_endpoint.rb +194 -192
- data/lib/chef_zero/endpoints/searches_endpoint.rb +18 -18
- data/lib/chef_zero/endpoints/server_api_version_endpoint.rb +14 -0
- data/lib/chef_zero/endpoints/system_recovery_endpoint.rb +30 -30
- data/lib/chef_zero/endpoints/user_association_request_endpoint.rb +40 -40
- 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 +12 -12
- data/lib/chef_zero/log.rb +7 -7
- data/lib/chef_zero/rest_base.rb +242 -214
- data/lib/chef_zero/rest_error_response.rb +11 -11
- data/lib/chef_zero/rest_request.rb +69 -65
- data/lib/chef_zero/rest_router.rb +45 -45
- data/lib/chef_zero/rspec.rb +308 -308
- data/lib/chef_zero/server.rb +642 -637
- data/lib/chef_zero/socketless_server_map.rb +92 -92
- 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 +29 -29
- 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 +43 -43
- data/lib/chef_zero/solr/solr_doc.rb +53 -53
- data/lib/chef_zero/solr/solr_parser.rb +203 -203
- data/lib/chef_zero/version.rb +3 -3
- data/spec/run_oc_pedant.rb +63 -56
- data/spec/search_spec.rb +32 -32
- data/spec/server_spec.rb +92 -91
- data/spec/socketless_server_map_spec.rb +76 -76
- data/spec/support/oc_pedant.rb +132 -134
- data/spec/support/stickywicket.pem +27 -27
- metadata +10 -15
- data/spec/run_pedant.rb +0 -103
- data/spec/support/pedant.rb +0 -129
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
require 'ffi_yajl'
|
|
2
|
-
require 'chef_zero/rest_base'
|
|
3
|
-
|
|
4
|
-
module ChefZero
|
|
5
|
-
module Endpoints
|
|
6
|
-
# Typical REST list endpoint (/roles or /data/BAG)
|
|
7
|
-
class RestListEndpoint < RestBase
|
|
8
|
-
def initialize(server, identity_keys = [ 'name' ])
|
|
9
|
-
super(server)
|
|
10
|
-
identity_keys = [ identity_keys ] if identity_keys.is_a?(String)
|
|
11
|
-
@identity_keys = identity_keys
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
attr_reader :identity_keys
|
|
15
|
-
|
|
16
|
-
def get(request)
|
|
17
|
-
# Get the result
|
|
18
|
-
result_hash = {}
|
|
19
|
-
list_data(request).sort.each do |name|
|
|
20
|
-
result_hash[name] = "#{build_uri(request.base_uri, request.rest_path + [name])}"
|
|
21
|
-
end
|
|
22
|
-
json_response(200, result_hash)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def post(request)
|
|
26
|
-
contents = request.body
|
|
27
|
-
key = get_key(contents)
|
|
28
|
-
if key.nil?
|
|
29
|
-
error(400, "Must specify #{identity_keys.map { |k| k.inspect }.join(' or ')} in JSON")
|
|
30
|
-
else
|
|
31
|
-
create_data(request, request.rest_path, key, contents)
|
|
32
|
-
json_response(201, {'uri' => "#{build_uri(request.base_uri, request.rest_path + [key])}"})
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def get_key(contents)
|
|
37
|
-
json = FFI_Yajl::Parser.parse(contents, :create_additions => false)
|
|
38
|
-
identity_keys.map { |k| json[k] }.select { |v| v }.first
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
1
|
+
require 'ffi_yajl'
|
|
2
|
+
require 'chef_zero/rest_base'
|
|
3
|
+
|
|
4
|
+
module ChefZero
|
|
5
|
+
module Endpoints
|
|
6
|
+
# Typical REST list endpoint (/roles or /data/BAG)
|
|
7
|
+
class RestListEndpoint < RestBase
|
|
8
|
+
def initialize(server, identity_keys = [ 'name' ])
|
|
9
|
+
super(server)
|
|
10
|
+
identity_keys = [ identity_keys ] if identity_keys.is_a?(String)
|
|
11
|
+
@identity_keys = identity_keys
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attr_reader :identity_keys
|
|
15
|
+
|
|
16
|
+
def get(request)
|
|
17
|
+
# Get the result
|
|
18
|
+
result_hash = {}
|
|
19
|
+
list_data(request).sort.each do |name|
|
|
20
|
+
result_hash[name] = "#{build_uri(request.base_uri, request.rest_path + [name])}"
|
|
21
|
+
end
|
|
22
|
+
json_response(200, result_hash)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def post(request)
|
|
26
|
+
contents = request.body
|
|
27
|
+
key = get_key(contents)
|
|
28
|
+
if key.nil?
|
|
29
|
+
error(400, "Must specify #{identity_keys.map { |k| k.inspect }.join(' or ')} in JSON")
|
|
30
|
+
else
|
|
31
|
+
create_data(request, request.rest_path, key, contents)
|
|
32
|
+
json_response(201, {'uri' => "#{build_uri(request.base_uri, request.rest_path + [key])}"})
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def get_key(contents)
|
|
37
|
+
json = FFI_Yajl::Parser.parse(contents, :create_additions => false)
|
|
38
|
+
identity_keys.map { |k| json[k] }.select { |v| v }.first
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
require 'ffi_yajl'
|
|
2
|
-
require 'chef_zero/rest_base'
|
|
3
|
-
require 'chef_zero/rest_error_response'
|
|
4
|
-
|
|
5
|
-
module ChefZero
|
|
6
|
-
module Endpoints
|
|
7
|
-
# Typical REST leaf endpoint (/roles/NAME or /data/BAG/NAME)
|
|
8
|
-
class RestObjectEndpoint < RestBase
|
|
9
|
-
def initialize(server, identity_keys = [ 'name' ])
|
|
10
|
-
super(server)
|
|
11
|
-
identity_keys = [ identity_keys ] if identity_keys.is_a?(String)
|
|
12
|
-
@identity_keys = identity_keys
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
attr_reader :identity_keys
|
|
16
|
-
|
|
17
|
-
def get(request)
|
|
18
|
-
already_json_response(200, populate_defaults(request, get_data(request)))
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def put(request)
|
|
22
|
-
# We grab the old body to trigger a 404 if it doesn't exist
|
|
23
|
-
old_body = get_data(request)
|
|
24
|
-
request_json = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
|
|
25
|
-
key = identity_keys.map { |k| request_json[k] }.select { |v| v }.first
|
|
26
|
-
key ||= request.rest_path[-1]
|
|
27
|
-
# If it's a rename, check for conflict and delete the old value
|
|
28
|
-
rename = key != request.rest_path[-1]
|
|
29
|
-
if rename
|
|
30
|
-
begin
|
|
31
|
-
create_data(request, request.rest_path[0..-2], key, request.body, :data_store_exceptions)
|
|
32
|
-
rescue DataStore::DataAlreadyExistsError
|
|
33
|
-
return error(409, "Cannot rename '#{request.rest_path[-1]}' to '#{key}': '#{key}' already exists")
|
|
34
|
-
end
|
|
35
|
-
delete_data(request)
|
|
36
|
-
already_json_response(201, populate_defaults(request, request.body))
|
|
37
|
-
else
|
|
38
|
-
set_data(request, request.rest_path, request.body)
|
|
39
|
-
already_json_response(200, populate_defaults(request, request.body))
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def delete(request)
|
|
44
|
-
result = get_data(request)
|
|
45
|
-
delete_data(request)
|
|
46
|
-
already_json_response(200, populate_defaults(request, result))
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def patch_request_body(request)
|
|
50
|
-
existing_value = get_data(request, nil, :nil)
|
|
51
|
-
if existing_value
|
|
52
|
-
request_json = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
|
|
53
|
-
existing_json = FFI_Yajl::Parser.parse(existing_value, :create_additions => false)
|
|
54
|
-
merged_json = existing_json.merge(request_json)
|
|
55
|
-
if merged_json.size > request_json.size
|
|
56
|
-
return FFI_Yajl::Encoder.encode(merged_json, :pretty => true)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
request.body
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
1
|
+
require 'ffi_yajl'
|
|
2
|
+
require 'chef_zero/rest_base'
|
|
3
|
+
require 'chef_zero/rest_error_response'
|
|
4
|
+
|
|
5
|
+
module ChefZero
|
|
6
|
+
module Endpoints
|
|
7
|
+
# Typical REST leaf endpoint (/roles/NAME or /data/BAG/NAME)
|
|
8
|
+
class RestObjectEndpoint < RestBase
|
|
9
|
+
def initialize(server, identity_keys = [ 'name' ])
|
|
10
|
+
super(server)
|
|
11
|
+
identity_keys = [ identity_keys ] if identity_keys.is_a?(String)
|
|
12
|
+
@identity_keys = identity_keys
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
attr_reader :identity_keys
|
|
16
|
+
|
|
17
|
+
def get(request)
|
|
18
|
+
already_json_response(200, populate_defaults(request, get_data(request)))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def put(request)
|
|
22
|
+
# We grab the old body to trigger a 404 if it doesn't exist
|
|
23
|
+
old_body = get_data(request)
|
|
24
|
+
request_json = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
|
|
25
|
+
key = identity_keys.map { |k| request_json[k] }.select { |v| v }.first
|
|
26
|
+
key ||= request.rest_path[-1]
|
|
27
|
+
# If it's a rename, check for conflict and delete the old value
|
|
28
|
+
rename = key != request.rest_path[-1]
|
|
29
|
+
if rename
|
|
30
|
+
begin
|
|
31
|
+
create_data(request, request.rest_path[0..-2], key, request.body, :data_store_exceptions)
|
|
32
|
+
rescue DataStore::DataAlreadyExistsError
|
|
33
|
+
return error(409, "Cannot rename '#{request.rest_path[-1]}' to '#{key}': '#{key}' already exists")
|
|
34
|
+
end
|
|
35
|
+
delete_data(request)
|
|
36
|
+
already_json_response(201, populate_defaults(request, request.body))
|
|
37
|
+
else
|
|
38
|
+
set_data(request, request.rest_path, request.body)
|
|
39
|
+
already_json_response(200, populate_defaults(request, request.body))
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def delete(request)
|
|
44
|
+
result = get_data(request)
|
|
45
|
+
delete_data(request)
|
|
46
|
+
already_json_response(200, populate_defaults(request, result))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def patch_request_body(request)
|
|
50
|
+
existing_value = get_data(request, nil, :nil)
|
|
51
|
+
if existing_value
|
|
52
|
+
request_json = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
|
|
53
|
+
existing_json = FFI_Yajl::Parser.parse(existing_value, :create_additions => false)
|
|
54
|
+
merged_json = existing_json.merge(request_json)
|
|
55
|
+
if merged_json.size > request_json.size
|
|
56
|
+
return FFI_Yajl::Encoder.encode(merged_json, :pretty => true)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
request.body
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
require 'ffi_yajl'
|
|
2
|
-
require 'chef_zero/endpoints/rest_object_endpoint'
|
|
3
|
-
require 'chef_zero/chef_data/data_normalizer'
|
|
4
|
-
|
|
5
|
-
module ChefZero
|
|
6
|
-
module Endpoints
|
|
7
|
-
# /roles/NAME
|
|
8
|
-
class RoleEndpoint < RestObjectEndpoint
|
|
9
|
-
def populate_defaults(request, response_json)
|
|
10
|
-
role = FFI_Yajl::Parser.parse(response_json, :create_additions => false)
|
|
11
|
-
role = ChefData::DataNormalizer.normalize_role(role, request.rest_path[3])
|
|
12
|
-
FFI_Yajl::Encoder.encode(role, :pretty => true)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
1
|
+
require 'ffi_yajl'
|
|
2
|
+
require 'chef_zero/endpoints/rest_object_endpoint'
|
|
3
|
+
require 'chef_zero/chef_data/data_normalizer'
|
|
4
|
+
|
|
5
|
+
module ChefZero
|
|
6
|
+
module Endpoints
|
|
7
|
+
# /roles/NAME
|
|
8
|
+
class RoleEndpoint < RestObjectEndpoint
|
|
9
|
+
def populate_defaults(request, response_json)
|
|
10
|
+
role = FFI_Yajl::Parser.parse(response_json, :create_additions => false)
|
|
11
|
+
role = ChefData::DataNormalizer.normalize_role(role, request.rest_path[3])
|
|
12
|
+
FFI_Yajl::Encoder.encode(role, :pretty => true)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
require 'ffi_yajl'
|
|
2
|
-
require 'chef_zero/rest_base'
|
|
3
|
-
|
|
4
|
-
module ChefZero
|
|
5
|
-
module Endpoints
|
|
6
|
-
# /roles/NAME/environments
|
|
7
|
-
class RoleEnvironmentsEndpoint < RestBase
|
|
8
|
-
def get(request)
|
|
9
|
-
role = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
|
|
10
|
-
json_response(200, [ '_default' ] + (role['env_run_lists'].keys || []))
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
1
|
+
require 'ffi_yajl'
|
|
2
|
+
require 'chef_zero/rest_base'
|
|
3
|
+
|
|
4
|
+
module ChefZero
|
|
5
|
+
module Endpoints
|
|
6
|
+
# /roles/NAME/environments
|
|
7
|
+
class RoleEnvironmentsEndpoint < RestBase
|
|
8
|
+
def get(request)
|
|
9
|
+
role = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
|
|
10
|
+
json_response(200, [ '_default' ] + (role['env_run_lists'].keys || []))
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
require 'chef_zero/rest_base'
|
|
2
|
-
require 'chef_zero/rest_error_response'
|
|
3
|
-
require 'ffi_yajl'
|
|
4
|
-
|
|
5
|
-
module ChefZero
|
|
6
|
-
module Endpoints
|
|
7
|
-
# /sandboxes/ID
|
|
8
|
-
class SandboxEndpoint < RestBase
|
|
9
|
-
def put(request)
|
|
10
|
-
existing_sandbox = FFI_Yajl::Parser.parse(get_data(request), :create_additions => false)
|
|
11
|
-
existing_sandbox['checksums'].each do |checksum|
|
|
12
|
-
if !exists_data?(request, request.rest_path[0..1] + ['file_store', 'checksums', checksum])
|
|
13
|
-
raise RestErrorResponse.new(503, "Checksum not uploaded: #{checksum}")
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
delete_data(request)
|
|
17
|
-
json_response(200, {
|
|
18
|
-
:guid => request.rest_path[3],
|
|
19
|
-
:name => request.rest_path[3],
|
|
20
|
-
:checksums => existing_sandbox['checksums'],
|
|
21
|
-
:create_time => existing_sandbox['create_time'],
|
|
22
|
-
:is_completed => true
|
|
23
|
-
})
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
1
|
+
require 'chef_zero/rest_base'
|
|
2
|
+
require 'chef_zero/rest_error_response'
|
|
3
|
+
require 'ffi_yajl'
|
|
4
|
+
|
|
5
|
+
module ChefZero
|
|
6
|
+
module Endpoints
|
|
7
|
+
# /sandboxes/ID
|
|
8
|
+
class SandboxEndpoint < RestBase
|
|
9
|
+
def put(request)
|
|
10
|
+
existing_sandbox = FFI_Yajl::Parser.parse(get_data(request), :create_additions => false)
|
|
11
|
+
existing_sandbox['checksums'].each do |checksum|
|
|
12
|
+
if !exists_data?(request, request.rest_path[0..1] + ['file_store', 'checksums', checksum])
|
|
13
|
+
raise RestErrorResponse.new(503, "Checksum not uploaded: #{checksum}")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
delete_data(request)
|
|
17
|
+
json_response(200, {
|
|
18
|
+
:guid => request.rest_path[3],
|
|
19
|
+
:name => request.rest_path[3],
|
|
20
|
+
:checksums => existing_sandbox['checksums'],
|
|
21
|
+
:create_time => existing_sandbox['create_time'],
|
|
22
|
+
:is_completed => true
|
|
23
|
+
})
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
require 'ffi_yajl'
|
|
2
|
-
require 'chef_zero/rest_base'
|
|
3
|
-
|
|
4
|
-
module ChefZero
|
|
5
|
-
module Endpoints
|
|
6
|
-
# /sandboxes
|
|
7
|
-
class SandboxesEndpoint < RestBase
|
|
8
|
-
def initialize(server)
|
|
9
|
-
super(server)
|
|
10
|
-
@next_id = 1
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def post(request)
|
|
14
|
-
sandbox_checksums = []
|
|
15
|
-
|
|
16
|
-
needed_checksums = FFI_Yajl::Parser.parse(request.body, :create_additions => false)['checksums']
|
|
17
|
-
result_checksums = {}
|
|
18
|
-
needed_checksums.keys.each do |needed_checksum|
|
|
19
|
-
if list_data(request, request.rest_path[0..1] + ['file_store', 'checksums']).include?(needed_checksum)
|
|
20
|
-
result_checksums[needed_checksum] = { :needs_upload => false }
|
|
21
|
-
else
|
|
22
|
-
result_checksums[needed_checksum] = {
|
|
23
|
-
:needs_upload => true,
|
|
24
|
-
:url => build_uri(request.base_uri, request.rest_path[0..1] + ['file_store', 'checksums', needed_checksum])
|
|
25
|
-
}
|
|
26
|
-
sandbox_checksums << needed_checksum
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# There is an obvious race condition here.
|
|
31
|
-
id = @next_id.to_s
|
|
32
|
-
@next_id+=1
|
|
33
|
-
|
|
34
|
-
time_str = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S%z')
|
|
35
|
-
time_str = "#{time_str[0..21]}:#{time_str[22..23]}"
|
|
36
|
-
|
|
37
|
-
create_data(request, request.rest_path, id, FFI_Yajl::Encoder.encode({
|
|
38
|
-
:create_time => time_str,
|
|
39
|
-
:checksums => sandbox_checksums
|
|
40
|
-
}, :pretty => true))
|
|
41
|
-
|
|
42
|
-
json_response(201, {
|
|
43
|
-
:uri => build_uri(request.base_uri, request.rest_path + [id]),
|
|
44
|
-
:checksums => result_checksums,
|
|
45
|
-
:sandbox_id => id
|
|
46
|
-
})
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
1
|
+
require 'ffi_yajl'
|
|
2
|
+
require 'chef_zero/rest_base'
|
|
3
|
+
|
|
4
|
+
module ChefZero
|
|
5
|
+
module Endpoints
|
|
6
|
+
# /sandboxes
|
|
7
|
+
class SandboxesEndpoint < RestBase
|
|
8
|
+
def initialize(server)
|
|
9
|
+
super(server)
|
|
10
|
+
@next_id = 1
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def post(request)
|
|
14
|
+
sandbox_checksums = []
|
|
15
|
+
|
|
16
|
+
needed_checksums = FFI_Yajl::Parser.parse(request.body, :create_additions => false)['checksums']
|
|
17
|
+
result_checksums = {}
|
|
18
|
+
needed_checksums.keys.each do |needed_checksum|
|
|
19
|
+
if list_data(request, request.rest_path[0..1] + ['file_store', 'checksums']).include?(needed_checksum)
|
|
20
|
+
result_checksums[needed_checksum] = { :needs_upload => false }
|
|
21
|
+
else
|
|
22
|
+
result_checksums[needed_checksum] = {
|
|
23
|
+
:needs_upload => true,
|
|
24
|
+
:url => build_uri(request.base_uri, request.rest_path[0..1] + ['file_store', 'checksums', needed_checksum])
|
|
25
|
+
}
|
|
26
|
+
sandbox_checksums << needed_checksum
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# There is an obvious race condition here.
|
|
31
|
+
id = @next_id.to_s
|
|
32
|
+
@next_id+=1
|
|
33
|
+
|
|
34
|
+
time_str = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S%z')
|
|
35
|
+
time_str = "#{time_str[0..21]}:#{time_str[22..23]}"
|
|
36
|
+
|
|
37
|
+
create_data(request, request.rest_path, id, FFI_Yajl::Encoder.encode({
|
|
38
|
+
:create_time => time_str,
|
|
39
|
+
:checksums => sandbox_checksums
|
|
40
|
+
}, :pretty => true))
|
|
41
|
+
|
|
42
|
+
json_response(201, {
|
|
43
|
+
:uri => build_uri(request.base_uri, request.rest_path + [id]),
|
|
44
|
+
:checksums => result_checksums,
|
|
45
|
+
:sandbox_id => id
|
|
46
|
+
})
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -1,192 +1,194 @@
|
|
|
1
|
-
require 'ffi_yajl'
|
|
2
|
-
require 'chef_zero/endpoints/rest_object_endpoint'
|
|
3
|
-
require 'chef_zero/chef_data/data_normalizer'
|
|
4
|
-
require 'chef_zero/rest_error_response'
|
|
5
|
-
require 'chef_zero/solr/solr_parser'
|
|
6
|
-
require 'chef_zero/solr/solr_doc'
|
|
7
|
-
|
|
8
|
-
module ChefZero
|
|
9
|
-
module Endpoints
|
|
10
|
-
# /search/INDEX
|
|
11
|
-
class SearchEndpoint < RestBase
|
|
12
|
-
def get(request)
|
|
13
|
-
|
|
14
|
-
results
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
data[key] =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
'
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
when '
|
|
53
|
-
[ ['
|
|
54
|
-
when '
|
|
55
|
-
[ ['
|
|
56
|
-
when '
|
|
57
|
-
[ ['
|
|
58
|
-
|
|
59
|
-
[ ['
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
deep_merge!(value['
|
|
73
|
-
deep_merge!(value['
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
value
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
'
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
#
|
|
144
|
-
#
|
|
145
|
-
#
|
|
146
|
-
#
|
|
147
|
-
#
|
|
148
|
-
#
|
|
149
|
-
#
|
|
150
|
-
#
|
|
151
|
-
#
|
|
152
|
-
#
|
|
153
|
-
#
|
|
154
|
-
#
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
when
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
dest[src_key] = src_value
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
dest = source
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
dest = source
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
end
|
|
1
|
+
require 'ffi_yajl'
|
|
2
|
+
require 'chef_zero/endpoints/rest_object_endpoint'
|
|
3
|
+
require 'chef_zero/chef_data/data_normalizer'
|
|
4
|
+
require 'chef_zero/rest_error_response'
|
|
5
|
+
require 'chef_zero/solr/solr_parser'
|
|
6
|
+
require 'chef_zero/solr/solr_doc'
|
|
7
|
+
|
|
8
|
+
module ChefZero
|
|
9
|
+
module Endpoints
|
|
10
|
+
# /search/INDEX
|
|
11
|
+
class SearchEndpoint < RestBase
|
|
12
|
+
def get(request)
|
|
13
|
+
orgname = request.rest_path[1]
|
|
14
|
+
results = search(request, orgname)
|
|
15
|
+
results['rows'] = results['rows'].map { |name,uri,value,search_value| value }
|
|
16
|
+
json_response(200, results)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def post(request)
|
|
20
|
+
orgname = request.rest_path[1]
|
|
21
|
+
full_results = search(request, orgname)
|
|
22
|
+
keys = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
|
|
23
|
+
partial_results = full_results['rows'].map do |name, uri, doc, search_value|
|
|
24
|
+
data = {}
|
|
25
|
+
keys.each_pair do |key, path|
|
|
26
|
+
if path.size > 0
|
|
27
|
+
value = search_value
|
|
28
|
+
path.each do |path_part|
|
|
29
|
+
value = value[path_part] if !value.nil?
|
|
30
|
+
end
|
|
31
|
+
data[key] = value
|
|
32
|
+
else
|
|
33
|
+
data[key] = nil
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
{
|
|
37
|
+
'url' => uri,
|
|
38
|
+
'data' => data
|
|
39
|
+
}
|
|
40
|
+
end
|
|
41
|
+
json_response(200, {
|
|
42
|
+
'rows' => partial_results,
|
|
43
|
+
'start' => full_results['start'],
|
|
44
|
+
'total' => full_results['total']
|
|
45
|
+
})
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def search_container(request, index, orgname)
|
|
51
|
+
relative_parts, normalize_proc = case index
|
|
52
|
+
when 'client'
|
|
53
|
+
[ ['clients'], Proc.new { |client, name| ChefData::DataNormalizer.normalize_client(client, name, orgname) } ]
|
|
54
|
+
when 'node'
|
|
55
|
+
[ ['nodes'], Proc.new { |node, name| ChefData::DataNormalizer.normalize_node(node, name) } ]
|
|
56
|
+
when 'environment'
|
|
57
|
+
[ ['environments'], Proc.new { |environment, name| ChefData::DataNormalizer.normalize_environment(environment, name) } ]
|
|
58
|
+
when 'role'
|
|
59
|
+
[ ['roles'], Proc.new { |role, name| ChefData::DataNormalizer.normalize_role(role, name) } ]
|
|
60
|
+
else
|
|
61
|
+
[ ['data', index], Proc.new { |data_bag_item, id| ChefData::DataNormalizer.normalize_data_bag_item(data_bag_item, index, id, 'DELETE') } ]
|
|
62
|
+
end
|
|
63
|
+
[
|
|
64
|
+
request.rest_path[0..1] + relative_parts,
|
|
65
|
+
normalize_proc
|
|
66
|
+
]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def expand_for_indexing(value, index, id)
|
|
70
|
+
if index == 'node'
|
|
71
|
+
result = {}
|
|
72
|
+
deep_merge!(value['default'] || {}, result)
|
|
73
|
+
deep_merge!(value['normal'] || {}, result)
|
|
74
|
+
deep_merge!(value['override'] || {}, result)
|
|
75
|
+
deep_merge!(value['automatic'] || {}, result)
|
|
76
|
+
result['recipe'] = []
|
|
77
|
+
result['role'] = []
|
|
78
|
+
if value['run_list']
|
|
79
|
+
value['run_list'].each do |run_list_entry|
|
|
80
|
+
if run_list_entry =~ /^(recipe|role)\[(.*)\]/
|
|
81
|
+
result[$1] << $2
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
value.each_pair do |key, value|
|
|
86
|
+
result[key] = value unless %w(default normal override automatic).include?(key)
|
|
87
|
+
end
|
|
88
|
+
result
|
|
89
|
+
|
|
90
|
+
elsif !%w(client environment role).include?(index)
|
|
91
|
+
ChefData::DataNormalizer.normalize_data_bag_item(value, index, id, 'GET')
|
|
92
|
+
else
|
|
93
|
+
value
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def search(request, orgname = nil)
|
|
98
|
+
# Extract parameters
|
|
99
|
+
index = request.rest_path[3]
|
|
100
|
+
query_string = request.query_params['q'] || '*:*'
|
|
101
|
+
solr_query = ChefZero::Solr::SolrParser.new(query_string).parse
|
|
102
|
+
sort_string = request.query_params['sort']
|
|
103
|
+
start = request.query_params['start']
|
|
104
|
+
start = start.to_i if start
|
|
105
|
+
rows = request.query_params['rows']
|
|
106
|
+
rows = rows.to_i if rows
|
|
107
|
+
|
|
108
|
+
# Get the search container
|
|
109
|
+
container, expander = search_container(request, index, orgname)
|
|
110
|
+
|
|
111
|
+
# Search!
|
|
112
|
+
result = []
|
|
113
|
+
list_data(request, container).each do |name|
|
|
114
|
+
value = get_data(request, container + [name])
|
|
115
|
+
expanded = expander.call(FFI_Yajl::Parser.parse(value, :create_additions => false), name)
|
|
116
|
+
result << [ name, build_uri(request.base_uri, container + [name]), expanded, expand_for_indexing(expanded, index, name) ]
|
|
117
|
+
end
|
|
118
|
+
result = result.select do |name, uri, value, search_value|
|
|
119
|
+
solr_query.matches_doc?(ChefZero::Solr::SolrDoc.new(search_value, name))
|
|
120
|
+
end
|
|
121
|
+
total = result.size
|
|
122
|
+
|
|
123
|
+
# Sort
|
|
124
|
+
if sort_string
|
|
125
|
+
sort_key, sort_order = sort_string.split(/\s+/, 2)
|
|
126
|
+
result = result.sort_by { |name,uri,value,search_value| ChefZero::Solr::SolrDoc.new(search_value, name)[sort_key] }
|
|
127
|
+
result = result.reverse if sort_order == "DESC"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Paginate
|
|
131
|
+
if start
|
|
132
|
+
result = result[start..start+(rows||-1)]
|
|
133
|
+
end
|
|
134
|
+
{
|
|
135
|
+
'rows' => result,
|
|
136
|
+
'start' => start || 0,
|
|
137
|
+
'total' => total
|
|
138
|
+
}
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
private
|
|
142
|
+
|
|
143
|
+
# Deep Merge core documentation.
|
|
144
|
+
# deep_merge! method permits merging of arbitrary child elements. The two top level
|
|
145
|
+
# elements must be hashes. These hashes can contain unlimited (to stack limit) levels
|
|
146
|
+
# of child elements. These child elements to not have to be of the same types.
|
|
147
|
+
# Where child elements are of the same type, deep_merge will attempt to merge them together.
|
|
148
|
+
# Where child elements are not of the same type, deep_merge will skip or optionally overwrite
|
|
149
|
+
# the destination element with the contents of the source element at that level.
|
|
150
|
+
# So if you have two hashes like this:
|
|
151
|
+
# source = {:x => [1,2,3], :y => 2}
|
|
152
|
+
# dest = {:x => [4,5,'6'], :y => [7,8,9]}
|
|
153
|
+
# dest.deep_merge!(source)
|
|
154
|
+
# Results: {:x => [1,2,3,4,5,'6'], :y => 2}
|
|
155
|
+
# By default, "deep_merge!" will overwrite any unmergeables and merge everything else.
|
|
156
|
+
# To avoid this, use "deep_merge" (no bang/exclamation mark)
|
|
157
|
+
def deep_merge!(source, dest)
|
|
158
|
+
# if dest doesn't exist, then simply copy source to it
|
|
159
|
+
if dest.nil?
|
|
160
|
+
dest = source; return dest
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
case source
|
|
164
|
+
when nil
|
|
165
|
+
dest
|
|
166
|
+
when Hash
|
|
167
|
+
source.each do |src_key, src_value|
|
|
168
|
+
if dest.kind_of?(Hash)
|
|
169
|
+
if dest[src_key]
|
|
170
|
+
dest[src_key] = deep_merge!(src_value, dest[src_key])
|
|
171
|
+
else # dest[src_key] doesn't exist so we take whatever source has
|
|
172
|
+
dest[src_key] = src_value
|
|
173
|
+
end
|
|
174
|
+
else # dest isn't a hash, so we overwrite it completely
|
|
175
|
+
dest = source
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
when Array
|
|
179
|
+
if dest.kind_of?(Array)
|
|
180
|
+
dest = dest | source
|
|
181
|
+
else
|
|
182
|
+
dest = source
|
|
183
|
+
end
|
|
184
|
+
when String
|
|
185
|
+
dest = source
|
|
186
|
+
else # src_hash is not an array or hash, so we'll have to overwrite dest
|
|
187
|
+
dest = source
|
|
188
|
+
end
|
|
189
|
+
dest
|
|
190
|
+
end # deep_merge!
|
|
191
|
+
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|