From cb821526aecd1a0b0c15b84e3549c3f568a73972 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Mon, 19 Jan 2015 10:37:25 -0800 Subject: REVERT ME - use local copy of pedant for now --- Gemfile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 3845ad6..3009cd7 100644 --- a/Gemfile +++ b/Gemfile @@ -2,5 +2,12 @@ source 'https://rubygems.org' gemspec gem 'rest-client', :github => 'opscode/rest-client' -gem 'chef-pedant', :github => 'opscode/chef-pedant', :ref => '81f3b4ecbc09d04950f2819b38a6a8f906ada2a7' +# TODO: REVERT THIS +#gem 'chef-pedant', :github => 'opscode/chef-pedant', :ref => '81f3b4ecbc09d04950f2819b38a6a8f906ada2a7' gem 'chef', :github => 'opscode/chef', :ref => 'a2dee150e68a611249577a8adcb2c3e329d6762d' + +# TODO: REVERT THIS +gem 'chef-pedant', path: "../chef-pedant" + +# TODO: and this +gem 'oc-chef-pedant', path: "../oc-chef-pedant" -- cgit v1.2.1 From af2b187a9b7856951317e5de06c62f721e40522d Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Mon, 19 Jan 2015 10:37:46 -0800 Subject: Add desc to rake tasks so you can see them in rake -T --- Rakefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Rakefile b/Rakefile index 3a3eb96..209b5df 100644 --- a/Rakefile +++ b/Rakefile @@ -5,14 +5,17 @@ require 'chef_zero/version' task :default => :pedant +desc "run specs" task :spec do system('rspec spec/*_spec.rb') end +desc "run pedant" task :pedant do require File.expand_path('spec/run_pedant') end +desc "run oc pedant" task :oc_pedant do require File.expand_path('spec/run_oc_pedant') end -- cgit v1.2.1 From a81096de5d36afbacc6613378d6f837a34535678 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Tue, 20 Jan 2015 17:30:20 -0800 Subject: Show invalid data in error message --- lib/chef_zero/data_store/memory_store_v2.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/chef_zero/data_store/memory_store_v2.rb b/lib/chef_zero/data_store/memory_store_v2.rb index 9f8b80e..d330972 100644 --- a/lib/chef_zero/data_store/memory_store_v2.rb +++ b/lib/chef_zero/data_store/memory_store_v2.rb @@ -47,7 +47,7 @@ module ChefZero def create(path, name, data, *options) if !data.is_a?(String) - raise "set only works with strings" + raise "set only works with strings (given data: #{data.inspect})" end parent = _get(path, options.include?(:create_dir)) -- cgit v1.2.1 From 3840ba64b808a935451e450fe4691d96409d28f1 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Tue, 20 Jan 2015 17:30:53 -0800 Subject: Add policies endpoint --- lib/chef_zero/endpoints/policies_endpoint.rb | 127 +++++++++++++++++++++++++++ lib/chef_zero/server.rb | 3 +- 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 lib/chef_zero/endpoints/policies_endpoint.rb diff --git a/lib/chef_zero/endpoints/policies_endpoint.rb b/lib/chef_zero/endpoints/policies_endpoint.rb new file mode 100644 index 0000000..c115398 --- /dev/null +++ b/lib/chef_zero/endpoints/policies_endpoint.rb @@ -0,0 +1,127 @@ +require 'ffi_yajl' +require 'chef_zero/endpoints/rest_object_endpoint' +require 'chef_zero/chef_data/data_normalizer' + +module ChefZero + module Endpoints + # /policies/:group/:name + class PoliciesEndpoint < RestObjectEndpoint + def initialize(server) + super(server, 'id') + end + + def get(request) + already_json_response(200, get_data(request)) + end + + # Right now we're allowing PUT to create. + def put(request) + error = validate(request) + return error if error + + code = create_or_update(request) + already_json_response(code, request.body) + end + + def delete(request) + result = get_data(request, request.rest_path) + delete_data(request, request.rest_path, :data_store_exceptions) + already_json_response(200, result) + end + + def create_or_update(request) + set_data(request, request.rest_path, request.body, :data_store_exceptions) + 200 + rescue ChefZero::DataStore::DataNotFoundError + name = request.rest_path[4] + data_store.create(request.rest_path[0..3], name, request.body, :create_dir) + 201 + end + + private + + def validate(request) + req_object = validate_json(request.body) + validate_name(request, req_object) || + validate_run_list(req_object) || + validate_each_run_list_item(req_object) || + validate_cookbook_locks_collection(req_object) || + validate_each_cookbook_locks_item(req_object) + end + + def validate_json(request_body) + FFI_Yajl::Parser.parse(request_body) + # TODO: rescue parse error, return 400 + # error(400, "Must specify #{identity_keys.map { |k| k.inspect }.join(' or ')} in JSON") + end + + def validate_name(request, req_object) + if !req_object.key?("name") + error(400, "Must specify 'name' in JSON") + elsif req_object["name"] != URI.decode(request.rest_path[4]) + error(400, "'name' field in JSON must match the policy name in the URL") + elsif req_object["name"].size > 255 + error(400, "'name' field in JSON must be 255 characters or fewer") + elsif req_object["name"] !~ /^[\-[:alnum:]_\.\:]+$/ + error(400, "'name' field in JSON must be contain only alphanumeric, hypen, underscore, and dot characters") + end + end + + def validate_run_list(req_object) + if !req_object.key?("run_list") + error(400, "Must specify 'run_list' in JSON") + elsif !req_object["run_list"].kind_of?(Array) + error(400, "'run_list' must be an Array of run list items") + end + end + + def validate_each_run_list_item(req_object) + req_object["run_list"].each do |run_list_item| + if res_400 = validate_run_list_item(run_list_item) + return res_400 + end + end + nil + end + + def validate_run_list_item(run_list_item) + if !run_list_item.kind_of?(String) + error(400, "Items in run_list must be strings in fully qualified recipe format, like recipe[cookbook::recipe]") + elsif run_list_item !~ /\Arecipe\[[^\s]+::[^\s]+\]\Z/ + error(400, "Items in run_list must be strings in fully qualified recipe format, like recipe[cookbook::recipe]") + end + end + + def validate_cookbook_locks_collection(req_object) + if !req_object.key?("cookbook_locks") + error(400, "Must specify 'cookbook_locks' in JSON") + elsif !req_object["cookbook_locks"].kind_of?(Hash) + error(400, "'cookbook_locks' must be a JSON object of cookbook_name: lock_data pairs") + end + end + + def validate_each_cookbook_locks_item(req_object) + req_object["cookbook_locks"].each do |cookbook_name, lock| + if res_400 = validate_cookbook_locks_item(cookbook_name, lock) + return res_400 + end + end + nil + end + + def validate_cookbook_locks_item(cookbook_name, lock) + if !lock.kind_of?(Hash) + error(400, "cookbook_lock entries must be a JSON object") + elsif !lock.key?("identifier") + error(400, "cookbook_lock entries must contain an 'identifier' field") + elsif !lock.key?("dotted_decimal_identifier") + error(400, "cookbook_lock entries must contain an 'dotted_decimal_identifier' field") + elsif lock["identifier"].size > 255 + error(400, "cookbook_lock entries 'identifier' field must be 255 or fewer characters") + end + end + + end + end +end + diff --git a/lib/chef_zero/server.rb b/lib/chef_zero/server.rb index fb2b127..de2a3f5 100644 --- a/lib/chef_zero/server.rb +++ b/lib/chef_zero/server.rb @@ -69,6 +69,7 @@ require 'chef_zero/endpoints/organization_users_endpoint' require 'chef_zero/endpoints/organization_user_endpoint' require 'chef_zero/endpoints/organization_validator_key_endpoint' require 'chef_zero/endpoints/principal_endpoint' +require 'chef_zero/endpoints/policies_endpoint' require 'chef_zero/endpoints/role_endpoint' require 'chef_zero/endpoints/role_environments_endpoint' require 'chef_zero/endpoints/sandboxes_endpoint' @@ -358,7 +359,6 @@ module ChefZero # } # } def load_data(contents, org_name = nil) - passed_org = !!org_name org_name ||= options[:single_org] if org_name.nil? && contents.keys != [ 'users' ] raise "Must pass an org name to load_data or run in single_org mode" @@ -516,6 +516,7 @@ module ChefZero [ "/organizations/*/environments/*/roles/*", EnvironmentRoleEndpoint.new(self) ], [ "/organizations/*/nodes", RestListEndpoint.new(self) ], [ "/organizations/*/nodes/*", NodeEndpoint.new(self) ], + [ "/organizations/*/policies/*/*", PoliciesEndpoint.new(self) ], [ "/organizations/*/principals/*", PrincipalEndpoint.new(self) ], [ "/organizations/*/roles", RestListEndpoint.new(self) ], [ "/organizations/*/roles/*", RoleEndpoint.new(self) ], -- cgit v1.2.1 From c8d59328d6ed3b1e4fb45c4d08bbf20a3be59e71 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Tue, 27 Jan 2015 14:49:55 -0800 Subject: Update bundle and test config for latest pedant --- Gemfile | 8 +------- spec/run_pedant.rb | 2 ++ spec/support/pedant.rb | 4 ++++ 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 3009cd7..06f24e8 100644 --- a/Gemfile +++ b/Gemfile @@ -2,12 +2,6 @@ source 'https://rubygems.org' gemspec gem 'rest-client', :github => 'opscode/rest-client' -# TODO: REVERT THIS -#gem 'chef-pedant', :github => 'opscode/chef-pedant', :ref => '81f3b4ecbc09d04950f2819b38a6a8f906ada2a7' +gem 'chef-pedant', :github => 'opscode/chef-pedant', :ref => '0a3547aa38b98f57bf856aee055d42af4d2de06c' gem 'chef', :github => 'opscode/chef', :ref => 'a2dee150e68a611249577a8adcb2c3e329d6762d' -# TODO: REVERT THIS -gem 'chef-pedant', path: "../chef-pedant" - -# TODO: and this -gem 'oc-chef-pedant', path: "../oc-chef-pedant" diff --git a/spec/run_pedant.rb b/spec/run_pedant.rb index 3657da8..2caf1ff 100644 --- a/spec/run_pedant.rb +++ b/spec/run_pedant.rb @@ -72,11 +72,13 @@ begin Pedant.config.suite = 'api' Pedant.config[:config_file] = 'spec/support/pedant.rb' + Pedant.setup([ '--skip-knife', '--skip-validation', '--skip-authentication', '--skip-authorization', + '--skip-keys', '--skip-omnibus' ]) diff --git a/spec/support/pedant.rb b/spec/support/pedant.rb index d6100d2..29a0ec1 100644 --- a/spec/support/pedant.rb +++ b/spec/support/pedant.rb @@ -75,6 +75,10 @@ superuser_name 'admin' superuser_key key webui_key key +# The Policies endpoint is feature-flagged during development. Zero supports +# the policies endpoint, so turn it on: +policies? true + # Set the platform_class platform_class Pedant::OpenSourcePlatform -- cgit v1.2.1 From 606c36f731ff6af0ae24c603229097f18537a6f3 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Tue, 27 Jan 2015 14:51:06 -0800 Subject: Set backtraces on "nested" exceptions Future ruby has automagic nested exceptions but with current ruby raising a new exception during rescue obscures the backtrace --- lib/chef_zero/data_store/v1_to_v2_adapter.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/chef_zero/data_store/v1_to_v2_adapter.rb b/lib/chef_zero/data_store/v1_to_v2_adapter.rb index 576f27d..d9ea6e1 100644 --- a/lib/chef_zero/data_store/v1_to_v2_adapter.rb +++ b/lib/chef_zero/data_store/v1_to_v2_adapter.rb @@ -112,9 +112,13 @@ module ChefZero begin yield rescue DataAlreadyExistsError => e - raise DataAlreadyExistsError.new([ 'organizations', single_org ] + e.path, e) + err = DataAlreadyExistsError.new([ 'organizations', single_org ] + e.path, e) + err.set_backtrace(e.backtrace) + raise err rescue DataNotFoundError => e - raise DataNotFoundError.new([ 'organizations', single_org ] + e.path, e) + err = DataNotFoundError.new([ 'organizations', single_org ] + e.path, e) + err.set_backtrace(e.backtrace) + raise e end end -- cgit v1.2.1 From 1f01d551a48dc86cdb59caf9ed340a19e78db69a Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Wed, 28 Jan 2015 15:32:43 -0800 Subject: Filter out some oc-pedant tests that aren't supported --- spec/run_oc_pedant.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/run_oc_pedant.rb b/spec/run_oc_pedant.rb index 562bf6a..79d92e7 100644 --- a/spec/run_oc_pedant.rb +++ b/spec/run_oc_pedant.rb @@ -34,6 +34,9 @@ begin Pedant.config[:config_file] = 'spec/support/oc_pedant.rb' Pedant.setup([ '--skip-knife', + '--skip-keys', + '--skip-controls', + '--skip-acl', '--skip-validation', '--skip-authentication', '--skip-authorization', -- cgit v1.2.1 From fef75d564476d868438ac80889a3bbc65de6d845 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Wed, 28 Jan 2015 15:33:09 -0800 Subject: Update pedant and chef to mutually compatible versions --- Gemfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 06f24e8..0041f61 100644 --- a/Gemfile +++ b/Gemfile @@ -2,6 +2,7 @@ source 'https://rubygems.org' gemspec gem 'rest-client', :github => 'opscode/rest-client' -gem 'chef-pedant', :github => 'opscode/chef-pedant', :ref => '0a3547aa38b98f57bf856aee055d42af4d2de06c' -gem 'chef', :github => 'opscode/chef', :ref => 'a2dee150e68a611249577a8adcb2c3e329d6762d' +gem 'chef-pedant', :github => 'opscode/chef-pedant', :tag => '1.0.41' + +gem 'chef', :github => 'opscode/chef', :ref => '92eefc79bb28d217b15099655244228b9e1efec7' -- cgit v1.2.1 From ff6c5d36be4f84bf284bcdb5470323b167d150a4 Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Wed, 28 Jan 2015 17:55:36 -0800 Subject: Check before create/update to determine correct status code The memore store and ChefFS store have different behaviors when writing to an existing object, so work around that by checking for the existence of the item before creating/updating. --- lib/chef_zero/endpoints/policies_endpoint.rb | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/chef_zero/endpoints/policies_endpoint.rb b/lib/chef_zero/endpoints/policies_endpoint.rb index c115398..992d5ae 100644 --- a/lib/chef_zero/endpoints/policies_endpoint.rb +++ b/lib/chef_zero/endpoints/policies_endpoint.rb @@ -19,7 +19,15 @@ module ChefZero error = validate(request) return error if error - code = create_or_update(request) + code = + if data_store.exists?(request.rest_path) + set_data(request, request.rest_path, request.body, :data_store_exceptions) + 200 + else + name = request.rest_path[4] + data_store.create(request.rest_path[0..3], name, request.body, :create_dir) + 201 + end already_json_response(code, request.body) end @@ -29,15 +37,6 @@ module ChefZero already_json_response(200, result) end - def create_or_update(request) - set_data(request, request.rest_path, request.body, :data_store_exceptions) - 200 - rescue ChefZero::DataStore::DataNotFoundError - name = request.rest_path[4] - data_store.create(request.rest_path[0..3], name, request.body, :create_dir) - 201 - end - private def validate(request) -- cgit v1.2.1 From fb454e1b87462f951bea3ec666351293072d160a Mon Sep 17 00:00:00 2001 From: danielsdeleo Date: Wed, 28 Jan 2015 16:08:43 -0800 Subject: Remove unsupported ruby from travis * Chef Client no longer supports Ruby 1.9.3 or 1.8, so drop both of those. * Drop the patch version number from MRI versions so we just use the latest patch * Turn off sudo. This allows us to run on the faster container-based build cluster --- .travis.yml | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index 985730f..c0b640e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,38 +1,28 @@ -rvm: 1.9.3 - +rvm: 2.0 gemfile: Gemfile +sudo: false script: bundle exec rake pedant matrix: include: - - rvm: 1.8.7 - - rvm: 1.8.7 - env: SKIP_PEDANT=true - gemfile: gemfiles/no-pedant.gemfile - - rvm: jruby-19mode - - rvm: jruby-19mode - env: SKIP_PEDANT=true - gemfile: gemfiles/no-pedant.gemfile - - rvm: 2.0.0 - - rvm: 2.1.1 - - rvm: 2.1.1 + - rvm: 2.0 + - rvm: 2.1 + - rvm: 2.1 env: SINGLE_ORG=true - - rvm: 2.1.1 + - rvm: 2.1 env: CHEF_FS=true - - rvm: 2.1.1 + - rvm: 2.1 env: FILE_STORE=true - - rvm: 2.1.1 + - rvm: 2.1 script: bundle exec rake chef_spec env: TEST=chef_spec - - rvm: 2.1.1 + - rvm: 2.1 script: bundle exec rake spec env: TEST=rake_spec allow_failures: - - rvm: 1.8.7 - - rvm: jruby-19mode - - rvm: 2.1.1 + - rvm: 2.1 gemfile: gemfiles/latest-chef.gemfile script: bundle exec rake chef_spec enc: TEST=chef_spec_latest -- cgit v1.2.1