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