summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml12
-rw-r--r--CHANGELOG.md52
-rw-r--r--Gemfile4
-rw-r--r--Rakefile16
-rwxr-xr-xbin/chef-zero9
-rw-r--r--chef-zero.gemspec13
-rw-r--r--gemfiles/berkshelf.gemfile15
-rw-r--r--gemfiles/latest-chef.gemfile5
-rw-r--r--gemfiles/no-pedant.gemfile4
-rw-r--r--gemfiles/oc-chef-pedant.gemfile6
-rw-r--r--lib/chef_zero/chef_data/cookbook_data.rb10
-rw-r--r--lib/chef_zero/chef_data/data_normalizer.rb2
-rw-r--r--lib/chef_zero/endpoints/actor_endpoint.rb23
-rw-r--r--lib/chef_zero/endpoints/actor_keys_endpoint.rb13
-rw-r--r--lib/chef_zero/endpoints/actors_endpoint.rb34
-rw-r--r--lib/chef_zero/endpoints/organization_user_default_key_endpoint.rb16
-rw-r--r--lib/chef_zero/endpoints/organization_user_key_endpoint.rb17
-rw-r--r--lib/chef_zero/endpoints/organization_user_keys_endpoint.rb17
-rw-r--r--lib/chef_zero/rest_request.rb12
-rw-r--r--lib/chef_zero/rest_router.rb4
-rw-r--r--lib/chef_zero/server.rb69
-rw-r--r--lib/chef_zero/solr/query/regexpable_query.rb4
-rw-r--r--lib/chef_zero/solr/query/unary_operator.rb6
-rw-r--r--lib/chef_zero/version.rb2
-rw-r--r--spec/search_spec.rb4
-rw-r--r--spec/server_spec.rb4
27 files changed, 253 insertions, 121 deletions
diff --git a/.gitignore b/.gitignore
index c13d06c..e29766c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ InstalledFiles
_yardoc
coverage
doc/
+binstubs/
lib/bundler/man
pkg
rdoc
diff --git a/.travis.yml b/.travis.yml
index 46648d9..4994db3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,4 @@
-rvm: 2.0
+rvm: 2.1
gemfile: Gemfile
# This prevents testing branches that are created just for PRs
@@ -18,8 +18,6 @@ script:
matrix:
include:
- - rvm: 2.0
- - rvm: 2.1
- rvm: 2.1
env: PEDANT_KNIFE_TESTS=true PEDANT_ALLOW_RVM=1
- rvm: 2.1
@@ -39,11 +37,3 @@ matrix:
script: bundle exec rake spec
env: TEST=rake_spec
-# allow_failures:
-# - rvm: 2.1
-# gemfile: gemfiles/latest-chef.gemfile
-# script: bundle exec rake chef_spec
-# enc: TEST=chef_spec_latest
-# - rvm: 2.1.1
-# gemfile: gemfiles/berkshelf.gemfile
-# script: bundle exec rake berkshelf_spec
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cce1efb..8627141 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,59 @@
# Change Log
-## [Unreleased](https://github.com/chef/chef-zero/tree/HEAD)
+## [4.7.1](https://github.com/chef/chef-zero/tree/4.7.1) (2016-07-07)
+[Full Changelog](https://github.com/chef/chef-zero/compare/v4.7.0...4.7.1)
-[Full Changelog](https://github.com/chef/chef-zero/compare/v4.4.2...HEAD)
+**Implemented enhancements:**
+
+- Downgrade info log message to debug [\#221](https://github.com/chef/chef-zero/pull/221) ([stanhu](https://github.com/stanhu))
+
+## [v4.7.0](https://github.com/chef/chef-zero/tree/v4.7.0) (2016-06-30)
+[Full Changelog](https://github.com/chef/chef-zero/compare/v4.6.2...v4.7.0)
+
+**Implemented enhancements:**
+
+- Add external\_authentication\_uid to actors endpoint for querying [\#217](https://github.com/chef/chef-zero/pull/217) ([kmacgugan](https://github.com/kmacgugan))
+
+**Merged pull requests:**
+
+- Depend on rack \< 2 to restore Ruby 2.1 compat [\#219](https://github.com/chef/chef-zero/pull/219) ([tas50](https://github.com/tas50))
+
+## [v4.6.2](https://github.com/chef/chef-zero/tree/v4.6.2) (2016-04-28)
+[Full Changelog](https://github.com/chef/chef-zero/compare/v4.6.1...v4.6.2)
+
+**Fixed bugs:**
+
+- Log responses only at debug log level [\#216](https://github.com/chef/chef-zero/pull/216) ([stevendanna](https://github.com/stevendanna))
+
+## [v4.6.1](https://github.com/chef/chef-zero/tree/v4.6.1) (2016-04-14)
+[Full Changelog](https://github.com/chef/chef-zero/compare/v4.6.0...v4.6.1)
+
+**Fixed bugs:**
+
+- Actually merge key data in user PUT response [\#214](https://github.com/chef/chef-zero/pull/214) ([jkeiser](https://github.com/jkeiser))
+- Fix users endpoint in OSC compat mode to use a data store URL [\#213](https://github.com/chef/chef-zero/pull/213) ([jkeiser](https://github.com/jkeiser))
+
+## [v4.6.0](https://github.com/chef/chef-zero/tree/v4.6.0) (2016-04-14)
+[Full Changelog](https://github.com/chef/chef-zero/compare/v4.5.0...v4.6.0)
+
+**Implemented enhancements:**
+
+- Enable listening on more than one address [\#208](https://github.com/chef/chef-zero/pull/208) ([jaymzh](https://github.com/jaymzh))
+- Implemented GET /orgs/ORG/users/USER/keys\(/key\) endpoint recently added to server. [\#205](https://github.com/chef/chef-zero/pull/205) ([tylercloke](https://github.com/tylercloke))
+- Implement APIv1 behaviors [\#201](https://github.com/chef/chef-zero/pull/201) ([danielsdeleo](https://github.com/danielsdeleo))
+- Make user and client keys endpoints pass Pedant specs [\#199](https://github.com/chef/chef-zero/pull/199) ([jrunning](https://github.com/jrunning))
+- fix necessary for metadata gem [\#197](https://github.com/chef/chef-zero/pull/197) ([lamont-granquist](https://github.com/lamont-granquist))
+
+**Fixed bugs:**
+
+- Fix bugs related to Array vs Enumerator vs Port for options\[:port/host\]. [\#212](https://github.com/chef/chef-zero/pull/212) ([tylercloke](https://github.com/tylercloke))
+
+## [v4.5.0](https://github.com/chef/chef-zero/tree/v4.5.0) (2016-01-29)
+[Full Changelog](https://github.com/chef/chef-zero/compare/v4.4.2...v4.5.0)
**Merged pull requests:**
+- Run chef-zero against master Chef in travis [\#195](https://github.com/chef/chef-zero/pull/195) ([jkeiser](https://github.com/jkeiser))
- Make ACLs for policies/policy\_groups/cookbook\_artifacts work [\#194](https://github.com/chef/chef-zero/pull/194) ([jkeiser](https://github.com/jkeiser))
- Return 410 on /controls so we stop skipping that pedant spec. [\#192](https://github.com/chef/chef-zero/pull/192) ([randomcamel](https://github.com/randomcamel))
- Enable container specs. [\#191](https://github.com/chef/chef-zero/pull/191) ([randomcamel](https://github.com/randomcamel))
diff --git a/Gemfile b/Gemfile
index f11fdb4..ca2d322 100644
--- a/Gemfile
+++ b/Gemfile
@@ -5,6 +5,10 @@ gemspec
gem 'oc-chef-pedant', :github => 'chef/chef-server'
+group :changelog do
+ gem "github_changelog_generator"
+end
+
# bundler resolve failure on "rspec_junit_formatter"
# gem 'chef-pedant', :github => 'opscode/chef-pedant', :ref => "server-cli-option"
diff --git a/Rakefile b/Rakefile
index bbb984c..c43a6a3 100644
--- a/Rakefile
+++ b/Rakefile
@@ -52,11 +52,15 @@ task :berkshelf_spec do
system("cd #{gem_path} && thor spec:ci")
end
-require 'github_changelog_generator/task'
+begin
+ require "github_changelog_generator/task"
-GitHubChangelogGenerator::RakeTask.new :changelog do |config|
- # config.future_release = ChefZero::VERSION
- config.enhancement_labels = "enhancement,Enhancement,New Feature".split(',')
- config.bug_labels = "bug,Bug,Improvement,Upstream Bug".split(',')
- config.exclude_labels = "duplicate,question,invalid,wontfix,no_changelog".split(',')
+ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
+ config.future_release = ChefZero::VERSION
+ config.enhancement_labels = "enhancement,Enhancement,New Feature,Feature".split(",")
+ config.bug_labels = "bug,Bug,Improvement,Upstream Bug".split(",")
+ config.exclude_labels = "duplicate,question,invalid,wontfix,no_changelog,Exclude From Changelog,Question,Discussion".split(",")
+ end
+rescue LoadError
+ puts "github_changelog_generator is not available. gem install github_changelog_generator to generate changelogs"
end
diff --git a/bin/chef-zero b/bin/chef-zero
index 231d71b..33fc0e1 100755
--- a/bin/chef-zero
+++ b/bin/chef-zero
@@ -31,7 +31,8 @@ OptionParser.new do |opts|
opts.banner = "Usage: chef-zero [ARGS]"
opts.on("-H", "--host HOST", "Host to bind to (default: 127.0.0.1)") do |value|
- options[:host] = value
+ options[:host] ||= []
+ options[:host] << value
end
opts.on("-p", "--port PORT", "Port to listen on (e.g. 8889, or 8500-8600 or 8885,8888)") do |value|
@@ -98,7 +99,11 @@ if options[:daemon]
Process.daemon(true)
server.start(true)
else
- abort 'Process.daemon requires Ruby >= 1.9'
+ if ENV['OS'] == 'Windows_NT'
+ abort 'Daemonization is not supported on Windows. Running 'start chef-zero' will fork the process.'
+ else
+ abort 'Process.daemon requires Ruby >= 1.9'
+ end
end
else
server.start(true)
diff --git a/chef-zero.gemspec b/chef-zero.gemspec
index d512955..8114a81 100644
--- a/chef-zero.gemspec
+++ b/chef-zero.gemspec
@@ -8,22 +8,23 @@ Gem::Specification.new do |s|
s.summary = 'Self-contained, easy-setup, fast-start in-memory Chef server for testing and solo setup purposes'
s.description = s.summary
s.author = 'John Keiser'
- s.email = 'jkeiser@opscode.com'
- s.homepage = 'http://www.opscode.com'
+ s.email = 'jkeiser@chef.io'
+ s.homepage = 'http://www.chef.io'
s.license = 'Apache 2.0'
- s.add_dependency 'mixlib-log', '~> 1.3'
- s.add_dependency 'hashie', '>= 2.0', '< 4.0'
+ s.required_ruby_version = ">= 2.1.0"
+
+ s.add_dependency 'mixlib-log', '~> 1.3'
+ s.add_dependency 'hashie', '>= 2.0', '< 4.0'
s.add_dependency 'uuidtools', '~> 2.1'
s.add_dependency 'ffi-yajl', '~> 2.2'
- s.add_dependency 'rack'
+ s.add_dependency 'rack', '< 2' # 2.0 requires Ruby 2.2+
s.add_development_dependency 'pry'
s.add_development_dependency 'pry-byebug'
s.add_development_dependency 'pry-stack_explorer'
s.add_development_dependency 'rake'
s.add_development_dependency 'rspec'
- s.add_development_dependency 'github_changelog_generator'
s.add_development_dependency 'chef'
s.bindir = 'bin'
diff --git a/gemfiles/berkshelf.gemfile b/gemfiles/berkshelf.gemfile
deleted file mode 100644
index ca99e91..0000000
--- a/gemfiles/berkshelf.gemfile
+++ /dev/null
@@ -1,15 +0,0 @@
-source 'https://rubygems.org'
-
-gemspec :path => "../"
-
-gem 'berkshelf', :github => 'berkshelf'
-
-# development dependencies of berkshelf
-gem 'aruba', '~> 0.5'
-gem 'fuubar', '~> 1.1'
-gem 'rake', '~> 0.9'
-gem 'rspec', '~> 2.13'
-gem 'spork', '~> 0.9'
-gem 'test-kitchen', '~> 1.2'
-gem 'webmock', '~> 1.11'
-gem 'yard', '~> 0.8'
diff --git a/gemfiles/latest-chef.gemfile b/gemfiles/latest-chef.gemfile
deleted file mode 100644
index 47420d6..0000000
--- a/gemfiles/latest-chef.gemfile
+++ /dev/null
@@ -1,5 +0,0 @@
-source 'https://rubygems.org'
-
-gemspec :path => "../"
-
-gem 'chef', :github => 'chef/chef'
diff --git a/gemfiles/no-pedant.gemfile b/gemfiles/no-pedant.gemfile
deleted file mode 100644
index 7784f18..0000000
--- a/gemfiles/no-pedant.gemfile
+++ /dev/null
@@ -1,4 +0,0 @@
-source 'https://rubygems.org'
-
-gemspec :path => "../"
-
diff --git a/gemfiles/oc-chef-pedant.gemfile b/gemfiles/oc-chef-pedant.gemfile
deleted file mode 100644
index dcdee27..0000000
--- a/gemfiles/oc-chef-pedant.gemfile
+++ /dev/null
@@ -1,6 +0,0 @@
-source 'https://rubygems.org'
-gemspec :path => '../'
-
-gem 'rest-client', :github => 'chef/rest-client', :branch => 'lcg/1.6.7-version-lying'
-gem 'oc-chef-pedant', :github => 'chef/oc-chef-pedant', :tag => '2.0.0'
-gem 'chef', :github => 'chef/chef'
diff --git a/lib/chef_zero/chef_data/cookbook_data.rb b/lib/chef_zero/chef_data/cookbook_data.rb
index e690fde..4fd0320 100644
--- a/lib/chef_zero/chef_data/cookbook_data.rb
+++ b/lib/chef_zero/chef_data/cookbook_data.rb
@@ -129,11 +129,15 @@ module ChefZero
self[key][cookbook] = version_constraints.first || ">= 0.0.0"
end
- def method_missing(key, value = nil)
- if value.nil?
+ def method_missing(key, *values)
+ if values.nil?
self[key.to_sym]
else
- store key.to_sym, value
+ if values.length > 1
+ store key.to_sym, values
+ else
+ store key.to_sym, values.first
+ end
end
end
end
diff --git a/lib/chef_zero/chef_data/data_normalizer.rb b/lib/chef_zero/chef_data/data_normalizer.rb
index da3802d..e819f1d 100644
--- a/lib/chef_zero/chef_data/data_normalizer.rb
+++ b/lib/chef_zero/chef_data/data_normalizer.rb
@@ -163,7 +163,7 @@ module ChefZero
node['chef_type'] ||= 'node'
node['chef_environment'] ||= '_default'
node['override'] ||= {}
- node['normal'] ||= {}
+ node['normal'] ||= {"tags" => []}
node['default'] ||= {}
node['automatic'] ||= {}
node['run_list'] ||= []
diff --git a/lib/chef_zero/endpoints/actor_endpoint.rb b/lib/chef_zero/endpoints/actor_endpoint.rb
index 28d8131..dd2caf2 100644
--- a/lib/chef_zero/endpoints/actor_endpoint.rb
+++ b/lib/chef_zero/endpoints/actor_endpoint.rb
@@ -161,22 +161,23 @@ module ChefZero
# Return the data store keys path for the request client or user, e.g.
#
- # [ "organizations", <org>, "client_keys", <client>, "keys" ]
- #
- # Or:
- #
- # [ "user_keys", <user>, "keys" ]
+ # /organizations/ORG/clients/CLIENT -> /organizations/ORG/client_keys/CLIENT/keys
+ # /organizations/ORG/users/USER -> /organizations/ORG/user_keys/USER/keys
+ # /users/USER -> /user_keys/USER
#
def keys_path_base(request, client_or_user_name=nil)
rest_path = (rest_path || request.rest_path).dup
- rest_path[-1] = client_or_user_name if client_or_user_name
-
- if client?(request, rest_path)
- [ *rest_path[0..1], "client_keys" ]
+ rest_path = rest_path.dup
+ case rest_path[-2]
+ when "users"
+ rest_path[-2] = "user_keys"
+ when "clients"
+ rest_path[-2] = "client_keys"
else
- [ "user_keys" ]
+ raise "Unexpected URL #{rest_path.join("/")}: cannot determine key path"
end
- .push(rest_path.last, "keys")
+ rest_path << "keys"
+ rest_path
end
end
end
diff --git a/lib/chef_zero/endpoints/actor_keys_endpoint.rb b/lib/chef_zero/endpoints/actor_keys_endpoint.rb
index ba91a6b..f3624d6 100644
--- a/lib/chef_zero/endpoints/actor_keys_endpoint.rb
+++ b/lib/chef_zero/endpoints/actor_keys_endpoint.rb
@@ -8,7 +8,7 @@ module ChefZero
DEFAULT_PUBLIC_KEY_NAME = "default"
DATE_FORMAT = "%FT%TZ" # e.g. 2015-12-24T21:00:00Z
- def get(request)
+ def get(request, alt_uri_root=nil)
path = data_path(request)
# Get actor or 404 if it doesn't exist
@@ -18,7 +18,7 @@ module ChefZero
key_names.unshift(DEFAULT_PUBLIC_KEY_NAME) if actor_has_default_public_key?(actor_json)
result = key_names.map do |key_name|
- list_key(request, [ *path, key_name ])
+ list_key(request, [ *path, key_name ], alt_uri_root)
end
json_response(200, result)
@@ -90,7 +90,7 @@ module ChefZero
end
end
- def list_key(request, data_path)
+ def list_key(request, data_path, alt_uri_root=nil)
key_name, expiration_date =
if data_path[-1] == DEFAULT_PUBLIC_KEY_NAME
[ DEFAULT_PUBLIC_KEY_NAME, "infinity" ]
@@ -103,7 +103,7 @@ module ChefZero
DateTime.now > DateTime.strptime(expiration_date, DATE_FORMAT)
{ "name" => key_name,
- "uri" => key_uri(request, key_name),
+ "uri" => key_uri(request, key_name, alt_uri_root),
"expired" => expired }
end
@@ -111,8 +111,9 @@ module ChefZero
request.rest_path[2] == "clients"
end
- def key_uri(request, key_name)
- build_uri(request.base_uri, [ *request.rest_path, key_name ])
+ def key_uri(request, key_name, alt_uri_root=nil)
+ uri_root = alt_uri_root.nil? ? request.rest_path : alt_uri_root
+ build_uri(request.base_uri, [ *uri_root, key_name ])
end
def actor_path(request)
diff --git a/lib/chef_zero/endpoints/actors_endpoint.rb b/lib/chef_zero/endpoints/actors_endpoint.rb
index cc02246..6297aed 100644
--- a/lib/chef_zero/endpoints/actors_endpoint.rb
+++ b/lib/chef_zero/endpoints/actors_endpoint.rb
@@ -8,17 +8,12 @@ module ChefZero
def get(request)
response = super(request)
- if request.query_params['email']
- results = parse_json(response[2])
- new_results = {}
- results.each do |name, url|
- record = get_data(request, request.rest_path + [ name ], :nil)
- if record
- record = parse_json(record)
- new_results[name] = url if record['email'] == request.query_params['email']
- end
- end
- response[2] = to_json(new_results)
+ # apply query filters: if one applies, stop processing rest
+ # (precendence matches chef-server: https://github.com/chef/chef-server/blob/268a0c9/src/oc_erchef/apps/chef_objects/src/chef_user.erl#L554-L559)
+ if value = request.query_params['external_authentication_uid']
+ response[2] = filter('external_authentication_uid', value, request, response[2])
+ elsif value = request.query_params['email']
+ response[2] = filter('email', value, request, response[2])
end
if request.query_params['verbose']
@@ -65,7 +60,7 @@ module ChefZero
response =
if request.api_v0?
- user_data.merge(key_data)
+ user_data.merge!(key_data)
elsif skip_key_create && !public_key
user_data
else
@@ -85,6 +80,21 @@ module ChefZero
result
end
end
+
+ private
+
+ def filter(key, value, request, resp)
+ results = parse_json(resp)
+ new_results = {}
+ results.each do |name, url|
+ record = get_data(request, request.rest_path + [ name ], :nil)
+ if record
+ record = parse_json(record)
+ new_results[name] = url if record[key] == value
+ end
+ end
+ to_json(new_results)
+ end
end
end
end
diff --git a/lib/chef_zero/endpoints/organization_user_default_key_endpoint.rb b/lib/chef_zero/endpoints/organization_user_default_key_endpoint.rb
new file mode 100644
index 0000000..953edc1
--- /dev/null
+++ b/lib/chef_zero/endpoints/organization_user_default_key_endpoint.rb
@@ -0,0 +1,16 @@
+require 'chef_zero/rest_base'
+
+module ChefZero
+ module Endpoints
+ # GET /organizations/ORG/users/USER/keys/default
+ class OrganizationUserDefaultKeyEndpoint < RestBase
+ def get(request)
+ # 404 if it doesn't exist
+ get_data(request, request.rest_path[0..3])
+ # Just use the /users/USER/keys/default endpoint
+ request.rest_path = request.rest_path[2..-1]
+ ActorDefaultKeyEndpoint.new(server).get(request)
+ end
+ end
+ end
+end
diff --git a/lib/chef_zero/endpoints/organization_user_key_endpoint.rb b/lib/chef_zero/endpoints/organization_user_key_endpoint.rb
new file mode 100644
index 0000000..e0c114c
--- /dev/null
+++ b/lib/chef_zero/endpoints/organization_user_key_endpoint.rb
@@ -0,0 +1,17 @@
+require 'chef_zero/rest_base'
+require 'chef_zero/endpoints/actor_keys_endpoint'
+
+module ChefZero
+ module Endpoints
+ # GET /organizations/ORG/users/USER/keys/NAME
+ class OrganizationUserKeyEndpoint < RestBase
+ def get(request)
+ # 404 if not a member of the org
+ get_data(request, request.rest_path[0..3])
+ # Just use the /users/USER/keys endpoint
+ request.rest_path = request.rest_path[2..-1]
+ ActorKeyEndpoint.new(server).get(request)
+ end
+ end
+ end
+end
diff --git a/lib/chef_zero/endpoints/organization_user_keys_endpoint.rb b/lib/chef_zero/endpoints/organization_user_keys_endpoint.rb
new file mode 100644
index 0000000..96a84fe
--- /dev/null
+++ b/lib/chef_zero/endpoints/organization_user_keys_endpoint.rb
@@ -0,0 +1,17 @@
+require 'chef_zero/rest_base'
+
+module ChefZero
+ module Endpoints
+ # GET /organizations/ORG/users/USER/keys
+ class OrganizationUserKeysEndpoint < RestBase
+ def get(request)
+ # 404 if it doesn't exist
+ get_data(request, request.rest_path[0..3])
+ # Just use the /users/USER/keys/key endpoint
+ original_path = request.rest_path
+ request.rest_path = request.rest_path[2..-1]
+ ActorKeysEndpoint.new(server).get(request, original_path)
+ end
+ end
+ end
+end
diff --git a/lib/chef_zero/rest_request.rb b/lib/chef_zero/rest_request.rb
index 60738cf..c12ea31 100644
--- a/lib/chef_zero/rest_request.rb
+++ b/lib/chef_zero/rest_request.rb
@@ -14,7 +14,13 @@ module ChefZero
attr_accessor :rest_base_prefix
def base_uri
- @base_uri ||= "#{env['rack.url_scheme']}://#{env['HTTP_HOST']}#{env['SCRIPT_NAME']}"
+ # Load balancer awareness
+ if env['HTTP_X_FORWARDED_PROTO']
+ scheme = env['HTTP_X_FORWARDED_PROTO']
+ else
+ scheme = env['rack.url_scheme']
+ end
+ @base_uri ||= "#{scheme}://#{env['HTTP_HOST']}#{env['SCRIPT_NAME']}"
end
def base_uri=(value)
@@ -41,6 +47,10 @@ module ChefZero
@rest_path ||= rest_base_prefix + env['PATH_INFO'].split('/').select { |part| part != "" }
end
+ def rest_path=(rest_path)
+ @rest_path = rest_path
+ end
+
def body=(body)
@body = body
end
diff --git a/lib/chef_zero/rest_router.rb b/lib/chef_zero/rest_router.rb
index 889c810..a93af8b 100644
--- a/lib/chef_zero/rest_router.rb
+++ b/lib/chef_zero/rest_router.rb
@@ -39,7 +39,7 @@ module ChefZero
end
def log_request(request)
- ChefZero::Log.info do
+ ChefZero::Log.debug do
"#{request.method} /#{request.rest_path.join("/")}".tap do |msg|
next unless request.method =~ /^(POST|PUT)$/
@@ -60,7 +60,7 @@ module ChefZero
end
def log_response(response)
- ChefZero::Log.info {
+ ChefZero::Log.debug {
[ "",
"--- RESPONSE (#{response[0]}) ---",
response[2].chomp,
diff --git a/lib/chef_zero/server.rb b/lib/chef_zero/server.rb
index 7d508ca..19744b1 100644
--- a/lib/chef_zero/server.rb
+++ b/lib/chef_zero/server.rb
@@ -43,6 +43,9 @@ require 'chef_zero/endpoints/acl_endpoint'
require 'chef_zero/endpoints/actor_endpoint'
require 'chef_zero/endpoints/actors_endpoint'
require 'chef_zero/endpoints/actor_key_endpoint'
+require 'chef_zero/endpoints/organization_user_key_endpoint'
+require 'chef_zero/endpoints/organization_user_default_key_endpoint'
+require 'chef_zero/endpoints/organization_user_keys_endpoint'
require 'chef_zero/endpoints/actor_default_key_endpoint'
require 'chef_zero/endpoints/actor_keys_endpoint'
require 'chef_zero/endpoints/cookbooks_endpoint'
@@ -108,7 +111,7 @@ module ChefZero
class Server
DEFAULT_OPTIONS = {
- :host => '127.0.0.1',
+ :host => ['127.0.0.1'],
:port => 8889,
:log_level => :warn,
:generate_real_keys => true,
@@ -139,6 +142,7 @@ module ChefZero
def port
if @port
@port
+ # If options[:port] is not an Array or an Enumerable, it is just an Integer.
elsif !options[:port].respond_to?(:each)
options[:port]
else
@@ -161,10 +165,11 @@ module ChefZero
#
def url
sch = @options[:ssl] ? 'https' : 'http'
- @url ||= if @options[:host].include?(':')
- URI("#{sch}://[#{@options[:host]}]:#{port}").to_s
+ hosts = Array(@options[:host])
+ @url ||= if hosts.first.include?(':')
+ URI("#{sch}://[#{hosts.first}]:#{port}").to_s
else
- URI("#{sch}://#{@options[:host]}:#{port}").to_s
+ URI("#{sch}://#{hosts.first}:#{port}").to_s
end
end
@@ -262,12 +267,26 @@ module ChefZero
# @return [Thread]
# the thread the background process is running in
#
+ def listen(hosts, port)
+ hosts.each do |host|
+ @server.listen(host, port)
+ end
+ true
+ rescue Errno::EADDRINUSE
+ ChefZero::Log.warn("Port #{port} not available")
+ @server.listeners.each { |l| l.close }
+ @server.listeners.clear
+ false
+ end
+
def start_background(wait = 5)
@server = WEBrick::HTTPServer.new(
:DoNotListen => true,
:AccessLog => [],
:Logger => WEBrick::Log.new(StringIO.new, 7),
+ :RequestTimeout => 300,
:SSLEnable => options[:ssl],
+ :SSLOptions => ssl_opts,
:SSLCertName => [ [ 'CN', WEBrick::Utils::getservername ] ],
:StartCallback => proc {
@running = true
@@ -277,22 +296,17 @@ module ChefZero
@server.mount('/', Rack::Handler::WEBrick, app)
# Pick a port
- if options[:port].respond_to?(:each)
- options[:port].each do |port|
- begin
- @server.listen(options[:host], port)
- @port = port
- break
- rescue Errno::EADDRINUSE
- ChefZero::Log.info("Port #{port} in use: #{$!}")
- end
- end
- if !@port
- raise Errno::EADDRINUSE, "No port in :port range #{options[:port]} is available"
+ # If options[:port] can be an Enumerator, an Array, or an Integer,
+ # we need something that can respond to .each (Enum and Array can already).
+ Array(options[:port]).each do |port|
+ if listen(Array(options[:host]), port)
+ @port = port
+ break
end
- else
- @server.listen(options[:host], options[:port])
- @port = options[:port]
+ end
+ if !@port
+ raise Errno::EADDRINUSE,
+ "No port in :port range #{options[:port]} is available"
end
# Start the server in the background
@@ -526,7 +540,7 @@ module ChefZero
[
[ "/organizations/*/users", ActorsEndpoint.new(self) ],
[ "/organizations/*/users/*", ActorEndpoint.new(self) ],
- [ "/organizations/*/authenticate_user", OrganizationAuthenticateUserEndpoint.new(self) ],
+ [ "/organizations/*/authenticate_user", OrganizationAuthenticateUserEndpoint.new(self) ]
]
else
# EC-only
@@ -547,7 +561,6 @@ module ChefZero
[ "/authenticate_user", AuthenticateUserEndpoint.new(self) ],
[ "/system_recovery", SystemRecoveryEndpoint.new(self) ],
[ "/license", LicenseEndpoint.new(self) ],
-
[ "/organizations", OrganizationsEndpoint.new(self) ],
[ "/organizations/*", OrganizationEndpoint.new(self) ],
[ "/organizations/*/_validator_key", OrganizationValidatorKeyEndpoint.new(self) ],
@@ -573,6 +586,9 @@ module ChefZero
[ "/organizations/*/clients/*/keys", ActorKeysEndpoint.new(self) ],
[ "/organizations/*/clients/*/keys/default", ActorDefaultKeyEndpoint.new(self) ],
[ "/organizations/*/clients/*/keys/*", ActorKeyEndpoint.new(self) ],
+ [ "/organizations/*/users/*/keys", OrganizationUserKeysEndpoint.new(self) ],
+ [ "/organizations/*/users/*/keys/default", OrganizationUserDefaultKeyEndpoint.new(self) ],
+ [ "/organizations/*/users/*/keys/*", OrganizationUserKeyEndpoint.new(self) ],
[ "/organizations/*/controls", ControlsEndpoint.new(self) ],
[ "/organizations/*/cookbooks", CookbooksEndpoint.new(self) ],
[ "/organizations/*/cookbooks/*", CookbookEndpoint.new(self) ],
@@ -694,5 +710,16 @@ module ChefZero
end
value
end
+
+ ## Disable unsecure ssl
+ ## Ref: https://www.ruby-lang.org/en/news/2014/10/27/changing-default-settings-of-ext-openssl/
+ def ssl_opts
+ ssl_opts = OpenSSL::SSL::OP_ALL
+ ssl_opts &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS)
+ ssl_opts |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
+ ssl_opts |= OpenSSL::SSL::OP_NO_SSLv2 if defined?(OpenSSL::SSL::OP_NO_SSLv2)
+ ssl_opts |= OpenSSL::SSL::OP_NO_SSLv3 if defined?(OpenSSL::SSL::OP_NO_SSLv3)
+ ssl_opts
+ end
end
end
diff --git a/lib/chef_zero/solr/query/regexpable_query.rb b/lib/chef_zero/solr/query/regexpable_query.rb
index 241e675..cebc011 100644
--- a/lib/chef_zero/solr/query/regexpable_query.rb
+++ b/lib/chef_zero/solr/query/regexpable_query.rb
@@ -21,8 +21,8 @@ module ChefZero
end
DEFAULT_FIELD = "text"
- WORD_CHARACTER = "[A-Za-z0-9@._':]"
- NON_WORD_CHARACTER = "[^A-Za-z0-9@._':]"
+ WORD_CHARACTER = "[A-Za-z0-9@._':\-]"
+ NON_WORD_CHARACTER = "[^A-Za-z0-9@._':\-]"
end
end
end
diff --git a/lib/chef_zero/solr/query/unary_operator.rb b/lib/chef_zero/solr/query/unary_operator.rb
index fc46c0d..a873932 100644
--- a/lib/chef_zero/solr/query/unary_operator.rb
+++ b/lib/chef_zero/solr/query/unary_operator.rb
@@ -16,8 +16,7 @@ module ChefZero
def matches_doc?(doc)
case @operator
- when '-'
- when 'NOT'
+ when '-', 'NOT'
!operand.matches_doc?(doc)
when '+'
# TODO This operator uses relevance to eliminate other, unrelated
@@ -28,8 +27,7 @@ module ChefZero
def matches_values?(values)
case @operator
- when '-'
- when 'NOT'
+ when '-', 'NOT'
!operand.matches_values?(values)
when '+'
# TODO This operator uses relevance to eliminate other, unrelated
diff --git a/lib/chef_zero/version.rb b/lib/chef_zero/version.rb
index 6fb6e7e..d39f82c 100644
--- a/lib/chef_zero/version.rb
+++ b/lib/chef_zero/version.rb
@@ -1,3 +1,3 @@
module ChefZero
- VERSION = '4.5.0'
+ VERSION = '4.7.1'
end
diff --git a/spec/search_spec.rb b/spec/search_spec.rb
index df0522c..54392a6 100644
--- a/spec/search_spec.rb
+++ b/spec/search_spec.rb
@@ -24,6 +24,10 @@ describe ChefZero::Solr::SolrParser do
search_for('foo:[a TO c]').size.should eq(1)
end
+ it "handles -" do
+ search_for('-foo:a').size.should eq(1)
+ end
+
it "handles wildcard ranges" do
search_for('foo:[* TO c]').size.should eq(1)
search_for('foo:[c TO *]').size.should eq(1)
diff --git a/spec/server_spec.rb b/spec/server_spec.rb
index d46084f..123a13e 100644
--- a/spec/server_spec.rb
+++ b/spec/server_spec.rb
@@ -27,6 +27,10 @@ describe ChefZero::Server do
expect { ChefZero::Server.new(:port => 8889.upto(8889)).start_background }.to raise_error Errno::EADDRINUSE
end
+ it 'has a very patient request timeout' do
+ expect(@server.server.config[:RequestTimeout]).to eq 300
+ end
+
context 'accept headers' do
def get_nodes(accepts)
uri = URI(@server.url)