summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom May <thom@clearairturbulence.org>2015-04-09 19:44:51 +0100
committerThom May <thom@clearairturbulence.org>2015-04-09 19:44:51 +0100
commitad10282d962aa2c09130b29b4ebcf10e4ae321e5 (patch)
tree590e827408f7a3466e4cc7f5cde17f9dcfc907f2
parent648c9f91d4a0ccbcf661a5ee4d3ec67d8538a5f3 (diff)
parent604a1e63722832bed6f0109218652a3f384f90cb (diff)
downloadchef-ad10282d962aa2c09130b29b4ebcf10e4ae321e5.tar.gz
Merge pull request #3067 from chef/tm/knife_status_environment
Allow knife status to filter by environment
-rw-r--r--lib/chef/knife/core/status_presenter.rb23
-rw-r--r--lib/chef/knife/status.rb38
-rw-r--r--spec/unit/knife/status_spec.rb72
3 files changed, 112 insertions, 21 deletions
diff --git a/lib/chef/knife/core/status_presenter.rb b/lib/chef/knife/core/status_presenter.rb
index 3298d5e4ac..9cf839d3a6 100644
--- a/lib/chef/knife/core/status_presenter.rb
+++ b/lib/chef/knife/core/status_presenter.rb
@@ -66,16 +66,16 @@ class Chef
list.each do |node|
result = {}
- result["name"] = node.name
- result["chef_environment"] = node.chef_environment
- ip = (node[:ec2] && node[:ec2][:public_ipv4]) || node[:ipaddress]
- fqdn = (node[:ec2] && node[:ec2][:public_hostname]) || node[:fqdn]
+ result["name"] = node["name"] || node.name
+ result["chef_environment"] = node["chef_environment"]
+ ip = (node["ec2"] && node["ec2"]["public_ipv4"]) || node["ipaddress"]
+ fqdn = (node["ec2"] && node["ec2"]["public_hostname"]) || node["fqdn"]
result["ip"] = ip if ip
result["fqdn"] = fqdn if fqdn
- result["run_list"] = node.run_list if config[:run_list]
- result["ohai_time"] = node[:ohai_time]
- result["platform"] = node[:platform] if node[:platform]
- result["platform_version"] = node[:platform_version] if node[:platform_version]
+ result["run_list"] = node.run_list if config["run_list"]
+ result["ohai_time"] = node["ohai_time"]
+ result["platform"] = node["platform"] if node["platform"]
+ result["platform_version"] = node["platform_version"] if node["platform_version"]
if config[:long_output]
result["default"] = node.default_attrs
@@ -99,11 +99,12 @@ class Chef
# special case ec2 with their split horizon whatsis.
ip = (node[:ec2] && node[:ec2][:public_ipv4]) || node[:ipaddress]
fqdn = (node[:ec2] && node[:ec2][:public_hostname]) || node[:fqdn]
+ name = node['name'] || node.name
- hours, minutes, seconds = time_difference_in_hms(node["ohai_time"])
+ hours, minutes, _ = time_difference_in_hms(node["ohai_time"])
hours_text = "#{hours} hour#{hours == 1 ? ' ' : 's'}"
minutes_text = "#{minutes} minute#{minutes == 1 ? ' ' : 's'}"
- run_list = "#{node.run_list}" if config[:run_list]
+ run_list = "#{node['run_list']}" if config[:run_list]
if hours > 24
color = :red
text = hours_text
@@ -116,7 +117,7 @@ class Chef
end
line_parts = Array.new
- line_parts << @ui.color(text, color) + ' ago' << node.name
+ line_parts << @ui.color(text, color) + ' ago' << name
line_parts << fqdn if fqdn
line_parts << ip if ip
line_parts << run_list if run_list
diff --git a/lib/chef/knife/status.rb b/lib/chef/knife/status.rb
index 93e81f8f03..35868b376f 100644
--- a/lib/chef/knife/status.rb
+++ b/lib/chef/knife/status.rb
@@ -22,6 +22,7 @@ require 'chef/knife/core/status_presenter'
class Chef
class Knife
class Status < Knife
+ include Knife::Core::NodeFormattingOptions
deps do
require 'chef/search/query'
@@ -44,20 +45,43 @@ class Chef
:long => "--hide-healthy",
:description => "Hide nodes that have run chef in the last hour"
+ def append_to_query(term)
+ @query << " AND " unless @query.empty?
+ @query << term
+ end
+
def run
ui.use_presenter Knife::Core::StatusPresenter
- all_nodes = []
- q = Chef::Search::Query.new
- query = @name_args[0] ? @name_args[0].dup : '*:*'
+
+ if config[:long_output]
+ opts = {}
+ else
+ opts = {filter_result:
+ { name: ["name"], ipaddress: ["ipaddress"], ohai_time: ["ohai_time"],
+ ec2: ["ec2"], run_list: ["run_list"], platform: ["platform"],
+ platform_version: ["platform_version"], chef_environment: ["chef_environment"]}}
+ end
+
+ @query ||= ""
+ append_to_query(@name_args[0]) if @name_args[0]
+ append_to_query("chef_environment:#{config[:environment]}") if config[:environment]
+
if config[:hide_healthy]
time = Time.now.to_i
- query_unhealthy = "NOT ohai_time:[" << (time - 60*60).to_s << " TO " << time.to_s << "]"
- query << ' AND ' << query_unhealthy << @name_args[0] if @name_args[0]
- query = query_unhealthy unless @name_args[0]
+ # AND NOT is not valid lucene syntax, so don't use append_to_query
+ @query << " " unless @query.empty?
+ @query << "NOT ohai_time:[#{(time - 60*60).to_s} TO #{time.to_s}]"
end
- q.search(:node, query) do |node|
+
+ @query = @query.empty? ? "*:*" : @query
+
+ all_nodes = []
+ q = Chef::Search::Query.new
+ Chef::Log.info("Sending query: #{@query}")
+ q.search(:node, @query, opts) do |node|
all_nodes << node
end
+
output(all_nodes.sort { |n1, n2|
if (config[:sort_reverse] || Chef::Config[:knife][:sort_status_reverse])
(n2["ohai_time"] or 0) <=> (n1["ohai_time"] or 0)
diff --git a/spec/unit/knife/status_spec.rb b/spec/unit/knife/status_spec.rb
index 2522bc61b1..ee44f3b3fd 100644
--- a/spec/unit/knife/status_spec.rb
+++ b/spec/unit/knife/status_spec.rb
@@ -24,15 +24,81 @@ describe Chef::Knife::Status do
n.automatic_attrs["fqdn"] = "foobar"
n.automatic_attrs["ohai_time"] = 1343845969
end
- query = double("Chef::Search::Query")
- allow(query).to receive(:search).and_yield(node)
- allow(Chef::Search::Query).to receive(:new).and_return(query)
+ allow(Time).to receive(:now).and_return(Time.at(1428573420))
+ @query = double("Chef::Search::Query")
+ allow(@query).to receive(:search).and_yield(node)
+ allow(Chef::Search::Query).to receive(:new).and_return(@query)
@knife = Chef::Knife::Status.new
@stdout = StringIO.new
allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
describe "run" do
+ let(:opts) {{filter_result:
+ { name: ["name"], ipaddress: ["ipaddress"], ohai_time: ["ohai_time"],
+ ec2: ["ec2"], run_list: ["run_list"], platform: ["platform"],
+ platform_version: ["platform_version"], chef_environment: ["chef_environment"]}}}
+
+ it "should default to searching for everything" do
+ expect(@query).to receive(:search).with(:node, "*:*", opts)
+ @knife.run
+ end
+
+ it "should filter healthy nodes" do
+ @knife.config[:hide_healthy] = true
+ expect(@query).to receive(:search).with(:node, "NOT ohai_time:[1428569820 TO 1428573420]", opts)
+ @knife.run
+ end
+
+ it "should filter by environment" do
+ @knife.config[:environment] = "production"
+ expect(@query).to receive(:search).with(:node, "chef_environment:production", opts)
+ @knife.run
+ end
+
+ it "should filter by environment and health" do
+ @knife.config[:environment] = "production"
+ @knife.config[:hide_healthy] = true
+ expect(@query).to receive(:search).with(:node, "chef_environment:production NOT ohai_time:[1428569820 TO 1428573420]", opts)
+ @knife.run
+ end
+
+ it "should not use partial search with long output" do
+ @knife.config[:long_output] = true
+ expect(@query).to receive(:search).with(:node, "*:*", {})
+ @knife.run
+ end
+
+ context "with a custom query" do
+ before :each do
+ @knife.instance_variable_set(:@name_args, ["name:my_custom_name"])
+ end
+
+ it "should allow a custom query to be specified" do
+ expect(@query).to receive(:search).with(:node, "name:my_custom_name", opts)
+ @knife.run
+ end
+
+ it "should filter healthy nodes" do
+ @knife.config[:hide_healthy] = true
+ expect(@query).to receive(:search).with(:node, "name:my_custom_name NOT ohai_time:[1428569820 TO 1428573420]", opts)
+ @knife.run
+ end
+
+ it "should filter by environment" do
+ @knife.config[:environment] = "production"
+ expect(@query).to receive(:search).with(:node, "name:my_custom_name AND chef_environment:production", opts)
+ @knife.run
+ end
+
+ it "should filter by environment and health" do
+ @knife.config[:environment] = "production"
+ @knife.config[:hide_healthy] = true
+ expect(@query).to receive(:search).with(:node, "name:my_custom_name AND chef_environment:production NOT ohai_time:[1428569820 TO 1428573420]", opts)
+ @knife.run
+ end
+ end
+
it "should not colorize output unless it's writing to a tty" do
@knife.run
expect(@stdout.string.match(/foobar/)).not_to be_nil