summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Kantrowitz <noah@coderanger.net>2018-06-23 22:24:23 -0700
committerNoah Kantrowitz <noah@coderanger.net>2018-06-23 22:24:23 -0700
commit78e28e201e2e196e214e946c153c8a6ae1aa2a3c (patch)
tree21bdabb641edb6a4533b4f073c81972656bf1d83
parente47ea80c9ef408e9bf8d4efef851899fceff7b6c (diff)
downloadchef-78e28e201e2e196e214e946c153c8a6ae1aa2a3c.tar.gz
Add a new `knife config` command.
This helps to inspect the configuration, aid in debugging, and work with scripts. Signed-off-by: Noah Kantrowitz <noah@coderanger.net>
-rw-r--r--lib/chef/knife/config.rb116
1 files changed, 116 insertions, 0 deletions
diff --git a/lib/chef/knife/config.rb b/lib/chef/knife/config.rb
new file mode 100644
index 0000000000..5362afbb8c
--- /dev/null
+++ b/lib/chef/knife/config.rb
@@ -0,0 +1,116 @@
+#
+# Author:: Joshua Timberman <opensource@housepub.org>
+# Copyright:: Copyright (c) 2012, Joshua Timberman
+# Copyright:: Copyright (c) 2018, Noah Kantrowitz
+# 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
+ class Config < Knife
+ banner "knife config [OPTION...] (options)\nDisplays the value of Chef::Config[OPTION] (or all config values)"
+
+ option :all,
+ short: "-a",
+ long: "--all",
+ description: "Include options that are not set in the configuration",
+ default: false
+
+ option :raw,
+ short: "-r",
+ long: "--raw",
+ description: "Display a each value with no formatting",
+ default: false
+
+ def run
+ if config[:format] == "summary" && !config[:raw]
+ # If using the default, human-readable output, also show which config files are being loaded.
+ # Some of this is a bit hacky since it duplicates
+ wcl = self.class.config_loader
+ if wcl.credentials_found
+ loading_from("credentials", ChefConfig::PathHelper.home(".chef", "credentials"))
+ end
+ if wcl.config_location
+ loading_from("configuration", wcl.config_location)
+ end
+ if Chef::Config[:config_d_dir]
+ wcl.find_dot_d(Chef::Config[:config_d_dir]).each do |path|
+ loading_from(".d/ configuration", wcl.config_location)
+ end
+ end
+ end
+
+ # Dump the whole config, including defaults is --all was given.
+ config_data = Chef::Config.save(config[:all])
+ # Two special cases, these are set during knife startup but we don't usually care about them.
+ unless config[:all]
+ config_data.delete(:color)
+ # Only keep these if true, false is much less important because it's the default.
+ config_data.delete(:local_mode) unless config_data[:local_mode]
+ config_data.delete(:enforce_path_sanity) unless config_data[:enforce_path_sanity]
+ end
+
+ # Extract the data to show.
+ output_data = {}
+ if @name_args.empty?
+ output_data = config_data
+ else
+ @name_args.each do |filter|
+ if filter =~ %r{^/(.*)/(i?)$}
+ # It's a regex.
+ filter_re = Regexp.new($1, $2 ? Regexp::IGNORECASE : 0)
+ config_data.each do |key, value|
+ output_data[key] = value if key.to_s =~ filter_re
+ end
+ else
+ # It's a dotted path string.
+ output_data[filter] = filter.split(/\./).inject(config_data) do |memo, filter_part|
+ if memo.is_a?(Hash)
+ memo[filter_part.to_sym]
+ else
+ nil
+ end
+ end
+ end
+ end
+ end
+
+ # Show the data.
+ if config[:raw]
+ output_data.each_value do |value|
+ ui.msg(value)
+ end
+ else
+ ui.output(output_data)
+ end
+ end
+
+ private
+
+ # Display a banner about loading from a config file.
+ #
+ # @api private
+ # @param type_of_file [String] Description of the file for the banner.
+ # @param path [String] Path of the file.
+ # @return [nil]
+ def loading_from(type_of_file, path)
+ path = Pathname.new(path).realpath
+ ui.msg(ui.color("Loading from #{type_of_file} file #{path}", :yellow))
+ end
+ end
+ end
+end