chef-zero 4.3.0 → 4.3.1
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 -155
- data/Rakefile +31 -31
- data/bin/chef-zero +100 -100
- data/lib/chef_zero.rb +10 -10
- 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 +208 -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 -94
- 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 -22
- 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 +46 -46
- data/lib/chef_zero/endpoints/organization_user_base.rb +15 -15
- data/lib/chef_zero/endpoints/organization_user_endpoint.rb +26 -26
- 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 +62 -62
- data/lib/chef_zero/endpoints/policies_endpoint.rb +151 -151
- 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 -194
- 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/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 -242
- data/lib/chef_zero/rest_error_response.rb +11 -11
- data/lib/chef_zero/rest_request.rb +69 -69
- data/lib/chef_zero/rest_router.rb +45 -45
- data/lib/chef_zero/rspec.rb +308 -308
- data/lib/chef_zero/server.rb +642 -642
- 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 -63
- data/spec/search_spec.rb +32 -32
- data/spec/server_spec.rb +92 -92
- data/spec/socketless_server_map_spec.rb +76 -76
- data/spec/support/oc_pedant.rb +132 -132
- data/spec/support/stickywicket.pem +27 -27
- metadata +3 -3
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
require 'ffi_yajl'
|
|
2
|
-
require 'chef_zero/endpoints/rest_list_endpoint'
|
|
3
|
-
|
|
4
|
-
module ChefZero
|
|
5
|
-
module Endpoints
|
|
6
|
-
# /users, /organizations/ORG/clients or /organizations/ORG/users
|
|
7
|
-
class ActorsEndpoint < RestListEndpoint
|
|
8
|
-
def get(request)
|
|
9
|
-
response = super(request)
|
|
10
|
-
|
|
11
|
-
if request.query_params['email']
|
|
12
|
-
results = FFI_Yajl::Parser.parse(response[2], :create_additions => false)
|
|
13
|
-
new_results = {}
|
|
14
|
-
results.each do |name, url|
|
|
15
|
-
record = get_data(request, request.rest_path + [ name ], :nil)
|
|
16
|
-
if record
|
|
17
|
-
record = FFI_Yajl::Parser.parse(record, :create_additions => false)
|
|
18
|
-
new_results[name] = url if record['email'] == request.query_params['email']
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
response[2] = FFI_Yajl::Encoder.encode(new_results, :pretty => true)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
if request.query_params['verbose']
|
|
25
|
-
results = FFI_Yajl::Parser.parse(response[2], :create_additions => false)
|
|
26
|
-
results.each do |name, url|
|
|
27
|
-
record = get_data(request, request.rest_path + [ name ], :nil)
|
|
28
|
-
if record
|
|
29
|
-
record = FFI_Yajl::Parser.parse(record, :create_additions => false)
|
|
30
|
-
record = ChefData::DataNormalizer.normalize_user(record, name, identity_keys, server.options[:osc_compat])
|
|
31
|
-
results[name] = record
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
response[2] = FFI_Yajl::Encoder.encode(results, :pretty => true)
|
|
35
|
-
end
|
|
36
|
-
response
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def post(request)
|
|
40
|
-
# First, find out if the user actually posted a public key. If not, make
|
|
41
|
-
# one.
|
|
42
|
-
request_body = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
|
|
43
|
-
public_key = request_body['public_key']
|
|
44
|
-
if !public_key
|
|
45
|
-
private_key, public_key = server.gen_key_pair
|
|
46
|
-
request_body['public_key'] = public_key
|
|
47
|
-
request.body = FFI_Yajl::Encoder.encode(request_body, :pretty => true)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
result = super(request)
|
|
51
|
-
|
|
52
|
-
if result[0] == 201
|
|
53
|
-
# If we generated a key, stuff it in the response.
|
|
54
|
-
response = FFI_Yajl::Parser.parse(result[2], :create_additions => false)
|
|
55
|
-
response['private_key'] = private_key if private_key
|
|
56
|
-
response['public_key'] = public_key unless request.rest_path[0] == 'users'
|
|
57
|
-
json_response(201, response)
|
|
58
|
-
else
|
|
59
|
-
result
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
1
|
+
require 'ffi_yajl'
|
|
2
|
+
require 'chef_zero/endpoints/rest_list_endpoint'
|
|
3
|
+
|
|
4
|
+
module ChefZero
|
|
5
|
+
module Endpoints
|
|
6
|
+
# /users, /organizations/ORG/clients or /organizations/ORG/users
|
|
7
|
+
class ActorsEndpoint < RestListEndpoint
|
|
8
|
+
def get(request)
|
|
9
|
+
response = super(request)
|
|
10
|
+
|
|
11
|
+
if request.query_params['email']
|
|
12
|
+
results = FFI_Yajl::Parser.parse(response[2], :create_additions => false)
|
|
13
|
+
new_results = {}
|
|
14
|
+
results.each do |name, url|
|
|
15
|
+
record = get_data(request, request.rest_path + [ name ], :nil)
|
|
16
|
+
if record
|
|
17
|
+
record = FFI_Yajl::Parser.parse(record, :create_additions => false)
|
|
18
|
+
new_results[name] = url if record['email'] == request.query_params['email']
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
response[2] = FFI_Yajl::Encoder.encode(new_results, :pretty => true)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
if request.query_params['verbose']
|
|
25
|
+
results = FFI_Yajl::Parser.parse(response[2], :create_additions => false)
|
|
26
|
+
results.each do |name, url|
|
|
27
|
+
record = get_data(request, request.rest_path + [ name ], :nil)
|
|
28
|
+
if record
|
|
29
|
+
record = FFI_Yajl::Parser.parse(record, :create_additions => false)
|
|
30
|
+
record = ChefData::DataNormalizer.normalize_user(record, name, identity_keys, server.options[:osc_compat])
|
|
31
|
+
results[name] = record
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
response[2] = FFI_Yajl::Encoder.encode(results, :pretty => true)
|
|
35
|
+
end
|
|
36
|
+
response
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def post(request)
|
|
40
|
+
# First, find out if the user actually posted a public key. If not, make
|
|
41
|
+
# one.
|
|
42
|
+
request_body = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
|
|
43
|
+
public_key = request_body['public_key']
|
|
44
|
+
if !public_key
|
|
45
|
+
private_key, public_key = server.gen_key_pair
|
|
46
|
+
request_body['public_key'] = public_key
|
|
47
|
+
request.body = FFI_Yajl::Encoder.encode(request_body, :pretty => true)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
result = super(request)
|
|
51
|
+
|
|
52
|
+
if result[0] == 201
|
|
53
|
+
# If we generated a key, stuff it in the response.
|
|
54
|
+
response = FFI_Yajl::Parser.parse(result[2], :create_additions => false)
|
|
55
|
+
response['private_key'] = private_key if private_key
|
|
56
|
+
response['public_key'] = public_key unless request.rest_path[0] == 'users'
|
|
57
|
+
json_response(201, response)
|
|
58
|
+
else
|
|
59
|
+
result
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
require 'ffi_yajl'
|
|
2
|
-
require 'chef_zero/rest_base'
|
|
3
|
-
|
|
4
|
-
module ChefZero
|
|
5
|
-
module Endpoints
|
|
6
|
-
# /authenticate_user
|
|
7
|
-
class AuthenticateUserEndpoint < RestBase
|
|
8
|
-
def post(request)
|
|
9
|
-
request_json = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
|
|
10
|
-
name = request_json['username']
|
|
11
|
-
password = request_json['password']
|
|
12
|
-
begin
|
|
13
|
-
user = data_store.get(['users', name])
|
|
14
|
-
rescue ChefZero::DataStore::DataNotFoundError
|
|
15
|
-
raise RestErrorResponse.new(401, "Bad username or password")
|
|
16
|
-
end
|
|
17
|
-
user = FFI_Yajl::Parser.parse(user, :create_additions => false)
|
|
18
|
-
user = ChefData::DataNormalizer.normalize_user(user, name, [ 'username' ], server.options[:osc_compat])
|
|
19
|
-
if user['password'] != password
|
|
20
|
-
raise RestErrorResponse.new(401, "Bad username or password")
|
|
21
|
-
end
|
|
22
|
-
# Include only particular user data in the response
|
|
23
|
-
user.keep_if { |key,value| %w(first_name last_name display_name email username).include?(key) }
|
|
24
|
-
json_response(200, {
|
|
25
|
-
'status' => 'linked',
|
|
26
|
-
'user' => user
|
|
27
|
-
})
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
1
|
+
require 'ffi_yajl'
|
|
2
|
+
require 'chef_zero/rest_base'
|
|
3
|
+
|
|
4
|
+
module ChefZero
|
|
5
|
+
module Endpoints
|
|
6
|
+
# /authenticate_user
|
|
7
|
+
class AuthenticateUserEndpoint < RestBase
|
|
8
|
+
def post(request)
|
|
9
|
+
request_json = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
|
|
10
|
+
name = request_json['username']
|
|
11
|
+
password = request_json['password']
|
|
12
|
+
begin
|
|
13
|
+
user = data_store.get(['users', name])
|
|
14
|
+
rescue ChefZero::DataStore::DataNotFoundError
|
|
15
|
+
raise RestErrorResponse.new(401, "Bad username or password")
|
|
16
|
+
end
|
|
17
|
+
user = FFI_Yajl::Parser.parse(user, :create_additions => false)
|
|
18
|
+
user = ChefData::DataNormalizer.normalize_user(user, name, [ 'username' ], server.options[:osc_compat])
|
|
19
|
+
if user['password'] != password
|
|
20
|
+
raise RestErrorResponse.new(401, "Bad username or password")
|
|
21
|
+
end
|
|
22
|
+
# Include only particular user data in the response
|
|
23
|
+
user.keep_if { |key,value| %w(first_name last_name display_name email username).include?(key) }
|
|
24
|
+
json_response(200, {
|
|
25
|
+
'status' => 'linked',
|
|
26
|
+
'user' => user
|
|
27
|
+
})
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -1,22 +1,22 @@
|
|
|
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
|
-
# /organizations/ORG/containers/NAME
|
|
8
|
-
class ContainerEndpoint < RestObjectEndpoint
|
|
9
|
-
def initialize(server)
|
|
10
|
-
super(server, %w(id containername))
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
undef_method(:put)
|
|
14
|
-
|
|
15
|
-
def populate_defaults(request, response_json)
|
|
16
|
-
container = FFI_Yajl::Parser.parse(response_json, :create_additions => false)
|
|
17
|
-
container = ChefData::DataNormalizer.normalize_container(container, request.rest_path[3])
|
|
18
|
-
FFI_Yajl::Encoder.encode(container, :pretty => true)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
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
|
+
# /organizations/ORG/containers/NAME
|
|
8
|
+
class ContainerEndpoint < RestObjectEndpoint
|
|
9
|
+
def initialize(server)
|
|
10
|
+
super(server, %w(id containername))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
undef_method(:put)
|
|
14
|
+
|
|
15
|
+
def populate_defaults(request, response_json)
|
|
16
|
+
container = FFI_Yajl::Parser.parse(response_json, :create_additions => false)
|
|
17
|
+
container = ChefData::DataNormalizer.normalize_container(container, request.rest_path[3])
|
|
18
|
+
FFI_Yajl::Encoder.encode(container, :pretty => true)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
require 'ffi_yajl'
|
|
2
|
-
require 'chef_zero/endpoints/rest_list_endpoint'
|
|
3
|
-
|
|
4
|
-
module ChefZero
|
|
5
|
-
module Endpoints
|
|
6
|
-
# /organizations/ORG/containers
|
|
7
|
-
class ContainersEndpoint < RestListEndpoint
|
|
8
|
-
def initialize(server)
|
|
9
|
-
super(server, %w(id containername))
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
1
|
+
require 'ffi_yajl'
|
|
2
|
+
require 'chef_zero/endpoints/rest_list_endpoint'
|
|
3
|
+
|
|
4
|
+
module ChefZero
|
|
5
|
+
module Endpoints
|
|
6
|
+
# /organizations/ORG/containers
|
|
7
|
+
class ContainersEndpoint < RestListEndpoint
|
|
8
|
+
def initialize(server)
|
|
9
|
+
super(server, %w(id containername))
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
require 'chef_zero/endpoints/cookbooks_base'
|
|
2
|
-
|
|
3
|
-
module ChefZero
|
|
4
|
-
module Endpoints
|
|
5
|
-
# /cookbooks/NAME
|
|
6
|
-
class CookbookEndpoint < CookbooksBase
|
|
7
|
-
def get(request)
|
|
8
|
-
filter = request.rest_path[3]
|
|
9
|
-
case filter
|
|
10
|
-
when '_latest'
|
|
11
|
-
result = {}
|
|
12
|
-
filter_cookbooks(all_cookbooks_list(request), {}, 1) do |name, versions|
|
|
13
|
-
if versions.size > 0
|
|
14
|
-
result[name] = build_uri(request.base_uri, request.rest_path[0..1] + ['cookbooks', name, versions[0]])
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
json_response(200, result)
|
|
18
|
-
when '_recipes'
|
|
19
|
-
result = []
|
|
20
|
-
filter_cookbooks(all_cookbooks_list(request), {}, 1) do |name, versions|
|
|
21
|
-
if versions.size > 0
|
|
22
|
-
cookbook = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', name, versions[0]]), :create_additions => false)
|
|
23
|
-
result += recipe_names(name, cookbook)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
json_response(200, result.sort)
|
|
27
|
-
else
|
|
28
|
-
cookbook_list = { filter => list_data(request, request.rest_path) }
|
|
29
|
-
json_response(200, format_cookbooks_list(request, cookbook_list))
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def latest_version(versions)
|
|
34
|
-
sorted = versions.sort_by { |version| Gem::Version.new(version.dup) }
|
|
35
|
-
sorted[-1]
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
1
|
+
require 'chef_zero/endpoints/cookbooks_base'
|
|
2
|
+
|
|
3
|
+
module ChefZero
|
|
4
|
+
module Endpoints
|
|
5
|
+
# /cookbooks/NAME
|
|
6
|
+
class CookbookEndpoint < CookbooksBase
|
|
7
|
+
def get(request)
|
|
8
|
+
filter = request.rest_path[3]
|
|
9
|
+
case filter
|
|
10
|
+
when '_latest'
|
|
11
|
+
result = {}
|
|
12
|
+
filter_cookbooks(all_cookbooks_list(request), {}, 1) do |name, versions|
|
|
13
|
+
if versions.size > 0
|
|
14
|
+
result[name] = build_uri(request.base_uri, request.rest_path[0..1] + ['cookbooks', name, versions[0]])
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
json_response(200, result)
|
|
18
|
+
when '_recipes'
|
|
19
|
+
result = []
|
|
20
|
+
filter_cookbooks(all_cookbooks_list(request), {}, 1) do |name, versions|
|
|
21
|
+
if versions.size > 0
|
|
22
|
+
cookbook = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', name, versions[0]]), :create_additions => false)
|
|
23
|
+
result += recipe_names(name, cookbook)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
json_response(200, result.sort)
|
|
27
|
+
else
|
|
28
|
+
cookbook_list = { filter => list_data(request, request.rest_path) }
|
|
29
|
+
json_response(200, format_cookbooks_list(request, cookbook_list))
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def latest_version(versions)
|
|
34
|
+
sorted = versions.sort_by { |version| Gem::Version.new(version.dup) }
|
|
35
|
+
sorted[-1]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -1,119 +1,119 @@
|
|
|
1
|
-
require 'ffi_yajl'
|
|
2
|
-
require 'chef_zero/endpoints/rest_object_endpoint'
|
|
3
|
-
require 'chef_zero/rest_error_response'
|
|
4
|
-
require 'chef_zero/chef_data/data_normalizer'
|
|
5
|
-
require 'chef_zero/data_store/data_not_found_error'
|
|
6
|
-
|
|
7
|
-
module ChefZero
|
|
8
|
-
module Endpoints
|
|
9
|
-
# /organizations/ORG/cookbooks/NAME/VERSION
|
|
10
|
-
class CookbookVersionEndpoint < RestObjectEndpoint
|
|
11
|
-
def get(request)
|
|
12
|
-
if request.rest_path[4] == "_latest" || request.rest_path[4] == "latest"
|
|
13
|
-
request.rest_path[4] = latest_version(list_data(request, request.rest_path[0..3]))
|
|
14
|
-
end
|
|
15
|
-
super(request)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def put(request)
|
|
19
|
-
name = request.rest_path[3]
|
|
20
|
-
version = request.rest_path[4]
|
|
21
|
-
existing_cookbook = get_data(request, request.rest_path, :nil)
|
|
22
|
-
|
|
23
|
-
# Honor frozen
|
|
24
|
-
if existing_cookbook
|
|
25
|
-
existing_cookbook_json = FFI_Yajl::Parser.parse(existing_cookbook, :create_additions => false)
|
|
26
|
-
if existing_cookbook_json['frozen?']
|
|
27
|
-
if request.query_params['force'] != "true"
|
|
28
|
-
raise RestErrorResponse.new(409, "The cookbook #{name} at version #{version} is frozen. Use the 'force' option to override.")
|
|
29
|
-
end
|
|
30
|
-
# For some reason, you are forever unable to modify "frozen?" on a frozen cookbook.
|
|
31
|
-
request_body = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
|
|
32
|
-
if !request_body['frozen?']
|
|
33
|
-
request_body['frozen?'] = true
|
|
34
|
-
request.body = FFI_Yajl::Encoder.encode(request_body, :pretty => true)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# Set the cookbook
|
|
40
|
-
set_data(request, request.rest_path, request.body, :create_dir, :create)
|
|
41
|
-
|
|
42
|
-
# If the cookbook was updated, check for deleted files and clean them up
|
|
43
|
-
if existing_cookbook
|
|
44
|
-
missing_checksums = get_checksums(existing_cookbook) - get_checksums(request.body)
|
|
45
|
-
if missing_checksums.size > 0
|
|
46
|
-
hoover_unused_checksums(missing_checksums, request)
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
already_json_response(existing_cookbook ? 200 : 201, populate_defaults(request, request.body))
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def delete(request)
|
|
54
|
-
if request.rest_path[4] == "_latest" || request.rest_path[4] == "latest"
|
|
55
|
-
request.rest_path[4] = latest_version(list_data(request, request.rest_path[0..3]))
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
deleted_cookbook = get_data(request)
|
|
59
|
-
|
|
60
|
-
response = super(request)
|
|
61
|
-
cookbook_name = request.rest_path[3]
|
|
62
|
-
cookbook_path = request.rest_path[0..1] + ['cookbooks', cookbook_name]
|
|
63
|
-
if exists_data_dir?(request, cookbook_path) && list_data(request, cookbook_path).size == 0
|
|
64
|
-
delete_data_dir(request, cookbook_path)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Hoover deleted files, if they exist
|
|
68
|
-
hoover_unused_checksums(get_checksums(deleted_cookbook), request)
|
|
69
|
-
response
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def get_checksums(cookbook)
|
|
73
|
-
result = []
|
|
74
|
-
FFI_Yajl::Parser.parse(cookbook, :create_additions => false).each_pair do |key, value|
|
|
75
|
-
if value.is_a?(Array)
|
|
76
|
-
value.each do |file|
|
|
77
|
-
if file.is_a?(Hash) && file.has_key?('checksum')
|
|
78
|
-
result << file['checksum']
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
result.uniq
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
private
|
|
87
|
-
|
|
88
|
-
def hoover_unused_checksums(deleted_checksums, request)
|
|
89
|
-
data_store.list(request.rest_path[0..1] + ['cookbooks']).each do |cookbook_name|
|
|
90
|
-
data_store.list(request.rest_path[0..1] + ['cookbooks', cookbook_name]).each do |version|
|
|
91
|
-
cookbook = data_store.get(request.rest_path[0..1] + ['cookbooks', cookbook_name, version], request)
|
|
92
|
-
deleted_checksums = deleted_checksums - get_checksums(cookbook)
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
deleted_checksums.each do |checksum|
|
|
96
|
-
# There can be a race here if multiple cookbooks are uploading.
|
|
97
|
-
# This deals with an exception on delete, but things can still get deleted
|
|
98
|
-
# that shouldn't be.
|
|
99
|
-
begin
|
|
100
|
-
delete_data(request, request.rest_path[0..1] + ['file_store', 'checksums', checksum], :data_store_exceptions)
|
|
101
|
-
rescue ChefZero::DataStore::DataNotFoundError
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def populate_defaults(request, response_json)
|
|
107
|
-
# Inject URIs into each cookbook file
|
|
108
|
-
cookbook = FFI_Yajl::Parser.parse(response_json, :create_additions => false)
|
|
109
|
-
cookbook = ChefData::DataNormalizer.normalize_cookbook(self, request.rest_path[0..1], cookbook, request.rest_path[3], request.rest_path[4], request.base_uri, request.method)
|
|
110
|
-
FFI_Yajl::Encoder.encode(cookbook, :pretty => true)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def latest_version(versions)
|
|
114
|
-
sorted = versions.sort_by { |version| Gem::Version.new(version.dup) }
|
|
115
|
-
sorted[-1]
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
end
|
|
1
|
+
require 'ffi_yajl'
|
|
2
|
+
require 'chef_zero/endpoints/rest_object_endpoint'
|
|
3
|
+
require 'chef_zero/rest_error_response'
|
|
4
|
+
require 'chef_zero/chef_data/data_normalizer'
|
|
5
|
+
require 'chef_zero/data_store/data_not_found_error'
|
|
6
|
+
|
|
7
|
+
module ChefZero
|
|
8
|
+
module Endpoints
|
|
9
|
+
# /organizations/ORG/cookbooks/NAME/VERSION
|
|
10
|
+
class CookbookVersionEndpoint < RestObjectEndpoint
|
|
11
|
+
def get(request)
|
|
12
|
+
if request.rest_path[4] == "_latest" || request.rest_path[4] == "latest"
|
|
13
|
+
request.rest_path[4] = latest_version(list_data(request, request.rest_path[0..3]))
|
|
14
|
+
end
|
|
15
|
+
super(request)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def put(request)
|
|
19
|
+
name = request.rest_path[3]
|
|
20
|
+
version = request.rest_path[4]
|
|
21
|
+
existing_cookbook = get_data(request, request.rest_path, :nil)
|
|
22
|
+
|
|
23
|
+
# Honor frozen
|
|
24
|
+
if existing_cookbook
|
|
25
|
+
existing_cookbook_json = FFI_Yajl::Parser.parse(existing_cookbook, :create_additions => false)
|
|
26
|
+
if existing_cookbook_json['frozen?']
|
|
27
|
+
if request.query_params['force'] != "true"
|
|
28
|
+
raise RestErrorResponse.new(409, "The cookbook #{name} at version #{version} is frozen. Use the 'force' option to override.")
|
|
29
|
+
end
|
|
30
|
+
# For some reason, you are forever unable to modify "frozen?" on a frozen cookbook.
|
|
31
|
+
request_body = FFI_Yajl::Parser.parse(request.body, :create_additions => false)
|
|
32
|
+
if !request_body['frozen?']
|
|
33
|
+
request_body['frozen?'] = true
|
|
34
|
+
request.body = FFI_Yajl::Encoder.encode(request_body, :pretty => true)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Set the cookbook
|
|
40
|
+
set_data(request, request.rest_path, request.body, :create_dir, :create)
|
|
41
|
+
|
|
42
|
+
# If the cookbook was updated, check for deleted files and clean them up
|
|
43
|
+
if existing_cookbook
|
|
44
|
+
missing_checksums = get_checksums(existing_cookbook) - get_checksums(request.body)
|
|
45
|
+
if missing_checksums.size > 0
|
|
46
|
+
hoover_unused_checksums(missing_checksums, request)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
already_json_response(existing_cookbook ? 200 : 201, populate_defaults(request, request.body))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def delete(request)
|
|
54
|
+
if request.rest_path[4] == "_latest" || request.rest_path[4] == "latest"
|
|
55
|
+
request.rest_path[4] = latest_version(list_data(request, request.rest_path[0..3]))
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
deleted_cookbook = get_data(request)
|
|
59
|
+
|
|
60
|
+
response = super(request)
|
|
61
|
+
cookbook_name = request.rest_path[3]
|
|
62
|
+
cookbook_path = request.rest_path[0..1] + ['cookbooks', cookbook_name]
|
|
63
|
+
if exists_data_dir?(request, cookbook_path) && list_data(request, cookbook_path).size == 0
|
|
64
|
+
delete_data_dir(request, cookbook_path)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Hoover deleted files, if they exist
|
|
68
|
+
hoover_unused_checksums(get_checksums(deleted_cookbook), request)
|
|
69
|
+
response
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def get_checksums(cookbook)
|
|
73
|
+
result = []
|
|
74
|
+
FFI_Yajl::Parser.parse(cookbook, :create_additions => false).each_pair do |key, value|
|
|
75
|
+
if value.is_a?(Array)
|
|
76
|
+
value.each do |file|
|
|
77
|
+
if file.is_a?(Hash) && file.has_key?('checksum')
|
|
78
|
+
result << file['checksum']
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
result.uniq
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def hoover_unused_checksums(deleted_checksums, request)
|
|
89
|
+
data_store.list(request.rest_path[0..1] + ['cookbooks']).each do |cookbook_name|
|
|
90
|
+
data_store.list(request.rest_path[0..1] + ['cookbooks', cookbook_name]).each do |version|
|
|
91
|
+
cookbook = data_store.get(request.rest_path[0..1] + ['cookbooks', cookbook_name, version], request)
|
|
92
|
+
deleted_checksums = deleted_checksums - get_checksums(cookbook)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
deleted_checksums.each do |checksum|
|
|
96
|
+
# There can be a race here if multiple cookbooks are uploading.
|
|
97
|
+
# This deals with an exception on delete, but things can still get deleted
|
|
98
|
+
# that shouldn't be.
|
|
99
|
+
begin
|
|
100
|
+
delete_data(request, request.rest_path[0..1] + ['file_store', 'checksums', checksum], :data_store_exceptions)
|
|
101
|
+
rescue ChefZero::DataStore::DataNotFoundError
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def populate_defaults(request, response_json)
|
|
107
|
+
# Inject URIs into each cookbook file
|
|
108
|
+
cookbook = FFI_Yajl::Parser.parse(response_json, :create_additions => false)
|
|
109
|
+
cookbook = ChefData::DataNormalizer.normalize_cookbook(self, request.rest_path[0..1], cookbook, request.rest_path[3], request.rest_path[4], request.base_uri, request.method)
|
|
110
|
+
FFI_Yajl::Encoder.encode(cookbook, :pretty => true)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def latest_version(versions)
|
|
114
|
+
sorted = versions.sort_by { |version| Gem::Version.new(version.dup) }
|
|
115
|
+
sorted[-1]
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|