ridley 0.10.2 → 0.11.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 (85) hide show
  1. data/README.md +147 -216
  2. data/lib/ridley.rb +2 -0
  3. data/lib/ridley/bootstrap_bindings/unix_template_binding.rb +21 -25
  4. data/lib/ridley/bootstrap_bindings/windows_template_binding.rb +29 -34
  5. data/lib/ridley/bootstrapper.rb +2 -2
  6. data/lib/ridley/bootstrapper/context.rb +5 -5
  7. data/lib/ridley/chef.rb +0 -1
  8. data/lib/ridley/chef/cookbook.rb +0 -9
  9. data/lib/ridley/chef_object.rb +128 -0
  10. data/lib/ridley/chef_objects.rb +3 -0
  11. data/lib/ridley/chef_objects/client_object.rb +55 -0
  12. data/lib/ridley/chef_objects/cookbook_object.rb +190 -0
  13. data/lib/ridley/chef_objects/data_bag_item_obect.rb +104 -0
  14. data/lib/ridley/chef_objects/data_bag_object.rb +31 -0
  15. data/lib/ridley/chef_objects/environment_object.rb +59 -0
  16. data/lib/ridley/chef_objects/node_object.rb +161 -0
  17. data/lib/ridley/chef_objects/role_object.rb +62 -0
  18. data/lib/ridley/chef_objects/sandbox_object.rb +58 -0
  19. data/lib/ridley/client.rb +76 -45
  20. data/lib/ridley/connection.rb +1 -1
  21. data/lib/ridley/errors.rb +8 -1
  22. data/lib/ridley/host_connector.rb +26 -6
  23. data/lib/ridley/host_connector/ssh.rb +3 -3
  24. data/lib/ridley/host_connector/ssh/worker.rb +7 -9
  25. data/lib/ridley/host_connector/winrm/worker.rb +4 -5
  26. data/lib/ridley/mixin/bootstrap_binding.rb +1 -12
  27. data/lib/ridley/resource.rb +51 -171
  28. data/lib/ridley/resources/client_resource.rb +18 -68
  29. data/lib/ridley/resources/cookbook_resource.rb +181 -381
  30. data/lib/ridley/resources/data_bag_item_resource.rb +55 -161
  31. data/lib/ridley/resources/data_bag_resource.rb +20 -61
  32. data/lib/ridley/resources/environment_resource.rb +9 -64
  33. data/lib/ridley/resources/node_resource.rb +135 -311
  34. data/lib/ridley/resources/role_resource.rb +1 -57
  35. data/lib/ridley/resources/sandbox_resource.rb +80 -65
  36. data/lib/ridley/resources/search_resource.rb +99 -0
  37. data/lib/ridley/sandbox_uploader.rb +12 -52
  38. data/lib/ridley/version.rb +1 -1
  39. data/spec/acceptance/bootstrapping_spec.rb +1 -1
  40. data/spec/acceptance/client_resource_spec.rb +15 -37
  41. data/spec/acceptance/data_bag_item_resource_spec.rb +8 -14
  42. data/spec/acceptance/data_bag_resource_spec.rb +1 -1
  43. data/spec/acceptance/environment_resource_spec.rb +13 -22
  44. data/spec/acceptance/node_resource_spec.rb +10 -29
  45. data/spec/acceptance/role_resource_spec.rb +14 -13
  46. data/spec/acceptance/sandbox_resource_spec.rb +2 -2
  47. data/spec/support/shared_examples/ridley_resource.rb +2 -23
  48. data/spec/unit/ridley/bootstrap_bindings/unix_template_binding_spec.rb +3 -4
  49. data/spec/unit/ridley/bootstrap_bindings/windows_template_binding_spec.rb +3 -5
  50. data/spec/unit/ridley/bootstrapper/context_spec.rb +2 -3
  51. data/spec/unit/ridley/bootstrapper_spec.rb +1 -1
  52. data/spec/unit/ridley/chef_object_spec.rb +240 -0
  53. data/spec/unit/ridley/chef_objects/client_object_spec.rb +11 -0
  54. data/spec/unit/ridley/chef_objects/cookbook_object_spec.rb +93 -0
  55. data/spec/unit/ridley/chef_objects/data_bag_item_object_spec.rb +74 -0
  56. data/spec/unit/ridley/chef_objects/data_bag_object_spec.rb +9 -0
  57. data/spec/unit/ridley/chef_objects/environment_object_spec.rb +57 -0
  58. data/spec/unit/ridley/chef_objects/node_object_spec.rb +252 -0
  59. data/spec/unit/ridley/chef_objects/role_object_spec.rb +57 -0
  60. data/spec/unit/ridley/chef_objects/sandbox_object_spec.rb +66 -0
  61. data/spec/unit/ridley/client_spec.rb +51 -51
  62. data/spec/unit/ridley/host_connector/ssh/worker_spec.rb +4 -4
  63. data/spec/unit/ridley/host_connector/ssh_spec.rb +26 -24
  64. data/spec/unit/ridley/host_connector/winrm/worker_spec.rb +3 -4
  65. data/spec/unit/ridley/host_connector/winrm_spec.rb +4 -4
  66. data/spec/unit/ridley/host_connector_spec.rb +40 -3
  67. data/spec/unit/ridley/mixin/bootstrap_binding_spec.rb +1 -1
  68. data/spec/unit/ridley/resource_spec.rb +81 -109
  69. data/spec/unit/ridley/resources/client_resource_spec.rb +18 -33
  70. data/spec/unit/ridley/resources/cookbook_resource_spec.rb +56 -230
  71. data/spec/unit/ridley/resources/data_bag_item_resource_spec.rb +2 -57
  72. data/spec/unit/ridley/resources/data_bag_resource_spec.rb +12 -7
  73. data/spec/unit/ridley/resources/environment_resource_spec.rb +10 -118
  74. data/spec/unit/ridley/resources/node_resource_spec.rb +83 -394
  75. data/spec/unit/ridley/resources/role_resource_spec.rb +2 -56
  76. data/spec/unit/ridley/resources/sandbox_resource_spec.rb +139 -136
  77. data/spec/unit/ridley/resources/search_resource_spec.rb +234 -0
  78. data/spec/unit/ridley/sandbox_uploader_spec.rb +13 -58
  79. metadata +36 -17
  80. data/lib/ridley/chef/chefignore.rb +0 -76
  81. data/lib/ridley/resources/encrypted_data_bag_item_resource.rb +0 -55
  82. data/lib/ridley/resources/search.rb +0 -101
  83. data/spec/fixtures/chefignore +0 -8
  84. data/spec/unit/ridley/chef/chefignore_spec.rb +0 -40
  85. data/spec/unit/ridley/resources/search_spec.rb +0 -221
@@ -1,63 +1,7 @@
1
1
  module Ridley
2
2
  # @author Jamie Winsor <reset@riotgames.com>
3
3
  class RoleResource < Ridley::Resource
4
- set_chef_id "name"
5
- set_chef_type "role"
6
- set_chef_json_class "Chef::Role"
7
4
  set_resource_path "roles"
8
-
9
- attribute :name,
10
- required: true
11
-
12
- attribute :description,
13
- default: String.new
14
-
15
- attribute :default_attributes,
16
- default: Hashie::Mash.new
17
-
18
- attribute :override_attributes,
19
- default: Hashie::Mash.new
20
-
21
- attribute :run_list,
22
- default: Array.new
23
-
24
- attribute :env_run_lists,
25
- default: Hash.new
26
-
27
- # Set a role level override attribute given the dotted path representation of the Chef
28
- # attribute and value
29
- #
30
- # @example setting and saving a node level override attribute
31
- #
32
- # obj = node.role("why_god_why")
33
- # obj.set_override_attribute("my_app.billing.enabled", false)
34
- # obj.save
35
- #
36
- # @param [String] key
37
- # @param [Object] value
38
- #
39
- # @return [HashWithIndifferentAccess]
40
- def set_override_attribute(key, value)
41
- attr_hash = HashWithIndifferentAccess.from_dotted_path(key, value)
42
- self.override_attributes = self.override_attributes.deep_merge(attr_hash)
43
- end
44
-
45
- # Set a role level default attribute given the dotted path representation of the Chef
46
- # attribute and value
47
- #
48
- # @example setting and saving a node level default attribute
49
- #
50
- # obj = node.role("why_god_why")
51
- # obj.set_default_attribute("my_app.billing.enabled", false)
52
- # obj.save
53
- #
54
- # @param [String] key
55
- # @param [Object] value
56
- #
57
- # @return [HashWithIndifferentAccess]
58
- def set_default_attribute(key, value)
59
- attr_hash = HashWithIndifferentAccess.from_dotted_path(key, value)
60
- self.default_attributes = self.default_attributes.deep_merge(attr_hash)
61
- end
5
+ represented_by Ridley::RoleObject
62
6
  end
63
7
  end
@@ -1,86 +1,101 @@
1
1
  module Ridley
2
2
  # @author Jamie Winsor <reset@riotgames.com>
3
- class SandboxResource
4
- class << self
5
- # Create a new Sandbox on the client's Chef Server. A Sandbox requires an
6
- # array of file checksums which lets the Chef Server know what the signature
7
- # of the contents to be uploaded will look like.
8
- #
9
- # @param [Ridley::Client] client
10
- # @param [Array] checksums
11
- # a hash of file checksums
12
- #
13
- # @example using the Ridley client to create a sandbox
14
- # client.sandbox.create([
15
- # "385ea5490c86570c7de71070bce9384a",
16
- # "f6f73175e979bd90af6184ec277f760c",
17
- # "2e03dd7e5b2e6c8eab1cf41ac61396d5"
18
- # ])
19
- #
20
- # @return [Array<Ridley::SandboxResource>]
21
- def create(client, checksums = [])
22
- sumhash = { checksums: Hash.new }.tap do |chks|
23
- Array(checksums).each { |chk| chks[:checksums][chk] = nil }
24
- end
3
+ class SandboxResource < Ridley::Resource
4
+ set_resource_path "sandboxes"
5
+ represented_by Ridley::SandboxObject
25
6
 
26
- new(client, client.connection.post("sandboxes", MultiJson.encode(sumhash)).body)
27
- end
7
+ finalizer do
8
+ uploader.terminate if uploader && uploader.alive?
28
9
  end
29
10
 
30
- include Chozo::VariaModel
31
-
32
- attribute :sandbox_id,
33
- type: String
34
-
35
- attribute :uri,
36
- type: String
37
-
38
- attribute :checksums,
39
- type: Hash
40
-
41
- attribute :is_completed,
42
- type: Boolean,
43
- default: false
44
-
45
- attr_reader :client
11
+ def initialize(connection_registry, client_name, client_key, options = {})
12
+ super(connection_registry)
13
+ options = options.reverse_merge(pool_size: 4)
14
+ @uploader = SandboxUploader.pool(size: options[:pool_size], args: [ client_name, client_key, options ])
15
+ end
46
16
 
17
+ # Create a new Sandbox on the client's Chef Server. A Sandbox requires an
18
+ # array of file checksums which lets the Chef Server know what the signature
19
+ # of the contents to be uploaded will look like.
20
+ #
47
21
  # @param [Ridley::Client] client
48
- # @param [Hash] new_attrs
49
- def initialize(client, new_attrs = {})
50
- @client = client
51
- mass_assign(new_attrs)
22
+ # @param [Array] checksums
23
+ # a hash of file checksums
24
+ #
25
+ # @example using the Ridley client to create a sandbox
26
+ # client.sandbox.create([
27
+ # "385ea5490c86570c7de71070bce9384a",
28
+ # "f6f73175e979bd90af6184ec277f760c",
29
+ # "2e03dd7e5b2e6c8eab1cf41ac61396d5"
30
+ # ])
31
+ #
32
+ # @return [Array<Ridley::SandboxResource>]
33
+ def create(checksums = [])
34
+ sumhash = { checksums: Hash.new }.tap do |chks|
35
+ Array(checksums).each { |chk| chks[:checksums][chk] = nil }
36
+ end
37
+ new(connection.post(self.class.resource_path, MultiJson.encode(sumhash)).body)
52
38
  end
53
39
 
54
- # Return information about the given checksum
55
- #
56
- # @example
57
- # sandbox.checksum("e5a0f6b48d0712382295ff30bec1f9cc") => {
58
- # needs_upload: true,
59
- # url: "https://s3.amazonaws.com/opscode-platform-production-data/organization"
60
- # }
40
+ # @param [#chef_id] object
61
41
  #
62
- # @param [#to_sym] chk_id
63
- # checksum to retrieve information about
42
+ # @raise [Ridley::Errors::SandboxCommitError]
43
+ # @raise [Ridley::Errors::ResourceNotFound]
44
+ # @raise [Ridley::Errors::PermissionDenied]
64
45
  #
65
46
  # @return [Hash]
66
- # a hash containing the checksum information
67
- def checksum(chk_id)
68
- checksums[chk_id.to_sym]
47
+ def commit(object)
48
+ chef_id = object.respond_to?(:chef_id) ? object.chef_id : object
49
+ connection.put("#{self.class.resource_path}/#{chef_id}", MultiJson.encode(is_completed: true)).body
50
+ rescue Ridley::Errors::HTTPBadRequest => ex
51
+ abort Ridley::Errors::SandboxCommitError.new(ex.message)
52
+ rescue Ridley::Errors::HTTPNotFound => ex
53
+ abort Ridley::Errors::ResourceNotFound.new(ex.message)
54
+ rescue Ridley::Errors::HTTPUnauthorized, Ridley::Errors::HTTPForbidden => ex
55
+ abort Ridley::Errors::PermissionDenied.new(ex.message)
69
56
  end
70
57
 
71
- # Concurrently upload all of this sandboxes files into the checksum containers of the sandbox
72
- def upload(checksums)
73
- SandboxUploader.upload(self, checksums)
58
+ # Concurrently upload all of the files in the given sandbox
59
+ #
60
+ # @param [Ridley::SandboxObject] sandbox
61
+ # @param [Hash] checksums
62
+ # a hash of file checksums and file paths
63
+ #
64
+ # @example
65
+ # SandboxUploader.upload(sandbox,
66
+ # "e5a0f6b48d0712382295ff30bec1f9cc" => "/Users/reset/code/rbenv-cookbook/recipes/default.rb",
67
+ # "de6532a7fbe717d52020dc9f3ae47dbe" => "/Users/reset/code/rbenv-cookbook/recipes/ohai_plugin.rb"
68
+ # )
69
+ #
70
+ # @return [Array<Hash>]
71
+ def upload(object, checksums)
72
+ checksums.collect do |chk_id, path|
73
+ uploader.future(:upload, object, chk_id, path)
74
+ end.map(&:value)
75
+ end
76
+
77
+ def update(*args)
78
+ raise RuntimeError, "action not supported"
74
79
  end
75
80
 
76
- # Notify the Chef Server that uploading to this sandbox has completed
77
- def commit
78
- response = client.connection.put("sandboxes/#{sandbox_id}", MultiJson.encode(is_completed: true)).body
79
- set_attribute(:is_completed, response[:is_completed])
81
+ def all(*args)
82
+ raise RuntimeError, "action not supported"
80
83
  end
81
84
 
82
- def to_s
83
- "#{sandbox_id}: #{checksums}"
85
+ def find(*args)
86
+ raise RuntimeError, "action not supported"
84
87
  end
88
+
89
+ def delete(*args)
90
+ raise RuntimeError, "action not supported"
91
+ end
92
+
93
+ def delete_all(*args)
94
+ raise RuntimeError, "action not supported"
95
+ end
96
+
97
+ private
98
+
99
+ attr_reader :uploader
85
100
  end
86
101
  end
@@ -0,0 +1,99 @@
1
+ module Ridley
2
+ # @author Jamie Winsor <reset@riotgames.com>
3
+ class SearchResource < Ridley::Resource
4
+ class << self
5
+ # @param [String] query_string
6
+ #
7
+ # @option options [String] :sort
8
+ # a sort string such as 'name DESC'
9
+ # @option options [Integer] :rows
10
+ # how many rows to return
11
+ # @option options [Integer] :start
12
+ # the result number to start from
13
+ #
14
+ # @return [Hash]
15
+ def build_query(query_string, options = {})
16
+ {}.tap do |query_opts|
17
+ query_opts[:q] = query_string unless query_string.nil?
18
+ query_opts[:sort] = options[:sort] unless options[:sort].nil?
19
+ query_opts[:rows] = options[:rows] unless options[:rows].nil?
20
+ query_opts[:start] = options[:start] unless options[:start].nil?
21
+ end
22
+ end
23
+
24
+ # @param [#to_s] index
25
+ #
26
+ # @return [String]
27
+ def query_uri(index)
28
+ "#{resource_path}/#{index}"
29
+ end
30
+ end
31
+
32
+ set_resource_path "search"
33
+
34
+ # Returns an array of possible search indexes to be search on
35
+ #
36
+ # @param [Ridley::Client] client
37
+ #
38
+ # @example
39
+ #
40
+ # Search.indexes(client) => [ :client, :environment, :node, :role ]
41
+ #
42
+ # @return [Array<String, Symbol>]
43
+ def indexes
44
+ connection.get(self.class.resource_path).body.collect { |name, _| name }
45
+ end
46
+
47
+ # Executes the built up query on the search's client
48
+ #
49
+ # @param [#to_sym, #to_s] index
50
+ # @param [#to_s] query_string
51
+ #
52
+ # @option options [String] :sort
53
+ # a sort string such as 'name DESC'
54
+ # @option options [Integer] :rows
55
+ # how many rows to return
56
+ # @option options [Integer] :start
57
+ # the result number to start from
58
+ #
59
+ # @example
60
+ # Search.new(client, :role)
61
+ # search.run =>
62
+ # {
63
+ # total: 1,
64
+ # start: 0,
65
+ # rows: [
66
+ # {
67
+ # name: "ridley-test-role",
68
+ # default_attributes: {},
69
+ # json_class: "Chef::Role",
70
+ # env_run_lists: {},
71
+ # run_list: [],
72
+ # description: "a test role for Ridley!",
73
+ # chef_type: "role",
74
+ # override_attributes: {}
75
+ # }
76
+ # ]
77
+ # }
78
+ #
79
+ # @return [Array<ChefObject>, Hash]
80
+ def run(index, query_string, options = {})
81
+ query_uri = self.class.query_uri(index)
82
+ query = self.class.build_query(query_string, options)
83
+ response = connection.get(query_uri, query).body
84
+
85
+ case index.to_sym
86
+ when :node
87
+ response[:rows].collect { |row| Ridley::NodeObject.new(row) }
88
+ when :role
89
+ response[:rows].collect { |row| Ridley::RoleObject.new(row) }
90
+ when :client
91
+ response[:rows].collect { |row| Ridley::ClientObject.new(row) }
92
+ when :environment
93
+ response[:rows].collect { |row| Ridley::EnvironmentObject.new(row) }
94
+ else
95
+ response[:rows]
96
+ end
97
+ end
98
+ end
99
+ end
@@ -3,24 +3,6 @@ module Ridley
3
3
  # @api private
4
4
  class SandboxUploader
5
5
  class << self
6
- # Concurrently upload all of the files in the given sandbox and then clean up
7
- # after ourselves
8
- #
9
- # @param [Ridley::SandboxResource] sandbox
10
- # @param [Hash] checksums
11
- #
12
- # @option options [Integer] :pool_size (12)
13
- # the amount of concurrent uploads to perform
14
- def upload(sandbox, checksums, options = {})
15
- options = options.reverse_merge(
16
- pool_size: 12
17
- )
18
- uploader = pool(size: options[:pool_size], args: [sandbox])
19
- uploader.multi_upload(checksums)
20
- ensure
21
- uploader.terminate if uploader && uploader.alive?
22
- end
23
-
24
6
  # Return the checksum of the contents of the file at the given filepath
25
7
  #
26
8
  # @param [String] path
@@ -55,45 +37,29 @@ module Ridley
55
37
  end
56
38
  end
57
39
 
58
- extend Forwardable
59
40
  include Celluloid
60
41
 
61
- attr_reader :sandbox
62
-
63
- def_delegator :sandbox, :client
64
- def_delegator :sandbox, :checksum
65
-
66
- def initialize(sandbox)
67
- @sandbox = sandbox
68
- end
42
+ attr_reader :client_name
43
+ attr_reader :client_key
44
+ attr_reader :options
69
45
 
70
- # Concurrently upload multiple files into a sandbox
71
- #
72
- # @param [Hash] checksums
73
- # a hash of file checksums and file paths
74
- #
75
- # @example uploading multiple checksums
76
- #
77
- # sandbox.multi_upload(
78
- # "e5a0f6b48d0712382295ff30bec1f9cc" => "/Users/reset/code/rbenv-cookbook/recipes/default.rb",
79
- # "de6532a7fbe717d52020dc9f3ae47dbe" => "/Users/reset/code/rbenv-cookbook/recipes/ohai_plugin.rb"
80
- # )
81
- def multi_upload(checksums)
82
- checksums.collect do |chk_id, path|
83
- future.upload(chk_id, path)
84
- end.map(&:value)
46
+ def initialize(client_name, client_key, options = {})
47
+ @client_name = client_name
48
+ @client_key = client_key
49
+ @options = options
85
50
  end
86
51
 
87
52
  # Upload one file into the sandbox for the given checksum id
88
53
  #
54
+ # @param [Ridley::SandboxObject] sandbox
89
55
  # @param [String] chk_id
90
56
  # checksum of the file being uploaded
91
57
  # @param [String] path
92
58
  # path to the file to upload
93
59
  #
94
60
  # @return [Hash, nil]
95
- def upload(chk_id, path)
96
- checksum = self.checksum(chk_id)
61
+ def upload(sandbox, chk_id, path)
62
+ checksum = sandbox.checksum(chk_id)
97
63
 
98
64
  unless checksum[:needs_upload]
99
65
  return nil
@@ -109,17 +75,11 @@ module Ridley
109
75
  upload_path = url.path
110
76
  url.path = ""
111
77
 
112
- # versions prior to OSS Chef 11 will strip the port to upload the file to in the checksum
113
- # url returned. This will ensure we are uploading to the proper location.
114
- if client.connection.foss?
115
- url.port = URI(client.connection.server_url).port
116
- end
117
-
118
78
  begin
119
- Faraday.new(url, client.options.slice(*Connection::VALID_OPTIONS)) do |c|
79
+ Faraday.new(url, self.options) do |c|
120
80
  c.response :chef_response
121
81
  c.response :follow_redirects
122
- c.request :chef_auth, client.client_name, client.client_key
82
+ c.request :chef_auth, self.client_name, self.client_key
123
83
  c.adapter :net_http
124
84
  end.put(upload_path, contents, headers)
125
85
  rescue Ridley::Errors::HTTPError => ex
@@ -1,3 +1,3 @@
1
1
  module Ridley
2
- VERSION = "0.10.2"
2
+ VERSION = "0.11.0.rc1"
3
3
  end
@@ -23,7 +23,7 @@ describe "Bootstrapping a node", type: "acceptance" do
23
23
 
24
24
  it "returns an array of response objects" do
25
25
  pending
26
-
26
+
27
27
  connection.node.bootstrap("33.33.33.10").should_not have_errors
28
28
  end
29
29
  end