spice 0.4.2 → 0.5.0.beta.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.
- data/.watchr +22 -0
- data/Gemfile +14 -1
- data/Rakefile +5 -0
- data/lib/spice.rb +1 -1
- data/lib/spice/client.rb +4 -4
- data/lib/spice/connection.rb +9 -4
- data/lib/spice/node.rb +7 -0
- data/lib/spice/version.rb +1 -1
- data/spec/spec_helper.rb +29 -19
- data/spec/spice/chef_spec.rb +31 -83
- data/spec/spice/client_spec.rb +42 -85
- data/spec/spice/cookbook_spec.rb +42 -81
- data/spec/spice/data_bag_spec.rb +84 -85
- data/spec/spice/node_spec.rb +75 -0
- data/spec/spice/role_spec.rb +61 -0
- data/spec/spice/search_spec.rb +2 -0
- data/{file.txt → spec/support/chef_requests.rb} +0 -0
- data/spec/support/client_requests.rb +52 -54
- data/spec/support/cookbook_requests.rb +53 -130
- data/spec/support/node_requests.rb +138 -0
- data/spec/support/requests.rb +97 -97
- data/spec/support/role_requests.rb +95 -0
- data/spice.gemspec +2 -3
- metadata +17 -22
- data/spec/support/vcr.rb +0 -8
data/.watchr
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
def run_spec(file)
|
2
|
+
unless File.exist?(file)
|
3
|
+
puts "#{file} does not exist"
|
4
|
+
return
|
5
|
+
end
|
6
|
+
|
7
|
+
puts "Running #{file}"
|
8
|
+
system "bundle exec rspec #{file}"
|
9
|
+
puts
|
10
|
+
end
|
11
|
+
|
12
|
+
watch("spec/.*/*_spec\.rb") do |match|
|
13
|
+
run_spec match[0]
|
14
|
+
end
|
15
|
+
|
16
|
+
watch("lib/(.*/.*)\.rb") do |match|
|
17
|
+
run_spec %{spec/#{match[1]}_spec.rb}
|
18
|
+
end
|
19
|
+
|
20
|
+
watch("lib/spice.rb") do |match|
|
21
|
+
run_spec %{spec/spice_spec.rb}
|
22
|
+
end
|
data/Gemfile
CHANGED
@@ -1,3 +1,16 @@
|
|
1
1
|
source "http://rubygems.org"
|
2
2
|
|
3
|
-
|
3
|
+
gem 'rest-client'
|
4
|
+
gem 'mixlib-authentication'
|
5
|
+
gem 'yajl-ruby'
|
6
|
+
|
7
|
+
group :development, :test do
|
8
|
+
gem "yard", "~> 0.6.4"
|
9
|
+
gem "rspec", "~> 2.5.0"
|
10
|
+
gem "cucumber", "~> 0.10.0"
|
11
|
+
gem "webmock", "~> 1.6.2"
|
12
|
+
gem "timecop", "~> 0.3.5"
|
13
|
+
gem 'watchr'
|
14
|
+
gem 'spork', '~> 0.9.0.rc'
|
15
|
+
gem 'webmock', '~> 1.6.2'
|
16
|
+
end
|
data/Rakefile
CHANGED
data/lib/spice.rb
CHANGED
data/lib/spice/client.rb
CHANGED
@@ -3,7 +3,7 @@ module Spice
|
|
3
3
|
def self.all(options={})
|
4
4
|
if options[:complete]
|
5
5
|
results = []
|
6
|
-
connection.get("
|
6
|
+
connection.get("clients").map { |c| c[0] }.each do |client|
|
7
7
|
results << connection.get("/clients/#{client}")
|
8
8
|
end
|
9
9
|
results
|
@@ -24,19 +24,19 @@ module Spice
|
|
24
24
|
|
25
25
|
def self.create(options={})
|
26
26
|
raise ArgumentError, "Option :name must be present" unless options[:name]
|
27
|
-
connection.post("/clients",
|
27
|
+
connection.post("/clients", options)
|
28
28
|
end
|
29
29
|
|
30
30
|
def self.update(options={})
|
31
31
|
raise ArgumentError, "Option :name must be present" unless options[:name]
|
32
32
|
name = options.delete(:name)
|
33
|
-
connection.put("/clients/#{name}",
|
33
|
+
connection.put("/clients/#{name}", options)
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.delete(options={})
|
37
37
|
raise ArgumentError, "Option :name must be present" unless options[:name]
|
38
38
|
name = options.delete(:name)
|
39
|
-
connection.delete("/clients/#{name}",
|
39
|
+
connection.delete("/clients/#{name}", options)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
data/lib/spice/connection.rb
CHANGED
@@ -17,10 +17,12 @@ module Spice
|
|
17
17
|
|
18
18
|
def get(path, headers={})
|
19
19
|
begin
|
20
|
-
RestClient.get(
|
20
|
+
response = RestClient.get(
|
21
21
|
"#{@url}#{path}",
|
22
22
|
build_headers(:GET, "#{@url_path}#{path}", headers)
|
23
23
|
)
|
24
|
+
# response
|
25
|
+
response
|
24
26
|
rescue => e
|
25
27
|
e.response
|
26
28
|
end
|
@@ -28,11 +30,12 @@ module Spice
|
|
28
30
|
|
29
31
|
def post(path, payload, headers={})
|
30
32
|
begin
|
31
|
-
RestClient.post(
|
33
|
+
response = RestClient.post(
|
32
34
|
"#{@url}#{path}",
|
33
35
|
JSON.generate(payload),
|
34
36
|
build_headers(:POST, "#{@url_path}#{path}", headers, JSON.generate(payload))
|
35
37
|
)
|
38
|
+
response
|
36
39
|
rescue => e
|
37
40
|
e.response
|
38
41
|
end
|
@@ -40,11 +43,12 @@ module Spice
|
|
40
43
|
|
41
44
|
def put(path, payload, headers={})
|
42
45
|
begin
|
43
|
-
RestClient.put(
|
46
|
+
response = RestClient.put(
|
44
47
|
"#{@url}#{path}",
|
45
48
|
JSON.generate(payload),
|
46
49
|
build_headers(:PUT, "#{@url_path}#{path}", headers, JSON.generate(payload))
|
47
50
|
)
|
51
|
+
response
|
48
52
|
rescue => e
|
49
53
|
e.response
|
50
54
|
end
|
@@ -52,10 +56,11 @@ module Spice
|
|
52
56
|
|
53
57
|
def delete(path, headers={})
|
54
58
|
begin
|
55
|
-
RestClient.delete(
|
59
|
+
response = RestClient.delete(
|
56
60
|
"#{@url}#{path}",
|
57
61
|
build_headers(:DELETE, "#{@url_path}#{path}", headers)
|
58
62
|
)
|
63
|
+
response
|
59
64
|
rescue => e
|
60
65
|
e.response
|
61
66
|
end
|
data/lib/spice/node.rb
CHANGED
@@ -15,6 +15,13 @@ module Spice
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.create(options={})
|
18
|
+
raise ArgumentError, "Option :name must be present" unless options[:name]
|
19
|
+
options[:chef_type] ||= "node"
|
20
|
+
options[:json_class] ||= "Chef::Node"
|
21
|
+
options[:attributes] ||= {}
|
22
|
+
options[:overrides] ||= {}
|
23
|
+
options[:defaults] ||={}
|
24
|
+
options[:run_list] ||= []
|
18
25
|
connection.post("/nodes", options)
|
19
26
|
end
|
20
27
|
|
data/lib/spice/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,24 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'bundler'
|
4
|
-
Bundler.require
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spork'
|
5
3
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
require '
|
4
|
+
Spork.prefork do
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
6
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
|
+
require 'bundler'
|
8
|
+
Bundler.require
|
10
9
|
|
11
|
-
require '
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
require 'rspec'
|
11
|
+
require 'webmock/rspec'
|
12
|
+
require 'timecop'
|
13
|
+
require 'rest-client'
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
require 'spice'
|
16
|
+
# Requires supporting files with custom matchers and macros, etc,
|
17
|
+
# in ./support/ and its subdirectories.
|
18
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
19
|
+
|
20
|
+
RSpec.configure do |config|
|
21
|
+
config.before do
|
22
|
+
Timecop.freeze
|
23
|
+
Spice.mock
|
24
|
+
end
|
25
|
+
config.after do
|
26
|
+
Timecop.return
|
27
|
+
end
|
23
28
|
end
|
24
29
|
end
|
30
|
+
|
31
|
+
Spork.each_run do
|
32
|
+
require 'spice'
|
33
|
+
# This code will be run each time you run your specs.
|
34
|
+
end
|
data/spec/spice/chef_spec.rb
CHANGED
@@ -9,97 +9,45 @@ module Spice
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
describe
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
:status => 200,
|
19
|
-
:body => '{"testclient":"http://localhost:4000/clients/testclient",
|
20
|
-
"goodclient":"http://localhost:4000/clients/goodclient"}',
|
21
|
-
:headers => {})
|
22
|
-
end
|
23
|
-
it "should return a list of all clients" do
|
24
|
-
JSON.parse(clients).length.should == 2
|
25
|
-
end
|
26
|
-
it "should provide valid client" do
|
27
|
-
clients["testclient"].should == "testclient"
|
28
|
-
end
|
12
|
+
describe ".clients" do
|
13
|
+
before { stub_client_list }
|
14
|
+
subject { Chef.clients }
|
15
|
+
|
16
|
+
it { should have_body(client_list_response) }
|
17
|
+
it { should respond_with(200) }
|
29
18
|
end
|
30
19
|
|
31
|
-
describe
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
:status => 200,
|
38
|
-
:body => '{"testnode":"http://localhost:4000/nodes/testnode"}',
|
39
|
-
:headers => {}
|
40
|
-
)
|
41
|
-
end
|
42
|
-
it "should return a list of all nodes" do
|
43
|
-
JSON.parse(nodes).length.should == 1
|
44
|
-
# nodes.first["testnode"].should == "http://localhost:4000/nodes/testnode"
|
45
|
-
end
|
46
|
-
it "should provide valid node" do
|
47
|
-
nodes["testnode"].should == "testnode"
|
48
|
-
end
|
20
|
+
describe ".cookbooks" do
|
21
|
+
before { stub_cookbook_list }
|
22
|
+
subject { Chef.cookbooks }
|
23
|
+
|
24
|
+
it { should have_body(cookbook_list_response) }
|
25
|
+
it { should respond_with(200) }
|
49
26
|
end
|
50
27
|
|
51
|
-
describe
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
:body => '{"testdata":"http://localhost:4000/data/testdata"}',
|
58
|
-
:headers => {}
|
59
|
-
)
|
60
|
-
end
|
61
|
-
it "should return a list of all data bags" do
|
62
|
-
JSON.parse(data_bags).length.should == 1
|
63
|
-
end
|
64
|
-
it "should provide valid data" do
|
65
|
-
data_bags["testdata"].should == "testdata"
|
66
|
-
end
|
28
|
+
describe ".data_bags" do
|
29
|
+
before { stub_data_bag_list }
|
30
|
+
subject { Chef.data_bags }
|
31
|
+
|
32
|
+
it { should have_body(data_bag_list_response) }
|
33
|
+
it { should respond_with(200) }
|
67
34
|
end
|
68
35
|
|
69
|
-
describe
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
:body => '{"testrole":"testrole"}',
|
76
|
-
:headers => {}
|
77
|
-
)
|
78
|
-
end
|
79
|
-
it "should return a list of all roles" do
|
80
|
-
JSON.parse(roles).length.should == 1
|
81
|
-
end
|
82
|
-
it "should provide valid role" do
|
83
|
-
roles["testrole"].should == "testrole"
|
84
|
-
end
|
36
|
+
describe ".nodes" do
|
37
|
+
before { stub_node_list }
|
38
|
+
subject { Chef.nodes }
|
39
|
+
|
40
|
+
it { should have_body(node_list_response) }
|
41
|
+
it { should respond_with(200) }
|
85
42
|
end
|
86
43
|
|
87
|
-
describe
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
:body => '{"testcookbook":"http://localhost:4000/cookbooks/testcookbook"}',
|
94
|
-
:headers => {}
|
95
|
-
)
|
96
|
-
end
|
97
|
-
it "should return a list of all cookbooks" do
|
98
|
-
JSON.parse(cookbooks).length.should == 1
|
99
|
-
end
|
100
|
-
it "should provide valid cookbook" do
|
101
|
-
cookbooks["testcookbook"].should == "testcookbook"
|
102
|
-
end
|
44
|
+
describe ".roles" do
|
45
|
+
before { stub_role_list }
|
46
|
+
subject { Chef.roles }
|
47
|
+
|
48
|
+
it { should have_body(role_list_response) }
|
49
|
+
it { should respond_with(200) }
|
103
50
|
end
|
51
|
+
|
104
52
|
end
|
105
53
|
end
|
data/spec/spice/client_spec.rb
CHANGED
@@ -3,109 +3,66 @@ require 'spec_helper'
|
|
3
3
|
module Spice
|
4
4
|
describe Client do
|
5
5
|
describe ".all" do
|
6
|
-
before {
|
6
|
+
before { stub_client_list }
|
7
|
+
subject { Client.all }
|
7
8
|
|
8
|
-
it
|
9
|
-
|
10
|
-
Client.all.length.should == 1
|
11
|
-
end
|
9
|
+
it { should have_body(client_list_response) }
|
10
|
+
it { should respond_with(200) }
|
12
11
|
end
|
13
|
-
|
12
|
+
|
14
13
|
describe ".show" do
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
client["admin"].should == true
|
22
|
-
end
|
14
|
+
context "if the client is found" do
|
15
|
+
before { stub_client_show }
|
16
|
+
subject { Client.show(:name => "testclient") }
|
17
|
+
|
18
|
+
it { should have_body(client_show_response) }
|
19
|
+
it { should respond_with(200) }
|
23
20
|
end
|
24
21
|
|
25
|
-
context "
|
26
|
-
|
27
|
-
|
28
|
-
lambda { Client.show(:name => "applesauce") }.
|
29
|
-
should raise_error(RestClient::ResourceNotFound)
|
30
|
-
end
|
22
|
+
context "if the client is not found" do
|
23
|
+
before { stub_client_show(404) }
|
24
|
+
subject { Client.show(:name => "testclient") }
|
31
25
|
|
32
|
-
it
|
33
|
-
|
34
|
-
lambda {Client.show() }.should raise_error ArgumentError
|
35
|
-
end
|
26
|
+
it { should_not have_body(client_show_response) }
|
27
|
+
it { should respond_with(404) }
|
36
28
|
end
|
37
29
|
end
|
38
|
-
|
30
|
+
|
39
31
|
describe ".create" do
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
it "creates a valid non-admin client" do
|
44
|
-
stub_client_create("spork")
|
45
|
-
client = Client.create(:name => "spork", :admin => false)
|
46
|
-
client["private_key"].should == "RSA PRIVATE KEY"
|
47
|
-
client["uri"].should == "http://http://localhost:4000/clients/spork"
|
48
|
-
end
|
32
|
+
context "if the client can be created" do
|
33
|
+
before { stub_client_create }
|
34
|
+
subject { Client.create(:name => "testclient") }
|
49
35
|
|
50
|
-
it
|
51
|
-
|
52
|
-
response = Client.create(:name => "pants", :admin => true)
|
53
|
-
response["private_key"].should == "RSA PRIVATE KEY"
|
54
|
-
response["uri"].should == "http://http://localhost:4000/clients/pants"
|
55
|
-
|
56
|
-
stub_client_show("pants")
|
57
|
-
client = Client.show(:name => "pants")
|
58
|
-
client["admin"].should == true
|
59
|
-
end
|
36
|
+
it { should have_body(client_create_response) }
|
37
|
+
it { should respond_with(201) }
|
60
38
|
end
|
61
39
|
|
62
|
-
context "
|
63
|
-
|
64
|
-
|
65
|
-
lambda { Client.create(:name => "pants", :admin => false) }.
|
66
|
-
should raise_error(RestClient::Conflict)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe ".update" do
|
72
|
-
before { }
|
73
|
-
|
74
|
-
context "valid" do
|
75
|
-
it "makes a client an admin" do
|
76
|
-
stub_client_update("awesome", true, false, 200)
|
77
|
-
Client.update(:name => "awesome", :admin => true, :private_key => false)
|
78
|
-
end
|
40
|
+
context "if the client already exists" do
|
41
|
+
before { stub_client_create(409) }
|
42
|
+
subject { Client.create(:name => "testclient") }
|
79
43
|
|
80
|
-
it
|
81
|
-
|
82
|
-
|
83
|
-
end
|
84
|
-
end
|
44
|
+
it { should have_body(client_conflict) }
|
45
|
+
it { should respond_with(409) }
|
46
|
+
end
|
85
47
|
end
|
86
|
-
|
48
|
+
|
87
49
|
describe ".delete" do
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end
|
50
|
+
context "if the client can be deleted" do
|
51
|
+
before { stub_client_delete }
|
52
|
+
subject { Client.delete(:name => "testclient") }
|
53
|
+
|
54
|
+
it { should have_body(client_delete_response) }
|
55
|
+
it { should respond_with(200) }
|
95
56
|
end
|
96
|
-
|
97
|
-
context "
|
98
|
-
|
99
|
-
|
100
|
-
lambda {Client.delete }.should raise_error ArgumentError
|
101
|
-
end
|
57
|
+
|
58
|
+
context "if the client cannot be deleted" do
|
59
|
+
before { stub_client_delete(404) }
|
60
|
+
subject { Client.delete(:name => "testclient") }
|
102
61
|
|
103
|
-
it
|
104
|
-
|
105
|
-
lambda { Client.delete(:name => "spork") }.
|
106
|
-
should raise_error(RestClient::ResourceNotFound)
|
107
|
-
end
|
62
|
+
it { should have_body(client_not_found) }
|
63
|
+
it { should respond_with(404) }
|
108
64
|
end
|
109
65
|
end
|
66
|
+
|
110
67
|
end
|
111
68
|
end
|