diff options
author | Tim Smith <tsmith@chef.io> | 2019-04-17 11:35:49 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-17 11:35:49 -0700 |
commit | 5f97ba11186b0632378a33259155188b6e902613 (patch) | |
tree | a1a18f081edaf69a7c1971c87a87d518dd347ae3 | |
parent | cec85f352ad95930daad53b8dda6032d6ce7b537 (diff) | |
parent | ce52c853611eb6c6572a367c9a425b7426a2b977 (diff) | |
download | chef-5f97ba11186b0632378a33259155188b6e902613.tar.gz |
Merge pull request #8384 from chef/btm/8077-backport
Backport #8077 to Chef 14
-rw-r--r-- | lib/chef/knife/data_bag_edit.rb | 2 | ||||
-rw-r--r-- | spec/integration/knife/data_bag_create_spec.rb | 95 | ||||
-rw-r--r-- | spec/integration/knife/data_bag_edit_spec.rb | 104 | ||||
-rw-r--r-- | spec/integration/knife/data_bag_show_spec.rb | 71 | ||||
-rw-r--r-- | spec/unit/knife/data_bag_edit_spec.rb | 3 |
5 files changed, 244 insertions, 31 deletions
diff --git a/lib/chef/knife/data_bag_edit.rb b/lib/chef/knife/data_bag_edit.rb index 5d76762058..6c7f73ad6c 100644 --- a/lib/chef/knife/data_bag_edit.rb +++ b/lib/chef/knife/data_bag_edit.rb @@ -43,7 +43,7 @@ class Chef exit(1) end else - return item, false + return item.raw_data, false end end diff --git a/spec/integration/knife/data_bag_create_spec.rb b/spec/integration/knife/data_bag_create_spec.rb index 5ee7a2f00d..e60f3c06fd 100644 --- a/spec/integration/knife/data_bag_create_spec.rb +++ b/spec/integration/knife/data_bag_create_spec.rb @@ -27,29 +27,98 @@ describe "knife data bag create", :workstation do let(:err) { "Created data_bag[foo]\n" } let(:out) { "Created data_bag_item[bar]\n" } let(:exists) { "Data bag foo already exists\n" } + let(:secret) { "abc" } when_the_chef_server "is empty" do - it "creates a new data bag" do - knife("data bag create foo").should_succeed stderr: err + context "with encryption key" do + it "creates a new data bag and item" do + pretty_json = Chef::JSONCompat.to_json_pretty({ id: "bar", test: "pass" }) + allow(Chef::JSONCompat).to receive(:to_json_pretty).and_return(pretty_json) + knife("data bag create foo bar --secret #{secret}").should_succeed stdout: out, stderr: err + expect(knife("data bag show foo bar --secret #{secret}").stderr).to eq("Encrypted data bag detected, decrypting with provided secret.\n") + expect(knife("data bag show foo bar --secret #{secret}").stdout).to eq("id: bar\ntest: pass\n") + end + + it "creates a new data bag and an empty item" do + knife("data bag create foo bar --secret #{secret}").should_succeed stdout: out, stderr: err + expect(knife("data bag show foo bar --secret #{secret}").stderr).to eq("WARNING: Unencrypted data bag detected, ignoring any provided secret options.\n") + expect(knife("data bag show foo bar --secret #{secret}").stdout).to eq("id: bar\n") + end end - it "creates a new data bag and item" do - knife("data bag create foo bar").should_succeed stdout: out, stderr: err + context "without encryption key" do + it "creates a new data bag" do + knife("data bag create foo").should_succeed stderr: err + expect(knife("data bag show foo").stderr).to eq("") + end + + it "creates a new data bag and item" do + knife("data bag create foo bar").should_succeed stdout: out, stderr: err + expect(knife("data bag show foo").stdout).to eq("bar\n") + end end + end - it "adds a new item to an existing bag" do - knife("data bag create foo").should_succeed stderr: err - knife("data bag create foo bar").should_succeed stdout: out, stderr: exists + when_the_chef_server "has some data bags" do + before do + data_bag "foo", {} + data_bag "bag", { "box" => {} } end - it "refuses to add an existing data bag" do - knife("data bag create foo").should_succeed stderr: err - knife("data bag create foo").should_succeed stderr: exists + context "with encryption key" do + it "creates a new data bag and item" do + pretty_json = Chef::JSONCompat.to_json_pretty({ id: "bar", test: "pass" }) + allow(Chef::JSONCompat).to receive(:to_json_pretty).and_return(pretty_json) + knife("data bag create rocket bar --secret #{secret}").should_succeed stdout: out, stderr: <<~EOM + Created data_bag[rocket] + EOM + expect(knife("data bag show rocket bar --secret #{secret}").stderr).to eq("Encrypted data bag detected, decrypting with provided secret.\n") + expect(knife("data bag show rocket bar --secret #{secret}").stdout).to eq("id: bar\ntest: pass\n") + end + + it "creates a new data bag and an empty item" do + knife("data bag create rocket bar --secret #{secret}").should_succeed stdout: out, stderr: <<~EOM + Created data_bag[rocket] + EOM + expect(knife("data bag show rocket bar --secret #{secret}").stderr).to eq("WARNING: Unencrypted data bag detected, ignoring any provided secret options.\n") + expect(knife("data bag show rocket bar --secret #{secret}").stdout).to eq("id: bar\n") + end + + it "adds a new item to an existing bag" do + knife("data bag create foo bar --secret #{secret}").should_succeed stdout: out, stderr: exists + expect(knife("data bag show foo bar --secret #{secret}").stderr).to eq("WARNING: Unencrypted data bag detected, ignoring any provided secret options.\n") + expect(knife("data bag show foo bar --secret #{secret}").stdout).to eq("id: bar\n") + end + + it "fails to add an existing item" do + expect { knife("data bag create bag box --secret #{secret}") }.to raise_error(Net::HTTPClientException) + end end - it "fails to add an existing item" do - knife("data bag create foo bar").should_succeed stdout: out, stderr: err - expect { knife("data bag create foo bar") }.to raise_error(Net::HTTPClientException) + context "without encryption key" do + it "creates a new data bag" do + knife("data bag create rocket").should_succeed stderr: <<~EOM + Created data_bag[rocket] + EOM + end + + it "creates a new data bag and item" do + knife("data bag create rocket bar").should_succeed stdout: out, stderr: <<~EOM + Created data_bag[rocket] + EOM + end + + it "adds a new item to an existing bag" do + knife("data bag create foo bar").should_succeed stdout: out, stderr: exists + end + + it "refuses to create an existing data bag" do + knife("data bag create foo").should_succeed stderr: exists + end + + it "fails to add an existing item" do + expect { knife("data bag create bag box") }.to raise_error(Net::HTTPClientException) + end end end end diff --git a/spec/integration/knife/data_bag_edit_spec.rb b/spec/integration/knife/data_bag_edit_spec.rb new file mode 100644 index 0000000000..cb3e84b9c6 --- /dev/null +++ b/spec/integration/knife/data_bag_edit_spec.rb @@ -0,0 +1,104 @@ +# +# Copyright:: Copyright 2013-2016, Chef Software Inc. +# 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 "support/shared/integration/integration_helper" +require "support/shared/context/config" +require "chef/knife/data_bag_edit" + +describe "knife data bag edit", :workstation do + include IntegrationSupport + include KnifeSupport + + include_context "default config options" + + let(:out) { "Saved data_bag_item[box]\n" } + let(:err) { "Saving data bag unencrypted. To encrypt it, provide an appropriate secret.\n" } + let(:secret) { "abc" } + let(:encrypt) { "Encrypted data bag detected, decrypting with provided secret.\n" } + + when_the_chef_server "is empty" do + context "with encryption key" do + it "fails to edit an item" do + expect { knife("data bag edit bag box --secret #{secret}") }.to raise_error(Net::HTTPClientException) + end + end + + context "without encryption key" do + it "fails to edit an item" do + expect { knife("data bag edit bag box") }.to raise_error(Net::HTTPClientException) + end + end + end + + when_the_chef_server "has some data bags" do + before do + data_bag "foo", {} + data_bag "bag", { "box" => {} } + data_bag "rocket", { "falcon9" => { heavy: "true" }, "atlas" => {}, "ariane" => {} } + data_bag "encrypt", { "box" => { id: "box", foo: { "encrypted_data": "J8N0pJ+LFDQF3XvhzWgkSBOuZZn8Og==\n", "iv": "4S1sb4zLnMt71SXV\n", "auth_tag": "4ChINhxz4WmqOizvZNoPPg==\n", "version": 3, "cipher": "aes-256-gcm" } } } + end + + context "with encryption key" do + it "fails to edit a non-existing item" do + expect { knife("data bag edit foo box --secret #{secret}") }.to raise_error(Net::HTTPClientException) + end + + it "edits an encrypted data bag item" do + pretty_json = Chef::JSONCompat.to_json_pretty({ id: "box", foo: "bar" }) + allow(Chef::JSONCompat).to receive(:to_json_pretty).and_return(pretty_json) + knife("data bag edit encrypt box --secret #{secret}") + knife("data bag show encrypt box --secret #{secret}").should_succeed stderr: encrypt, stdout: <<~EOM + foo: bar + id: box + EOM + end + + it "encrypts an unencrypted data bag item" do + knife("data bag edit rocket falcon9 --secret #{secret}") + knife("data bag show rocket falcon9 --secret #{secret}").should_succeed stderr: encrypt, stdout: <<~EOM + heavy: true + id: falcon9 + EOM + end + end + + context "without encryption key" do + it "fails to edit a non-existing item" do + expect { knife("data bag edit foo box") }.to raise_error(Net::HTTPClientException) + end + it "edits an empty data bag item" do + pretty_json = Chef::JSONCompat.to_json_pretty({ id: "box", ab: "abc" }) + allow(Chef::JSONCompat).to receive(:to_json_pretty).and_return(pretty_json) + knife("data bag edit bag box").should_succeed stderr: err, stdout: out + knife("data bag show bag box").should_succeed <<~EOM + ab: abc + id: box + EOM + end + it "edits a non-empty data bag item" do + pretty_json = Chef::JSONCompat.to_json_pretty({ id: "falcon9", heavy: false }) + allow(Chef::JSONCompat).to receive(:to_json_pretty).and_return(pretty_json) + knife("data bag edit rocket falcon9").should_succeed stderr: err, stdout: <<~EOM + Saved data_bag_item[falcon9] + EOM + knife("data bag show rocket falcon9").should_succeed <<~EOM + heavy: false + id: falcon9 + EOM + end + end + end +end diff --git a/spec/integration/knife/data_bag_show_spec.rb b/spec/integration/knife/data_bag_show_spec.rb index 5fefec5266..42553dc478 100644 --- a/spec/integration/knife/data_bag_show_spec.rb +++ b/spec/integration/knife/data_bag_show_spec.rb @@ -24,30 +24,71 @@ describe "knife data bag show", :workstation do include_context "default config options" - when_the_chef_server "has some data bags" do + when_the_chef_server "is empty" do + it "raises error if try to retrieve it" do + expect { knife("data bag show bag") }.to raise_error(Net::HTTPServerException) + end + end + + when_the_chef_server "contains data bags" do + let(:right_secret) { "abc" } + let(:wrong_secret) { "ab" } + let(:err) { "Encrypted data bag detected, decrypting with provided secret.\n" } before do data_bag "x", {} data_bag "canteloupe", {} data_bag "rocket", { "falcon9" => { heavy: "true" }, "atlas" => {}, "ariane" => {} } + data_bag "encrypt", { "box" => { id: "box", foo: { "encrypted_data": "J8N0pJ+LFDQF3XvhzWgkSBOuZZn8Og==\n", "iv": "4S1sb4zLnMt71SXV\n", "auth_tag": "4ChINhxz4WmqOizvZNoPPg==\n", "version": 3, "cipher": "aes-256-gcm" } } } end - it "with an empty data bag" do - knife("data bag show canteloupe").should_succeed "\n" - end + context "with encrypted data" do + context "provided secret key" do + it "shows data if secret key is correct" do + knife("data bag show encrypt box --secret #{right_secret}").should_succeed stderr: err, stdout: <<~EOM + foo: bar + id: box + EOM + end - it "with a bag with some items" do - knife("data bag show rocket").should_succeed <<~EOM - ariane - atlas - falcon9 -EOM + it "raises error if secret key is incorrect" do + expect { knife("data bag show encrypt box --secret #{wrong_secret}") }.to raise_error(Chef::EncryptedDataBagItem::DecryptionFailure) + end + end + + context "not provided secret key" do + it "shows encrypted data with a warning" do + expect(knife("data bag show encrypt box").stderr).to eq("WARNING: Encrypted data bag detected, but no secret provided for decoding. Displaying encrypted data.\n") + end + end end - it "with a single item" do - knife("data bag show rocket falcon9").should_succeed <<~EOM - heavy: true - id: falcon9 -EOM + context "with unencrypted data" do + context "provided secret key" do + it "shows unencrypted data with a warning" do + expect(knife("data bag show rocket falcon9 --secret #{right_secret}").stderr).to eq("WARNING: Unencrypted data bag detected, ignoring any provided secret options.\n") + end + end + + context "not provided secret key" do + it "shows null with an empty data bag" do + knife("data bag show canteloupe").should_succeed "\n" + end + + it "show list of items in a bag" do + knife("data bag show rocket").should_succeed <<~EOM + ariane + atlas + falcon9 + EOM + end + + it "show data of the item" do + knife("data bag show rocket falcon9").should_succeed <<~EOM + heavy: true + id: falcon9 + EOM + end + end end end end diff --git a/spec/unit/knife/data_bag_edit_spec.rb b/spec/unit/knife/data_bag_edit_spec.rb index ff131a7d91..4d7ce68aa2 100644 --- a/spec/unit/knife/data_bag_edit_spec.rb +++ b/spec/unit/knife/data_bag_edit_spec.rb @@ -49,8 +49,7 @@ describe Chef::Knife::DataBagEdit do let(:is_encrypted?) { false } let(:transmitted_hash) { raw_edited_hash } - let(:data_to_edit) { db } - + let(:data_to_edit) { db.raw_data } shared_examples_for "editing a data bag" do it "correctly edits then uploads the data bag" do expect(Chef::DataBagItem).to receive(:load).with(bag_name, item_name).and_return(db) |