chef-server-api 0.10.0.beta.1 → 0.10.0.beta.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +16 -0
- data/app/controllers/cookbooks.rb +46 -2
- data/lib/chef-server-api/version.rb +1 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/unit/cookbooks_controller_spec.rb +70 -0
- data/spec/unit/environments_controller_spec.rb +9 -9
- data/spec/unit/nodes_controller_environments_spec.rb +5 -5
- data/spec/unit/nodes_controller_spec.rb +1 -1
- metadata +3 -2
data/Rakefile
CHANGED
@@ -18,6 +18,22 @@ Rake::GemPackageTask.new(spec) do |pkg|
|
|
18
18
|
pkg.gem_spec = spec
|
19
19
|
end
|
20
20
|
|
21
|
+
begin
|
22
|
+
require 'rspec/core/rake_task'
|
23
|
+
|
24
|
+
desc "Run all specs in spec directory"
|
25
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
26
|
+
t.pattern = FileList['spec/unit/**/*_spec.rb']
|
27
|
+
end
|
28
|
+
rescue LoadError
|
29
|
+
desc "Install rspec to run the specs"
|
30
|
+
task :spec do
|
31
|
+
abort "rspec is not available, (sudo) gem install rspec to run tests"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
task :default => :spec
|
21
37
|
desc "Install the gem"
|
22
38
|
task :install => :package do
|
23
39
|
sh %{gem install pkg/#{GEM_NAME}-#{ChefServerApi::VERSION} --no-rdoc --no-ri}
|
@@ -41,13 +41,22 @@ class Cookbooks < Application
|
|
41
41
|
include Chef::Mixin::Checksum
|
42
42
|
include Merb::TarballHelper
|
43
43
|
|
44
|
+
def index
|
45
|
+
if request.env['HTTP_X_CHEF_VERSION'] =~ /0\.9/
|
46
|
+
index_09
|
47
|
+
else
|
48
|
+
index_010
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# GET /cookbooks
|
44
53
|
# returns data in the format of:
|
45
54
|
# {"apache2" => {
|
46
55
|
# :url => "http://url",
|
47
56
|
# :versions => [{:url => "http://url/1.0.0", :version => "1.0.0"}, {:url => "http://url/0.0.1", :version=>"0.0.1"}]
|
48
57
|
# }
|
49
58
|
# }
|
50
|
-
def
|
59
|
+
def index_010
|
51
60
|
cookbook_list = Chef::CookbookVersion.cdb_list
|
52
61
|
# cookbook_list is in the format of {"apache2" => [0.0.1, 0.0.0]} where the version numbers are DepSelector::Version objects
|
53
62
|
num_versions = num_versions!
|
@@ -58,6 +67,22 @@ class Cookbooks < Application
|
|
58
67
|
})
|
59
68
|
end
|
60
69
|
|
70
|
+
# GET /cookbooks
|
71
|
+
#
|
72
|
+
# returns data in the format of:
|
73
|
+
# {
|
74
|
+
# "apache2" => "http://url/apache2",
|
75
|
+
# "python" => "http://url/python"
|
76
|
+
# }
|
77
|
+
def index_09
|
78
|
+
cookbook_list = Chef::CookbookVersion.cdb_list_latest(false).keys.sort
|
79
|
+
response = Hash.new
|
80
|
+
cookbook_list.map! do |cookbook_name|
|
81
|
+
response[cookbook_name] = absolute_url(:cookbook, :cookbook_name => cookbook_name)
|
82
|
+
end
|
83
|
+
display response
|
84
|
+
end
|
85
|
+
|
61
86
|
def index_recipes
|
62
87
|
recipes_with_versions = Chef::CookbookVersion.cdb_list(true).inject({}) do|memo, f|
|
63
88
|
memo[f.name] ||= {}
|
@@ -67,6 +92,14 @@ class Cookbooks < Application
|
|
67
92
|
display recipes_with_versions
|
68
93
|
end
|
69
94
|
|
95
|
+
def show_versions
|
96
|
+
if request.env['HTTP_X_CHEF_VERSION'] =~ /0\.9/
|
97
|
+
show_versions_09
|
98
|
+
else
|
99
|
+
show_versions_010
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
70
103
|
# GET /cookbooks/:cookbook_name
|
71
104
|
#
|
72
105
|
# returns data in the format of:
|
@@ -75,7 +108,7 @@ class Cookbooks < Application
|
|
75
108
|
# :versions => [{:url => "http://url/1.0.0", :version => "1.0.0"}, {:url => "http://url/0.0.1", :version=>"0.0.1"}]
|
76
109
|
# }
|
77
110
|
# }
|
78
|
-
def
|
111
|
+
def show_versions_010
|
79
112
|
versions = Chef::CookbookVersion.cdb_by_name(cookbook_name)
|
80
113
|
raise NotFound, "Cannot find a cookbook named #{cookbook_name}" unless versions && versions.size > 0
|
81
114
|
num_versions = num_versions!("all")
|
@@ -83,6 +116,17 @@ class Cookbooks < Application
|
|
83
116
|
display({ cookbook_name => expand_cookbook_urls(cookbook_name, cb_versions, num_versions) })
|
84
117
|
end
|
85
118
|
|
119
|
+
# GET /cookbooks/:cookbook_name
|
120
|
+
#
|
121
|
+
# returns data in the format of:
|
122
|
+
# {"apache2" => ["1.0.0", "0.0.1"]}
|
123
|
+
def show_versions_09
|
124
|
+
versions = Chef::CookbookVersion.cdb_by_name(cookbook_name)
|
125
|
+
raise NotFound, "Cannot find a cookbook named #{requested_cookbook_name}" unless versions && versions.size > 0
|
126
|
+
|
127
|
+
display versions
|
128
|
+
end
|
129
|
+
|
86
130
|
def show
|
87
131
|
cookbook = get_cookbook_version(cookbook_name, cookbook_version)
|
88
132
|
display cookbook.generate_manifest_with_urls { |opts| absolute_url(:cookbook_file, opts) }
|
data/spec/spec_helper.rb
CHANGED
@@ -23,6 +23,8 @@ require "rspec"
|
|
23
23
|
Merb.push_path(:spec_helpers, "spec" / "spec_helpers", "**/*.rb")
|
24
24
|
Merb.push_path(:spec_fixtures, "spec" / "fixtures", "**/*.rb")
|
25
25
|
|
26
|
+
$:.unshift(File.expand_path('../../app/', __FILE__))
|
27
|
+
|
26
28
|
Merb.start_environment(:testing => true, :adapter => 'runner', :environment => ENV['MERB_ENV'] || 'test')
|
27
29
|
|
28
30
|
RSpec.configure do |config|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Daniel DeLeo (<dan@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2011 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
20
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_model_helper')
|
21
|
+
require 'chef/node'
|
22
|
+
require 'pp'
|
23
|
+
|
24
|
+
describe "Coobkooks Controller" do
|
25
|
+
before do
|
26
|
+
Merb.logger.set_log(StringIO.new)
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "when several versions of multiple cookbooks exist" do
|
30
|
+
before do
|
31
|
+
@cookbook_a_versions = (0...7).map { |i| "1.0.#{i}"}
|
32
|
+
@cookbook_b_versions = (0...3).map { |i| "2.0.#{i}" }
|
33
|
+
Chef::CookbookVersion.stub!(:cdb_list).and_return("cookbook-a" => @cookbook_a_versions, "cookbook-b" => @cookbook_b_versions)
|
34
|
+
Chef::CookbookVersion.stub!(:cdb_list_latest).and_return('cookbook-a' => '1.0.6', 'cookbook-b' => '2.0.2')
|
35
|
+
Chef::CookbookVersion.stub!(:cdb_by_name).with('cookbook-a').and_return("cookbook-a" => @cookbook_a_versions)
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "when handling requests from 0.10 and newer clients" do
|
39
|
+
it "lists the latest version of all cookbooks" do
|
40
|
+
expected = {}
|
41
|
+
expected_cookbook_a_data = [ @cookbook_a_versions.map {|v| {"url" => "#{root_url}/cookbooks/cookbook-a/#{v}", "version" => v}}.last ]
|
42
|
+
expected['cookbook-a'] = {"url" => "#{root_url}/cookbooks/cookbook-a", "versions" => expected_cookbook_a_data}
|
43
|
+
expected_cookbook_b_data = [ @cookbook_b_versions.map {|v| {"url" => "#{root_url}/cookbooks/cookbook-b/#{v}", "version" => v}}.last ]
|
44
|
+
expected['cookbook-b'] = {"url" => "#{root_url}/cookbooks/cookbook-b", "versions" => expected_cookbook_b_data}
|
45
|
+
get_json('/cookbooks').should == expected
|
46
|
+
end
|
47
|
+
|
48
|
+
it "shows the versions of a cookbook" do
|
49
|
+
expected = {}
|
50
|
+
expected_cookbook_a_data = @cookbook_a_versions.map {|v| {"url" => "#{root_url}/cookbooks/cookbook-a/#{v}", "version" => v}}.reverse
|
51
|
+
expected['cookbook-a'] = {"url" => "#{root_url}/cookbooks/cookbook-a", "versions" => expected_cookbook_a_data}
|
52
|
+
get_json('/cookbooks/cookbook-a').should == expected
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "when handling requests from 0.9 clients" do
|
57
|
+
it "lists the latest versions of cookbooks by URL" do
|
58
|
+
expected = {}
|
59
|
+
expected['cookbook-a'] = "#{root_url}/cookbooks/cookbook-a"
|
60
|
+
expected['cookbook-b'] = "#{root_url}/cookbooks/cookbook-b"
|
61
|
+
get_json('/cookbooks', {}, {'HTTP_X_CHEF_VERSION' => '0.9.14'} ).should == expected
|
62
|
+
end
|
63
|
+
|
64
|
+
it "shows the versions of a cookbook by URL" do
|
65
|
+
expected = {'cookbook-a' => @cookbook_a_versions}
|
66
|
+
get_json('/cookbooks/cookbook-a', {}, {'HTTP_X_CHEF_VERSION' => '0.9.14'}).should == expected
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -26,7 +26,7 @@ describe "Environments controller" do
|
|
26
26
|
Merb.logger.set_log(StringIO.new)
|
27
27
|
|
28
28
|
@env1 = make_environment("env1")
|
29
|
-
|
29
|
+
|
30
30
|
@filtered_cookbook_list_env1 = make_filtered_cookbook_hash(make_cookbook("cookbook1", "1.0.0"),
|
31
31
|
make_cookbook("cookbook2", "1.0.0"))
|
32
32
|
@filtered_cookbook_list_env1["cookbook_noversions"] = Array.new
|
@@ -51,7 +51,7 @@ describe "Environments controller" do
|
|
51
51
|
|
52
52
|
# Env1 pins both versions at 1.0.0. Expect only the one we ask for, cookbook1,
|
53
53
|
# back in the result.
|
54
|
-
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env1").and_return(@filtered_cookbook_list_env1)
|
54
|
+
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env1", nil).and_return(@filtered_cookbook_list_env1)
|
55
55
|
response = post_json("/environments/env1/cookbook_versions", {"run_list" => ["recipe[cookbook1]"]})
|
56
56
|
response.should be_kind_of(Hash)
|
57
57
|
response.keys.size.should == 1
|
@@ -62,7 +62,7 @@ describe "Environments controller" do
|
|
62
62
|
it "should expect the passed-in run_list using the correct environment: two run_list items" do
|
63
63
|
# Ask for both cookbook1 and cookbook2 back. Expect version 2.0.0 for
|
64
64
|
# each, as those are what's appropriate for the environment.
|
65
|
-
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env2").and_return(@filtered_cookbook_list_env2)
|
65
|
+
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env2", nil).and_return(@filtered_cookbook_list_env2)
|
66
66
|
response = post_json("/environments/env2/cookbook_versions", {"run_list" => ["recipe[cookbook2]", "recipe[cookbook1]"]})
|
67
67
|
response.should be_kind_of(Hash)
|
68
68
|
response.keys.size.should == 2
|
@@ -73,7 +73,7 @@ describe "Environments controller" do
|
|
73
73
|
end
|
74
74
|
|
75
75
|
it "should return the newest version of a cookbook when given multiple versions" do
|
76
|
-
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env_many_versions").and_return(@filtered_cookbook_list_env_many_versions)
|
76
|
+
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env_many_versions", nil).and_return(@filtered_cookbook_list_env_many_versions)
|
77
77
|
response = post_json("/environments/env_many_versions/cookbook_versions", {"run_list" => ["recipe[cookbook1]"]})
|
78
78
|
|
79
79
|
response.should be_kind_of(Hash)
|
@@ -83,7 +83,7 @@ describe "Environments controller" do
|
|
83
83
|
end
|
84
84
|
|
85
85
|
it "should return the asked-for, older version of a cookbook if the version is specified in the run_list" do
|
86
|
-
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env_many_versions").and_return(@filtered_cookbook_list_env_many_versions)
|
86
|
+
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env_many_versions", nil).and_return(@filtered_cookbook_list_env_many_versions)
|
87
87
|
response = post_json("/environments/env_many_versions/cookbook_versions", {"run_list" => ["recipe[cookbook1@1.0.0]"]})
|
88
88
|
|
89
89
|
response.should be_kind_of(Hash)
|
@@ -93,7 +93,7 @@ describe "Environments controller" do
|
|
93
93
|
end
|
94
94
|
|
95
95
|
it "should report no_such_cookbook if given a dependency on a non-existant cookbook" do
|
96
|
-
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env1").and_return(@filtered_cookbook_list_env1)
|
96
|
+
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env1", nil).and_return(@filtered_cookbook_list_env1)
|
97
97
|
expected_error = {
|
98
98
|
"message" => "Run list contains invalid items: no such cookbook cookbook_nosuch.",
|
99
99
|
"non_existent_cookbooks" => ["cookbook_nosuch"],
|
@@ -106,7 +106,7 @@ describe "Environments controller" do
|
|
106
106
|
end
|
107
107
|
|
108
108
|
it "should report no_such_version if given a dependency on a cookbook that doesn't have any valid versions for an environment" do
|
109
|
-
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env1").and_return(@filtered_cookbook_list_env1)
|
109
|
+
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env1", nil).and_return(@filtered_cookbook_list_env1)
|
110
110
|
expected_error = {
|
111
111
|
"message" => "Run list contains invalid items: no versions match the constraints on cookbook cookbook_noversions.",
|
112
112
|
"non_existent_cookbooks" => [],
|
@@ -121,7 +121,7 @@ describe "Environments controller" do
|
|
121
121
|
# TODO; have top-level cookbooks depend on other, non-existent cookbooks,
|
122
122
|
# to get the other kind of exceptions.
|
123
123
|
it "should report multiple failures (compound exceptions) if there is more than one error in dependencies" do
|
124
|
-
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env1").and_return(@filtered_cookbook_list_env1)
|
124
|
+
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env1", nil).and_return(@filtered_cookbook_list_env1)
|
125
125
|
|
126
126
|
expected_error = {
|
127
127
|
"message" => "Run list contains invalid items: no such cookbooks cookbook_nosuch_1, cookbook_nosuch_2; no versions match the constraints on cookbook cookbook_noversions.",
|
@@ -130,7 +130,7 @@ describe "Environments controller" do
|
|
130
130
|
}.to_json
|
131
131
|
|
132
132
|
lambda {
|
133
|
-
response = post_json("/environments/env1/cookbook_versions",
|
133
|
+
response = post_json("/environments/env1/cookbook_versions",
|
134
134
|
{"run_list" => ["recipe[cookbook_nosuch_1]", "recipe[cookbook_nosuch_2]", "recipe[cookbook_noversions]"]})
|
135
135
|
}.should raise_error(Merb::ControllerExceptions::PreconditionFailed, expected_error)
|
136
136
|
end
|
@@ -60,7 +60,7 @@ describe "Nodes controller - environments and run_list expansion" do
|
|
60
60
|
# Test that node@_default resolves to use cookbook cb_for_default
|
61
61
|
Chef::Node.should_receive(:cdb_load).with("node1").and_return(@node1)
|
62
62
|
Chef::Role.should_receive(:cdb_load).with("role1", nil).and_return(@role1)
|
63
|
-
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("_default").and_return(@all_filtered_cookbook_list)
|
63
|
+
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("_default", nil).and_return(@all_filtered_cookbook_list)
|
64
64
|
|
65
65
|
response = get_json("/nodes/node1/cookbooks")
|
66
66
|
response.should be_kind_of(Hash)
|
@@ -73,7 +73,7 @@ describe "Nodes controller - environments and run_list expansion" do
|
|
73
73
|
@node1.chef_environment("env1")
|
74
74
|
Chef::Node.should_receive(:cdb_load).with("node1").and_return(@node1)
|
75
75
|
Chef::Role.should_receive(:cdb_load).with("role1", nil).and_return(@role1)
|
76
|
-
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env1").and_return(@all_filtered_cookbook_list)
|
76
|
+
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env1", nil).and_return(@all_filtered_cookbook_list)
|
77
77
|
|
78
78
|
response = get_json("/nodes/node1/cookbooks")
|
79
79
|
response.should be_kind_of(Hash)
|
@@ -87,7 +87,7 @@ describe "Nodes controller - environments and run_list expansion" do
|
|
87
87
|
@node1.chef_environment("env_fallback")
|
88
88
|
Chef::Node.should_receive(:cdb_load).with("node1").and_return(@node1)
|
89
89
|
Chef::Role.should_receive(:cdb_load).with("role1", nil).and_return(@role1)
|
90
|
-
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env_fallback").and_return(@all_filtered_cookbook_list)
|
90
|
+
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("env_fallback", nil).and_return(@all_filtered_cookbook_list)
|
91
91
|
|
92
92
|
response = get_json("/nodes/node1/cookbooks")
|
93
93
|
response.should be_kind_of(Hash)
|
@@ -103,7 +103,7 @@ describe "Nodes controller - environments and run_list expansion" do
|
|
103
103
|
}.to_json
|
104
104
|
|
105
105
|
Chef::Node.should_receive(:cdb_load).with("node_containing_nosuch_cookbook").and_return(@node_containing_nosuch_cookbook)
|
106
|
-
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("_default").and_return(@all_filtered_cookbook_list)
|
106
|
+
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("_default", nil).and_return(@all_filtered_cookbook_list)
|
107
107
|
|
108
108
|
lambda {
|
109
109
|
response = get_json("/nodes/node_containing_nosuch_cookbook/cookbooks")
|
@@ -120,7 +120,7 @@ describe "Nodes controller - environments and run_list expansion" do
|
|
120
120
|
|
121
121
|
Chef::Node.should_receive(:cdb_load).with("node_containing_role_containing_nosuch_cookbook").and_return(@node_containing_role_containing_nosuch_cookbook)
|
122
122
|
Chef::Role.should_receive(:cdb_load).with("role_containing_nosuch_cookbook", nil).and_return(@role_containing_nosuch_cookbook)
|
123
|
-
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("_default").and_return(@all_filtered_cookbook_list)
|
123
|
+
Chef::Environment.should_receive(:cdb_load_filtered_cookbook_versions).with("_default", nil).and_return(@all_filtered_cookbook_list)
|
124
124
|
|
125
125
|
lambda {
|
126
126
|
response = get_json("/nodes/node_containing_role_containing_nosuch_cookbook/cookbooks")
|
@@ -34,7 +34,7 @@ describe "Nodes controller" do
|
|
34
34
|
res = get_json("/nodes")
|
35
35
|
|
36
36
|
expected_response = returned_node_list.inject({}) do |res,node_name|
|
37
|
-
res[node_name] = "#{root_url}/#{node_name}"
|
37
|
+
res[node_name] = "#{root_url}/nodes/#{node_name}"
|
38
38
|
res
|
39
39
|
end
|
40
40
|
res.should == expected_response
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: chef-server-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 7
|
5
|
-
version: 0.10.0.beta.
|
5
|
+
version: 0.10.0.beta.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Opscode
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-30 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -150,6 +150,7 @@ files:
|
|
150
150
|
- spec/spec.opts
|
151
151
|
- spec/spec_helper.rb
|
152
152
|
- spec/spec_model_helper.rb
|
153
|
+
- spec/unit/cookbooks_controller_spec.rb
|
153
154
|
- spec/unit/environments_controller_spec.rb
|
154
155
|
- spec/unit/nodes_controller_environments_spec.rb
|
155
156
|
- spec/unit/nodes_controller_spec.rb
|