diff options
author | Thom May <thom@may.lt> | 2017-03-14 17:09:51 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-14 17:09:51 +0000 |
commit | 5f998d4e2b9d4c88bf1e58d1f1c19dc4d17ffeff (patch) | |
tree | e719e34d1185150eecfcc52c83364052d9652a8d | |
parent | 813117990834b2dbc53c7f81995670ac246a52c8 (diff) | |
parent | b0cb79f89d7ed5efafd81e01d28dcce1014f41b3 (diff) | |
download | chef-5f998d4e2b9d4c88bf1e58d1f1c19dc4d17ffeff.tar.gz |
Merge pull request #5899 from chef/tm/remove_json_autoinflate
Kill JSON auto inflate with fire
-rw-r--r-- | lib/chef/api_client.rb | 5 | ||||
-rw-r--r-- | lib/chef/cookbook_version.rb | 5 | ||||
-rw-r--r-- | lib/chef/data_bag.rb | 6 | ||||
-rw-r--r-- | lib/chef/data_bag_item.rb | 6 | ||||
-rw-r--r-- | lib/chef/environment.rb | 5 | ||||
-rw-r--r-- | lib/chef/json_compat.rb | 94 | ||||
-rw-r--r-- | lib/chef/key.rb | 5 | ||||
-rw-r--r-- | lib/chef/knife/core/ui.rb | 3 | ||||
-rw-r--r-- | lib/chef/node.rb | 6 | ||||
-rw-r--r-- | lib/chef/org.rb | 5 | ||||
-rw-r--r-- | lib/chef/resource.rb | 11 | ||||
-rw-r--r-- | lib/chef/resource_collection.rb | 10 | ||||
-rw-r--r-- | lib/chef/resource_collection/resource_collection_serialization.rb | 9 | ||||
-rw-r--r-- | lib/chef/resource_collection/resource_list.rb | 6 | ||||
-rw-r--r-- | lib/chef/resource_collection/resource_set.rb | 8 | ||||
-rw-r--r-- | lib/chef/role.rb | 6 | ||||
-rw-r--r-- | lib/chef/user.rb | 5 | ||||
-rw-r--r-- | lib/chef/user_v1.rb | 5 | ||||
-rw-r--r-- | spec/unit/json_compat_spec.rb | 32 | ||||
-rw-r--r-- | spec/unit/knife/core/ui_spec.rb | 29 | ||||
-rw-r--r-- | spec/unit/resource_collection_spec.rb | 4 | ||||
-rw-r--r-- | spec/unit/resource_spec.rb | 2 |
22 files changed, 67 insertions, 200 deletions
diff --git a/lib/chef/api_client.rb b/lib/chef/api_client.rb index 6999a4f52d..087de3fdf9 100644 --- a/lib/chef/api_client.rb +++ b/lib/chef/api_client.rb @@ -140,11 +140,6 @@ class Chef client end - def self.json_create(data) - Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::ApiClient#from_hash") - from_hash(data) - end - def self.from_json(j) from_hash(Chef::JSONCompat.parse(j)) end diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb index 2037b5f972..7353941bb1 100644 --- a/lib/chef/cookbook_version.rb +++ b/lib/chef/cookbook_version.rb @@ -484,11 +484,6 @@ class Chef cookbook_version end - def self.json_create(o) - Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::CookbookVersion#from_hash") - from_hash(o) - end - def self.from_cb_artifact_data(o) from_hash(o) end diff --git a/lib/chef/data_bag.rb b/lib/chef/data_bag.rb index 4bb656a2c8..15531d7304 100644 --- a/lib/chef/data_bag.rb +++ b/lib/chef/data_bag.rb @@ -78,12 +78,6 @@ class Chef Chef::ServerAPI.new(Chef::Config[:chef_server_url]) end - # Create a Chef::Role from JSON - def self.json_create(o) - Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::DataBag#from_hash") - from_hash(o) - end - def self.from_hash(o) bag = new bag.name(o["name"]) diff --git a/lib/chef/data_bag_item.rb b/lib/chef/data_bag_item.rb index 2bd27e3eef..ddb520dc0b 100644 --- a/lib/chef/data_bag_item.rb +++ b/lib/chef/data_bag_item.rb @@ -139,12 +139,6 @@ class Chef item end - # Create a Chef::DataBagItem from JSON - def self.json_create(o) - Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::DataBagItem#from_hash") - from_hash(o) - end - # Load a Data Bag Item by name via either the RESTful API or local data_bag_path if run in solo mode def self.load(data_bag, name) if Chef::Config[:solo_legacy_mode] diff --git a/lib/chef/environment.rb b/lib/chef/environment.rb index 545a2e51eb..621a122440 100644 --- a/lib/chef/environment.rb +++ b/lib/chef/environment.rb @@ -216,11 +216,6 @@ class Chef end end - def self.json_create(o) - Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::Environment#from_hash") - from_hash(o) - end - def self.from_hash(o) environment = new environment.name(o["name"]) diff --git a/lib/chef/json_compat.rb b/lib/chef/json_compat.rb index c8f5496345..b819d5e57d 100644 --- a/lib/chef/json_compat.rb +++ b/lib/chef/json_compat.rb @@ -26,23 +26,6 @@ class Chef class JSONCompat JSON_MAX_NESTING = 1000 - JSON_CLASS = "json_class".freeze - - CHEF_APICLIENT = "Chef::ApiClient".freeze - CHEF_CHECKSUM = "Chef::Checksum".freeze - CHEF_COOKBOOKVERSION = "Chef::CookbookVersion".freeze - CHEF_DATABAG = "Chef::DataBag".freeze - CHEF_DATABAGITEM = "Chef::DataBagItem".freeze - CHEF_ENVIRONMENT = "Chef::Environment".freeze - CHEF_NODE = "Chef::Node".freeze - CHEF_ROLE = "Chef::Role".freeze - CHEF_SANDBOX = "Chef::Sandbox".freeze - CHEF_RESOURCE = "Chef::Resource".freeze - CHEF_RESOURCECOLLECTION = "Chef::ResourceCollection".freeze - CHEF_RESOURCESET = "Chef::ResourceCollection::ResourceSet".freeze - CHEF_RESOURCELIST = "Chef::ResourceCollection::ResourceList".freeze - CHEF_RUNLISTEXPANSION = "Chef::RunListExpansion".freeze - class <<self # API to use to avoid create_addtions @@ -63,40 +46,7 @@ class Chef raise Chef::Exceptions::JSON::ParseError, "Top level JSON object must be a Hash or Array. (actual: #{obj.class})" end - # The old default in the json gem (which we are mimicing because we - # sadly rely on this misfeature) is to "create additions" i.e., convert - # JSON objects into ruby objects. Explicit :create_additions => false - # is required to turn it off. - if opts[:create_additions].nil? || opts[:create_additions] - map_to_rb_obj(obj) - else - obj - end - end - - # Look at an object that's a basic type (from json parse) and convert it - # to an instance of Chef classes if desired. - def map_to_rb_obj(json_obj) - case json_obj - when Hash - mapped_hash = map_hash_to_rb_obj(json_obj) - if json_obj.has_key?(JSON_CLASS) && (class_to_inflate = class_for_json_class(json_obj[JSON_CLASS])) - class_to_inflate.json_create(mapped_hash) - else - mapped_hash - end - when Array - json_obj.map { |e| map_to_rb_obj(e) } - else - json_obj - end - end - - def map_hash_to_rb_obj(json_hash) - json_hash.each do |key, value| - json_hash[key] = map_to_rb_obj(value) - end - json_hash + obj end def to_json(obj, opts = nil) @@ -113,48 +63,6 @@ class Chef to_json(obj, options_map).chomp end - # Map +json_class+ to a Class object. We use a +case+ instead of a Hash - # assigned to a constant because otherwise this file could not be loaded - # until all the constants were defined, which means you'd have to load - # the world to get json, which would make knife very slow. - def class_for_json_class(json_class) - case json_class - when CHEF_APICLIENT - Chef::ApiClient - when CHEF_CHECKSUM - Chef::Checksum - when CHEF_COOKBOOKVERSION - Chef::CookbookVersion - when CHEF_DATABAG - Chef::DataBag - when CHEF_DATABAGITEM - Chef::DataBagItem - when CHEF_ENVIRONMENT - Chef::Environment - when CHEF_NODE - Chef::Node - when CHEF_ROLE - Chef::Role - when CHEF_SANDBOX - # a falsey return here will disable object inflation/"create - # additions" in the caller. In Chef 11 this is correct, we just have - # a dummy Chef::Sandbox class for compat with Chef 10 servers. - false - when CHEF_RESOURCE - Chef::Resource - when CHEF_RESOURCECOLLECTION - Chef::ResourceCollection - when CHEF_RESOURCESET - Chef::ResourceCollection::ResourceSet - when CHEF_RESOURCELIST - Chef::ResourceCollection::ResourceList - when /^Chef::Resource/ - Chef::Resource.find_descendants_by_name(json_class) - else - raise Chef::Exceptions::JSON::ParseError, "Unsupported `json_class` type '#{json_class}'" - end - end - end end end diff --git a/lib/chef/key.rb b/lib/chef/key.rb index c68fe1039c..bf8e533d62 100644 --- a/lib/chef/key.rb +++ b/lib/chef/key.rb @@ -222,11 +222,6 @@ class Chef Chef::Key.from_hash(Chef::JSONCompat.from_json(json)) end - def json_create(json) - Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::Key#from_json or one of the load_by methods.") - Chef::Key.from_json(json) - end - def list_by_user(actor, inflate = false) keys = Chef::ServerAPI.new(Chef::Config[:chef_server_root]).get("users/#{actor}/keys") list(keys, actor, :load_by_user, inflate) diff --git a/lib/chef/knife/core/ui.rb b/lib/chef/knife/core/ui.rb index 1fc6d3d0e2..d809a8fc45 100644 --- a/lib/chef/knife/core/ui.rb +++ b/lib/chef/knife/core/ui.rb @@ -180,8 +180,7 @@ class Chef if parse_output if object_class.nil? - Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please pass in the class to inflate or use #edit_hash") - Chef::JSONCompat.from_json(output) + raise ArgumentError, "Please pass in the object class to hydrate or use #edit_hash" else object_class.from_hash(Chef::JSONCompat.parse(output)) end diff --git a/lib/chef/node.rb b/lib/chef/node.rb index 1c2fbfee0f..92bdb5887b 100644 --- a/lib/chef/node.rb +++ b/lib/chef/node.rb @@ -508,12 +508,6 @@ class Chef self end - # Create a Chef::Node from JSON - def self.json_create(o) - Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::Node#from_hash") - from_hash(o) - end - def self.from_hash(o) return o if o.kind_of? Chef::Node node = new diff --git a/lib/chef/org.rb b/lib/chef/org.rb index bed5600920..73a129c7c1 100644 --- a/lib/chef/org.rb +++ b/lib/chef/org.rb @@ -122,11 +122,6 @@ class Chef Chef::Org.from_hash(Chef::JSONCompat.from_json(json)) end - def self.json_create(json) - Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::Org#from_json or Chef::Org#load.") - Chef::Org.from_json(json) - end - def self.load(org_name) response = Chef::ServerAPI.new(Chef::Config[:chef_server_root]).get("organizations/#{org_name}") Chef::Org.from_hash(response) diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index 23de50324c..f8cea08076 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -23,6 +23,7 @@ require "chef/dsl/data_query" require "chef/dsl/registry_helper" require "chef/dsl/reboot_pending" require "chef/dsl/resources" +require "chef/json_compat" require "chef/mixin/convert_to_class_name" require "chef/guard_interpreter/resource_guard_interpreter" require "chef/resource/conditional" @@ -715,7 +716,7 @@ class Chef result end - def self.json_create(o) + def self.from_hash(o) resource = new(o["instance_vars"]["@name"]) o["instance_vars"].each do |k, v| resource.instance_variable_set("@#{k}".to_sym, v) @@ -723,6 +724,14 @@ class Chef resource end + def self.json_create(o) + from_hash(o) + end + + def self.from_json(j) + from_hash(Chef::JSONCompat.parse(j)) + end + # # Resource Definition Interface (for resource developers) # diff --git a/lib/chef/resource_collection.rb b/lib/chef/resource_collection.rb index 8eaa2961c4..e450f4f19e 100644 --- a/lib/chef/resource_collection.rb +++ b/lib/chef/resource_collection.rb @@ -117,6 +117,16 @@ class Chef end end + def self.from_hash(o) + collection = new() + { "@resource_list" => "ResourceList", "@resource_set" => "ResourceSet" }.each_pair do |name, klass| + obj = Chef::ResourceCollection.const_get(klass).from_hash(o["instance_vars"].delete(name)) + collection.instance_variable_set(name.to_sym, obj) + end + collection.instance_variable_set(:@run_context, o["instance_vars"].delete("@run_context")) + collection + end + private def lookup_recursive(rc, key) diff --git a/lib/chef/resource_collection/resource_collection_serialization.rb b/lib/chef/resource_collection/resource_collection_serialization.rb index 647d28dfd0..4da1ad5048 100644 --- a/lib/chef/resource_collection/resource_collection_serialization.rb +++ b/lib/chef/resource_collection/resource_collection_serialization.rb @@ -15,6 +15,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # + +require "chef/json_compat" + class Chef class ResourceCollection module ResourceCollectionSerialization @@ -39,13 +42,17 @@ class Chef end module ClassMethods - def json_create(o) + def from_hash(o) collection = new() o["instance_vars"].each do |k, v| collection.instance_variable_set(k.to_sym, v) end collection end + + def from_json(j) + from_hash(Chef::JSONCompat.parse(j)) + end end def is_chef_resource!(arg) diff --git a/lib/chef/resource_collection/resource_list.rb b/lib/chef/resource_collection/resource_list.rb index 9fe012d4c3..75305f63a6 100644 --- a/lib/chef/resource_collection/resource_list.rb +++ b/lib/chef/resource_collection/resource_list.rb @@ -95,6 +95,12 @@ class Chef end end + def self.from_hash(o) + collection = new() + resources = o["instance_vars"]["@resources"].map { |r| Chef::Resource.from_hash(r) } + collection.instance_variable_set(:@resources, resources) + collection + end end end end diff --git a/lib/chef/resource_collection/resource_set.rb b/lib/chef/resource_collection/resource_set.rb index 1a73818790..2c7c0a0b91 100644 --- a/lib/chef/resource_collection/resource_set.rb +++ b/lib/chef/resource_collection/resource_set.rb @@ -132,6 +132,14 @@ class Chef end end + def self.from_hash(o) + collection = new() + rl = o["instance_vars"]["@resources_by_key"] + resources = rl.merge(rl) { |k, r| Chef::Resource.from_hash(r) } + collection.instance_variable_set(:@resources_by_key, resources) + collection + end + private def create_key(resource_type, instance_name) diff --git a/lib/chef/role.rb b/lib/chef/role.rb index 218894ef03..c22c77b70d 100644 --- a/lib/chef/role.rb +++ b/lib/chef/role.rb @@ -168,12 +168,6 @@ class Chef self end - # Create a Chef::Role from JSON - def self.json_create(o) - Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::Role#from_hash") - from_hash(o) - end - def self.from_hash(o) role = new role.name(o["name"]) diff --git a/lib/chef/user.rb b/lib/chef/user.rb index fffaa106f8..f52d0e2555 100644 --- a/lib/chef/user.rb +++ b/lib/chef/user.rb @@ -152,11 +152,6 @@ class Chef Chef::User.from_hash(Chef::JSONCompat.from_json(json)) end - def self.json_create(json) - Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::User#from_json or Chef::User#load.") - Chef::User.from_json(json) - end - def self.list(inflate = false) response = Chef::ServerAPI.new(Chef::Config[:chef_server_url], { :api_version => "0" }).get("users") users = if response.is_a?(Array) diff --git a/lib/chef/user_v1.rb b/lib/chef/user_v1.rb index b408bbe667..0ca17c6ed6 100644 --- a/lib/chef/user_v1.rb +++ b/lib/chef/user_v1.rb @@ -274,11 +274,6 @@ class Chef Chef::UserV1.from_hash(Chef::JSONCompat.from_json(json)) end - def self.json_create(json) - Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::UserV1#from_json or Chef::UserV1#load.") - Chef::UserV1.from_json(json) - end - def self.list(inflate = false) response = Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("users") users = if response.is_a?(Array) diff --git a/spec/unit/json_compat_spec.rb b/spec/unit/json_compat_spec.rb index 4da29fe4ec..38c2c60b2e 100644 --- a/spec/unit/json_compat_spec.rb +++ b/spec/unit/json_compat_spec.rb @@ -22,28 +22,6 @@ require "chef/json_compat" describe Chef::JSONCompat do before { Chef::Config[:treat_deprecation_warnings_as_errors] = false } - describe "#from_json with JSON containing an existing class" do - let(:json) { '{"json_class": "Chef::Role"}' } - - it "emits a deprecation warning" do - Chef::Config[:treat_deprecation_warnings_as_errors] = true - expect { Chef::JSONCompat.from_json(json) }.to raise_error Chef::Exceptions::DeprecatedFeatureError, - /Auto inflation of JSON data is deprecated. Please use Chef::Role#from_hash/ - end - - it "returns an instance of the class instead of a Hash" do - expect(Chef::JSONCompat.from_json(json).class).to eq Chef::Role - end - end - - describe "#from_json with JSON containing comments" do - let(:json) { %Q{{\n/* comment */\n// comment 2\n"json_class": "Chef::Role"}} } - - it "returns an instance of the class instead of a Hash" do - expect(Chef::JSONCompat.from_json(json).class).to eq Chef::Role - end - end - describe "#parse with JSON containing comments" do let(:json) { %Q{{\n/* comment */\n// comment 2\n"json_class": "Chef::Role"}} } @@ -52,16 +30,6 @@ describe Chef::JSONCompat do end end - describe 'with JSON containing "Chef::Sandbox" as a json_class value' do - require "chef/sandbox" # Only needed for this test - - let(:json) { '{"json_class": "Chef::Sandbox", "arbitrary": "data"}' } - - it "returns a Hash, because Chef::Sandbox is a dummy class" do - expect(Chef::JSONCompat.from_json(json)).to eq({ "json_class" => "Chef::Sandbox", "arbitrary" => "data" }) - end - end - describe "when pretty printing an object that defines #to_json" do class Foo def to_json(*a) diff --git a/spec/unit/knife/core/ui_spec.rb b/spec/unit/knife/core/ui_spec.rb index 38c72161e5..38614f44d9 100644 --- a/spec/unit/knife/core/ui_spec.rb +++ b/spec/unit/knife/core/ui_spec.rb @@ -34,16 +34,24 @@ describe Chef::Knife::UI do Chef::Config[:treat_deprecation_warnings_as_errors] = false end + class TestObject < OpenStruct + def self.from_hash(hsh) + new(hsh) + end + end + describe "edit" do ruby_for_json = { "foo" => "bar" } + ruby_from_json = TestObject.from_hash(ruby_for_json) json_from_ruby = "{\n \"foo\": \"bar\"\n}" json_from_editor = "{\n \"bar\": \"foo\"\n}" - ruby_from_editor = { "bar" => "foo" } + ruby_from_editor = TestObject.from_hash({ "bar" => "foo" }) my_editor = "veeeye" temp_path = "/tmp/bar/baz" - let(:subject) { @ui.edit_data(ruby_for_json, parse_output) } + let(:subject) { @ui.edit_data(ruby_for_json, parse_output, object_class: klass) } let(:parse_output) { false } + let(:klass) { nil } context "when editing is disabled" do before do @@ -57,17 +65,18 @@ describe Chef::Knife::UI do end context "when parse_output is true" do let(:parse_output) { true } + let(:klass) { TestObject } it "returns a ruby object" do - expect(subject).to eql(ruby_for_json) + expect(subject).to eql(ruby_from_json) end - - it "gives a deprecation error" do - Chef::Config[:treat_deprecation_warnings_as_errors] = true - expect { subject }.to raise_error Chef::Exceptions::DeprecatedFeatureError, - /Auto inflation of JSON data is deprecated./ + context "but no object class is provided" do + let(:klass) { nil } + it "raises an error" do + expect { subject }.to raise_error ArgumentError, + /Please pass in the object class to hydrate or use #edit_hash/ + end end end - end context "when editing is enabled" do @@ -94,6 +103,7 @@ describe Chef::Knife::UI do end context "when parse_output is true" do let(:parse_output) { true } + let(:klass) { TestObject } it "returns an edited ruby object" do expect(subject).to eql(ruby_from_editor) end @@ -145,6 +155,7 @@ describe Chef::Knife::UI do context "when parse_output is true" do let(:parse_output) { true } + let(:klass) { TestObject } it "returns an edited ruby object" do expect(subject).to eql(ruby_from_editor) end diff --git a/spec/unit/resource_collection_spec.rb b/spec/unit/resource_collection_spec.rb index 5feb34833a..76038e51b9 100644 --- a/spec/unit/resource_collection_spec.rb +++ b/spec/unit/resource_collection_spec.rb @@ -291,10 +291,10 @@ describe Chef::ResourceCollection do expect(rc.respond_to?(:from_json)).to eq(false) end - it "should convert from json using the CHEF::JSONCompat library" do + it "should convert from json using the Chef::JSONCompat library" do rc << resource json = Chef::JSONCompat.to_json(rc) - s_rc = Chef::JSONCompat.from_json(json) + s_rc = Chef::ResourceCollection.from_json(json) expect(s_rc).to be_a_kind_of(Chef::ResourceCollection) expect(s_rc[0].name).to eql(resource.name) end diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index df8ae3100a..c1aeb256fa 100644 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -484,7 +484,7 @@ describe Chef::Resource do describe "self.json_create" do it "should deserialize itself from json" do json = Chef::JSONCompat.to_json(resource) - serialized_node = Chef::JSONCompat.from_json(json) + serialized_node = Chef::Resource.from_json(json) expect(serialized_node).to be_a_kind_of(Chef::Resource) expect(serialized_node.name).to eql(resource.name) end |