summaryrefslogtreecommitdiff
path: root/lib/chef
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2018-07-03 14:35:03 -0700
committerGitHub <noreply@github.com>2018-07-03 14:35:03 -0700
commitd58df7b53ed79d81eee0340adf95aa364d6a9a6e (patch)
tree93ccc263ba4702acee53da10ac2ff5ae9145ec07 /lib/chef
parent7910a42ca5999ae44c5b6b3dc256558b32b42481 (diff)
parentf9e0314265a9f3200ad90eec5c7666ebce9afd6a (diff)
downloadchef-d58df7b53ed79d81eee0340adf95aa364d6a9a6e.tar.gz
Merge pull request #7390 from coderanger/yet-more-creds
knife config and a bunch of UX improvements
Diffstat (limited to 'lib/chef')
-rw-r--r--lib/chef/application/knife.rb1
-rw-r--r--lib/chef/knife/config_get.rb126
2 files changed, 127 insertions, 0 deletions
diff --git a/lib/chef/application/knife.rb b/lib/chef/application/knife.rb
index d8818cd5aa..76dd5707fe 100644
--- a/lib/chef/application/knife.rb
+++ b/lib/chef/application/knife.rb
@@ -154,6 +154,7 @@ class Chef::Application::Knife < Chef::Application
# Run knife
def run
+ ChefConfig::PathHelper.per_tool_home_environment = "KNIFE_HOME"
Mixlib::Log::Formatter.show_time = false
validate_and_parse_options
quiet_traps
diff --git a/lib/chef/knife/config_get.rb b/lib/chef/knife/config_get.rb
new file mode 100644
index 0000000000..23085d177c
--- /dev/null
+++ b/lib/chef/knife/config_get.rb
@@ -0,0 +1,126 @@
+#
+# 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 ConfigGet < Knife
+ banner "knife config get [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.
+ filter_parts = filter.split(/\./)
+ extract = lambda do |memo, filter_part|
+ memo.is_a?(Hash) ? memo[filter_part.to_sym] : nil
+ end
+ # Check against both config_data and all of the data, so that even
+ # in non-all mode, if you ask for a key that isn't in the non-all
+ # data, it will check against the broader set.
+ output_data[filter] = filter_parts.inject(config_data, &extract) || filter_parts.inject(Chef::Config.save(true), &extract)
+ end
+ end
+ end
+
+ # Fix up some values.
+ output_data.each do |key, value|
+ if value == STDOUT
+ output_data[key] = "STDOUT"
+ elsif value == STDERR
+ output_data[key] = "STDERR"
+ 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