ridley 0.7.0.beta → 0.7.0.rc1

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 (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