summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Smith <tsmith@chef.io>2021-09-23 16:32:19 -0700
committerGitHub <noreply@github.com>2021-09-23 16:32:19 -0700
commit10f9391e8283544ae13941d7521be3be01e20b75 (patch)
tree8fbf5aa296fbd4ae3236c82a48d448e313df5f40
parentf7f38591aa98dac71e2b4c83c23cfe39b16b9d99 (diff)
parent4060277bdf2eac72f2d871829109c4ae1c7c472a (diff)
downloadchef-10f9391e8283544ae13941d7521be3be01e20b75.tar.gz
Merge pull request #12062 from gogsbread/json
Add Json verifier
-rw-r--r--lib/chef/provider/file.rb1
-rw-r--r--lib/chef/resource/file/verification/json.rb50
-rw-r--r--spec/unit/resource/file/verification/json_spec.rb72
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