chef-zero 4.5.0 → 4.6.0

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.
@@ -1,11 +1,11 @@
1
1
  module ChefZero
2
2
  class RestErrorResponse < StandardError
3
+ attr_reader :response_code, :error
4
+
3
5
  def initialize(response_code, error)
4
6
  @response_code = response_code
5
7
  @error = error
8
+ super "#{response_code}: #{error}"
6
9
  end
7
-
8
- attr_reader :response_code
9
- attr_reader :error
10
10
  end
11
11
  end
@@ -2,6 +2,9 @@ require 'rack/request'
2
2
 
3
3
  module ChefZero
4
4
  class RestRequest
5
+
6
+ ZERO = "0".freeze
7
+
5
8
  def initialize(env, rest_base_prefix = [])
6
9
  @env = env
7
10
  @rest_base_prefix = rest_base_prefix
@@ -19,7 +22,11 @@ module ChefZero
19
22
  end
20
23
 
21
24
  def api_version
22
- @env['HTTP_X_OPS_SERVER_API_VERSION'] || 0
25
+ @env['HTTP_X_OPS_SERVER_API_VERSION'] || ZERO
26
+ end
27
+
28
+ def api_v0?
29
+ api_version == ZERO
23
30
  end
24
31
 
25
32
  def requestor
@@ -34,6 +41,10 @@ module ChefZero
34
41
  @rest_path ||= rest_base_prefix + env['PATH_INFO'].split('/').select { |part| part != "" }
35
42
  end
36
43
 
44
+ def rest_path=(rest_path)
45
+ @rest_path = rest_path
46
+ end
47
+
37
48
  def body=(body)
38
49
  @body = body
39
50
  end
@@ -1,3 +1,5 @@
1
+ require 'pp'
2
+
1
3
  module ChefZero
2
4
  class RestRouter
3
5
  def initialize(routes)
@@ -15,24 +17,18 @@ module ChefZero
15
17
  attr_accessor :not_found
16
18
 
17
19
  def call(request)
18
- begin
19
- ChefZero::Log.debug(request)
20
- ChefZero::Log.debug(request.body) if request.body
21
-
22
- clean_path = "/" + request.rest_path.join("/")
23
-
24
- response = find_endpoint(clean_path).call(request)
25
- ChefZero::Log.debug([
26
- "",
27
- "--- RESPONSE (#{response[0]}) ---",
28
- response[2],
29
- "--- END RESPONSE ---",
30
- ].join("\n"))
31
- return response
32
- rescue
33
- ChefZero::Log.error("#{$!.inspect}\n#{$!.backtrace.join("\n")}")
34
- [500, {"Content-Type" => "text/plain"}, "Exception raised! #{$!.inspect}\n#{$!.backtrace.join("\n")}"]
20
+ log_request(request)
21
+
22
+ clean_path = "/" + request.rest_path.join("/")
23
+
24
+ find_endpoint(clean_path).call(request).tap do |response|
25
+ log_response(response)
35
26
  end
27
+ rescue => ex
28
+ exception = "#{ex.inspect}\n#{ex.backtrace.join("\n")}"
29
+
30
+ ChefZero::Log.error(exception)
31
+ [ 500, { "Content-Type" => "text/plain" }, "Exception raised! #{exception}" ]
36
32
  end
37
33
 
38
34
  private
@@ -41,5 +37,36 @@ module ChefZero
41
37
  _, endpoint = routes.find { |route, endpoint| route.match(clean_path) }
42
38
  endpoint || not_found
43
39
  end
40
+
41
+ def log_request(request)
42
+ ChefZero::Log.info do
43
+ "#{request.method} /#{request.rest_path.join("/")}".tap do |msg|
44
+ next unless request.method =~ /^(POST|PUT)$/
45
+
46
+ if request.body.nil? || request.body.empty?
47
+ msg << " (no body)"
48
+ else
49
+ msg << [
50
+ "",
51
+ "--- #{request.method} BODY ---",
52
+ request.body.chomp,
53
+ "--- END #{request.method} BODY ---"
54
+ ].join("\n")
55
+ end
56
+ end
57
+ end
58
+
59
+ ChefZero::Log.debug { request.pretty_inspect }
60
+ end
61
+
62
+ def log_response(response)
63
+ ChefZero::Log.info {
64
+ [ "",
65
+ "--- RESPONSE (#{response[0]}) ---",
66
+ response[2].chomp,
67
+ "--- END RESPONSE ---",
68
+ ].join("\n")
69
+ }
70
+ end
44
71
  end
45
72
  end
@@ -67,7 +67,7 @@ module ChefZero
67
67
  if chef_server_options[:server_scope] != self.class.chef_server_options[:server_scope]
68
68
  raise "server_scope: #{chef_server_options[:server_scope]} will not be honored: it can only be set on when_the_chef_server!"
69
69
  end
70
- Log.debug("Starting Chef server with options #{chef_server_options}")
70
+ Log.info("Starting Chef server with options #{chef_server_options}")
71
71
 
72
72
  ChefZero::RSpec.set_server_options(chef_server_options)
73
73
 
@@ -40,8 +40,14 @@ require 'chef_zero/endpoints/rest_list_endpoint'
40
40
  require 'chef_zero/endpoints/authenticate_user_endpoint'
41
41
  require 'chef_zero/endpoints/acls_endpoint'
42
42
  require 'chef_zero/endpoints/acl_endpoint'
43
- require 'chef_zero/endpoints/actors_endpoint'
44
43
  require 'chef_zero/endpoints/actor_endpoint'
44
+ require 'chef_zero/endpoints/actors_endpoint'
45
+ require 'chef_zero/endpoints/actor_key_endpoint'
46
+ require 'chef_zero/endpoints/organization_user_key_endpoint'
47
+ require 'chef_zero/endpoints/organization_user_default_key_endpoint'
48
+ require 'chef_zero/endpoints/organization_user_keys_endpoint'
49
+ require 'chef_zero/endpoints/actor_default_key_endpoint'
50
+ require 'chef_zero/endpoints/actor_keys_endpoint'
45
51
  require 'chef_zero/endpoints/cookbooks_endpoint'
46
52
  require 'chef_zero/endpoints/cookbook_endpoint'
47
53
  require 'chef_zero/endpoints/cookbook_version_endpoint'
@@ -105,9 +111,9 @@ module ChefZero
105
111
  class Server
106
112
 
107
113
  DEFAULT_OPTIONS = {
108
- :host => '127.0.0.1',
114
+ :host => ['127.0.0.1'],
109
115
  :port => 8889,
110
- :log_level => :info,
116
+ :log_level => :warn,
111
117
  :generate_real_keys => true,
112
118
  :single_org => 'chef',
113
119
  :ssl => false
@@ -136,6 +142,7 @@ module ChefZero
136
142
  def port
137
143
  if @port
138
144
  @port
145
+ # If options[:port] is not an Array or an Enumerable, it is just an Integer.
139
146
  elsif !options[:port].respond_to?(:each)
140
147
  options[:port]
141
148
  else
@@ -158,10 +165,11 @@ module ChefZero
158
165
  #
159
166
  def url
160
167
  sch = @options[:ssl] ? 'https' : 'http'
161
- @url ||= if @options[:host].include?(':')
162
- URI("#{sch}://[#{@options[:host]}]:#{port}").to_s
168
+ hosts = Array(@options[:host])
169
+ @url ||= if hosts.first.include?(':')
170
+ URI("#{sch}://[#{hosts.first}]:#{port}").to_s
163
171
  else
164
- URI("#{sch}://#{@options[:host]}:#{port}").to_s
172
+ URI("#{sch}://#{hosts.first}:#{port}").to_s
165
173
  end
166
174
  end
167
175
 
@@ -259,6 +267,18 @@ module ChefZero
259
267
  # @return [Thread]
260
268
  # the thread the background process is running in
261
269
  #
270
+ def listen(hosts, port)
271
+ hosts.each do |host|
272
+ @server.listen(host, port)
273
+ end
274
+ true
275
+ rescue Errno::EADDRINUSE
276
+ ChefZero::Log.warn("Port #{port} not available")
277
+ @server.listeners.each { |l| l.close }
278
+ @server.listeners.clear
279
+ false
280
+ end
281
+
262
282
  def start_background(wait = 5)
263
283
  @server = WEBrick::HTTPServer.new(
264
284
  :DoNotListen => true,
@@ -274,22 +294,17 @@ module ChefZero
274
294
  @server.mount('/', Rack::Handler::WEBrick, app)
275
295
 
276
296
  # Pick a port
277
- if options[:port].respond_to?(:each)
278
- options[:port].each do |port|
279
- begin
280
- @server.listen(options[:host], port)
281
- @port = port
282
- break
283
- rescue Errno::EADDRINUSE
284
- ChefZero::Log.info("Port #{port} in use: #{$!}")
285
- end
286
- end
287
- if !@port
288
- raise Errno::EADDRINUSE, "No port in :port range #{options[:port]} is available"
297
+ # If options[:port] can be an Enumerator, an Array, or an Integer,
298
+ # we need something that can respond to .each (Enum and Array can already).
299
+ Array(options[:port]).each do |port|
300
+ if listen(Array(options[:host]), port)
301
+ @port = port
302
+ break
289
303
  end
290
- else
291
- @server.listen(options[:host], options[:port])
292
- @port = options[:port]
304
+ end
305
+ if !@port
306
+ raise Errno::EADDRINUSE,
307
+ "No port in :port range #{options[:port]} is available"
293
308
  end
294
309
 
295
310
  # Start the server in the background
@@ -523,7 +538,7 @@ module ChefZero
523
538
  [
524
539
  [ "/organizations/*/users", ActorsEndpoint.new(self) ],
525
540
  [ "/organizations/*/users/*", ActorEndpoint.new(self) ],
526
- [ "/organizations/*/authenticate_user", OrganizationAuthenticateUserEndpoint.new(self) ],
541
+ [ "/organizations/*/authenticate_user", OrganizationAuthenticateUserEndpoint.new(self) ]
527
542
  ]
528
543
  else
529
544
  # EC-only
@@ -537,11 +552,13 @@ module ChefZero
537
552
  [ "/users/*/association_requests", UserAssociationRequestsEndpoint.new(self) ],
538
553
  [ "/users/*/association_requests/count", UserAssociationRequestsCountEndpoint.new(self) ],
539
554
  [ "/users/*/association_requests/*", UserAssociationRequestEndpoint.new(self) ],
555
+ [ "/users/*/keys", ActorKeysEndpoint.new(self) ],
556
+ [ "/users/*/keys/default", ActorDefaultKeyEndpoint.new(self) ],
557
+ [ "/users/*/keys/*", ActorKeyEndpoint.new(self) ],
540
558
  [ "/users/*/organizations", UserOrganizationsEndpoint.new(self) ],
541
559
  [ "/authenticate_user", AuthenticateUserEndpoint.new(self) ],
542
560
  [ "/system_recovery", SystemRecoveryEndpoint.new(self) ],
543
561
  [ "/license", LicenseEndpoint.new(self) ],
544
-
545
562
  [ "/organizations", OrganizationsEndpoint.new(self) ],
546
563
  [ "/organizations/*", OrganizationEndpoint.new(self) ],
547
564
  [ "/organizations/*/_validator_key", OrganizationValidatorKeyEndpoint.new(self) ],
@@ -564,6 +581,12 @@ module ChefZero
564
581
  [ "/dummy", DummyEndpoint.new(self) ],
565
582
  [ "/organizations/*/clients", ActorsEndpoint.new(self) ],
566
583
  [ "/organizations/*/clients/*", ActorEndpoint.new(self) ],
584
+ [ "/organizations/*/clients/*/keys", ActorKeysEndpoint.new(self) ],
585
+ [ "/organizations/*/clients/*/keys/default", ActorDefaultKeyEndpoint.new(self) ],
586
+ [ "/organizations/*/clients/*/keys/*", ActorKeyEndpoint.new(self) ],
587
+ [ "/organizations/*/users/*/keys", OrganizationUserKeysEndpoint.new(self) ],
588
+ [ "/organizations/*/users/*/keys/default", OrganizationUserDefaultKeyEndpoint.new(self) ],
589
+ [ "/organizations/*/users/*/keys/*", OrganizationUserKeyEndpoint.new(self) ],
567
590
  [ "/organizations/*/controls", ControlsEndpoint.new(self) ],
568
591
  [ "/organizations/*/cookbooks", CookbooksEndpoint.new(self) ],
569
592
  [ "/organizations/*/cookbooks/*", CookbookEndpoint.new(self) ],
@@ -1,3 +1,3 @@
1
1
  module ChefZero
2
- VERSION = '4.5.0'
2
+ VERSION = '4.6.0'
3
3
  end
@@ -5,6 +5,42 @@ require 'bundler/setup'
5
5
  require 'chef_zero/server'
6
6
  require 'rspec/core'
7
7
 
8
+ # This file runs oc-chef-pedant specs and is invoked by `rake pedant`
9
+ # and other Rake tasks. Run `rake -T` to list tasks.
10
+ #
11
+ # Options for oc-chef-pedant and rspec can be specified via
12
+ # ENV['PEDANT_OPTS'] and ENV['RSPEC_OPTS'], respectively.
13
+ #
14
+ # The log level can be specified via ENV['LOG_LEVEL'].
15
+ #
16
+ # Example:
17
+ #
18
+ # $ PEDANT_OPTS="--focus-users --skip-keys" \
19
+ # > RSPEC_OPTS="--fail-fast --profile 5" \
20
+ # > LOG_LEVEL=debug \
21
+ # > rake pedant
22
+ #
23
+
24
+ DEFAULT_SERVER_OPTIONS = {
25
+ port: 8889,
26
+ single_org: false,
27
+ }.freeze
28
+
29
+ DEFAULT_LOG_LEVEL = :warn
30
+
31
+ def log_level
32
+ return ENV['LOG_LEVEL'].downcase.to_sym if ENV['LOG_LEVEL']
33
+ return :debug if ENV['DEBUG']
34
+ DEFAULT_LOG_LEVEL
35
+ end
36
+
37
+ def start_chef_server(opts={})
38
+ opts = DEFAULT_SERVER_OPTIONS.merge(opts)
39
+ opts[:log_level] = log_level
40
+
41
+ ChefZero::Server.new(opts).tap {|server| server.start_background }
42
+ end
43
+
8
44
  def start_cheffs_server(chef_repo_path)
9
45
  require 'chef/version'
10
46
  require 'chef/config'
@@ -34,37 +70,42 @@ def start_cheffs_server(chef_repo_path)
34
70
  data_store.set(%w(organizations pedant-testorg groups admins), '{ "users": [ "pivotal" ] }')
35
71
  data_store.set(%w(organizations pedant-testorg groups users), '{ "users": [ "pivotal" ] }')
36
72
 
37
- server = ChefZero::Server.new(
38
- port: 8889,
39
- data_store: data_store,
40
- single_org: false,
41
- #log_level: :debug
42
- )
43
- server.start_background
44
- server
73
+ start_chef_server(data_store: data_store)
45
74
  end
46
75
 
47
- tmpdir = nil
76
+ def pedant_args_from_env
77
+ args_from_env('PEDANT_OPTS')
78
+ end
79
+
80
+ def rspec_args_from_env
81
+ args_from_env('RSPEC_OPTS')
82
+ end
83
+
84
+ def args_from_env(key)
85
+ return [] unless ENV[key]
86
+ ENV[key].split
87
+ end
48
88
 
49
89
  begin
50
- if ENV['FILE_STORE']
51
- require 'tmpdir'
52
- require 'chef_zero/data_store/raw_file_store'
53
- tmpdir = Dir.mktmpdir
54
- data_store = ChefZero::DataStore::RawFileStore.new(tmpdir, true)
55
- data_store = ChefZero::DataStore::DefaultFacade.new(data_store, false, false)
56
- server = ChefZero::Server.new(:port => 8889, :single_org => false, :data_store => data_store)
57
- server.start_background
58
-
59
- elsif ENV['CHEF_FS']
60
- require 'tmpdir'
61
- tmpdir = Dir.mktmpdir
62
- server = start_cheffs_server(tmpdir)
90
+ tmpdir = nil
91
+ server =
92
+ if ENV['FILE_STORE']
93
+ require 'tmpdir'
94
+ require 'chef_zero/data_store/raw_file_store'
95
+ tmpdir = Dir.mktmpdir
96
+ data_store = ChefZero::DataStore::RawFileStore.new(tmpdir, true)
97
+ data_store = ChefZero::DataStore::DefaultFacade.new(data_store, false, false)
98
+
99
+ start_chef_server(data_store: data_store)
100
+
101
+ elsif ENV['CHEF_FS']
102
+ require 'tmpdir'
103
+ tmpdir = Dir.mktmpdir
104
+ start_cheffs_server(tmpdir)
63
105
 
64
- else
65
- server = ChefZero::Server.new(:port => 8889, :single_org => false)#, :log_level => :debug)
66
- server.start_background
67
- end
106
+ else
107
+ start_chef_server
108
+ end
68
109
 
69
110
  require 'rspec/core'
70
111
  require 'pedant'
@@ -83,6 +124,7 @@ begin
83
124
  '--skip-users',
84
125
  '--skip-organizations',
85
126
  '--skip-multiuser',
127
+ '--skip-user-keys',
86
128
 
87
129
  # chef-zero has some non-removable quirks, such as the fact that files
88
130
  # with 255-character names cannot be stored in local mode. This is
@@ -98,13 +140,17 @@ begin
98
140
  chef_fs_skips << '--skip-cookbook-artifacts'
99
141
  chef_fs_skips << '--skip-policies'
100
142
 
143
+ # Multi-keys don't work prior to 12.8
144
+ unless Gem::Requirement.new(">= 12.8.0").satisfied_by?(Gem::Version.new(Chef::VERSION))
145
+ chef_fs_skips << '--skip-keys'
146
+ end
147
+
101
148
  # These things aren't supported by Chef Zero in any mode of operation:
102
149
  default_skips = [
103
150
  # "the goal is that only authorization, authentication and validation tests
104
151
  # are turned off" - @jkeiser
105
152
  #
106
153
  # ...but we're not there yet
107
- '--skip-keys',
108
154
 
109
155
  # Chef Zero does not intend to support validation the way erchef does.
110
156
  '--skip-validation',
@@ -128,7 +174,6 @@ begin
128
174
  '--skip-usags',
129
175
 
130
176
  # Chef 12 features not yet 100% supported by Chef Zero
131
- '--skip-api-v1',
132
177
 
133
178
  # The universe endpoint is unlikely to ever make sense for Chef Zero
134
179
  '--skip-universe',
@@ -143,12 +188,10 @@ begin
143
188
  default_skips + chef_fs_skips + %w{ --skip-knife }
144
189
  end
145
190
 
146
- Pedant.setup(pedant_args)
147
-
148
- fail_fast = %w()#--fail-fast)
149
- #fail_fast = ["--fail-fast"]
191
+ Pedant.setup(pedant_args + pedant_args_from_env)
150
192
 
151
- result = RSpec::Core::Runner.run(Pedant.config.rspec_args + fail_fast)
193
+ rspec_args = Pedant.config.rspec_args + rspec_args_from_env
194
+ result = RSpec::Core::Runner.run(rspec_args)
152
195
 
153
196
  server.stop if server.running?
154
197
  ensure
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-zero
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.5.0
4
+ version: 4.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Keiser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-29 00:00:00.000000000 Z
11
+ date: 2016-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mixlib-log
@@ -156,20 +156,6 @@ dependencies:
156
156
  - - ">="
157
157
  - !ruby/object:Gem::Version
158
158
  version: '0'
159
- - !ruby/object:Gem::Dependency
160
- name: github_changelog_generator
161
- requirement: !ruby/object:Gem::Requirement
162
- requirements:
163
- - - ">="
164
- - !ruby/object:Gem::Version
165
- version: '0'
166
- type: :development
167
- prerelease: false
168
- version_requirements: !ruby/object:Gem::Requirement
169
- requirements:
170
- - - ">="
171
- - !ruby/object:Gem::Version
172
- version: '0'
173
159
  - !ruby/object:Gem::Dependency
174
160
  name: chef
175
161
  requirement: !ruby/object:Gem::Requirement
@@ -216,7 +202,10 @@ files:
216
202
  - lib/chef_zero/data_store/v2_to_v1_adapter.rb
217
203
  - lib/chef_zero/endpoints/acl_endpoint.rb
218
204
  - lib/chef_zero/endpoints/acls_endpoint.rb
205
+ - lib/chef_zero/endpoints/actor_default_key_endpoint.rb
219
206
  - lib/chef_zero/endpoints/actor_endpoint.rb
207
+ - lib/chef_zero/endpoints/actor_key_endpoint.rb
208
+ - lib/chef_zero/endpoints/actor_keys_endpoint.rb
220
209
  - lib/chef_zero/endpoints/actors_endpoint.rb
221
210
  - lib/chef_zero/endpoints/authenticate_user_endpoint.rb
222
211
  - lib/chef_zero/endpoints/container_endpoint.rb
@@ -253,7 +242,10 @@ files:
253
242
  - lib/chef_zero/endpoints/organization_authenticate_user_endpoint.rb
254
243
  - lib/chef_zero/endpoints/organization_endpoint.rb
255
244
  - lib/chef_zero/endpoints/organization_user_base.rb
245
+ - lib/chef_zero/endpoints/organization_user_default_key_endpoint.rb
256
246
  - lib/chef_zero/endpoints/organization_user_endpoint.rb
247
+ - lib/chef_zero/endpoints/organization_user_key_endpoint.rb
248
+ - lib/chef_zero/endpoints/organization_user_keys_endpoint.rb
257
249
  - lib/chef_zero/endpoints/organization_users_endpoint.rb
258
250
  - lib/chef_zero/endpoints/organization_validator_key_endpoint.rb
259
251
  - lib/chef_zero/endpoints/organizations_endpoint.rb
@@ -316,7 +308,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
316
308
  requirements:
317
309
  - - ">="
318
310
  - !ruby/object:Gem::Version
319
- version: '0'
311
+ version: 2.1.0
320
312
  required_rubygems_version: !ruby/object:Gem::Requirement
321
313
  requirements:
322
314
  - - ">="