chef-api 0.9.0 → 0.10.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef-api.rb +19 -20
  3. data/lib/chef-api/aclable.rb +35 -0
  4. data/lib/chef-api/authentication.rb +23 -25
  5. data/lib/chef-api/configurable.rb +14 -14
  6. data/lib/chef-api/connection.rb +69 -68
  7. data/lib/chef-api/defaults.rb +25 -24
  8. data/lib/chef-api/error_collection.rb +1 -1
  9. data/lib/chef-api/errors.rb +3 -3
  10. data/lib/chef-api/log.rb +7 -0
  11. data/lib/chef-api/multipart.rb +17 -17
  12. data/lib/chef-api/resource.rb +17 -15
  13. data/lib/chef-api/resources/base.rb +25 -23
  14. data/lib/chef-api/resources/client.rb +5 -3
  15. data/lib/chef-api/resources/collection_proxy.rb +4 -3
  16. data/lib/chef-api/resources/cookbook.rb +2 -2
  17. data/lib/chef-api/resources/cookbook_version.rb +1 -1
  18. data/lib/chef-api/resources/data_bag.rb +4 -4
  19. data/lib/chef-api/resources/data_bag_item.rb +2 -3
  20. data/lib/chef-api/resources/environment.rb +1 -1
  21. data/lib/chef-api/resources/group.rb +15 -0
  22. data/lib/chef-api/resources/node.rb +11 -8
  23. data/lib/chef-api/resources/organization.rb +2 -2
  24. data/lib/chef-api/resources/partial_search.rb +4 -4
  25. data/lib/chef-api/resources/principal.rb +1 -1
  26. data/lib/chef-api/resources/role.rb +2 -1
  27. data/lib/chef-api/resources/search.rb +6 -6
  28. data/lib/chef-api/resources/user.rb +5 -3
  29. data/lib/chef-api/util.rb +8 -8
  30. data/lib/chef-api/validator.rb +3 -3
  31. data/lib/chef-api/validators/base.rb +3 -3
  32. data/lib/chef-api/validators/required.rb +1 -1
  33. data/lib/chef-api/validators/type.rb +1 -1
  34. data/lib/chef-api/version.rb +1 -1
  35. data/templates/errors/abstract_method.erb +5 -0
  36. data/templates/errors/cannot_regenerate_key.erb +1 -0
  37. data/templates/errors/chef_api_error.erb +1 -0
  38. data/templates/errors/file_not_found.erb +1 -0
  39. data/templates/errors/http_bad_request.erb +3 -0
  40. data/templates/errors/http_forbidden_request.erb +3 -0
  41. data/templates/errors/http_gateway_timeout.erb +3 -0
  42. data/templates/errors/http_method_not_allowed.erb +3 -0
  43. data/templates/errors/http_not_acceptable.erb +3 -0
  44. data/templates/errors/http_not_found.erb +3 -0
  45. data/templates/errors/http_server_unavailable.erb +1 -0
  46. data/templates/errors/http_unauthorized_request.erb +3 -0
  47. data/templates/errors/insufficient_file_permissions.erb +1 -0
  48. data/templates/errors/invalid_resource.erb +1 -0
  49. data/templates/errors/invalid_validator.erb +1 -0
  50. data/templates/errors/missing_url_parameter.erb +1 -0
  51. data/templates/errors/not_a_directory.erb +1 -0
  52. data/templates/errors/resource_already_exists.erb +1 -0
  53. data/templates/errors/resource_not_found.erb +1 -0
  54. data/templates/errors/resource_not_mutable.erb +1 -0
  55. data/templates/errors/unknown_attribute.erb +1 -0
  56. metadata +44 -13
@@ -1,6 +1,7 @@
1
1
  module ChefAPI
2
2
  class Resource::Client < Resource::Base
3
- collection_path '/clients'
3
+ include ChefAPI::AclAble
4
+ collection_path "/clients"
4
5
 
5
6
  schema do
6
7
  attribute :name, type: String, primary: true, required: true
@@ -13,7 +14,7 @@ module ChefAPI
13
14
  end
14
15
 
15
16
  # @todo implement
16
- protect 'chef-webui', 'chef-validator'
17
+ protect "chef-webui", "chef-validator"
17
18
 
18
19
  class << self
19
20
  #
@@ -48,7 +49,7 @@ module ChefAPI
48
49
  #
49
50
  def initialize(attributes = {}, prefix = {})
50
51
  if certificate = attributes.delete(:certificate) ||
51
- attributes.delete('certificate')
52
+ attributes.delete("certificate")
52
53
  x509 = OpenSSL::X509::Certificate.new(certificate)
53
54
  attributes[:public_key] = x509.public_key.to_pem
54
55
  end
@@ -76,6 +77,7 @@ module ChefAPI
76
77
  #
77
78
  def regenerate_keys
78
79
  raise Error::CannotRegenerateKey if new_resource?
80
+
79
81
  update(private_key: true).save!
80
82
  self
81
83
  end
@@ -59,6 +59,7 @@ module ChefAPI
59
59
  #
60
60
  def fetch(id)
61
61
  return nil unless exists?(id)
62
+
62
63
  cached(id) { klass.from_url(get(id), prefix) }
63
64
  end
64
65
 
@@ -76,7 +77,7 @@ module ChefAPI
76
77
  # true if the resource exists, false otherwise
77
78
  #
78
79
  def exists?(id)
79
- collection.has_key?(id.to_s)
80
+ collection.key?(id.to_s)
80
81
  end
81
82
 
82
83
  #
@@ -131,9 +132,9 @@ module ChefAPI
131
132
  def inspect
132
133
  objects = collection
133
134
  .map { |id, _| cached(id) || klass.new(klass.schema.primary_key => id) }
134
- .map { |object| object.to_s }
135
+ .map(&:to_s)
135
136
 
136
- "#<#{self.class.name} [#{objects.join(', ')}]>"
137
+ "#<#{self.class.name} [#{objects.join(", ")}]>"
137
138
  end
138
139
 
139
140
  private
@@ -5,7 +5,7 @@ module ChefAPI
5
5
  # of +cookbook_version+ objects that fully detail the layout of a cookbook.
6
6
  #
7
7
  class Resource::Cookbook < Resource::Base
8
- collection_path '/cookbooks'
8
+ collection_path "/cookbooks"
9
9
 
10
10
  schema do
11
11
  attribute :name, type: String, primary: true, required: true
@@ -13,7 +13,7 @@ module ChefAPI
13
13
 
14
14
  has_many :versions,
15
15
  class_name: CookbookVersion,
16
- rest_endpoint: '/?num_versions=all'
16
+ rest_endpoint: "/?num_versions=all"
17
17
 
18
18
  class << self
19
19
  def from_json(response, prefix = {})
@@ -1,6 +1,6 @@
1
1
  module ChefAPI
2
2
  class Resource::CookbookVersion < Resource::Base
3
- collection_path '/cookbooks/:cookbook'
3
+ collection_path "/cookbooks/:cookbook"
4
4
 
5
5
  schema do
6
6
  attribute :name, type: String, primary: true, required: true
@@ -1,6 +1,6 @@
1
1
  module ChefAPI
2
2
  class Resource::DataBag < Resource::Base
3
- collection_path '/data'
3
+ collection_path "/data"
4
4
 
5
5
  schema do
6
6
  attribute :name, type: String, primary: true, required: true
@@ -26,9 +26,9 @@ module ChefAPI
26
26
  # @return [Array<DataBagItem>]
27
27
  #
28
28
  def from_file(path, name = File.basename(path))
29
- path = File.expand_path(path)
29
+ path = File.expand_path(path)
30
30
 
31
- raise Error::FileNotFound.new(path: path) unless File.exists?(path)
31
+ raise Error::FileNotFound.new(path: path) unless File.exist?(path)
32
32
  raise Error::NotADirectory.new(path: path) unless File.directory?(path)
33
33
 
34
34
  raise ArgumentError unless File.directory?(path)
@@ -36,7 +36,7 @@ module ChefAPI
36
36
  bag = new(name: name)
37
37
 
38
38
  Util.fast_collect(Dir["#{path}/*.json"]) do |item|
39
- DataBagItem.from_file(item, bag)
39
+ Resource::DataBagItem.from_file(item, bag)
40
40
  end
41
41
  end
42
42
 
@@ -1,6 +1,6 @@
1
1
  module ChefAPI
2
2
  class Resource::DataBagItem < Resource::Base
3
- collection_path '/data/:bag'
3
+ collection_path "/data/:bag"
4
4
 
5
5
  schema do
6
6
  attribute :id, type: String, primary: true, required: true
@@ -28,11 +28,10 @@ module ChefAPI
28
28
  def initialize(attributes = {}, prefix = {}, bag = nil)
29
29
  @bag = bag || Resource::DataBag.fetch(prefix[:bag])
30
30
 
31
- id = attributes.delete(:id) || attributes.delete('id')
31
+ id = attributes.delete(:id) || attributes.delete("id")
32
32
  super({ id: id, data: attributes }, prefix)
33
33
  end
34
34
 
35
-
36
35
  #
37
36
  # Override the to_hash method to move data to the upper scope.
38
37
  #
@@ -1,6 +1,6 @@
1
1
  module ChefAPI
2
2
  class Resource::Environment < Resource::Base
3
- collection_path '/environments'
3
+ collection_path "/environments"
4
4
 
5
5
  schema do
6
6
  attribute :name, type: String, primary: true, required: true
@@ -0,0 +1,15 @@
1
+ module ChefAPI
2
+ class Resource::Group < Resource::Base
3
+ collection_path "/groups"
4
+
5
+ schema do
6
+ attribute :groupname, type: String, primary: true, required: true
7
+ attribute :name, type: String
8
+ attribute :orgname, type: String
9
+ attribute :actors, type: Array, default: []
10
+ attribute :users, type: Array, default: []
11
+ attribute :clients, type: Array, default: []
12
+ attribute :groups, type: Array, default: []
13
+ end
14
+ end
15
+ end
@@ -1,17 +1,20 @@
1
1
  module ChefAPI
2
2
  class Resource::Node < Resource::Base
3
- collection_path '/nodes'
3
+ include ChefAPI::AclAble
4
+ collection_path "/nodes"
4
5
 
5
6
  schema do
6
- attribute :name, type: String, primary: true, required: true
7
- attribute :automatic, type: Hash, default: {}
8
- attribute :default, type: Hash, default: {}
9
- attribute :normal, type: Hash, default: {}
10
- attribute :override, type: Hash, default: {}
11
- attribute :run_list, type: Array, default: []
7
+ attribute :name, type: String, primary: true, required: true
8
+ attribute :automatic, type: Hash, default: {}
9
+ attribute :default, type: Hash, default: {}
10
+ attribute :normal, type: Hash, default: {}
11
+ attribute :override, type: Hash, default: {}
12
+ attribute :run_list, type: Array, default: []
13
+ attribute :policy_name, type: String
14
+ attribute :policy_group, type: String
12
15
 
13
16
  # Enterprise Chef attributes
14
- attribute :chef_environment, type: String, default: '_default'
17
+ attribute :chef_environment, type: String, default: "_default"
15
18
  end
16
19
  end
17
20
  end
@@ -1,6 +1,6 @@
1
1
  module ChefAPI
2
2
  class Resource::Organization < Resource::Base
3
- collection_path '/organizations'
3
+ collection_path "/organizations"
4
4
 
5
5
  schema do
6
6
  attribute :name, type: String, primary: true, required: true
@@ -16,7 +16,7 @@ module ChefAPI
16
16
  ignore :billing_plan
17
17
  ignore :requester_id
18
18
  ignore :assigned_at
19
- ignore 'couchrest-type'
19
+ ignore "couchrest-type"
20
20
  end
21
21
  end
22
22
  end
@@ -1,6 +1,6 @@
1
1
  module ChefAPI
2
2
  class Resource::PartialSearch < Resource::Base
3
- collection_path '/search/:index'
3
+ collection_path "/search/:index"
4
4
 
5
5
  schema do
6
6
  attribute :total, type: Integer
@@ -24,19 +24,19 @@ module ChefAPI
24
24
  # @return [self]
25
25
  # the current resource
26
26
  #
27
- def query(index, keys, query = '*:*', options = {})
27
+ def query(index, keys, query = "*:*", options = {})
28
28
  return nil if index.nil?
29
29
 
30
30
  params = {}.tap do |o|
31
31
  o[:q] = query
32
32
  o[:rows] = options[:rows] || 1000
33
- o[:sort] = options[:sort] || 'X_CHEF_id_CHEF_X'
33
+ o[:sort] = options[:sort] || "X_CHEF_id_CHEF_X"
34
34
  o[:start] = options[:start] || 0
35
35
  end
36
36
 
37
37
  path = expanded_collection_path(index: index.to_s)
38
38
  response = connection.post(path, keys.to_json, params)
39
- response['rows'].map! { |row| row['data'] }
39
+ response["rows"].map! { |row| row["data"] }
40
40
  from_json(response, index: index.to_s)
41
41
  end
42
42
  end
@@ -1,6 +1,6 @@
1
1
  module ChefAPI
2
2
  class Resource::Principal < Resource::Base
3
- collection_path '/principals'
3
+ collection_path "/principals"
4
4
 
5
5
  schema do
6
6
  attribute :name, type: String, primary: true, required: true
@@ -1,6 +1,7 @@
1
1
  module ChefAPI
2
2
  class Resource::Role < Resource::Base
3
- collection_path '/roles'
3
+ include ChefAPI::AclAble
4
+ collection_path "/roles"
4
5
 
5
6
  schema do
6
7
  attribute :name, type: String, primary: true, required: true
@@ -1,6 +1,6 @@
1
1
  module ChefAPI
2
2
  class Resource::Search < Resource::Base
3
- collection_path '/search/:index'
3
+ collection_path "/search/:index"
4
4
 
5
5
  schema do
6
6
  attribute :total, type: Integer
@@ -22,22 +22,22 @@ module ChefAPI
22
22
  # @return [self]
23
23
  # the current resource
24
24
  #
25
- def query(index, query = '*:*', options = {})
25
+ def query(index, query = "*:*", options = {})
26
26
  return nil if index.nil?
27
27
 
28
28
  params = {}.tap do |o|
29
29
  o[:q] = query
30
30
  o[:rows] = options[:rows] || 1000
31
- o[:sort] = options[:sort] || 'X_CHEF_id_CHEF_X'
31
+ o[:sort] = options[:sort] || "X_CHEF_id_CHEF_X"
32
32
  o[:start] = options[:start] || 0
33
33
  end
34
34
 
35
35
  path = expanded_collection_path(index: index.to_s)
36
36
 
37
37
  response = if filter_result = options[:filter_result]
38
- connection.post(path, filter_result.to_json, params)
39
- else
40
- connection.get(path, params)
38
+ connection.post(path, filter_result.to_json, params)
39
+ else
40
+ connection.get(path, params)
41
41
  end
42
42
 
43
43
  from_json(response, index: index.to_s)
@@ -1,6 +1,8 @@
1
1
  module ChefAPI
2
2
  class Resource::User < Resource::Base
3
- collection_path '/users'
3
+ require "cgi" unless defined?(CGI)
4
+
5
+ collection_path "/users"
4
6
 
5
7
  schema do
6
8
  flavor :enterprise do
@@ -38,7 +40,7 @@ module ChefAPI
38
40
  # HEC/EC returns a slightly different response than OSC/CZ
39
41
  if users.is_a?(Array)
40
42
  users.each do |info|
41
- name = URI.escape(info['user']['username'])
43
+ name = CGI.escape(info["user"]["username"])
42
44
  response = connection.get("/users/#{name}")
43
45
  result = from_json(response, prefix)
44
46
 
@@ -75,7 +77,7 @@ module ChefAPI
75
77
  # the parsed JSON response from the server
76
78
  #
77
79
  def authenticate(options = {})
78
- connection.post('/authenticate_user', options.to_json)
80
+ connection.post("/authenticate_user", options.to_json)
79
81
  end
80
82
  end
81
83
  end
@@ -14,10 +14,10 @@ module ChefAPI
14
14
  def underscore(string)
15
15
  string
16
16
  .to_s
17
- .gsub(/::/, '/')
18
- .gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
19
- .gsub(/([a-z\d])([A-Z])/,'\1_\2')
20
- .tr('-', '_')
17
+ .gsub(/::/, "/")
18
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
19
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
20
+ .tr("-", "_")
21
21
  .downcase
22
22
  end
23
23
 
@@ -32,8 +32,8 @@ module ChefAPI
32
32
  def camelize(string)
33
33
  string
34
34
  .to_s
35
- .split('_')
36
- .map { |e| e.capitalize }
35
+ .split("_")
36
+ .map(&:capitalize)
37
37
  .join
38
38
  end
39
39
 
@@ -49,7 +49,7 @@ module ChefAPI
49
49
  length = options[:length] || 30
50
50
 
51
51
  if string.length > length
52
- string[0..length-3] + '...'
52
+ string[0..length - 3] + "..."
53
53
  else
54
54
  string
55
55
  end
@@ -77,7 +77,7 @@ module ChefAPI
77
77
  #
78
78
  def safe_read(path)
79
79
  path = File.expand_path(path)
80
- name = File.basename(path, '.*')
80
+ name = File.basename(path, ".*")
81
81
  contents = File.read(path)
82
82
 
83
83
  [name, contents]
@@ -1,8 +1,8 @@
1
1
  module ChefAPI
2
2
  module Validator
3
- autoload :Base, 'chef-api/validators/base'
4
- autoload :Required, 'chef-api/validators/required'
5
- autoload :Type, 'chef-api/validators/type'
3
+ autoload :Base, "chef-api/validators/base"
4
+ autoload :Required, "chef-api/validators/required"
5
+ autoload :Type, "chef-api/validators/type"
6
6
 
7
7
  #
8
8
  # Find a validator by the given key.
@@ -35,7 +35,7 @@ module ChefAPI
35
35
  # @return [Symbol]
36
36
  #
37
37
  def key
38
- name = self.class.name.split('::').last
38
+ name = self.class.name.split("::").last
39
39
  Util.underscore(name).to_sym
40
40
  end
41
41
 
@@ -47,7 +47,7 @@ module ChefAPI
47
47
  # the parent resource to validate against
48
48
  #
49
49
  def validate(resource)
50
- raise Error::AbstractMethod.new(method: 'Validators::Base#validate')
50
+ raise Error::AbstractMethod.new(method: "Validators::Base#validate")
51
51
  end
52
52
 
53
53
  #
@@ -76,7 +76,7 @@ module ChefAPI
76
76
  # @return [String]
77
77
  #
78
78
  def classname
79
- @classname ||= self.class.name.split('::')[1..-1].join('::')
79
+ @classname ||= self.class.name.split("::")[1..-1].join("::")
80
80
  end
81
81
  end
82
82
  end
@@ -4,7 +4,7 @@ module ChefAPI
4
4
  value = resource._attributes[attribute]
5
5
 
6
6
  if value.to_s.strip.empty?
7
- resource.errors.add(attribute, 'must be present')
7
+ resource.errors.add(attribute, "must be present")
8
8
  end
9
9
  end
10
10
  end
@@ -15,7 +15,7 @@ module ChefAPI
15
15
  value = resource._attributes[attribute]
16
16
 
17
17
  if value && !types.any? { |type| value.is_a?(type) }
18
- short_name = type.to_s.split('::').last
18
+ short_name = types.to_s.split("::").last
19
19
  resource.errors.add(attribute, "must be a kind of #{short_name}")
20
20
  end
21
21
  end
@@ -1,3 +1,3 @@
1
1
  module ChefAPI
2
- VERSION = '0.9.0'
2
+ VERSION = "0.10.10".freeze
3
3
  end
@@ -0,0 +1,5 @@
1
+ '<%= @method %>' is an abstract method. You must override this method in your subclass with the proper implementation and logic. For more information, please see the inline documentation for <%= @method %>. If you are not a developer, this is most likely a bug in the ChefAPI gem. Please file a bug report at:
2
+
3
+ https://github.com/sethvargo/chef-api/issues/new
4
+
5
+ and include the command(s) or code you ran to arrive at this error.
@@ -0,0 +1 @@
1
+ You attempted to regenerate the private key for a Client or User that does not yet exist on the remote Chef Server. You can only regenerate the key for an object that is persisted. Try saving this record this object before regenerating the key.
@@ -0,0 +1 @@
1
+ Oh no! Something really bad happened. I am not sure what actually happened because this is the catch-all error, but you should most definitely report an issue on GitHub at https://github.com/sethvargo/chef-api.