diff options
author | Tim Smith <tsmith@chef.io> | 2021-09-23 16:32:19 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-23 16:32:19 -0700 |
commit | 10f9391e8283544ae13941d7521be3be01e20b75 (patch) | |
tree | 8fbf5aa296fbd4ae3236c82a48d448e313df5f40 | |
parent | f7f38591aa98dac71e2b4c83c23cfe39b16b9d99 (diff) | |
parent | 4060277bdf2eac72f2d871829109c4ae1c7c472a (diff) | |
download | chef-10f9391e8283544ae13941d7521be3be01e20b75.tar.gz |
Merge pull request #12062 from gogsbread/json
Add Json verifier
-rw-r--r-- | lib/chef/provider/file.rb | 1 | ||||
-rw-r--r-- | lib/chef/resource/file/verification/json.rb | 50 | ||||
-rw-r--r-- | spec/unit/resource/file/verification/json_spec.rb | 72 |
3 files changed, 123 insertions, 0 deletions
diff --git a/lib/chef/provider/file.rb b/lib/chef/provider/file.rb index 8f77cc4641..4ac86a6c8a 100644 --- a/lib/chef/provider/file.rb +++ b/lib/chef/provider/file.rb @@ -27,6 +27,7 @@ require_relative "../scan_access_control" require_relative "../mixin/checksum" require_relative "../mixin/file_class" require_relative "../mixin/enforce_ownership_and_permissions" +require_relative "../resource/file/verification/json" require_relative "../resource/file/verification/yaml" require_relative "../util/backup" require_relative "../util/diff" diff --git a/lib/chef/resource/file/verification/json.rb b/lib/chef/resource/file/verification/json.rb new file mode 100644 index 0000000000..cb814a6839 --- /dev/null +++ b/lib/chef/resource/file/verification/json.rb @@ -0,0 +1,50 @@ +# +# Author:: Antony Thomas (<antonydeepak@gmail.com>) +# Copyright:: Copyright (c) Facebook, Inc. and its affiliates. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +class Chef + class Resource + class File + class Verification + + # + # Extends File verification to provide Json verification + # + # Example: + # file 'foo.json' do + # content '{"foo": "bar"}' + # verify :json + # end + # + # + + class Json < Chef::Resource::File::Verification + + provides :json + + def verify(path, opts = {}) + Chef::JSONCompat.parse(IO.read(path)) + true + rescue Chef::Exceptions::JSON::ParseError => e + Chef::Log.error("Json syntax verify failed with : #{e.message}") + false + end + end + end + end + end +end diff --git a/spec/unit/resource/file/verification/json_spec.rb b/spec/unit/resource/file/verification/json_spec.rb new file mode 100644 index 0000000000..78460a21e2 --- /dev/null +++ b/spec/unit/resource/file/verification/json_spec.rb @@ -0,0 +1,72 @@ +# +# Author:: Antony Thomas (<antonydeepak@gmail.com>) +# Copyright:: Copyright (c) Facebook, Inc. and its affiliates. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "spec_helper" + +describe Chef::Resource::File::Verification::Json do + let(:parent_resource) { Chef::Resource.new("llama") } + + before(:all) do + @valid_json = "valid-#{Time.now.to_i}.json" + f = File.new(@valid_json, "w") + f.write('{ + "foo": "bar" + }') + f.close + + @invalid_json = "invalid-#{Time.now.to_i}.json" + f = File.new(@invalid_json, "w") + f.write("{ + 'foo': 'bar' + }") + f.close + + @empty_json = "empty-#{Time.now.to_i}.json" + File.new(@empty_json, "w").close + end + + context "verify" do + it "returns true for valid json" do + v = Chef::Resource::File::Verification::Json.new(parent_resource, :json, {}) + expect(v.verify(@valid_json)).to eq(true) + end + + it "returns false for invalid json" do + v = Chef::Resource::File::Verification::Json.new(parent_resource, :json, {}) + expect(v.verify(@invalid_json)).to eq(false) + end + + it "returns true for empty file" do + # Expectation here is different from that of default JSON parser included in ruby 2.4+. + # The default parser considers empty string as invalid JSON + # https://stackoverflow.com/questions/30621802/why-does-json-parse-fail-with-the-empty-string, + # however JSONCompat parses an empty string to `nil`. + # We are retaining the behavior of JSONCompat for two reasons + # - It is universal inside Chef codebase + # - It can be helpful to not throw an error when a `file` or `template` is empty + v = Chef::Resource::File::Verification::Json.new(parent_resource, :json, {}) + expect(v.verify(@empty_json)).to eq(true) + end + end + + after(:all) do + File.delete(@valid_json) + File.delete(@invalid_json) + File.delete(@empty_json) + end +end |