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.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +36 -31
  3. data/LICENSE +201 -201
  4. data/Rakefile +73 -68
  5. data/bin/chef-zero +111 -111
  6. data/chef-zero.gemspec +34 -33
  7. data/lib/chef_zero/chef_data/acl_path.rb +140 -140
  8. data/lib/chef_zero/chef_data/cookbook_data.rb +237 -237
  9. data/lib/chef_zero/chef_data/data_normalizer.rb +276 -276
  10. data/lib/chef_zero/chef_data/default_creator.rb +476 -476
  11. data/lib/chef_zero/data_store/data_already_exists_error.rb +29 -29
  12. data/lib/chef_zero/data_store/data_error.rb +32 -32
  13. data/lib/chef_zero/data_store/data_not_found_error.rb +29 -29
  14. data/lib/chef_zero/data_store/default_facade.rb +143 -147
  15. data/lib/chef_zero/data_store/interface_v1.rb +67 -67
  16. data/lib/chef_zero/data_store/interface_v2.rb +18 -18
  17. data/lib/chef_zero/data_store/memory_store.rb +33 -33
  18. data/lib/chef_zero/data_store/memory_store_v2.rb +159 -159
  19. data/lib/chef_zero/data_store/raw_file_store.rb +143 -143
  20. data/lib/chef_zero/data_store/v1_to_v2_adapter.rb +150 -150
  21. data/lib/chef_zero/data_store/v2_to_v1_adapter.rb +105 -105
  22. data/lib/chef_zero/dist.rb +9 -9
  23. data/lib/chef_zero/endpoints/acl_endpoint.rb +39 -39
  24. data/lib/chef_zero/endpoints/acls_endpoint.rb +41 -41
  25. data/lib/chef_zero/endpoints/actor_default_key_endpoint.rb +78 -78
  26. data/lib/chef_zero/endpoints/actor_endpoint.rb +184 -184
  27. data/lib/chef_zero/endpoints/actor_key_endpoint.rb +62 -62
  28. data/lib/chef_zero/endpoints/actor_keys_endpoint.rb +129 -129
  29. data/lib/chef_zero/endpoints/actors_endpoint.rb +104 -104
  30. data/lib/chef_zero/endpoints/authenticate_user_endpoint.rb +32 -32
  31. data/lib/chef_zero/endpoints/container_endpoint.rb +22 -22
  32. data/lib/chef_zero/endpoints/containers_endpoint.rb +25 -25
  33. data/lib/chef_zero/endpoints/controls_endpoint.rb +16 -16
  34. data/lib/chef_zero/endpoints/cookbook_artifact_endpoint.rb +24 -24
  35. data/lib/chef_zero/endpoints/cookbook_artifact_identifier_endpoint.rb +68 -68
  36. data/lib/chef_zero/endpoints/cookbook_artifacts_endpoint.rb +34 -34
  37. data/lib/chef_zero/endpoints/cookbook_endpoint.rb +39 -39
  38. data/lib/chef_zero/endpoints/cookbook_version_endpoint.rb +136 -136
  39. data/lib/chef_zero/endpoints/cookbooks_base.rb +80 -80
  40. data/lib/chef_zero/endpoints/cookbooks_endpoint.rb +19 -19
  41. data/lib/chef_zero/endpoints/data_bag_endpoint.rb +45 -45
  42. data/lib/chef_zero/endpoints/data_bag_item_endpoint.rb +25 -25
  43. data/lib/chef_zero/endpoints/data_bags_endpoint.rb +23 -23
  44. data/lib/chef_zero/endpoints/dummy_endpoint.rb +29 -29
  45. data/lib/chef_zero/endpoints/environment_cookbook_endpoint.rb +24 -24
  46. data/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb +126 -126
  47. data/lib/chef_zero/endpoints/environment_cookbooks_endpoint.rb +22 -22
  48. data/lib/chef_zero/endpoints/environment_endpoint.rb +33 -33
  49. data/lib/chef_zero/endpoints/environment_nodes_endpoint.rb +23 -23
  50. data/lib/chef_zero/endpoints/environment_recipes_endpoint.rb +22 -22
  51. data/lib/chef_zero/endpoints/environment_role_endpoint.rb +36 -36
  52. data/lib/chef_zero/endpoints/file_store_file_endpoint.rb +22 -22
  53. data/lib/chef_zero/endpoints/group_endpoint.rb +20 -20
  54. data/lib/chef_zero/endpoints/groups_endpoint.rb +13 -13
  55. data/lib/chef_zero/endpoints/license_endpoint.rb +25 -25
  56. data/lib/chef_zero/endpoints/node_endpoint.rb +34 -34
  57. data/lib/chef_zero/endpoints/node_identifiers_endpoint.rb +22 -22
  58. data/lib/chef_zero/endpoints/nodes_endpoint.rb +34 -34
  59. data/lib/chef_zero/endpoints/not_found_endpoint.rb +11 -11
  60. data/lib/chef_zero/endpoints/organization_association_request_endpoint.rb +22 -22
  61. data/lib/chef_zero/endpoints/organization_association_requests_endpoint.rb +30 -30
  62. data/lib/chef_zero/endpoints/organization_authenticate_user_endpoint.rb +26 -26
  63. data/lib/chef_zero/endpoints/organization_endpoint.rb +47 -47
  64. data/lib/chef_zero/endpoints/organization_user_base.rb +15 -15
  65. data/lib/chef_zero/endpoints/organization_user_default_key_endpoint.rb +16 -16
  66. data/lib/chef_zero/endpoints/organization_user_endpoint.rb +26 -26
  67. data/lib/chef_zero/endpoints/organization_user_key_endpoint.rb +17 -17
  68. data/lib/chef_zero/endpoints/organization_user_keys_endpoint.rb +17 -17
  69. data/lib/chef_zero/endpoints/organization_users_endpoint.rb +43 -43
  70. data/lib/chef_zero/endpoints/organization_validator_key_endpoint.rb +20 -20
  71. data/lib/chef_zero/endpoints/organizations_endpoint.rb +61 -61
  72. data/lib/chef_zero/endpoints/policies_endpoint.rb +26 -26
  73. data/lib/chef_zero/endpoints/policy_endpoint.rb +24 -24
  74. data/lib/chef_zero/endpoints/policy_group_endpoint.rb +46 -46
  75. data/lib/chef_zero/endpoints/policy_group_policy_endpoint.rb +83 -83
  76. data/lib/chef_zero/endpoints/policy_groups_endpoint.rb +38 -38
  77. data/lib/chef_zero/endpoints/policy_revision_endpoint.rb +66 -66
  78. data/lib/chef_zero/endpoints/policy_revisions_endpoint.rb +15 -15
  79. data/lib/chef_zero/endpoints/principal_endpoint.rb +55 -55
  80. data/lib/chef_zero/endpoints/rest_list_endpoint.rb +42 -42
  81. data/lib/chef_zero/endpoints/rest_object_endpoint.rb +78 -78
  82. data/lib/chef_zero/endpoints/role_endpoint.rb +16 -16
  83. data/lib/chef_zero/endpoints/role_environments_endpoint.rb +14 -14
  84. data/lib/chef_zero/endpoints/sandbox_endpoint.rb +27 -27
  85. data/lib/chef_zero/endpoints/sandboxes_endpoint.rb +51 -51
  86. data/lib/chef_zero/endpoints/search_endpoint.rb +208 -208
  87. data/lib/chef_zero/endpoints/searches_endpoint.rb +18 -18
  88. data/lib/chef_zero/endpoints/server_api_version_endpoint.rb +14 -14
  89. data/lib/chef_zero/endpoints/system_recovery_endpoint.rb +30 -30
  90. data/lib/chef_zero/endpoints/universe_endpoint.rb +15 -15
  91. data/lib/chef_zero/endpoints/user_association_request_endpoint.rb +41 -41
  92. data/lib/chef_zero/endpoints/user_association_requests_count_endpoint.rb +19 -19
  93. data/lib/chef_zero/endpoints/user_association_requests_endpoint.rb +19 -19
  94. data/lib/chef_zero/endpoints/user_organizations_endpoint.rb +22 -22
  95. data/lib/chef_zero/endpoints/version_endpoint.rb +13 -13
  96. data/lib/chef_zero/log.rb +7 -7
  97. data/lib/chef_zero/rest_base.rb +332 -332
  98. data/lib/chef_zero/rest_error_response.rb +11 -11
  99. data/lib/chef_zero/rest_request.rb +84 -88
  100. data/lib/chef_zero/rest_router.rb +72 -72
  101. data/lib/chef_zero/rspec.rb +355 -355
  102. data/lib/chef_zero/server.rb +730 -730
  103. data/lib/chef_zero/socketless_server_map.rb +92 -93
  104. data/lib/chef_zero/solr/query/binary_operator.rb +52 -52
  105. data/lib/chef_zero/solr/query/phrase.rb +23 -23
  106. data/lib/chef_zero/solr/query/range_query.rb +46 -46
  107. data/lib/chef_zero/solr/query/regexpable_query.rb +30 -30
  108. data/lib/chef_zero/solr/query/subquery.rb +37 -37
  109. data/lib/chef_zero/solr/query/term.rb +45 -45
  110. data/lib/chef_zero/solr/query/unary_operator.rb +41 -41
  111. data/lib/chef_zero/solr/solr_doc.rb +53 -53
  112. data/lib/chef_zero/solr/solr_parser.rb +208 -208
  113. data/lib/chef_zero/version.rb +3 -3
  114. data/lib/chef_zero.rb +10 -10
  115. data/spec/run_oc_pedant.rb +226 -226
  116. data/spec/search_spec.rb +36 -36
  117. data/spec/server_spec.rb +96 -96
  118. data/spec/socketless_server_map_spec.rb +74 -74
  119. data/spec/support/oc_pedant.rb +149 -149
  120. data/spec/support/secrets.json +6 -6
  121. data/spec/support/stickywicket.pem +27 -27
  122. metadata +35 -18
@@ -1,29 +1,29 @@
1
-
2
- # pedant makes a couple of Solr-related calls from its search_utils.rb file that we can't work around (e.g.
3
- # with monkeypatching). the necessary Pedant::Config values are set in run_oc_pedant.rb. --cdoherty
4
- module ChefZero
5
- module Endpoints
6
- class DummyEndpoint < RestBase
7
- # called by #direct_solr_query, once each for roles, nodes, and data bag items. each RSpec example makes
8
- # 3 calls, with the expected sequence of return values [0, 1, 0].
9
- def get(request)
10
- # this could be made less brittle, but if things change to have more than 3 cycles, we should really
11
- # be notified by a spec failure.
12
- @mock_values ||= ([0, 1, 0] * 3).map { |val| make_response(val) }
13
-
14
- retval = @mock_values.shift
15
- json_response(200, retval)
16
- end
17
-
18
- # called by #force_solr_commit in pedant's , which doesn't check the return value.
19
- def post(request)
20
- # sure thing!
21
- json_response(200, { message: "This dummy POST endpoint didn't do anything." })
22
- end
23
-
24
- def make_response(value)
25
- { "response" => { "numFound" => value } }
26
- end
27
- end
28
- end
29
- end
1
+
2
+ # pedant makes a couple of Solr-related calls from its search_utils.rb file that we can't work around (e.g.
3
+ # with monkeypatching). the necessary Pedant::Config values are set in run_oc_pedant.rb. --cdoherty
4
+ module ChefZero
5
+ module Endpoints
6
+ class DummyEndpoint < RestBase
7
+ # called by #direct_solr_query, once each for roles, nodes, and data bag items. each RSpec example makes
8
+ # 3 calls, with the expected sequence of return values [0, 1, 0].
9
+ def get(request)
10
+ # this could be made less brittle, but if things change to have more than 3 cycles, we should really
11
+ # be notified by a spec failure.
12
+ @mock_values ||= ([0, 1, 0] * 3).map { |val| make_response(val) }
13
+
14
+ retval = @mock_values.shift
15
+ json_response(200, retval)
16
+ end
17
+
18
+ # called by #force_solr_commit in pedant's , which doesn't check the return value.
19
+ def post(request)
20
+ # sure thing!
21
+ json_response(200, { message: "This dummy POST endpoint didn't do anything." })
22
+ end
23
+
24
+ def make_response(value)
25
+ { "response" => { "numFound" => value } }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,24 +1,24 @@
1
- require "ffi_yajl" unless defined?(FFI_Yajl)
2
- require_relative "cookbooks_base"
3
-
4
- module ChefZero
5
- module Endpoints
6
- # /environments/NAME/cookbooks/NAME
7
- class EnvironmentCookbookEndpoint < CookbooksBase
8
- def get(request)
9
- cookbook_name = request.rest_path[5]
10
- environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]))
11
- constraints = environment["cookbook_versions"] || {}
12
- cookbook_versions = list_data(request, request.rest_path[0..1] + request.rest_path[4..5])
13
- if request.query_params["num_versions"] == "all"
14
- num_versions = nil
15
- elsif request.query_params["num_versions"]
16
- num_versions = request.query_params["num_versions"].to_i
17
- else
18
- num_versions = nil
19
- end
20
- json_response(200, format_cookbooks_list(request, { cookbook_name => cookbook_versions }, constraints, num_versions))
21
- end
22
- end
23
- end
24
- end
1
+ require "ffi_yajl" unless defined?(FFI_Yajl)
2
+ require_relative "cookbooks_base"
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /environments/NAME/cookbooks/NAME
7
+ class EnvironmentCookbookEndpoint < CookbooksBase
8
+ def get(request)
9
+ cookbook_name = request.rest_path[5]
10
+ environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]))
11
+ constraints = environment["cookbook_versions"] || {}
12
+ cookbook_versions = list_data(request, request.rest_path[0..1] + request.rest_path[4..5])
13
+ if request.query_params["num_versions"] == "all"
14
+ num_versions = nil
15
+ elsif request.query_params["num_versions"]
16
+ num_versions = request.query_params["num_versions"].to_i
17
+ else
18
+ num_versions = nil
19
+ end
20
+ json_response(200, format_cookbooks_list(request, { cookbook_name => cookbook_versions }, constraints, num_versions))
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,126 +1,126 @@
1
- require "ffi_yajl" unless defined?(FFI_Yajl)
2
- require_relative "../rest_base"
3
- require_relative "../rest_error_response"
4
-
5
- module ChefZero
6
- module Endpoints
7
- # /environments/NAME/cookbook_versions
8
- class EnvironmentCookbookVersionsEndpoint < RestBase
9
-
10
- def post(request)
11
- cookbook_names = list_data(request, request.rest_path[0..1] + ["cookbooks"])
12
-
13
- # Get the list of cookbooks and versions desired by the runlist
14
- desired_versions = {}
15
- run_list = FFI_Yajl::Parser.parse(request.body)["run_list"]
16
- run_list.each do |run_list_entry|
17
- if run_list_entry =~ /(.+)::.+\@(.+)/ || run_list_entry =~ /(.+)\@(.+)/
18
- raise RestErrorResponse.new(412, "No such cookbook: #{$1}") unless cookbook_names.include?($1)
19
- raise RestErrorResponse.new(412, "No such cookbook version for cookbook #{$1}: #{$2}") unless list_data(request, request.rest_path[0..1] + ["cookbooks", $1]).include?($2)
20
-
21
- desired_versions[$1] = [ $2 ]
22
- else
23
- desired_cookbook = run_list_entry.split("::")[0]
24
- raise RestErrorResponse.new(412, "No such cookbook: #{desired_cookbook}") unless cookbook_names.include?(desired_cookbook)
25
-
26
- desired_versions[desired_cookbook] = list_data(request, request.rest_path[0..1] + ["cookbooks", desired_cookbook])
27
- end
28
- end
29
-
30
- # Filter by environment constraints
31
- environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]))
32
- environment_constraints = environment["cookbook_versions"] || {}
33
-
34
- desired_versions.each_key do |name|
35
- desired_versions = filter_by_constraint(desired_versions, name, environment_constraints[name])
36
- end
37
-
38
- # Depsolve!
39
- solved = depsolve(request, desired_versions.keys, desired_versions, environment_constraints)
40
- unless solved
41
- if @last_missing_dep && !cookbook_names.include?(@last_missing_dep)
42
- return raise RestErrorResponse.new(412, "No such cookbook: #{@last_missing_dep}")
43
- elsif @last_constraint_failure
44
- return raise RestErrorResponse.new(412, "Could not satisfy version constraints for: #{@last_constraint_failure}")
45
- else
46
-
47
- return raise RestErrorResponse.new(412, "Unsolvable versions!")
48
- end
49
- end
50
-
51
- result = {}
52
- solved.each_pair do |name, versions|
53
- cookbook = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["cookbooks", name, versions[0]]))
54
- result[name] = ChefData::DataNormalizer.normalize_cookbook(self, request.rest_path[0..1], cookbook, name, versions[0], request.base_uri, "MIN", false, api_version: request.api_version)
55
- end
56
- json_response(200, result)
57
- end
58
-
59
- def depsolve(request, unsolved, desired_versions, environment_constraints)
60
- desired_versions.each do |cb, ver|
61
- if ver.empty?
62
- @last_constraint_failure = cb
63
- return nil
64
- end
65
- end
66
-
67
- # If everything is already
68
- solve_for = unsolved[0]
69
- return desired_versions unless solve_for
70
-
71
- # Go through each desired version of this cookbook, starting with the latest,
72
- # until we find one we can solve successfully with
73
- sort_versions(desired_versions[solve_for]).each do |desired_version|
74
- new_desired_versions = desired_versions.clone
75
- new_desired_versions[solve_for] = [ desired_version ]
76
- new_unsolved = unsolved[1..-1]
77
-
78
- # Pick this cookbook, and add dependencies
79
- cookbook_obj = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["cookbooks", solve_for, desired_version]))
80
- cookbook_metadata = cookbook_obj["metadata"] || {}
81
- cookbook_dependencies = cookbook_metadata["dependencies"] || {}
82
- dep_not_found = false
83
- cookbook_dependencies.each_pair do |dep_name, dep_constraint|
84
- # If the dep is not already in the list, add it to the list to solve
85
- # and bring in all environment-allowed cookbook versions to desired_versions
86
- unless new_desired_versions.key?(dep_name)
87
- new_unsolved += [dep_name]
88
- # If the dep is missing, we will try other versions of the cookbook that might not have the bad dep.
89
- unless exists_data_dir?(request, request.rest_path[0..1] + ["cookbooks", dep_name])
90
- @last_missing_dep = dep_name.to_s
91
- dep_not_found = true
92
- break
93
- end
94
- new_desired_versions[dep_name] = list_data(request, request.rest_path[0..1] + ["cookbooks", dep_name])
95
- new_desired_versions = filter_by_constraint(new_desired_versions, dep_name, environment_constraints[dep_name])
96
- end
97
- new_desired_versions = filter_by_constraint(new_desired_versions, dep_name, dep_constraint)
98
- end
99
-
100
- next if dep_not_found
101
-
102
- # Depsolve children with this desired version! First solution wins.
103
- result = depsolve(request, new_unsolved, new_desired_versions, environment_constraints)
104
- return result if result
105
- end
106
- nil
107
- end
108
-
109
- def sort_versions(versions)
110
- result = versions.sort_by { |version| Gem::Version.new(version.dup) }
111
- result.reverse
112
- end
113
-
114
- def filter_by_constraint(versions, cookbook_name, constraint)
115
- return versions unless constraint
116
-
117
- constraint = Gem::Requirement.new(constraint)
118
- new_versions = versions[cookbook_name]
119
- new_versions = new_versions.select { |version| constraint.satisfied_by?(Gem::Version.new(version.dup)) }
120
- result = versions.clone
121
- result[cookbook_name] = new_versions
122
- result
123
- end
124
- end
125
- end
126
- end
1
+ require "ffi_yajl" unless defined?(FFI_Yajl)
2
+ require_relative "../rest_base"
3
+ require_relative "../rest_error_response"
4
+
5
+ module ChefZero
6
+ module Endpoints
7
+ # /environments/NAME/cookbook_versions
8
+ class EnvironmentCookbookVersionsEndpoint < RestBase
9
+
10
+ def post(request)
11
+ cookbook_names = list_data(request, request.rest_path[0..1] + ["cookbooks"])
12
+
13
+ # Get the list of cookbooks and versions desired by the runlist
14
+ desired_versions = {}
15
+ run_list = FFI_Yajl::Parser.parse(request.body)["run_list"]
16
+ run_list.each do |run_list_entry|
17
+ if run_list_entry =~ /(.+)::.+\@(.+)/ || run_list_entry =~ /(.+)\@(.+)/
18
+ raise RestErrorResponse.new(412, "No such cookbook: #{$1}") unless cookbook_names.include?($1)
19
+ raise RestErrorResponse.new(412, "No such cookbook version for cookbook #{$1}: #{$2}") unless list_data(request, request.rest_path[0..1] + ["cookbooks", $1]).include?($2)
20
+
21
+ desired_versions[$1] = [ $2 ]
22
+ else
23
+ desired_cookbook = run_list_entry.split("::")[0]
24
+ raise RestErrorResponse.new(412, "No such cookbook: #{desired_cookbook}") unless cookbook_names.include?(desired_cookbook)
25
+
26
+ desired_versions[desired_cookbook] = list_data(request, request.rest_path[0..1] + ["cookbooks", desired_cookbook])
27
+ end
28
+ end
29
+
30
+ # Filter by environment constraints
31
+ environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]))
32
+ environment_constraints = environment["cookbook_versions"] || {}
33
+
34
+ desired_versions.each_key do |name|
35
+ desired_versions = filter_by_constraint(desired_versions, name, environment_constraints[name])
36
+ end
37
+
38
+ # Depsolve!
39
+ solved = depsolve(request, desired_versions.keys, desired_versions, environment_constraints)
40
+ unless solved
41
+ if @last_missing_dep && !cookbook_names.include?(@last_missing_dep)
42
+ return raise RestErrorResponse.new(412, "No such cookbook: #{@last_missing_dep}")
43
+ elsif @last_constraint_failure
44
+ return raise RestErrorResponse.new(412, "Could not satisfy version constraints for: #{@last_constraint_failure}")
45
+ else
46
+
47
+ return raise RestErrorResponse.new(412, "Unsolvable versions!")
48
+ end
49
+ end
50
+
51
+ result = {}
52
+ solved.each_pair do |name, versions|
53
+ cookbook = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["cookbooks", name, versions[0]]))
54
+ result[name] = ChefData::DataNormalizer.normalize_cookbook(self, request.rest_path[0..1], cookbook, name, versions[0], request.base_uri, "MIN", false, api_version: request.api_version)
55
+ end
56
+ json_response(200, result)
57
+ end
58
+
59
+ def depsolve(request, unsolved, desired_versions, environment_constraints)
60
+ desired_versions.each do |cb, ver|
61
+ if ver.empty?
62
+ @last_constraint_failure = cb
63
+ return nil
64
+ end
65
+ end
66
+
67
+ # If everything is already
68
+ solve_for = unsolved[0]
69
+ return desired_versions unless solve_for
70
+
71
+ # Go through each desired version of this cookbook, starting with the latest,
72
+ # until we find one we can solve successfully with
73
+ sort_versions(desired_versions[solve_for]).each do |desired_version|
74
+ new_desired_versions = desired_versions.clone
75
+ new_desired_versions[solve_for] = [ desired_version ]
76
+ new_unsolved = unsolved[1..-1]
77
+
78
+ # Pick this cookbook, and add dependencies
79
+ cookbook_obj = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["cookbooks", solve_for, desired_version]))
80
+ cookbook_metadata = cookbook_obj["metadata"] || {}
81
+ cookbook_dependencies = cookbook_metadata["dependencies"] || {}
82
+ dep_not_found = false
83
+ cookbook_dependencies.each_pair do |dep_name, dep_constraint|
84
+ # If the dep is not already in the list, add it to the list to solve
85
+ # and bring in all environment-allowed cookbook versions to desired_versions
86
+ unless new_desired_versions.key?(dep_name)
87
+ new_unsolved += [dep_name]
88
+ # If the dep is missing, we will try other versions of the cookbook that might not have the bad dep.
89
+ unless exists_data_dir?(request, request.rest_path[0..1] + ["cookbooks", dep_name])
90
+ @last_missing_dep = dep_name.to_s
91
+ dep_not_found = true
92
+ break
93
+ end
94
+ new_desired_versions[dep_name] = list_data(request, request.rest_path[0..1] + ["cookbooks", dep_name])
95
+ new_desired_versions = filter_by_constraint(new_desired_versions, dep_name, environment_constraints[dep_name])
96
+ end
97
+ new_desired_versions = filter_by_constraint(new_desired_versions, dep_name, dep_constraint)
98
+ end
99
+
100
+ next if dep_not_found
101
+
102
+ # Depsolve children with this desired version! First solution wins.
103
+ result = depsolve(request, new_unsolved, new_desired_versions, environment_constraints)
104
+ return result if result
105
+ end
106
+ nil
107
+ end
108
+
109
+ def sort_versions(versions)
110
+ result = versions.sort_by { |version| Gem::Version.new(version.dup) }
111
+ result.reverse
112
+ end
113
+
114
+ def filter_by_constraint(versions, cookbook_name, constraint)
115
+ return versions unless constraint
116
+
117
+ constraint = Gem::Requirement.new(constraint)
118
+ new_versions = versions[cookbook_name]
119
+ new_versions = new_versions.select { |version| constraint.satisfied_by?(Gem::Version.new(version.dup)) }
120
+ result = versions.clone
121
+ result[cookbook_name] = new_versions
122
+ result
123
+ end
124
+ end
125
+ end
126
+ end
@@ -1,22 +1,22 @@
1
- require "ffi_yajl" unless defined?(FFI_Yajl)
2
- require_relative "cookbooks_base"
3
-
4
- module ChefZero
5
- module Endpoints
6
- # /environments/NAME/cookbooks
7
- class EnvironmentCookbooksEndpoint < CookbooksBase
8
- def get(request)
9
- environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]))
10
- constraints = environment["cookbook_versions"] || {}
11
- if request.query_params["num_versions"] == "all"
12
- num_versions = nil
13
- elsif request.query_params["num_versions"]
14
- num_versions = request.query_params["num_versions"].to_i
15
- else
16
- num_versions = 1
17
- end
18
- json_response(200, format_cookbooks_list(request, all_cookbooks_list(request), constraints, num_versions))
19
- end
20
- end
21
- end
22
- end
1
+ require "ffi_yajl" unless defined?(FFI_Yajl)
2
+ require_relative "cookbooks_base"
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /environments/NAME/cookbooks
7
+ class EnvironmentCookbooksEndpoint < CookbooksBase
8
+ def get(request)
9
+ environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]))
10
+ constraints = environment["cookbook_versions"] || {}
11
+ if request.query_params["num_versions"] == "all"
12
+ num_versions = nil
13
+ elsif request.query_params["num_versions"]
14
+ num_versions = request.query_params["num_versions"].to_i
15
+ else
16
+ num_versions = 1
17
+ end
18
+ json_response(200, format_cookbooks_list(request, all_cookbooks_list(request), constraints, num_versions))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,33 +1,33 @@
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
- # /environments/NAME
8
- class EnvironmentEndpoint < RestObjectEndpoint
9
- def delete(request)
10
- if request.rest_path[3] == "_default"
11
- # 405, really?
12
- error(405, "The '_default' environment cannot be modified.")
13
- else
14
- super(request)
15
- end
16
- end
17
-
18
- def put(request)
19
- if request.rest_path[3] == "_default"
20
- error(405, "The '_default' environment cannot be modified.")
21
- else
22
- super(request)
23
- end
24
- end
25
-
26
- def populate_defaults(request, response_json)
27
- response = FFI_Yajl::Parser.parse(response_json)
28
- response = ChefData::DataNormalizer.normalize_environment(response, request.rest_path[3])
29
- FFI_Yajl::Encoder.encode(response, pretty: true)
30
- end
31
- end
32
- end
33
- 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
+ # /environments/NAME
8
+ class EnvironmentEndpoint < RestObjectEndpoint
9
+ def delete(request)
10
+ if request.rest_path[3] == "_default"
11
+ # 405, really?
12
+ error(405, "The '_default' environment cannot be modified.")
13
+ else
14
+ super(request)
15
+ end
16
+ end
17
+
18
+ def put(request)
19
+ if request.rest_path[3] == "_default"
20
+ error(405, "The '_default' environment cannot be modified.")
21
+ else
22
+ super(request)
23
+ end
24
+ end
25
+
26
+ def populate_defaults(request, response_json)
27
+ response = FFI_Yajl::Parser.parse(response_json)
28
+ response = ChefData::DataNormalizer.normalize_environment(response, request.rest_path[3])
29
+ FFI_Yajl::Encoder.encode(response, pretty: true)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,23 +1,23 @@
1
- require "ffi_yajl" unless defined?(FFI_Yajl)
2
- require_relative "../rest_base"
3
-
4
- module ChefZero
5
- module Endpoints
6
- # /environment/NAME/nodes
7
- class EnvironmentNodesEndpoint < RestBase
8
- def get(request)
9
- # 404 if environment does not exist
10
- get_data(request, request.rest_path[0..3])
11
-
12
- result = {}
13
- list_data(request, request.rest_path[0..1] + ["nodes"]).each do |name|
14
- node = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["nodes", name]))
15
- if node["chef_environment"] == request.rest_path[3]
16
- result[name] = build_uri(request.base_uri, request.rest_path[0..1] + ["nodes", name])
17
- end
18
- end
19
- json_response(200, result)
20
- end
21
- end
22
- end
23
- end
1
+ require "ffi_yajl" unless defined?(FFI_Yajl)
2
+ require_relative "../rest_base"
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /environment/NAME/nodes
7
+ class EnvironmentNodesEndpoint < RestBase
8
+ def get(request)
9
+ # 404 if environment does not exist
10
+ get_data(request, request.rest_path[0..3])
11
+
12
+ result = {}
13
+ list_data(request, request.rest_path[0..1] + ["nodes"]).each do |name|
14
+ node = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["nodes", name]))
15
+ if node["chef_environment"] == request.rest_path[3]
16
+ result[name] = build_uri(request.base_uri, request.rest_path[0..1] + ["nodes", name])
17
+ end
18
+ end
19
+ json_response(200, result)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,22 +1,22 @@
1
- require "ffi_yajl" unless defined?(FFI_Yajl)
2
- require_relative "cookbooks_base"
3
-
4
- module ChefZero
5
- module Endpoints
6
- # /environment/NAME/recipes
7
- class EnvironmentRecipesEndpoint < CookbooksBase
8
- def get(request)
9
- environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]))
10
- constraints = environment["cookbook_versions"] || {}
11
- result = []
12
- filter_cookbooks(all_cookbooks_list(request), constraints, 1) do |name, versions|
13
- if versions.size > 0
14
- cookbook = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["cookbooks", name, versions[0]]))
15
- result += recipe_names(name, cookbook)
16
- end
17
- end
18
- json_response(200, result.sort)
19
- end
20
- end
21
- end
22
- end
1
+ require "ffi_yajl" unless defined?(FFI_Yajl)
2
+ require_relative "cookbooks_base"
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /environment/NAME/recipes
7
+ class EnvironmentRecipesEndpoint < CookbooksBase
8
+ def get(request)
9
+ environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]))
10
+ constraints = environment["cookbook_versions"] || {}
11
+ result = []
12
+ filter_cookbooks(all_cookbooks_list(request), constraints, 1) do |name, versions|
13
+ if versions.size > 0
14
+ cookbook = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["cookbooks", name, versions[0]]))
15
+ result += recipe_names(name, cookbook)
16
+ end
17
+ end
18
+ json_response(200, result.sort)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,36 +1,36 @@
1
- require "ffi_yajl" unless defined?(FFI_Yajl)
2
- require_relative "cookbooks_base"
3
-
4
- module ChefZero
5
- module Endpoints
6
- # /environments/NAME/roles/NAME
7
- # /roles/NAME/environments/NAME
8
- class EnvironmentRoleEndpoint < CookbooksBase
9
- def get(request)
10
- # 404 if environment does not exist
11
- if request.rest_path[2] == "environments"
12
- environment_path = request.rest_path[0..1] + request.rest_path[2..3]
13
- role_path = request.rest_path[0..1] + request.rest_path[4..5]
14
- else
15
- environment_path = request.rest_path[0..1] + request.rest_path[4..5]
16
- role_path = request.rest_path[0..1] + request.rest_path[2..3]
17
- end
18
- # Verify that the environment exists
19
- get_data(request, environment_path)
20
-
21
- role = FFI_Yajl::Parser.parse(get_data(request, role_path))
22
- environment_name = environment_path[3]
23
- if environment_name == "_default"
24
- run_list = role["run_list"]
25
- else
26
- if role["env_run_lists"]
27
- run_list = role["env_run_lists"][environment_name]
28
- else
29
- run_list = nil
30
- end
31
- end
32
- json_response(200, { "run_list" => run_list })
33
- end
34
- end
35
- end
36
- end
1
+ require "ffi_yajl" unless defined?(FFI_Yajl)
2
+ require_relative "cookbooks_base"
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /environments/NAME/roles/NAME
7
+ # /roles/NAME/environments/NAME
8
+ class EnvironmentRoleEndpoint < CookbooksBase
9
+ def get(request)
10
+ # 404 if environment does not exist
11
+ if request.rest_path[2] == "environments"
12
+ environment_path = request.rest_path[0..1] + request.rest_path[2..3]
13
+ role_path = request.rest_path[0..1] + request.rest_path[4..5]
14
+ else
15
+ environment_path = request.rest_path[0..1] + request.rest_path[4..5]
16
+ role_path = request.rest_path[0..1] + request.rest_path[2..3]
17
+ end
18
+ # Verify that the environment exists
19
+ get_data(request, environment_path)
20
+
21
+ role = FFI_Yajl::Parser.parse(get_data(request, role_path))
22
+ environment_name = environment_path[3]
23
+ if environment_name == "_default"
24
+ run_list = role["run_list"]
25
+ else
26
+ if role["env_run_lists"]
27
+ run_list = role["env_run_lists"][environment_name]
28
+ else
29
+ run_list = nil
30
+ end
31
+ end
32
+ json_response(200, { "run_list" => run_list })
33
+ end
34
+ end
35
+ end
36
+ end