ridley 0.7.0.beta → 0.7.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/README.md +51 -54
  2. data/lib/ridley.rb +7 -13
  3. data/lib/ridley/client.rb +251 -0
  4. data/lib/ridley/connection.rb +32 -188
  5. data/lib/ridley/middleware/chef_auth.rb +4 -1
  6. data/lib/ridley/resource.rb +36 -42
  7. data/lib/ridley/resources.rb +3 -0
  8. data/lib/ridley/resources/{client.rb → client_resource.rb} +7 -20
  9. data/lib/ridley/resources/cookbook_resource.rb +121 -0
  10. data/lib/ridley/resources/{data_bag_item.rb → data_bag_item_resource.rb} +52 -63
  11. data/lib/ridley/resources/data_bag_resource.rb +74 -0
  12. data/lib/ridley/resources/encrypted_data_bag_item_resource.rb +55 -0
  13. data/lib/ridley/resources/{environment.rb → environment_resource.rb} +8 -21
  14. data/lib/ridley/resources/{node.rb → node_resource.rb} +24 -37
  15. data/lib/ridley/resources/{role.rb → role_resource.rb} +1 -14
  16. data/lib/ridley/resources/sandbox_resource.rb +86 -0
  17. data/lib/ridley/resources/search.rb +24 -55
  18. data/lib/ridley/sandbox_uploader.rb +118 -0
  19. data/lib/ridley/ssh.rb +2 -2
  20. data/lib/ridley/ssh/worker.rb +2 -1
  21. data/lib/ridley/version.rb +1 -1
  22. data/ridley.gemspec +1 -1
  23. data/spec/acceptance/bootstrapping_spec.rb +1 -1
  24. data/spec/acceptance/client_resource_spec.rb +18 -20
  25. data/spec/acceptance/cookbook_resource_spec.rb +4 -22
  26. data/spec/acceptance/data_bag_item_resource_spec.rb +5 -7
  27. data/spec/acceptance/data_bag_resource_spec.rb +4 -6
  28. data/spec/acceptance/environment_resource_spec.rb +14 -16
  29. data/spec/acceptance/node_resource_spec.rb +12 -14
  30. data/spec/acceptance/role_resource_spec.rb +13 -15
  31. data/spec/acceptance/sandbox_resource_spec.rb +7 -9
  32. data/spec/acceptance/search_resource_spec.rb +6 -8
  33. data/spec/support/shared_examples/ridley_resource.rb +23 -22
  34. data/spec/unit/ridley/client_spec.rb +153 -0
  35. data/spec/unit/ridley/connection_spec.rb +8 -221
  36. data/spec/unit/ridley/resources/{client_spec.rb → client_resource_spec.rb} +4 -4
  37. data/spec/unit/ridley/resources/cookbook_resource_spec.rb +5 -0
  38. data/spec/unit/ridley/resources/{data_bag_item_spec.rb → data_bag_item_resource_spec.rb} +2 -2
  39. data/spec/unit/ridley/resources/{data_bag_spec.rb → data_bag_resource_spec.rb} +3 -3
  40. data/spec/unit/ridley/resources/{environment_spec.rb → environment_resource_spec.rb} +4 -4
  41. data/spec/unit/ridley/resources/{node_spec.rb → node_resource_spec.rb} +4 -4
  42. data/spec/unit/ridley/resources/{role_spec.rb → role_resource_spec.rb} +3 -3
  43. data/spec/unit/ridley/resources/sandbox_resource_spec.rb +172 -0
  44. data/spec/unit/ridley/resources/search_spec.rb +34 -30
  45. data/spec/unit/ridley/sandbox_uploader_spec.rb +99 -0
  46. data/spec/unit/ridley/ssh_spec.rb +2 -2
  47. data/spec/unit/ridley_spec.rb +4 -12
  48. metadata +36 -28
  49. data/lib/ridley/dsl.rb +0 -58
  50. data/lib/ridley/resources/cookbook.rb +0 -51
  51. data/lib/ridley/resources/data_bag.rb +0 -81
  52. data/lib/ridley/resources/encrypted_data_bag_item.rb +0 -54
  53. data/lib/ridley/resources/sandbox.rb +0 -154
  54. data/spec/unit/ridley/resources/cookbook_spec.rb +0 -5
@@ -1,17 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Role API operations", type: "acceptance" do
4
- let(:server_url) { "https://api.opscode.com" }
4
+ let(:server_url) { "https://api.opscode.com/organizations/ridley" }
5
5
  let(:client_name) { "reset" }
6
6
  let(:client_key) { "/Users/reset/.chef/reset.pem" }
7
- let(:organization) { "ridley" }
8
7
 
9
8
  let(:connection) do
10
- Ridley.connection(
9
+ Ridley.new(
11
10
  server_url: server_url,
12
11
  client_name: client_name,
13
- client_key: client_key,
14
- organization: organization
12
+ client_key: client_key
15
13
  )
16
14
  end
17
15
 
@@ -22,7 +20,7 @@ describe "Role API operations", type: "acceptance" do
22
20
 
23
21
  describe "finding a role" do
24
22
  let(:target) do
25
- Ridley::Role.new(
23
+ Ridley::RoleResource.new(
26
24
  connection,
27
25
  name: "ridley-test",
28
26
  description: "a testing role for ridley"
@@ -33,21 +31,21 @@ describe "Role API operations", type: "acceptance" do
33
31
  connection.role.create(target)
34
32
  end
35
33
 
36
- it "returns the target Ridley::Role from the server" do
34
+ it "returns the target Ridley::RoleResource from the server" do
37
35
  connection.role.find(target.name).should eql(target)
38
36
  end
39
37
  end
40
38
 
41
39
  describe "creating a role" do
42
40
  let(:target) do
43
- Ridley::Role.new(
41
+ Ridley::RoleResource.new(
44
42
  connection,
45
43
  name: "ridley-test",
46
44
  description: "a testing role for ridley"
47
45
  )
48
46
  end
49
47
 
50
- it "returns a new Ridley::Role" do
48
+ it "returns a new Ridley::RoleResource" do
51
49
  connection.role.create(target).should eql(target)
52
50
  end
53
51
 
@@ -62,7 +60,7 @@ describe "Role API operations", type: "acceptance" do
62
60
 
63
61
  describe "deleting a role" do
64
62
  let(:target) do
65
- Ridley::Role.new(
63
+ Ridley::RoleResource.new(
66
64
  connection,
67
65
  name: "ridley-role-one"
68
66
  )
@@ -72,7 +70,7 @@ describe "Role API operations", type: "acceptance" do
72
70
  connection.role.create(target)
73
71
  end
74
72
 
75
- it "returns the deleted Ridley::Role resource" do
73
+ it "returns the deleted Ridley::RoleResource resource" do
76
74
  connection.role.delete(target).should eql(target)
77
75
  end
78
76
 
@@ -103,19 +101,19 @@ describe "Role API operations", type: "acceptance" do
103
101
  end
104
102
  end
105
103
 
106
- it "should return an array of Ridley::Role objects" do
104
+ it "should return an array of Ridley::RoleResource objects" do
107
105
  connection.sync do
108
106
  obj = role.all
109
107
 
110
108
  obj.should have(2).roles
111
- obj.should each be_a(Ridley::Role)
109
+ obj.should each be_a(Ridley::RoleResource)
112
110
  end
113
111
  end
114
112
  end
115
113
 
116
114
  describe "updating a role" do
117
115
  let(:target) do
118
- Ridley::Role.new(
116
+ Ridley::RoleResource.new(
119
117
  connection,
120
118
  name: "ridley-role-one"
121
119
  )
@@ -125,7 +123,7 @@ describe "Role API operations", type: "acceptance" do
125
123
  connection.role.create(target)
126
124
  end
127
125
 
128
- it "returns an updated Ridley::Role object" do
126
+ it "returns an updated Ridley::RoleResource object" do
129
127
  connection.role.update(target).should eql(target)
130
128
  end
131
129
 
@@ -1,17 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Sandbox API operations", type: "acceptance" do
4
- let(:server_url) { "https://api.opscode.com" }
4
+ let(:server_url) { "https://api.opscode.com/organizations/ridley" }
5
5
  let(:client_name) { "reset" }
6
6
  let(:client_key) { "/Users/reset/.chef/reset.pem" }
7
- let(:organization) { "ridley" }
8
7
 
9
8
  let(:connection) do
10
- Ridley.connection(
9
+ Ridley.new(
11
10
  server_url: server_url,
12
11
  client_name: client_name,
13
- client_key: client_key,
14
- organization: organization
12
+ client_key: client_key
15
13
  )
16
14
  end
17
15
 
@@ -20,14 +18,14 @@ describe "Sandbox API operations", type: "acceptance" do
20
18
 
21
19
  let(:checksums) do
22
20
  [
23
- Ridley::Sandbox.checksum(fixtures_path.join("recipe_one.rb")),
24
- Ridley::Sandbox.checksum(fixtures_path.join("recipe_two.rb"))
21
+ Ridley::SandboxUploader.checksum(fixtures_path.join("recipe_one.rb")),
22
+ Ridley::SandboxUploader.checksum(fixtures_path.join("recipe_two.rb"))
25
23
  ]
26
24
  end
27
25
 
28
26
  describe "creating a new sandbox" do
29
- it "returns an instance of Ridley::Sandbox" do
30
- connection.sandbox.create(checksums).should be_a(Ridley::Sandbox)
27
+ it "returns an instance of Ridley::SandboxResource" do
28
+ connection.sandbox.create(checksums).should be_a(Ridley::SandboxResource)
31
29
  end
32
30
 
33
31
  it "contains a value for sandbox_id" do
@@ -1,17 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Search API operations", type: "acceptance" do
4
- let(:server_url) { "https://api.opscode.com" }
4
+ let(:server_url) { "https://api.opscode.com/organizations/ridley" }
5
5
  let(:client_name) { "reset" }
6
6
  let(:client_key) { "/Users/reset/.chef/reset.pem" }
7
- let(:organization) { "ridley" }
8
7
 
9
- let(:connection) do
10
- Ridley.connection(
8
+ let(:client) do
9
+ Ridley.new(
11
10
  server_url: server_url,
12
11
  client_name: client_name,
13
- client_key: client_key,
14
- organization: organization
12
+ client_key: client_key
15
13
  )
16
14
  end
17
15
 
@@ -20,7 +18,7 @@ describe "Search API operations", type: "acceptance" do
20
18
 
21
19
  describe "listing indexes" do
22
20
  it "returns an array of indexes" do
23
- indexes = connection.search_indexes
21
+ indexes = client.search_indexes
24
22
 
25
23
  indexes.should include("role")
26
24
  indexes.should include("node")
@@ -32,7 +30,7 @@ describe "Search API operations", type: "acceptance" do
32
30
  describe "searching an index that doesn't exist" do
33
31
  it "it raises a Ridley::Errors::HTTPNotFound error" do
34
32
  lambda {
35
- connection.search(:notthere)
33
+ client.search(:notthere)
36
34
  }.should raise_error(Ridley::Errors::HTTPNotFound)
37
35
  end
38
36
  end
@@ -1,5 +1,6 @@
1
1
  shared_examples_for "a Ridley Resource" do |resource_klass|
2
2
  let(:connection) { double('connection', hosted?: true) }
3
+ let(:client) { double('client', connection: connection) }
3
4
  let(:active_connection) { double('active-connection') }
4
5
  let(:response) { double('response') }
5
6
 
@@ -7,20 +8,20 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
7
8
  subject { resource_klass }
8
9
 
9
10
  describe "::all" do
10
- it "sends a get request for the class' resource_path using the given connection" do
11
+ it "sends a get request for the class' resource_path using the given client" do
11
12
  response.stub(:body) { Hash.new }
12
- connection.should_receive(:get).with(subject.resource_path).and_return(response)
13
+ client.connection.should_receive(:get).with(subject.resource_path).and_return(response)
13
14
 
14
- subject.all(connection)
15
+ subject.all(client)
15
16
  end
16
17
  end
17
18
 
18
19
  describe "::find" do
19
20
  it "delegates to find!" do
20
21
  id = double('id')
21
- subject.should_receive(:find!).with(connection, id)
22
+ subject.should_receive(:find!).with(client, id)
22
23
 
23
- subject.find(connection, id)
24
+ subject.find(client, id)
24
25
  end
25
26
 
26
27
  context "when the resource is not found" do
@@ -31,12 +32,12 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
31
32
  end
32
33
 
33
34
  describe "::find!" do
34
- it "sends a get request to the given connection to the resource_path of the class for the given chef_id" do
35
+ it "sends a get request to the given client to the resource_path of the class for the given chef_id" do
35
36
  chef_id = "ridley_test"
36
37
  response.stub(:body) { Hash.new }
37
- connection.should_receive(:get).with("#{subject.resource_path}/#{chef_id}").and_return(response)
38
+ client.connection.should_receive(:get).with("#{subject.resource_path}/#{chef_id}").and_return(response)
38
39
 
39
- subject.find(connection, chef_id)
40
+ subject.find(client, chef_id)
40
41
  end
41
42
 
42
43
  context "when the resource is not found" do
@@ -47,34 +48,34 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
47
48
  end
48
49
 
49
50
  describe "::create" do
50
- it "sends a post request to the given connection using the includer's resource_path" do
51
+ it "sends a post request to the given client using the includer's resource_path" do
51
52
  attrs = {
52
53
  first_name: "jamie",
53
54
  last_name: "winsor"
54
55
  }
55
56
 
56
57
  response.stub(:body) { attrs }
57
- connection.should_receive(:post).with(subject.resource_path, duck_type(:to_json)).and_return(response)
58
+ client.connection.should_receive(:post).with(subject.resource_path, duck_type(:to_json)).and_return(response)
58
59
 
59
- subject.create(connection, attrs)
60
+ subject.create(client, attrs)
60
61
  end
61
62
  end
62
63
 
63
64
  describe "::delete" do
64
- it "sends a delete request to the given connection using the includer's resource_path for the given string" do
65
+ it "sends a delete request to the given client using the includer's resource_path for the given string" do
65
66
  response.stub(:body) { Hash.new }
66
- connection.should_receive(:delete).with("#{subject.resource_path}/ridley-test").and_return(response)
67
+ client.connection.should_receive(:delete).with("#{subject.resource_path}/ridley-test").and_return(response)
67
68
 
68
- subject.delete(connection, "ridley-test")
69
+ subject.delete(client, "ridley-test")
69
70
  end
70
71
 
71
72
  it "accepts an object that responds to 'chef_id'" do
72
73
  object = double("obj")
73
74
  object.stub(:chef_id) { "hello" }
74
75
  response.stub(:body) { Hash.new }
75
- connection.should_receive(:delete).with("#{subject.resource_path}/#{object.chef_id}").and_return(response)
76
+ client.connection.should_receive(:delete).with("#{subject.resource_path}/#{object.chef_id}").and_return(response)
76
77
 
77
- subject.delete(connection, object)
78
+ subject.delete(client, object)
78
79
  end
79
80
  end
80
81
 
@@ -85,19 +86,19 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
85
86
  end
86
87
 
87
88
  describe "::update" do
88
- it "sends a put request to the given connection using the includer's resource_path with the given object" do
89
+ it "sends a put request to the given client using the includer's resource_path with the given object" do
89
90
  subject.stub(:chef_id) { :name }
90
91
  subject.attribute(:name)
91
92
  object = subject.new(name: "hello")
92
93
  response.stub(:body) { Hash.new }
93
- connection.should_receive(:put).with("#{subject.resource_path}/#{object.chef_id}", duck_type(:to_json)).and_return(response)
94
+ client.connection.should_receive(:put).with("#{subject.resource_path}/#{object.chef_id}", duck_type(:to_json)).and_return(response)
94
95
 
95
- subject.update(connection, object)
96
+ subject.update(client, object)
96
97
  end
97
98
  end
98
99
  end
99
100
 
100
- subject { resource_klass.new(connection) }
101
+ subject { resource_klass.new(client) }
101
102
 
102
103
  describe "#save" do
103
104
  context "when the object is valid" do
@@ -106,7 +107,7 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
106
107
  it "sends a create message to the implementing class" do
107
108
  updated = double('updated')
108
109
  updated.stub(:attributes).and_return(Hash.new)
109
- subject.class.should_receive(:create).with(connection, subject).and_return(updated)
110
+ subject.class.should_receive(:create).with(client, subject).and_return(updated)
110
111
 
111
112
  subject.save
112
113
  end
@@ -183,7 +184,7 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
183
184
 
184
185
  before(:each) do
185
186
  subject.class.attribute(:fake_attribute)
186
- subject.class.stub(:find).with(connection, subject).and_return(updated_subject)
187
+ subject.class.stub(:find).with(client, subject).and_return(updated_subject)
187
188
  end
188
189
 
189
190
  it "returns itself" do
@@ -0,0 +1,153 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::Client do
4
+ let(:server_url) { "https://api.opscode.com" }
5
+ let(:client_name) { "reset" }
6
+ let(:client_key) { fixtures_path.join("reset.pem").to_s }
7
+ let(:organization) { "vialstudios" }
8
+ let(:encrypted_data_bag_secret_path) { fixtures_path.join("reset.pem").to_s }
9
+
10
+ let(:config) do
11
+ {
12
+ server_url: server_url,
13
+ client_name: client_name,
14
+ client_key: client_key,
15
+ organization: organization,
16
+ encrypted_data_bag_secret_path: encrypted_data_bag_secret_path
17
+ }
18
+ end
19
+
20
+ describe "ClassMethods" do
21
+ subject { described_class }
22
+
23
+ describe "::initialize" do
24
+ let(:server_url) { "https://api.opscode.com/some_path" }
25
+
26
+ describe "parsing the 'server_url' option" do
27
+ before(:each) do
28
+ @conn = subject.new(
29
+ server_url: server_url,
30
+ client_name: client_name,
31
+ client_key: client_key
32
+ )
33
+ end
34
+
35
+ it "assigns a 'host' attribute from the given 'server_url' option" do
36
+ @conn.host.should eql("api.opscode.com")
37
+ end
38
+
39
+ it "assigns a 'scheme' attribute from the given 'server_url' option" do
40
+ @conn.scheme.should eql("https")
41
+ end
42
+
43
+ it "sets a 'path_prefix' to the root of the given 'server_url' option" do
44
+ @conn.path_prefix.should eql("/")
45
+ end
46
+ end
47
+
48
+ describe "with a server_url containing an organization" do
49
+ before(:each) do
50
+ @conn = subject.new(
51
+ server_url: "#{server_url}/organizations/#{organization}",
52
+ client_name: client_name,
53
+ client_key: client_key
54
+ )
55
+ end
56
+
57
+ it "gets the host data from the server_url" do
58
+ @conn.host.should eql("api.opscode.com")
59
+ @conn.scheme.should eql("https")
60
+ end
61
+
62
+ it "assigns the value of the 'organization' option to an 'organization' attribute" do
63
+ @conn.connection.organization.should eql(organization)
64
+ end
65
+
66
+ it "sets the 'path_prefix' of the connection the organization sub URI" do
67
+ @conn.path_prefix.should eql("/organizations/#{organization}")
68
+ end
69
+ end
70
+
71
+ it "raises 'ArgumentError' if a value for server_url is not given" do
72
+ lambda {
73
+ subject.new(
74
+ client_name: client_name,
75
+ client_key: client_key
76
+ )
77
+ }.should raise_error(ArgumentError, "Missing required option(s): 'server_url'")
78
+ end
79
+
80
+ it "raises if a value for client_name is not given" do
81
+ lambda {
82
+ subject.new(
83
+ server_url: server_url,
84
+ client_key: client_key
85
+ )
86
+ }.should raise_error(ArgumentError, "Missing required option(s): 'client_name'")
87
+ end
88
+
89
+ it "raises if a value for client_key is not given" do
90
+ lambda {
91
+ subject.new(
92
+ server_url: server_url,
93
+ client_name: client_name
94
+ )
95
+ }.should raise_error(ArgumentError, "Missing required option(s): 'client_key'")
96
+ end
97
+
98
+ it "raises a ClientKeyFileNotFound if the filepath for client_key is not found" do
99
+ config[:client_key] = "/tmp/nofile.xxsa"
100
+
101
+ lambda {
102
+ subject.new(config)
103
+ }.should raise_error(Ridley::Errors::ClientKeyFileNotFound)
104
+ end
105
+
106
+ it "expands the path of the client_key" do
107
+ config[:client_key] = "~/"
108
+
109
+ subject.new(config).client_key.should_not == "~/"
110
+ end
111
+ end
112
+
113
+ describe "::open" do
114
+ it "raises a LocalJumpError if no block is given" do
115
+ lambda {
116
+ subject.open(config)
117
+ }.should raise_error(LocalJumpError)
118
+ end
119
+ end
120
+ end
121
+
122
+ subject do
123
+ described_class.new(config)
124
+ end
125
+
126
+ describe "#encrypted_data_bag_secret" do
127
+ it "returns a string" do
128
+ subject.encrypted_data_bag_secret.should be_a(String)
129
+ end
130
+
131
+ context "when a encrypted_data_bag_secret_path is not provided" do
132
+ before(:each) do
133
+ subject.stub(:encrypted_data_bag_secret_path) { nil }
134
+ end
135
+
136
+ it "returns nil" do
137
+ subject.encrypted_data_bag_secret.should be_nil
138
+ end
139
+ end
140
+
141
+ context "when the file is not found at the given encrypted_data_bag_secret_path" do
142
+ before(:each) do
143
+ subject.stub(:encrypted_data_bag_secret_path) { fixtures_path.join("not.txt").to_s }
144
+ end
145
+
146
+ it "raises an EncryptedDataBagSecretNotFound erorr" do
147
+ lambda {
148
+ subject.encrypted_data_bag_secret
149
+ }.should raise_error(Ridley::Errors::EncryptedDataBagSecretNotFound)
150
+ end
151
+ end
152
+ end
153
+ end