diff options
-rw-r--r-- | lib/chef/knife/client_key_delete.rb | 76 | ||||
-rw-r--r-- | lib/chef/knife/key_delete.rb | 55 | ||||
-rw-r--r-- | lib/chef/knife/user_key_delete.rb | 76 | ||||
-rw-r--r-- | spec/support/key_helpers.rb | 5 | ||||
-rw-r--r-- | spec/unit/knife/key_create_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/knife/key_delete_spec.rb | 152 | ||||
-rw-r--r-- | spec/unit/knife/key_list_spec.rb | 2 |
7 files changed, 365 insertions, 3 deletions
diff --git a/lib/chef/knife/client_key_delete.rb b/lib/chef/knife/client_key_delete.rb new file mode 100644 index 0000000000..91c088a1d1 --- /dev/null +++ b/lib/chef/knife/client_key_delete.rb @@ -0,0 +1,76 @@ +# +# Author:: Tyler Cloke (tyler@chef.io) +# Copyright:: Copyright (c) 2015 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 'chef/knife' + +class Chef + class Knife + # Implements knife client key delete using Chef::Knife::KeyDelete + # as a service class. + # + # @author Tyler Cloke + # + # @attr_reader [String] actor the name of the client that this key is for + class ClientKeyDelete < Knife + banner "knife client key delete CLIENT KEYNAME" + + attr_reader :actor + + def initialize(argv=[]) + super(argv) + @service_object = nil + end + + def run + apply_params!(@name_args) + service_object.run + end + + def actor_field_name + 'client' + end + + def actor_missing_error + 'You must specify a client name' + end + + def keyname_missing_error + 'You must specify a key name' + end + + def service_object + @service_object ||= Chef::Knife::KeyDelete.new(@name, @actor, actor_field_name, ui) + end + + def apply_params!(params) + @actor = params[0] + if @actor.nil? + show_usage + ui.fatal(actor_missing_error) + exit 1 + end + @name = params[1] + if @name.nil? + show_usage + ui.fatal(keyname_missing_error) + exit 1 + end + end + end + end +end diff --git a/lib/chef/knife/key_delete.rb b/lib/chef/knife/key_delete.rb new file mode 100644 index 0000000000..fb996cff17 --- /dev/null +++ b/lib/chef/knife/key_delete.rb @@ -0,0 +1,55 @@ +# +# Author:: Tyler Cloke (<tyler@chef.io>) +# Copyright:: Copyright (c) 2015 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 'chef/key' + +class Chef + class Knife + # Service class for UserKeyDelete and ClientKeyDelete, used to delete keys. + # Implements common functionality of knife [user | org client] key delete. + # + # @author Tyler Cloke + # + # @attr_accessor [Hash] cli input, see UserKeyDelete and ClientKeyDelete for what could populate it + class KeyDelete + def initialize(name, actor, actor_field_name, ui) + @name = name + @actor = actor + @actor_field_name = actor_field_name + @ui = ui + end + + def confirm! + @ui.confirm("Do you really want to delete the key named #{@name} for the #{@actor_field_name} named #{@actor}") + end + + def print_destroyed + @ui.info("Destroyed key named #{@name} for the #{@actor_field_name} named #{@actor}") + end + + def run + key = Chef::Key.new(@actor, @actor_field_name) + key.name(@name) + confirm! + key.destroy + print_destroyed + end + + end + end +end diff --git a/lib/chef/knife/user_key_delete.rb b/lib/chef/knife/user_key_delete.rb new file mode 100644 index 0000000000..0bde52509f --- /dev/null +++ b/lib/chef/knife/user_key_delete.rb @@ -0,0 +1,76 @@ +# +# Author:: Tyler Cloke (tyler@chef.io) +# Copyright:: Copyright (c) 2015 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 'chef/knife' + +class Chef + class Knife + # Implements knife user key delete using Chef::Knife::KeyDelete + # as a service class. + # + # @author Tyler Cloke + # + # @attr_reader [String] actor the name of the client that this key is for + class UserKeyDelete < Knife + banner "knife user key delete USER KEYNAME" + + attr_reader :actor + + def initialize(argv=[]) + super(argv) + @service_object = nil + end + + def run + apply_params!(@name_args) + service_object.run + end + + def actor_field_name + 'user' + end + + def actor_missing_error + 'You must specify a user name' + end + + def keyname_missing_error + 'You must specify a key name' + end + + def service_object + @service_object ||= Chef::Knife::KeyDelete.new(@name, @actor, actor_field_name, ui) + end + + def apply_params!(params) + @actor = params[0] + if @actor.nil? + show_usage + ui.fatal(actor_missing_error) + exit 1 + end + @name = params[1] + if @name.nil? + show_usage + ui.fatal(keyname_missing_error) + exit 1 + end + end + end + end +end diff --git a/spec/support/key_helpers.rb b/spec/support/key_helpers.rb index 36ababc09a..4cb2b305a5 100644 --- a/spec/support/key_helpers.rb +++ b/spec/support/key_helpers.rb @@ -20,7 +20,6 @@ require 'spec_helper' shared_examples_for "a knife key command" do let(:stderr) { StringIO.new } - let(:params) { [] } let(:command) do c = described_class.new([]) c.ui.config[:disable_editing] = true @@ -31,7 +30,8 @@ shared_examples_for "a knife key command" do end context "before apply_params! is called" do - context "when apply_params! is called with invalid args" do + context "when apply_params! is called with invalid args (missing actor)" do + let(:params) { [] } it "shows the usage" do expect(command).to receive(:show_usage) expect { command.apply_params!(params) }.to exit_with_code(1) @@ -49,7 +49,6 @@ shared_examples_for "a knife key command" do end # before apply_params! is called context "after apply_params! is called with valid args" do - let(:params) { ["charmander"] } before do command.apply_params!(params) end diff --git a/spec/unit/knife/key_create_spec.rb b/spec/unit/knife/key_create_spec.rb index c24f57c9ac..5998e10274 100644 --- a/spec/unit/knife/key_create_spec.rb +++ b/spec/unit/knife/key_create_spec.rb @@ -58,6 +58,7 @@ describe "key create commands that inherit knife" do # defined in key_helper.rb it_should_behave_like "a knife key command" do let(:service_object) { instance_double(Chef::Knife::KeyCreate) } + let(:params) { ["charmander"] } end end @@ -66,6 +67,7 @@ describe "key create commands that inherit knife" do # defined in key_helper.rb it_should_behave_like "a knife key command" do let(:service_object) { instance_double(Chef::Knife::KeyCreate) } + let(:params) { ["charmander"] } end end end diff --git a/spec/unit/knife/key_delete_spec.rb b/spec/unit/knife/key_delete_spec.rb new file mode 100644 index 0000000000..788d125b02 --- /dev/null +++ b/spec/unit/knife/key_delete_spec.rb @@ -0,0 +1,152 @@ +# +# Author:: Tyler Cloke (<tyler@chef.io>) +# Copyright:: Copyright (c) 2015 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 'spec_helper' +require 'chef/knife/user_key_delete' +require 'chef/knife/client_key_delete' +require 'chef/knife/key_delete' +require 'chef/key' + +describe "key delete commands that inherit knife" do + shared_examples_for "a key delete command" do + let(:stderr) { StringIO.new } + let(:params) { [] } + let(:service_object) { instance_double(Chef::Knife::KeyDelete) } + let(:command) do + c = described_class.new([]) + c.ui.config[:disable_editing] = true + allow(c.ui).to receive(:stderr).and_return(stderr) + allow(c.ui).to receive(:stdout).and_return(stderr) + allow(c).to receive(:show_usage) + c + end + + context "before apply_params! is called" do + context "when apply_params! is called with invalid args (missing keyname)" do + let(:params) { ["charmander"] } + it "shows the usage" do + expect(command).to receive(:show_usage) + expect { command.apply_params!(params) }.to exit_with_code(1) + end + + it "outputs the proper error" do + expect { command.apply_params!(params) }.to exit_with_code(1) + expect(stderr.string).to include(command.keyname_missing_error) + end + + it "exits 1" do + expect { command.apply_params!(params) }.to exit_with_code(1) + end + end + end # before apply_params! is called + + context "after apply_params! is called with valid args" do + let(:params) { ["charmander", "charmander-key"] } + before do + command.apply_params!(params) + end + + context "when the service object is called" do + it "creates a new instance of Chef::Knife::KeyDelete with the correct args" do + expect(Chef::Knife::KeyDelete).to receive(:new). + with("charmander-key", "charmander", command.actor_field_name, command.ui). + and_return(service_object) + command.service_object + end + end # when the service object is called + end # after apply_params! is called with valid args + end # a key delete command + + describe Chef::Knife::UserKeyDelete do + it_should_behave_like "a key delete command" + # defined in key_helpers.rb + it_should_behave_like "a knife key command" do + let(:service_object) { instance_double(Chef::Knife::KeyDelete) } + let(:params) { ["charmander", "charmander-key"] } + end + end + + describe Chef::Knife::ClientKeyDelete do + it_should_behave_like "a key delete command" + # defined in key_helpers.rb + it_should_behave_like "a knife key command" do + let(:service_object) { instance_double(Chef::Knife::KeyDelete) } + let(:params) { ["charmander", "charmander-key"] } + end + end +end + +describe Chef::Knife::KeyDelete do + let(:actor) { "charmander" } + let(:keyname) { "charmander-key" } + let(:ui) { instance_double("Chef::Knife::UI") } + + shared_examples_for "key delete run command" do + let(:key_delete_object) { + described_class.new(keyname, actor, actor_field_name, ui,) + } + + before do + allow_any_instance_of(Chef::Key).to receive(:destroy) + allow(key_delete_object).to receive(:print_destroyed) + allow(key_delete_object).to receive(:confirm!) + end + + context "when the command is run" do + it "calls Chef::Key.new with the proper input" do + expect(Chef::Key).to receive(:new).with(actor, actor_field_name).and_call_original + key_delete_object.run + end + + it "calls name on the Chef::Key instance with the proper input" do + expect_any_instance_of(Chef::Key).to receive(:name).with(keyname) + key_delete_object.run + end + + it "calls destroy on the Chef::Key instance" do + expect_any_instance_of(Chef::Key).to receive(:destroy).once + key_delete_object.run + end + + it "calls confirm!" do + expect(key_delete_object).to receive(:confirm!) + key_delete_object.run + end + + it "calls print_destroyed" do + expect(key_delete_object).to receive(:print_destroyed) + key_delete_object.run + end + end # when the command is run + + + end # key delete run command + + context "when actor_field_name is 'user'" do + it_should_behave_like "key delete run command" do + let(:actor_field_name) { "user" } + end + end + + context "when actor_field_name is 'client'" do + it_should_behave_like "key delete run command" do + let(:actor_field_name) { "client" } + end + end +end + diff --git a/spec/unit/knife/key_list_spec.rb b/spec/unit/knife/key_list_spec.rb index b65697a105..aabe02ac02 100644 --- a/spec/unit/knife/key_list_spec.rb +++ b/spec/unit/knife/key_list_spec.rb @@ -58,6 +58,7 @@ describe "key list commands that inherit knife" do # defined in key_helpers.rb it_should_behave_like "a knife key command" do let(:service_object) { instance_double(Chef::Knife::KeyList) } + let(:params) { ["charmander"] } end end @@ -66,6 +67,7 @@ describe "key list commands that inherit knife" do # defined in key_helpers.rb it_should_behave_like "a knife key command" do let(:service_object) { instance_double(Chef::Knife::KeyList) } + let(:params) { ["charmander"] } end end end |