chef-api 0.8.0 → 0.10.7

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 (60) 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 +68 -67
  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 +22 -22
  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 +3 -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. metadata +25 -58
  36. data/.gitignore +0 -21
  37. data/.travis.yml +0 -18
  38. data/CHANGELOG.md +0 -63
  39. data/Gemfile +0 -12
  40. data/README.md +0 -352
  41. data/Rakefile +0 -11
  42. data/chef-api.gemspec +0 -25
  43. data/spec/integration/resources/client_spec.rb +0 -62
  44. data/spec/integration/resources/environment_spec.rb +0 -8
  45. data/spec/integration/resources/node_spec.rb +0 -8
  46. data/spec/integration/resources/partial_search_spec.rb +0 -23
  47. data/spec/integration/resources/role_spec.rb +0 -8
  48. data/spec/integration/resources/search_spec.rb +0 -21
  49. data/spec/integration/resources/user_spec.rb +0 -8
  50. data/spec/spec_helper.rb +0 -32
  51. data/spec/support/chef_server.rb +0 -198
  52. data/spec/support/cookbook.tar.gz +0 -0
  53. data/spec/support/shared/chef_api_resource.rb +0 -91
  54. data/spec/support/user.pem +0 -27
  55. data/spec/unit/authentication_spec.rb +0 -70
  56. data/spec/unit/defaults_spec.rb +0 -60
  57. data/spec/unit/errors_spec.rb +0 -294
  58. data/spec/unit/resources/base_spec.rb +0 -49
  59. data/spec/unit/resources/client_spec.rb +0 -53
  60. data/spec/unit/resources/connection_spec.rb +0 -53
data/Rakefile DELETED
@@ -1,11 +0,0 @@
1
- require 'bundler/gem_tasks'
2
-
3
- require 'rspec/core/rake_task'
4
- RSpec::Core::RakeTask.new do |t|
5
- t.rspec_opts = [
6
- '--color',
7
- '--format progress',
8
- ].join(' ')
9
- end
10
-
11
- task default: :spec
@@ -1,25 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'chef-api/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = 'chef-api'
8
- spec.version = ChefAPI::VERSION
9
- spec.authors = ['Seth Vargo']
10
- spec.email = ['sethvargo@gmail.com']
11
- spec.description = 'A tiny Chef API client with minimal dependencies'
12
- spec.summary = 'A Chef API client in Ruby'
13
- spec.homepage = 'https://github.com/sethvargo/chef-api'
14
- spec.license = 'Apache 2.0'
15
-
16
- spec.required_ruby_version = '>= 2.1'
17
-
18
- spec.files = `git ls-files`.split($/)
19
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
- spec.require_paths = ['lib']
22
-
23
- spec.add_dependency 'logify', '~> 0.1'
24
- spec.add_dependency 'mime-types'
25
- end
@@ -1,62 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module ChefAPI
4
- describe Resource::Client do
5
- it_behaves_like 'a Chef API resource', :client,
6
- update: { validator: true }
7
-
8
- describe '.from_file' do
9
- let(:private_key) do
10
- <<-EOH.strip.gsub(/^ {10}/, '')
11
- -----BEGIN RSA PRIVATE KEY-----
12
- MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI
13
- w+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoP
14
- kcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2
15
- hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NO
16
- Td0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcW
17
- yLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKd
18
- ELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1
19
- Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzf
20
- TK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnK
21
- iqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4A
22
- sClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf
23
- 4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iP
24
- cXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7Rk
25
- EjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pN
26
- CAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX
27
- 3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZG
28
- YEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj
29
- 3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+
30
- dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz
31
- 6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWC
32
- P9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDF
33
- llYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJ
34
- kda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH
35
- +vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQ
36
- NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s=
37
- -----END RSA PRIVATE KEY-----
38
- EOH
39
- end
40
-
41
- let(:client) { described_class.from_file('/path/to/bacon.pem') }
42
-
43
- before do
44
- allow(File).to receive(:read).and_return(private_key)
45
- end
46
-
47
- it 'loads the client from the server' do
48
- chef_server.create_client('bacon', validator: true)
49
-
50
- expect(client.name).to eq('bacon')
51
- expect(client.private_key).to eq(private_key)
52
- expect(client.validator).to be_truthy
53
- end
54
-
55
- it 'creates a new instance when the client does not exist' do
56
- expect(client.name).to eq('bacon')
57
- expect(client.validator).to be_falsey
58
- expect(client.new_resource?).to be_truthy
59
- end
60
- end
61
- end
62
- end
@@ -1,8 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module ChefAPI
4
- describe Resource::Environment do
5
- it_behaves_like 'a Chef API resource', :environment,
6
- update: { description: 'This is the new description' }
7
- end
8
- end
@@ -1,8 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module ChefAPI
4
- describe Resource::Node do
5
- it_behaves_like 'a Chef API resource', :node,
6
- update: { chef_environment: 'my_environment' }
7
- end
8
- end
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module ChefAPI
4
- describe Resource::PartialSearch do
5
- describe '.query' do
6
- it 'returns a partial search resource' do
7
- chef_server.send('create_client', 'bacon')
8
- results = described_class.query(:client, { name: ['name'] })
9
- expect(results).to be_a(described_class)
10
- end
11
-
12
- it 'returns partial data' do
13
- chef_server.send('create_node', 'bacon1', { foo: :bar })
14
- chef_server.send('create_node', 'bacon2', { foo: :baz, bar: :foo })
15
- keys = { data: ['bar'] }
16
- results = described_class.query(:node, keys, '*:*', start: 1)
17
- expect(results.total).to be == 2
18
- expect(results.rows.size).to be == 1
19
- expect(results.rows.first).to be == { 'data' => 'foo' }
20
- end
21
- end
22
- end
23
- end
@@ -1,8 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module ChefAPI
4
- describe Resource::Role do
5
- it_behaves_like 'a Chef API resource', :role,
6
- update: { description: 'This is the new description' }
7
- end
8
- end
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module ChefAPI
4
- describe Resource::Search do
5
- describe '.query' do
6
- it 'returns a search resource' do
7
- chef_server.send('create_client', 'bacon')
8
- results = described_class.query(:client)
9
- expect(results).to be_a(described_class)
10
- end
11
-
12
- it 'options are passed to the chef-server' do
13
- chef_server.send('create_node', 'bacon1', { foo: :bar })
14
- chef_server.send('create_node', 'bacon2', { foo: :baz })
15
- results = described_class.query(:node, '*:*', start: 1)
16
- expect(results.total).to be == 2
17
- expect(results.rows.size).to be == 1
18
- end
19
- end
20
- end
21
- end
@@ -1,8 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module ChefAPI
4
- describe Resource::User do
5
- it_behaves_like 'a Chef API resource', :user,
6
- update: { admin: true }
7
- end
8
- end
@@ -1,32 +0,0 @@
1
- require 'chef-api'
2
-
3
- RSpec.configure do |config|
4
- # Chef Server
5
- require 'support/chef_server'
6
- config.include(RSpec::ChefServer::DSL)
7
-
8
- # Shared Examples
9
- Dir[ChefAPI.root.join('spec/support/shared/**/*.rb')].each { |file| require file }
10
-
11
- # Basic configuraiton
12
- config.run_all_when_everything_filtered = true
13
- config.filter_run(:focus)
14
-
15
- #
16
- config.before(:each) do
17
- Logify.level = :fatal
18
- end
19
-
20
- # Run specs in random order to surface order dependencies. If you find an
21
- # order dependency and want to debug it, you can fix the order by providing
22
- # the seed, which is printed after each run.
23
- # --seed 1234
24
- config.order = 'random'
25
- end
26
-
27
- #
28
- # @return [String]
29
- #
30
- def rspec_support_file(*joins)
31
- File.join(File.expand_path('../support', __FILE__), *joins)
32
- end
@@ -1,198 +0,0 @@
1
- require 'chef_zero/server'
2
-
3
- module RSpec
4
- class ChefServer
5
- module DSL
6
- def chef_server
7
- RSpec::ChefServer
8
- end
9
- end
10
-
11
- class << self
12
- #
13
- # Delegate all methods to the singleton instance.
14
- #
15
- def method_missing(m, *args, &block)
16
- instance.send(m, *args, &block)
17
- end
18
-
19
- #
20
- # RSpec 3 checks +respond_to?+
21
- #
22
- def respond_to_missing?(m, include_private = false)
23
- instance.respond_to?(m, include_private) || super
24
- end
25
-
26
- #
27
- # @macro entity
28
- # @method create_$1(name, data = {})
29
- # Create a new $1 on the Chef Server
30
- #
31
- # @param [String] name
32
- # the name of the $1
33
- # @param [Hash] data
34
- # the list of data to load
35
- #
36
- #
37
- # @method $1(name)
38
- # Find a $1 at the given name
39
- #
40
- # @param [String] name
41
- # the name of the $1
42
- #
43
- # @return [$2, nil]
44
- #
45
- #
46
- # @method $3
47
- # The list of $1 on the Chef Server
48
- #
49
- # @return [Array<Hash>]
50
- # all the $1 on the Chef Server
51
- #
52
- #
53
- # @method has_$1?(name)
54
- # Determine if the Chef Server has the given $1
55
- #
56
- # @param [String] name
57
- # the name of the $1 to find
58
- #
59
- # @return [Boolean]
60
- #
61
- def entity(method, key)
62
- class_eval <<-EOH, __FILE__, __LINE__ + 1
63
- def create_#{method}(name, data = {})
64
- # Automatically set the "name" if no explicit one was given
65
- data[:name] ||= name
66
-
67
- # Convert it to JSON
68
- data = JSON.fast_generate(data)
69
-
70
- load_data(name, '#{key}', data)
71
- end
72
-
73
- def #{method}(name)
74
- data = get('#{key}', name)
75
- JSON.parse(data)
76
- rescue ChefZero::DataStore::DataNotFoundError
77
- nil
78
- end
79
-
80
- def #{key}
81
- get('#{key}')
82
- end
83
-
84
- def has_#{method}?(name)
85
- !get('#{key}', name).nil?
86
- rescue ChefZero::DataStore::DataNotFoundError
87
- false
88
- end
89
- EOH
90
- end
91
- end
92
-
93
- entity :client, :clients
94
- entity :data_bag, :data
95
- entity :environment, :environments
96
- entity :node, :nodes
97
- entity :role, :roles
98
- entity :user, :users
99
-
100
- require 'singleton'
101
- include Singleton
102
-
103
- #
104
- #
105
- #
106
- def initialize
107
- @server = ChefZero::Server.new({
108
- # This uses a random port
109
- port: port,
110
-
111
- # Shut up
112
- log_level: :fatal,
113
-
114
- # Disable the "old" way - this is actually +multi_tenant: true+
115
- single_org: false,
116
-
117
- # Don't generate real keys for faster test
118
- generate_real_keys: false,
119
- })
120
-
121
- ChefAPI.endpoint = @server.url
122
- ChefAPI.key = ChefZero::PRIVATE_KEY
123
- end
124
-
125
- #
126
- #
127
- #
128
- def start
129
- @server.start_background(1)
130
- end
131
-
132
- #
133
- # Clear all the information in the server. This hook is run after each
134
- # example group, giving the appearance of an "empty" Chef Server for
135
- # each test.
136
- #
137
- def clear
138
- @server.clear_data
139
- end
140
-
141
- #
142
- # Stop the server (since it might not be running)
143
- #
144
- def stop
145
- @server.stop if @server.running?
146
- end
147
-
148
- #
149
- # Get the path to an item in the data store.
150
- #
151
- def get(*args)
152
- if args.size == 1
153
- @server.data_store.list(args)
154
- else
155
- @server.data_store.get(args)
156
- end
157
- end
158
-
159
- #
160
- # Shortcut method for loading data into Chef Zero.
161
- #
162
- # @param [String] name
163
- # the name or id of the item to load
164
- # @param [String, Symbol] key
165
- # the key to load
166
- # @param [Hash] data
167
- # the data for the object, which will be converted to JSON and uploaded
168
- # to the server
169
- #
170
- def load_data(name, key, data = {})
171
- @server.load_data({ key => { name => data } })
172
- end
173
-
174
- private
175
-
176
- #
177
- # A randomly assigned, open port for run the Chef Zero server.
178
- #
179
- # @return [Fixnum]
180
- #
181
- def port
182
- return @port if @port
183
-
184
- @server = TCPServer.new('127.0.0.1', 0)
185
- @port = @server.addr[1].to_i
186
- @server.close
187
-
188
- return @port
189
- end
190
- end
191
- end
192
-
193
-
194
- RSpec.configure do |config|
195
- config.before(:suite) { RSpec::ChefServer.start }
196
- config.after(:each) { RSpec::ChefServer.clear }
197
- config.after(:suite) { RSpec::ChefServer.stop }
198
- end
Binary file
@@ -1,91 +0,0 @@
1
- shared_examples_for 'a Chef API resource' do |type, options = {}|
2
- let(:resource_id) { "my_#{type}" }
3
-
4
- describe '.fetch' do
5
- it 'returns nil when the resource does not exist' do
6
- expect(described_class.fetch('not_real')).to be_nil
7
- end
8
-
9
- it 'returns the resource' do
10
- chef_server.send("create_#{type}", resource_id)
11
- expect(described_class.fetch(resource_id).name).to eq(resource_id)
12
- end
13
- end
14
-
15
- describe '.build' do
16
- it 'builds a resource' do
17
- instance = described_class.build(name: resource_id)
18
- expect(instance).to be_a(described_class)
19
- end
20
-
21
- it 'does not create a remote resource' do
22
- described_class.build(name: resource_id)
23
- expect(chef_server).to_not send("have_#{type}", resource_id)
24
- end
25
- end
26
-
27
- describe '.create' do
28
- it 'creates a new remote resource' do
29
- described_class.create(name: resource_id)
30
- expect(chef_server).to send("have_#{type}", resource_id)
31
- end
32
-
33
- it 'raises an exception when the resource already exists' do
34
- chef_server.send("create_#{type}", resource_id)
35
- expect {
36
- described_class.create(name: resource_id)
37
- }.to raise_error(ChefAPI::Error::ResourceAlreadyExists)
38
- end
39
- end
40
-
41
- describe '.exists?' do
42
- it 'returns false when the resource does not exist' do
43
- expect(described_class.exists?(resource_id)).to be_falsey
44
- end
45
-
46
- it 'returns true when the resource exists' do
47
- chef_server.send("create_#{type}", resource_id)
48
- expect(described_class.exists?(resource_id)).to be_truthy
49
- end
50
- end
51
-
52
- describe '.destroy' do
53
- it "destroys the #{type} with the given ID" do
54
- chef_server.send("create_#{type}", resource_id)
55
- described_class.delete(resource_id)
56
-
57
- expect(chef_server).to_not send("have_#{type}", resource_id)
58
- end
59
-
60
- it 'does not raise an exception if the record does not exist' do
61
- expect { described_class.delete(resource_id) }.to_not raise_error
62
- end
63
- end
64
-
65
- describe '.update' do
66
- it 'updates an existing resource' do
67
- chef_server.send("create_#{type}", resource_id)
68
-
69
- options[:update].each do |key, value|
70
- described_class.update(resource_id, key => value)
71
- expect(chef_server.send(type, resource_id)[key.to_s]).to eq(value)
72
- end
73
- end
74
-
75
- it 'raises an exception when the resource does not exist' do
76
- expect {
77
- described_class.update(resource_id)
78
- }.to raise_error(ChefAPI::Error::ResourceNotFound)
79
- end
80
- end
81
-
82
- describe '.count' do
83
- it 'returns the total number of resources' do
84
- 5.times do |i|
85
- chef_server.send("create_#{type}", "#{resource_id}_#{i}")
86
- end
87
-
88
- expect(described_class.count).to be >= 5
89
- end
90
- end
91
- end