Skip to content

Commit 11198fe

Browse files
committed
print the list of nodes to be deleted in columns
1 parent 571dd9c commit 11198fe

2 files changed

Lines changed: 73 additions & 35 deletions

File tree

‎chef/lib/chef/knife/node_bulk_delete.rb‎

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,47 @@ class NodeBulkDelete < Knife
3030
banner "knife node bulk delete REGEX (options)"
3131

3232
def run
33-
if @name_args.length < 1
33+
if name_args.length < 1
3434
ui.fatal("You must supply a regular expression to match the results against")
3535
exit 42
36-
else
37-
bulk_delete(Chef::Node, "node", nil, nil, @name_args[0])
36+
end
37+
38+
39+
nodes_to_delete = {}
40+
matcher = /#{name_args[0]}/
41+
42+
all_nodes.each do |name, node|
43+
next unless name =~ matcher
44+
nodes_to_delete[name] = node
45+
end
46+
47+
if nodes_to_delete.empty?
48+
ui.msg "No nodes match the expression /#{name_args[0]}/"
49+
exit 0
50+
end
51+
52+
ui.msg("The following nodes will be deleted:")
53+
ui.msg("")
54+
ui.msg(ui.list(nodes_to_delete.keys.sort, :columns_down))
55+
ui.msg("")
56+
ui.confirm("Are you sure you want to delete these nodes")
57+
58+
59+
nodes_to_delete.sort.each do |name, node|
60+
node.destroy
61+
ui.msg("Deleted node #{name}")
3862
end
3963
end
64+
65+
def all_nodes
66+
node_uris_by_name = Chef::Node.list
67+
68+
node_uris_by_name.keys.inject({}) do |nodes_by_name, name|
69+
nodes_by_name[name] = Chef::Node.new.tap {|n| n.name(name)}
70+
nodes_by_name
71+
end
72+
end
73+
4074
end
4175
end
4276
end

‎chef/spec/unit/knife/node_bulk_delete_spec.rb‎

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
# Licensed under the Apache License, Version 2.0 (the "License");
77
# you may not use this file except in compliance with the License.
88
# You may obtain a copy of the License at
9-
#
9+
#
1010
# http://www.apache.org/licenses/LICENSE-2.0
11-
#
11+
#
1212
# Unless required by applicable law or agreed to in writing, software
1313
# distributed under the License is distributed on an "AS IS" BASIS,
1414
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -24,51 +24,64 @@
2424

2525
Chef::Config[:node_name] = "webmonkey.example.com"
2626
@knife = Chef::Knife::NodeBulkDelete.new
27-
@knife.config = {
28-
:print_after => nil
29-
}
30-
@knife.name_args = ["."]
31-
@knife.stub!(:output).and_return(true)
32-
@knife.stub!(:confirm).and_return(true)
27+
@knife.name_args = ["."]
28+
@stdout = StringIO.new
29+
@knife.ui.stub!(:stdout).and_return(@stdout)
30+
@knife.ui.stub!(:confirm).and_return(true)
3331
@nodes = Hash.new
3432
%w{adam brent jacob}.each do |node_name|
35-
node = Chef::Node.new()
36-
node.name(node_name)
37-
node.stub!(:destroy).and_return(true)
38-
@nodes[node_name] = node
33+
@nodes[node_name] = "http://localhost:4000/nodes/#{node_name}"
3934
end
40-
Chef::Node.stub!(:list).and_return(@nodes)
4135
end
4236

43-
describe "run" do
44-
45-
it "should get the list of inflated nodes" do
37+
describe "when creating the list of nodes" do
38+
it "fetches the node list" do
39+
expected = @nodes.inject({}) do |inflatedish, (name, uri)|
40+
inflatedish[name] = Chef::Node.new.tap {|n| n.name(name)}
41+
inflatedish
42+
end
4643
Chef::Node.should_receive(:list).and_return(@nodes)
47-
@knife.run
44+
# I hate not having == defined for anything :(
45+
actual = @knife.all_nodes
46+
actual.keys.should =~ expected.keys
47+
actual.values.map {|n| n.name }.should =~ %w[adam brent jacob]
48+
end
49+
end
50+
51+
describe "run" do
52+
before do
53+
@inflatedish_list = @nodes.keys.inject({}) do |nodes_by_name, name|
54+
node = Chef::Node.new()
55+
node.name(name)
56+
node.stub!(:destroy).and_return(true)
57+
nodes_by_name[name] = node
58+
nodes_by_name
59+
end
60+
@knife.stub!(:all_nodes).and_return(@inflatedish_list)
4861
end
4962

5063
it "should print the nodes you are about to delete" do
51-
@knife.should_receive(:output).with(@knife.format_list_for_display(@nodes))
5264
@knife.run
65+
@stdout.string.should match(/#{@knife.ui.list(@nodes.keys.sort, :columns_down)}/)
5366
end
5467

5568
it "should confirm you really want to delete them" do
56-
@knife.should_receive(:confirm)
69+
@knife.ui.should_receive(:confirm)
5770
@knife.run
5871
end
5972

6073
it "should delete each node" do
61-
@nodes.each_value do |n|
74+
@inflatedish_list.each_value do |n|
6275
n.should_receive(:destroy)
6376
end
6477
@knife.run
6578
end
6679

6780
it "should only delete nodes that match the regex" do
6881
@knife.name_args = ['adam']
69-
@nodes['adam'].should_receive(:destroy)
70-
@nodes['brent'].should_not_receive(:destroy)
71-
@nodes['jacob'].should_not_receive(:destroy)
82+
@inflatedish_list['adam'].should_receive(:destroy)
83+
@inflatedish_list['brent'].should_not_receive(:destroy)
84+
@inflatedish_list['jacob'].should_not_receive(:destroy)
7285
@knife.run
7386
end
7487

@@ -77,15 +90,6 @@
7790
lambda { @knife.run }.should raise_error(SystemExit)
7891
end
7992

80-
describe "with -p or --print-after" do
81-
it "should pretty print the node, formatted for display" do
82-
@knife.config[:print_after] = true
83-
@nodes.each_value do |n|
84-
@knife.should_receive(:output).with(@knife.format_for_display(n))
85-
end
86-
@knife.run
87-
end
88-
end
8993
end
9094
end
9195

0 commit comments

Comments
 (0)