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
@@ -0,0 +1,121 @@
1
+ module Ridley
2
+ # @author Jamie Winsor <jamie@vialstudios.com>
3
+ class CookbookResource < Ridley::Resource
4
+ class << self
5
+ def create(*args)
6
+ raise NotImplementedError
7
+ end
8
+
9
+ def delete(*args)
10
+ raise NotImplementedError
11
+ end
12
+
13
+ def delete_all(*args)
14
+ raise NotImplementedError
15
+ end
16
+
17
+ # @param [Ridley::Client] client
18
+ # @param [String, #chef_id] object
19
+ # @param [String] version
20
+ #
21
+ # @return [nil, CookbookResource]
22
+ def find(client, object, version = nil)
23
+ find!(client, object, version)
24
+ rescue Errors::HTTPNotFound
25
+ nil
26
+ end
27
+
28
+ # @param [Ridley::Client] client
29
+ # @param [String, #chef_id] object
30
+ # @param [String] version
31
+ #
32
+ # @raise [Errors::HTTPNotFound]
33
+ # if a resource with the given chef_id is not found
34
+ #
35
+ # @return [CookbookResource]
36
+ def find!(client, object, version = nil)
37
+ chef_id = object.respond_to?(:chef_id) ? object.chef_id : object
38
+ fetch_uri = "#{self.resource_path}/#{chef_id}"
39
+
40
+ unless version.nil?
41
+ fetch_uri = File.join(fetch_uri, version)
42
+ end
43
+
44
+ new(client, client.connection.get(fetch_uri).body)
45
+ end
46
+
47
+ # Save a new Cookbook Version of the given name, version with the
48
+ # given manifest of files and checksums.
49
+ #
50
+ # @param [Ridley::Client] client
51
+ # @param [String] name
52
+ # @param [String] version
53
+ # @param [String] manifest
54
+ # a JSON blob containing file names, file paths, and checksums for each
55
+ # that describe the cookbook version being uploaded.
56
+ #
57
+ # @option options [Boolean] :freeze
58
+ # @option options [Boolean] :force
59
+ #
60
+ # @return [Hash]
61
+ def save(client, name, version, manifest, options = {})
62
+ freeze = options.fetch(:freeze, false)
63
+ force = options.fetch(:force, false)
64
+
65
+ url = "cookbooks/#{name}/#{version}"
66
+ url << "?force=true" if force
67
+
68
+ client.connection.put(url, manifest)
69
+ end
70
+
71
+ def update(*args)
72
+ raise NotImplementedError
73
+ end
74
+ end
75
+
76
+ set_chef_id "name"
77
+ set_chef_type "cookbook"
78
+ set_chef_json_class "Chef::Cookbook"
79
+ set_resource_path "cookbooks"
80
+
81
+ attribute :name,
82
+ required: true
83
+
84
+ # Broken until resolved: https://github.com/reset/chozo/issues/17
85
+ # attribute :attributes,
86
+ # type: Array
87
+
88
+ attribute :cookbook_name,
89
+ type: String
90
+
91
+ attribute :definitions,
92
+ type: Array
93
+
94
+ attribute :files,
95
+ type: Array
96
+
97
+ attribute :libraries,
98
+ type: Array
99
+
100
+ attribute :metadata,
101
+ type: Hashie::Mash
102
+
103
+ attribute :providers,
104
+ type: Array
105
+
106
+ attribute :recipes,
107
+ type: Array
108
+
109
+ attribute :resources,
110
+ type: Array
111
+
112
+ attribute :root_files,
113
+ type: Array
114
+
115
+ attribute :templates,
116
+ type: Array
117
+
118
+ attribute :version,
119
+ type: String
120
+ end
121
+ end
@@ -1,114 +1,108 @@
1
1
  module Ridley
2
2
  # @author Jamie Winsor <jamie@vialstudios.com>
3
- class DataBagItem < Ridley::Resource
3
+ class DataBagItemResource < Ridley::Resource
4
4
  class << self
5
- # @param [Ridley::Connection] connection
5
+ # @param [Ridley::Client] client
6
6
  #
7
7
  # @return [Array<Object>]
8
- def all(connection, data_bag)
9
- connection.get("#{data_bag.class.resource_path}/#{data_bag.name}").body.collect do |id, location|
10
- new(connection, data_bag, id: id)
8
+ def all(client, data_bag)
9
+ client.connection.get("#{data_bag.class.resource_path}/#{data_bag.name}").body.collect do |id, location|
10
+ new(client, data_bag, id: id)
11
11
  end
12
12
  end
13
13
 
14
- # @param [Ridley::Connection] connection
15
- # @param [Ridley::DataBag] data_bag
14
+ # @param [Ridley::Client] client
15
+ # @param [Ridley::DataBagResource] data_bag
16
16
  # @param [String, #chef_id] object
17
17
  #
18
- # @return [nil, Ridley::DataBagItem]
19
- def find(connection, data_bag, object)
20
- find!(connection, data_bag, object)
18
+ # @return [nil, Ridley::DataBagItemResource]
19
+ def find(client, data_bag, object)
20
+ find!(client, data_bag, object)
21
21
  rescue Errors::HTTPNotFound
22
22
  nil
23
23
  end
24
24
 
25
- # @param [Ridley::Connection] connection
26
- # @param [Ridley::DataBag] data_bag
25
+ # @param [Ridley::Client] client
26
+ # @param [Ridley::DataBagResource] data_bag
27
27
  # @param [String, #chef_id] object
28
28
  #
29
29
  # @raise [Errors::HTTPNotFound]
30
30
  # if a resource with the given chef_id is not found
31
31
  #
32
- # @return [Ridley::DataBagItem]
33
- def find!(connection, data_bag, object)
32
+ # @return [Ridley::DataBagItemResource]
33
+ def find!(client, data_bag, object)
34
34
  chef_id = object.respond_to?(:chef_id) ? object.chef_id : object
35
- new(connection, data_bag).from_hash(connection.get("#{data_bag.class.resource_path}/#{data_bag.name}/#{chef_id}").body)
35
+ new(client, data_bag).from_hash(client.connection.get("#{data_bag.class.resource_path}/#{data_bag.name}/#{chef_id}").body)
36
36
  end
37
37
 
38
- # @param [Ridley::Connection] connection
39
- # @param [Ridley::DataBag] data_bag
38
+ # @param [Ridley::Client] client
39
+ # @param [Ridley::DataBagResource] data_bag
40
40
  # @param [#to_hash] object
41
41
  #
42
- # @return [Ridley::DataBagItem]
43
- def create(connection, data_bag, object)
44
- resource = new(connection, data_bag, object.to_hash)
42
+ # @return [Ridley::DataBagItemResource]
43
+ def create(client, data_bag, object)
44
+ resource = new(client, data_bag, object.to_hash)
45
45
  unless resource.valid?
46
46
  raise Errors::InvalidResource.new(resource.errors)
47
47
  end
48
48
 
49
- new_attributes = connection.post("#{data_bag.class.resource_path}/#{data_bag.name}", resource.to_json).body
49
+ new_attributes = client.connection.post("#{data_bag.class.resource_path}/#{data_bag.name}", resource.to_json).body
50
50
  resource.from_hash(resource.attributes.deep_merge(new_attributes))
51
51
  resource
52
52
  end
53
53
 
54
- # @param [Ridley::Connection] connection
55
- # @param [Ridley::DataBag] data_bag
54
+ # @param [Ridley::Client] client
55
+ # @param [Ridley::DataBagResource] data_bag
56
56
  # @param [String, #chef_id] object
57
57
  #
58
- # @return [Ridley::DataBagItem]
59
- def delete(connection, data_bag, object)
58
+ # @return [Ridley::DataBagItemResource]
59
+ def delete(client, data_bag, object)
60
60
  chef_id = object.respond_to?(:chef_id) ? object.chef_id : object
61
- new(connection, data_bag).from_hash(connection.delete("#{data_bag.class.resource_path}/#{data_bag.name}/#{chef_id}").body)
61
+ new(client, data_bag).from_hash(client.connection.delete("#{data_bag.class.resource_path}/#{data_bag.name}/#{chef_id}").body)
62
62
  end
63
63
 
64
- # @param [Ridley::Connection] connection
65
- # @param [Ridley::DataBag] data_bag
64
+ # @param [Ridley::Client] client
65
+ # @param [Ridley::DataBagResource] data_bag
66
66
  #
67
- # @return [Array<Ridley::DataBagItem>]
68
- def delete_all(connection, data_bag)
67
+ # @return [Array<Ridley::DataBagItemResource>]
68
+ def delete_all(client, data_bag)
69
69
  mutex = Mutex.new
70
70
  deleted = []
71
- resources = all(connection, data_bag)
72
-
73
- connection.thread_count.times.collect do
74
- Thread.new(connection, data_bag, resources, deleted) do |connection, data_bag, resources, deleted|
75
- while resource = mutex.synchronize { resources.pop }
76
- result = delete(connection, data_bag, resource)
77
- mutex.synchronize { deleted << result }
78
- end
79
- end
80
- end.each(&:join)
81
-
82
- deleted
71
+
72
+ all(client, data_bag).collect do |resource|
73
+ Celluloid::Future.new {
74
+ delete(client, data_bag, resource)
75
+ }
76
+ end.map(&:value)
83
77
  end
84
78
 
85
- # @param [Ridley::Connection] connection
86
- # @param [Ridley::DataBag] data_bag
79
+ # @param [Ridley::Client] client
80
+ # @param [Ridley::DataBagResource] data_bag
87
81
  # @param [#to_hash] object
88
82
  #
89
- # @return [Ridley::DataBagItem]
90
- def update(connection, data_bag, object)
91
- resource = new(connection, data_bag, object.to_hash)
92
- new(connection, data_bag).from_hash(
93
- connection.put("#{data_bag.class.resource_path}/#{data_bag.name}/#{resource.chef_id}", resource.to_json).body
83
+ # @return [Ridley::DataBagItemResource]
84
+ def update(client, data_bag, object)
85
+ resource = new(client, data_bag, object.to_hash)
86
+ new(client, data_bag).from_hash(
87
+ client.connection.put("#{data_bag.class.resource_path}/#{data_bag.name}/#{resource.chef_id}", resource.to_json).body
94
88
  )
95
89
  end
96
90
  end
97
91
 
98
92
  set_assignment_mode :carefree
99
93
 
100
- # @return [Ridley::DataBag]
94
+ # @return [Ridley::DataBagResource]
101
95
  attr_reader :data_bag
102
96
 
103
97
  attribute :id,
104
98
  type: String,
105
99
  required: true
106
100
 
107
- # @param [Ridley::Connection] connection
108
- # @param [Ridley::DataBag] data_bag
101
+ # @param [Ridley::Client] client
102
+ # @param [Ridley::DataBagResource] data_bag
109
103
  # @param [#to_hash] new_attrs
110
- def initialize(connection, data_bag, new_attrs = {})
111
- super(connection, new_attrs)
104
+ def initialize(client, data_bag, new_attrs = {})
105
+ super(client, new_attrs)
112
106
  @data_bag = data_bag
113
107
  end
114
108
 
@@ -130,7 +124,7 @@ module Ridley
130
124
  def save
131
125
  raise Errors::InvalidResource.new(self.errors) unless valid?
132
126
 
133
- mass_assign(self.class.create(connection, data_bag, self).attributes)
127
+ mass_assign(self.class.create(client, data_bag, self).attributes)
134
128
  true
135
129
  rescue Errors::HTTPConflict
136
130
  self.update
@@ -150,7 +144,7 @@ module Ridley
150
144
 
151
145
  cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
152
146
  cipher.decrypt
153
- cipher.pkcs5_keyivgen(connection.encrypted_data_bag_secret)
147
+ cipher.pkcs5_keyivgen(client.encrypted_data_bag_secret)
154
148
  decrypted_value = cipher.update(decoded_value) + cipher.final
155
149
 
156
150
  YAML.load(decrypted_value)
@@ -160,7 +154,7 @@ module Ridley
160
154
  #
161
155
  # @return [Object]
162
156
  def reload
163
- mass_assign(self.class.find(connection, data_bag, self).attributes)
157
+ mass_assign(self.class.find(client, data_bag, self).attributes)
164
158
  self
165
159
  end
166
160
 
@@ -174,7 +168,7 @@ module Ridley
174
168
  def update
175
169
  raise Errors::InvalidResource.new(self.errors) unless valid?
176
170
 
177
- mass_assign(sself.class.update(connection, data_bag, self).attributes)
171
+ mass_assign(sself.class.update(client, data_bag, self).attributes)
178
172
  true
179
173
  end
180
174
 
@@ -191,10 +185,5 @@ module Ridley
191
185
  def to_s
192
186
  self.attributes
193
187
  end
194
-
195
- private
196
-
197
- # @return [Ridley::Connection]
198
- attr_reader :connection
199
188
  end
200
189
  end
@@ -0,0 +1,74 @@
1
+ require 'ridley/resources/data_bag_item_resource'
2
+ require 'ridley/resources/encrypted_data_bag_item_resource'
3
+
4
+ module Ridley
5
+ # @author Jamie Winsor <jamie@vialstudios.com>
6
+ # @api private
7
+ class DBIChainLink
8
+ attr_reader :data_bag
9
+ attr_reader :client
10
+ attr_reader :klass
11
+
12
+ # @param [Ridley::DataBagResource] data_bag
13
+ # @param [Ridley::Client] client
14
+ #
15
+ # @option options [Boolean] :encrypted (false)
16
+ def initialize(data_bag, client, options = {})
17
+ options[:encrypted] ||= false
18
+
19
+ @data_bag = data_bag
20
+ @client = client
21
+ @klass = options[:encrypted] ? Ridley::EncryptedDataBagItemResource : Ridley::DataBagItemResource
22
+ end
23
+
24
+ def new(*args)
25
+ klass.send(:new, client, data_bag, *args)
26
+ end
27
+
28
+ def method_missing(fun, *args, &block)
29
+ klass.send(fun, client, data_bag, *args, &block)
30
+ end
31
+ end
32
+
33
+ # @author Jamie Winsor <jamie@vialstudios.com>
34
+ class DataBagResource < Ridley::Resource
35
+ class << self
36
+ # @param [Ridley::Client] client
37
+ # @param [String, #chef_id] object
38
+ #
39
+ # @return [nil, Ridley::DataBagResource]
40
+ def find(client, object)
41
+ find!(client, object)
42
+ rescue Errors::HTTPNotFound
43
+ nil
44
+ end
45
+
46
+ # @param [Ridley::Client] client
47
+ # @param [String, #chef_id] object
48
+ #
49
+ # @raise [Errors::HTTPNotFound]
50
+ # if a resource with the given chef_id is not found
51
+ #
52
+ # @return [Ridley::DataBagResource]
53
+ def find!(client, object)
54
+ chef_id = object.respond_to?(:chef_id) ? object.chef_id : object
55
+ client.connection.get("#{self.resource_path}/#{chef_id}")
56
+ new(client, name: chef_id)
57
+ end
58
+ end
59
+
60
+ set_chef_id "name"
61
+ set_resource_path "data"
62
+
63
+ attribute :name,
64
+ required: true
65
+
66
+ def item
67
+ DBIChainLink.new(self, client)
68
+ end
69
+
70
+ def encrypted_item
71
+ DBIChainLink.new(self, client, encrypted: true)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,55 @@
1
+ module Ridley
2
+ # @author Jamie Winsor <jamie@vialstudios.com>
3
+ class EncryptedDataBagItemResource
4
+ class << self
5
+ # Finds a data bag item and decrypts it.
6
+ #
7
+ # @param [Ridley::Client] client
8
+ # @param [Ridley::DataBagResource] data_bag
9
+ # @param [String, #chef_id] object
10
+ #
11
+ # @return [nil, Ridley::DataBagItemResource]
12
+ def find(client, data_bag, object)
13
+ find!(client, data_bag, object)
14
+ rescue Errors::HTTPNotFound
15
+ nil
16
+ end
17
+
18
+ # Finds a data bag item and decrypts it. Throws an exception if the item doesn't exist.
19
+ #
20
+ # @param [Ridley::Client] client
21
+ # @param [Ridley::DataBagResource] data_bag
22
+ # @param [String, #chef_id] object
23
+ #
24
+ # @raise [Errors::HTTPNotFound]
25
+ # if a resource with the given chef_id is not found
26
+ #
27
+ # @return [nil, Ridley::DataBagItemResource]
28
+ def find!(client, data_bag, object)
29
+ data_bag_item = DataBagItem.find!(client, data_bag, object)
30
+ data_bag_item.decrypt
31
+ new(client, data_bag, data_bag_item.attributes)
32
+ end
33
+ end
34
+
35
+ attr_reader :data_bag
36
+ attr_reader :attributes
37
+
38
+ # @param [Ridley::Client] client
39
+ # @param [Ridley::DataBagResource] data_bag
40
+ # @param [#to_hash] attributes
41
+ def initialize(client, data_bag, attributes = {})
42
+ @client = client
43
+ @data_bag = data_bag
44
+ @attributes = attributes
45
+ end
46
+
47
+ def to_s
48
+ self.attributes
49
+ end
50
+
51
+ private
52
+
53
+ attr_reader :client
54
+ end
55
+ end