chef-api 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef-api/version.rb +1 -1
  3. metadata +6 -70
  4. data/.gitignore +0 -21
  5. data/.travis.yml +0 -18
  6. data/CHANGELOG.md +0 -63
  7. data/Gemfile +0 -12
  8. data/README.md +0 -352
  9. data/Rakefile +0 -11
  10. data/chef-api.gemspec +0 -25
  11. data/spec/integration/resources/client_spec.rb +0 -62
  12. data/spec/integration/resources/environment_spec.rb +0 -8
  13. data/spec/integration/resources/node_spec.rb +0 -8
  14. data/spec/integration/resources/partial_search_spec.rb +0 -23
  15. data/spec/integration/resources/role_spec.rb +0 -8
  16. data/spec/integration/resources/search_spec.rb +0 -21
  17. data/spec/integration/resources/user_spec.rb +0 -8
  18. data/spec/spec_helper.rb +0 -32
  19. data/spec/support/chef_server.rb +0 -198
  20. data/spec/support/cookbook.tar.gz +0 -0
  21. data/spec/support/shared/chef_api_resource.rb +0 -91
  22. data/spec/support/user.pem +0 -27
  23. data/spec/unit/authentication_spec.rb +0 -70
  24. data/spec/unit/defaults_spec.rb +0 -60
  25. data/spec/unit/errors_spec.rb +0 -294
  26. data/spec/unit/resources/base_spec.rb +0 -49
  27. data/spec/unit/resources/client_spec.rb +0 -53
  28. data/spec/unit/resources/connection_spec.rb +0 -53
  29. data/templates/errors/abstract_method.erb +0 -5
  30. data/templates/errors/cannot_regenerate_key.erb +0 -1
  31. data/templates/errors/chef_api_error.erb +0 -1
  32. data/templates/errors/file_not_found.erb +0 -1
  33. data/templates/errors/http_bad_request.erb +0 -3
  34. data/templates/errors/http_forbidden_request.erb +0 -3
  35. data/templates/errors/http_gateway_timeout.erb +0 -3
  36. data/templates/errors/http_method_not_allowed.erb +0 -3
  37. data/templates/errors/http_not_acceptable.erb +0 -3
  38. data/templates/errors/http_not_found.erb +0 -3
  39. data/templates/errors/http_server_unavailable.erb +0 -1
  40. data/templates/errors/http_unauthorized_request.erb +0 -3
  41. data/templates/errors/insufficient_file_permissions.erb +0 -1
  42. data/templates/errors/invalid_resource.erb +0 -1
  43. data/templates/errors/invalid_validator.erb +0 -1
  44. data/templates/errors/missing_url_parameter.erb +0 -1
  45. data/templates/errors/not_a_directory.erb +0 -1
  46. data/templates/errors/resource_already_exists.erb +0 -1
  47. data/templates/errors/resource_not_found.erb +0 -1
  48. data/templates/errors/resource_not_mutable.erb +0 -1
  49. data/templates/errors/unknown_attribute.erb +0 -1
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