summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc A. Paradise <marc.paradise@gmail.com>2019-04-06 15:34:02 -0400
committerMarc A. Paradise <marc.paradise@gmail.com>2019-04-06 15:34:02 -0400
commit129d0299061d54635720389cec4824f7516eaa31 (patch)
treed106ab1f7c65023060f8ea9333c3e0e4c020679f
parent37fbedb4216bb5d448c807a3de5fb9205f4580e6 (diff)
downloadchef-mp/bootstrap-plus-consolidated-config.tar.gz
Attempting to consolidate ocnfig. May not work because of how merge config excludes keys that are not explicitly declared as optionsmp/bootstrap-plus-consolidated-config
Signed-off-by: Marc A. Paradise <marc.paradise@gmail.com>
-rw-r--r--lib/chef/knife/bootstrap.rb47
-rw-r--r--lib/chef/knife/bootstrap/chef_vault_handler.rb16
-rw-r--r--lib/chef/knife/bootstrap/client_builder.rb44
-rw-r--r--lib/chef/knife/bootstrap/templates/chef-full.erb23
-rw-r--r--lib/chef/knife/bootstrap/templates/windows-chef-client-msi.erb18
-rw-r--r--lib/chef/knife/core/bootstrap_context.rb121
-rw-r--r--lib/chef/knife/core/windows_bootstrap_context.rb119
-rw-r--r--spec/unit/knife/bootstrap_spec.rb33
-rw-r--r--spec/unit/knife/core/bootstrap_context_spec.rb33
9 files changed, 214 insertions, 240 deletions
diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb
index c6e214650b..4252cfdf7f 100644
--- a/lib/chef/knife/bootstrap.rb
+++ b/lib/chef/knife/bootstrap.rb
@@ -22,7 +22,6 @@ require "erubis"
require "chef/knife/bootstrap/chef_vault_handler"
require "chef/knife/bootstrap/client_builder"
require "chef/util/path_helper"
-require "chef/knife/bootstrap/options"
class Chef
class Knife
@@ -32,9 +31,6 @@ class Chef
WINRM_AUTH_PROTOCOL_LIST = %w{plaintext kerberos ssl negotiate}.freeze
include DataBagSecretOptions
- # Command line flags and options for bootstrap - there's a large number of them
- # so we'll keep this file a little smaller by splitting them out.
- include Bootstrap::Options
# Common connectivity options
option :connection_user,
short: "-U USERNAME",
@@ -352,14 +348,21 @@ class Chef
banner "knife bootstrap [PROTOCOL://][USER@]FQDN (options)"
def initialize(argv = [])
+ # These options need to be present in the CLI options hash
+ # in order for Knife#merge_config to merge them properly
+ # with Chef::Config[:knife].
+ self.class.options[:ssh_user] = self.class.options[:connection_user]
+ self.class.options[:winrm_user] = self.class.options[:connection_user]
+ self.class.options[:ssh_port] = self.class.options[:connection_port]
+ self.class.options[:winrm_port] = self.class.options[:connection_port]
+ # knife config
super
@client_builder = Chef::Knife::Bootstrap::ClientBuilder.new(
- chef_config: Chef::Config,
- knife_config: config,
+ config: config,
ui: ui
)
@chef_vault_handler = Chef::Knife::Bootstrap::ChefVaultHandler.new(
- knife_config: config,
+ config: config,
ui: ui
)
end
@@ -440,19 +443,19 @@ class Chef
@bootstrap_context ||=
if target_host.base_os == :windows
require "chef/knife/core/windows_bootstrap_context"
- Knife::Core::WindowsBootstrapContext.new(config, config[:run_list], Chef::Config, secret)
+ Knife::Core::WindowsBootstrapContext.new(config, config[:run_list], secret)
else
require "chef/knife/core/bootstrap_context"
- Knife::Core::BootstrapContext.new(config, config[:run_list], Chef::Config, secret)
+ Knife::Core::BootstrapContext.new(config, config[:run_list], secret)
end
end
def first_boot_attributes
- @config[:first_boot_attributes] || @config[:first_boot_attributes_from_file] || {}
+ config[:first_boot_attributes] || config[:first_boot_attributes_from_file] || {}
end
def render_template
- @config[:first_boot_attributes] = first_boot_attributes
+ config[:first_boot_attributes] = first_boot_attributes
template_file = find_template
template = IO.read(template_file).chomp
Erubis::Eruby.new(template).evaluate(bootstrap_context)
@@ -574,7 +577,7 @@ class Chef
# Fail if both first_boot_attributes and first_boot_attributes_from_file
# are set.
def validate_first_boot_attributes!
- if @config[:first_boot_attributes] && @config[:first_boot_attributes_from_file]
+ if config[:first_boot_attributes] && config[:first_boot_attributes_from_file]
raise Chef::Exceptions::BootstrapCommandInputError
end
true
@@ -860,7 +863,14 @@ class Chef
}
end
- # Looks up configuration entries, first in the class member
+ #
+ # Looks up configuration entries in the config field,
+ # which is a merge of cli config + defaults + knife config
+ # Because some keys can be kept in knife config under alternative
+ # names (eg -> connection_user -> winrm_user|ssh_user),
+ # we'll fall back to lookuping up under the provided alt_config_key
+ #
+ # merged 'config' fieldLooks up configuration entries, first in the class member
# `config` which contains options populated from CLI flags.
# If the entry is not found there, Chef::Config[:knife][KEY]
# is checked.
@@ -868,16 +878,13 @@ class Chef
# knife_config_key should be specified if the knife config lookup
# key is different from the CLI flag lookup key.
#
- def config_value(key, knife_config_key = nil, default = nil)
+ def config_value(key, alt_config_key = nil, default = nil)
if config.key? key
config[key]
+ elsif config.key? alt_config_key
+ config[alt_config_key]
else
- lookup_key = knife_config_key || key
- if Chef::Config[:knife].key?(lookup_key)
- Chef::Config[:knife][lookup_key]
- else
- default
- end
+ default
end
end
diff --git a/lib/chef/knife/bootstrap/chef_vault_handler.rb b/lib/chef/knife/bootstrap/chef_vault_handler.rb
index 24ed0eb379..176315f2a0 100644
--- a/lib/chef/knife/bootstrap/chef_vault_handler.rb
+++ b/lib/chef/knife/bootstrap/chef_vault_handler.rb
@@ -23,7 +23,7 @@ class Chef
class ChefVaultHandler
# @return [Hash] knife merged config, typically @config
- attr_accessor :knife_config
+ attr_accessor :config
# @return [Chef::Knife::UI] ui object for output
attr_accessor :ui
@@ -31,11 +31,11 @@ class Chef
# @return [Chef::ApiClient] vault client
attr_reader :client
- # @param knife_config [Hash] knife merged config, typically @config
+ # @param config [Hash] knife merged config, typically @config
# @param ui [Chef::Knife::UI] ui object for output
- def initialize(knife_config: {}, ui: nil)
- @knife_config = knife_config
- @ui = ui
+ def initialize(config: {}, ui: nil)
+ @config = config
+ @ui = ui
end
# Updates the chef vault items for the newly created client.
@@ -87,17 +87,17 @@ class Chef
# @return [String] string with serialized JSON representing the chef vault items
def bootstrap_vault_json
- knife_config[:bootstrap_vault_json]
+ config[:bootstrap_vault_json]
end
# @return [String] JSON text in a file representing the chef vault items
def bootstrap_vault_file
- knife_config[:bootstrap_vault_file]
+ config[:bootstrap_vault_file]
end
# @return [Hash] Ruby object representing the chef vault items to create
def bootstrap_vault_item
- knife_config[:bootstrap_vault_item]
+ config[:bootstrap_vault_item]
end
# Helper to return a ruby object represeting all the data bags and items
diff --git a/lib/chef/knife/bootstrap/client_builder.rb b/lib/chef/knife/bootstrap/client_builder.rb
index 5fb0edc31b..cc15791b9e 100644
--- a/lib/chef/knife/bootstrap/client_builder.rb
+++ b/lib/chef/knife/bootstrap/client_builder.rb
@@ -28,21 +28,19 @@ class Chef
class Bootstrap < Knife
class ClientBuilder
- # @return [Hash] knife merged config, typically @config
- attr_accessor :knife_config
- # @return [Hash] chef config object
- attr_accessor :chef_config
+ # @return [Hash] merged hash of CLI and knife config
+ attr_accessor :config
# @return [Chef::Knife::UI] ui object for output
attr_accessor :ui
# @return [Chef::ApiClient] client saved on run
attr_reader :client
- # @param knife_config [Hash] Hash of knife config settings
- # @param chef_config [Hash] Hash of chef config settings
+ # @param config [Hash] Hash of knife config settings
+ # @param config [Hash] Hash of chef config settings
# @param ui [Chef::Knife::UI] UI object for output
- def initialize(knife_config: {}, chef_config: {}, ui: nil)
- @knife_config = knife_config
- @chef_config = chef_config
+ def initialize(config: {}, ui: nil)
+ @config = config
+ @config = config
@ui = ui
end
@@ -78,39 +76,39 @@ class Chef
private
- # @return [String] node name from the knife_config
+ # @return [String] node name from the config
def node_name
- knife_config[:chef_node_name]
+ config[:chef_node_name]
end
- # @return [String] enviroment from the knife_config
+ # @return [String] enviroment from the config
def environment
- knife_config[:environment]
+ config[:environment]
end
- # @return [String] run_list from the knife_config
+ # @return [String] run_list from the config
def run_list
- knife_config[:run_list]
+ config[:run_list]
end
- # @return [String] policy_name from the knife_config
+ # @return [String] policy_name from the config
def policy_name
- knife_config[:policy_name]
+ config[:policy_name]
end
- # @return [String] policy_group from the knife_config
+ # @return [String] policy_group from the config
def policy_group
- knife_config[:policy_group]
+ config[:policy_group]
end
- # @return [Hash,Array] Object representation of json first-boot attributes from the knife_config
+ # @return [Hash,Array] Object representation of json first-boot attributes from the config
def first_boot_attributes
- knife_config[:first_boot_attributes]
+ config[:first_boot_attributes]
end
# @return [String] chef server url from the Chef::Config
def chef_server_url
- chef_config[:chef_server_url]
+ config[:chef_server_url]
end
# Accesses the run_list and coerces it into an Array, changing nils into
@@ -155,7 +153,7 @@ class Chef
node.environment(environment) if environment
node.policy_name = policy_name if policy_name
node.policy_group = policy_group if policy_group
- (knife_config[:tags] || []).each do |tag|
+ (config[:tags] || []).each do |tag|
node.tags << tag
end
node
diff --git a/lib/chef/knife/bootstrap/templates/chef-full.erb b/lib/chef/knife/bootstrap/templates/chef-full.erb
index 094cca1c08..845bb03e22 100644
--- a/lib/chef/knife/bootstrap/templates/chef-full.erb
+++ b/lib/chef/knife/bootstrap/templates/chef-full.erb
@@ -1,5 +1,4 @@
-sh -c '
-<%= "export https_proxy=\"#{knife_config[:bootstrap_proxy]}\"" if knife_config[:bootstrap_proxy] -%>
+<%= "export https_proxy=\"#{config[:bootstrap_proxy]}\"" if config[:bootstrap_proxy] -%>
if test "x$TMPDIR" = "x"; then
tmp="/tmp"
@@ -37,7 +36,7 @@ capture_tmp_stderr() {
# do_wget URL FILENAME
do_wget() {
echo "trying wget..."
- wget <%= "--proxy=on " if knife_config[:bootstrap_proxy] %> <%= knife_config[:bootstrap_wget_options] %> -O "$2" "$1" 2>$tmp_dir/stderr
+ wget <%= "--proxy=on " if config[:bootstrap_proxy] %> <%= config[:bootstrap_wget_options] %> -O "$2" "$1" 2>$tmp_dir/stderr
rc=$?
# check for 404
grep "ERROR 404" $tmp_dir/stderr 2>&1 >/dev/null
@@ -57,7 +56,7 @@ do_wget() {
# do_curl URL FILENAME
do_curl() {
echo "trying curl..."
- curl -sL <%= "--proxy \"#{knife_config[:bootstrap_proxy]}\" " if knife_config[:bootstrap_proxy] %> <%= knife_config[:bootstrap_curl_options] %> -D $tmp_dir/stderr -o "$2" "$1" 2>$tmp_dir/stderr
+ curl -sL <%= "--proxy \"#{config[:bootstrap_proxy]}\" " if config[:bootstrap_proxy] %> <%= config[:bootstrap_curl_options] %> -D $tmp_dir/stderr -o "$2" "$1" 2>$tmp_dir/stderr
rc=$?
# check for 404
grep "404 Not Found" $tmp_dir/stderr 2>&1 >/dev/null
@@ -164,14 +163,14 @@ do_download() {
<%# Run any custom commands before installing chef-client -%>
<%# Ex. wait for cloud-init to complete -%>
-<% if knife_config[:bootstrap_preinstall_command] %>
- <%= knife_config[:bootstrap_preinstall_command] %>
+<% if config[:bootstrap_preinstall_command] %>
+ <%= config[:bootstrap_preinstall_command] %>
<% end %>
-<% if knife_config[:bootstrap_install_command] %>
- <%= knife_config[:bootstrap_install_command] %>
+<% if config[:bootstrap_install_command] %>
+ <%= config[:bootstrap_install_command] %>
<% else %>
- install_sh="<%= knife_config[:bootstrap_url] ? knife_config[:bootstrap_url] : "https://omnitruck.chef.io/chef/install.sh" %>"
+ install_sh="<%= config[:bootstrap_url] ? config[:bootstrap_url] : "https://omnitruck.chef.io/chef/install.sh" %>"
if test -f /usr/bin/chef-client; then
echo "-----> Existing Chef installation detected"
else
@@ -214,10 +213,10 @@ mkdir -p /etc/chef/trusted_certs
<% end -%>
<%# Generate Ohai Hints -%>
-<% unless @chef_config[:knife][:hints].nil? || @chef_config[:knife][:hints].empty? -%>
+<% unless config[:hints].nil? || config[:hints].empty? -%>
mkdir -p /etc/chef/ohai/hints
-<% @chef_config[:knife][:hints].each do |name, hash| -%>
+<% config[:hints].each do |name, hash| -%>
cat > /etc/chef/ohai/hints/<%= name %>.json <<'EOP'
<%= Chef::JSONCompat.to_json(hash) %>
EOP
@@ -239,4 +238,4 @@ mkdir -p /etc/chef/client.d
echo "Starting the first Chef Client run..."
-<%= start_chef %>'
+<%= start_chef %>
diff --git a/lib/chef/knife/bootstrap/templates/windows-chef-client-msi.erb b/lib/chef/knife/bootstrap/templates/windows-chef-client-msi.erb
index c30a22bd94..a85fb9947c 100644
--- a/lib/chef/knife/bootstrap/templates/windows-chef-client-msi.erb
+++ b/lib/chef/knife/bootstrap/templates/windows-chef-client-msi.erb
@@ -21,7 +21,7 @@
@rem the line is read. See help for the /E switch from cmd.exe /? .
@setlocal ENABLEDELAYEDEXPANSION
-<%= "SETX HTTP_PROXY \"#{knife_config[:bootstrap_proxy]}\"" if knife_config[:bootstrap_proxy] %>
+<%= "SETX HTTP_PROXY \"#{config[:bootstrap_proxy]}\"" if config[:bootstrap_proxy] %>
@set BOOTSTRAP_DIRECTORY=<%= bootstrap_directory %>
@echo Checking for existing directory "%BOOTSTRAP_DIRECTORY%"...
@@ -96,10 +96,10 @@ goto architecture_select
goto Version10.0
:architecture_select
-<% if knife_config[:architecture] %>
- @set MACHINE_ARCH=<%= knife_config[:architecture] %>
+<% if config[:architecture] %>
+ @set MACHINE_ARCH=<%= config[:architecture] %>
- <% if knife_config[:architecture] == "x86_64" %>
+ <% if config[:architecture] == "x86_64" %>
IF "%PROCESSOR_ARCHITECTURE%"=="x86" IF not defined PROCESSOR_ARCHITEW6432 (
echo You specified bootstrap_architecture as x86_64 but the target machine is i386. A 64 bit program cannot run on a 32 bit machine. > "&2"
echo Exiting without bootstrapping. > "&2"
@@ -125,8 +125,8 @@ If !ERRORLEVEL!==0 (
:install
@rem If user has provided the custom installation command for chef-client then execute it
-<% if @chef_config[:knife][:bootstrap_install_command] %>
- <%= @chef_config[:knife][:bootstrap_install_command] %>
+<% if config[:bootstrap_install_command] %>
+ <%= config[:bootstrap_install_command] %>
<% else %>
@rem Install Chef using chef-client MSI installer
@@ -232,7 +232,7 @@ echo Writing validation key...
echo Validation key written.
@echo on
-<% if @config[:secret] -%>
+<% if config[:secret] -%>
> <%= bootstrap_directory %>\encrypted_data_bag_secret (
<%= secret %>
)
@@ -244,10 +244,10 @@ mkdir <%= bootstrap_directory %>\trusted_certs
<% end -%>
<%# Generate Ohai Hints -%>
-<% unless @chef_config[:knife][:hints].nil? || @chef_config[:knife][:hints].empty? -%>
+<% unless config[:hints].nil? || config[:hints].empty? -%>
mkdir <%= bootstrap_directory %>\ohai\hints
-<% @chef_config[:knife][:hints].each do |name, hash| -%>
+<% config[:hints].each do |name, hash| -%>
> <%= bootstrap_directory %>\ohai\hints\<%= name %>.json (
<%= escape_and_echo(hash.to_json) %>
)
diff --git a/lib/chef/knife/core/bootstrap_context.rb b/lib/chef/knife/core/bootstrap_context.rb
index 287fe0a50f..72a8ab1033 100644
--- a/lib/chef/knife/core/bootstrap_context.rb
+++ b/lib/chef/knife/core/bootstrap_context.rb
@@ -26,17 +26,17 @@ class Chef
# Instances of BootstrapContext are the context objects (i.e., +self+) for
# bootstrap templates. For backwards compatibility, they +must+ set the
# following instance variables:
- # * @config - a hash of knife's config values
+ # * @config - a hash of knife's @config values
# * @run_list - the run list for the node to boostrap
#
class BootstrapContext
attr_accessor :client_pem
+ attr_reader :config
- def initialize(config, run_list, chef_config, secret = nil)
+ def initialize(config, run_list, secret = nil)
@config = config
@run_list = run_list
- @chef_config = chef_config
@secret = secret
end
@@ -45,9 +45,9 @@ class Chef
end
def validation_key
- if @chef_config[:validation_key] &&
- File.exist?(File.expand_path(@chef_config[:validation_key]))
- IO.read(File.expand_path(@chef_config[:validation_key]))
+ if @config[:validation_key] &&
+ File.exist?(File.expand_path(@config[:validation_key]))
+ IO.read(File.expand_path(@config[:validation_key]))
else
false
end
@@ -68,31 +68,32 @@ class Chef
end
def get_log_location
- if !(@chef_config[:config_log_location].class == IO ) && (@chef_config[:config_log_location].nil? || @chef_config[:config_log_location].to_s.empty?)
+ if !(@config[:config_log_location].class == IO ) && (@config[:config_log_location].nil? || @config[:config_log_location].to_s.empty?)
"STDOUT"
- elsif @chef_config[:config_log_location].equal?(:win_evt)
- raise "The value :win_evt is not supported for config_log_location on Linux Platforms \n"
- elsif @chef_config[:config_log_location].equal?(:syslog)
+ elsif @config[:config_log_location].equal?(:win_evt)
+ raise "The value :win_evt is not supported for @config_log_location on Linux Platforms \n"
+ elsif @config[:config_log_location].equal?(:syslog)
":syslog"
- elsif @chef_config[:config_log_location].equal?(STDOUT)
+ elsif @config[:config_log_location].equal?(STDOUT)
"STDOUT"
- elsif @chef_config[:config_log_location].equal?(STDERR)
+ elsif @config[:config_log_location].equal?(STDERR)
"STDERR"
- elsif @chef_config[:config_log_location]
- %Q{"#{@chef_config[:config_log_location]}"}
+ elsif @config[:config_log_location]
+ %Q{"#{@config[:config_log_location]}"}
else
"STDOUT"
end
end
def config_content
+ require 'pry'; binding.pry
client_rb = <<~CONFIG
- chef_server_url "#{@chef_config[:chef_server_url]}"
- validation_client_name "#{@chef_config[:validation_client_name]}"
+ chef_server_url "#{@config[:chef_server_url]}"
+ validation_client_name "#{@config[:validation_client_name]}"
CONFIG
- if !(@chef_config[:config_log_level].nil? || @chef_config[:config_log_level].empty?)
- client_rb << %Q{log_level :#{@chef_config[:config_log_level]}\n}
+ if !(@config[:config_log_level].nil? || @config[:config_log_level].empty?)
+ client_rb << %Q{log_level :#{@config[:config_log_level]}\n}
end
client_rb << "log_location #{get_log_location}\n"
@@ -103,23 +104,23 @@ class Chef
client_rb << "# Using default node name (fqdn)\n"
end
- # We configure :verify_api_cert only when it's overridden on the CLI
- # or when specified in the knife config.
- if !@config[:node_verify_api_cert].nil? || knife_config.key?(:verify_api_cert)
- value = @config[:node_verify_api_cert].nil? ? knife_config[:verify_api_cert] : @config[:node_verify_api_cert]
+ # We @configure :verify_api_cert only when it's overridden on the CLI
+ # or when specified in the knife @config.
+ if !@config[:node_verify_api_cert].nil? || @config.key?(:verify_api_cert)
+ value = @config[:node_verify_api_cert].nil? ? @config[:verify_api_cert] : @config[:node_verify_api_cert]
client_rb << %Q{verify_api_cert #{value}\n}
end
- # We configure :ssl_verify_mode only when it's overridden on the CLI
- # or when specified in the knife config.
- if @config[:node_ssl_verify_mode] || knife_config.key?(:ssl_verify_mode)
+ # We @configure :ssl_verify_mode only when it's overridden on the CLI
+ # or when specified in the knife @config.
+ if @config[:node_ssl_verify_mode] || @config.key?(:ssl_verify_mode)
value = case @config[:node_ssl_verify_mode]
when "peer"
:verify_peer
when "none"
:verify_none
when nil
- knife_config[:ssl_verify_mode]
+ @config[:ssl_verify_mode]
else
nil
end
@@ -130,26 +131,26 @@ class Chef
end
if @config[:ssl_verify_mode]
- client_rb << %Q{ssl_verify_mode :#{knife_config[:ssl_verify_mode]}\n}
+ client_rb << %Q{ssl_verify_mode :#{@config[:ssl_verify_mode]}\n}
end
- if knife_config[:bootstrap_proxy]
- client_rb << %Q{http_proxy "#{knife_config[:bootstrap_proxy]}"\n}
- client_rb << %Q{https_proxy "#{knife_config[:bootstrap_proxy]}"\n}
+ if @config[:bootstrap_proxy]
+ client_rb << %Q{http_proxy "#{@config[:bootstrap_proxy]}"\n}
+ client_rb << %Q{https_proxy "#{@config[:bootstrap_proxy]}"\n}
end
- if knife_config[:bootstrap_proxy_user]
- client_rb << %Q{http_proxy_user "#{knife_config[:bootstrap_proxy_user]}"\n}
- client_rb << %Q{https_proxy_user "#{knife_config[:bootstrap_proxy_user]}"\n}
+ if @config[:bootstrap_proxy_user]
+ client_rb << %Q{http_proxy_user "#{@config[:bootstrap_proxy_user]}"\n}
+ client_rb << %Q{https_proxy_user "#{@config[:bootstrap_proxy_user]}"\n}
end
- if knife_config[:bootstrap_proxy_pass]
- client_rb << %Q{http_proxy_pass "#{knife_config[:bootstrap_proxy_pass]}"\n}
- client_rb << %Q{https_proxy_pass "#{knife_config[:bootstrap_proxy_pass]}"\n}
+ if @config[:bootstrap_proxy_pass]
+ client_rb << %Q{http_proxy_pass "#{@config[:bootstrap_proxy_pass]}"\n}
+ client_rb << %Q{https_proxy_pass "#{@config[:bootstrap_proxy_pass]}"\n}
end
- if knife_config[:bootstrap_no_proxy]
- client_rb << %Q{no_proxy "#{knife_config[:bootstrap_no_proxy]}"\n}
+ if @config[:bootstrap_no_proxy]
+ client_rb << %Q{no_proxy "#{@config[:bootstrap_no_proxy]}"\n}
end
if encrypted_data_bag_secret
@@ -165,7 +166,7 @@ class Chef
fips true
require "chef/version"
chef_version = ::Chef::VERSION.split(".")
- unless chef_version[0].to_i > 12 || (chef_version[0].to_i == 12 && chef_version[1].to_i >= 8)
+ unless chef_version[0].to_i > 12 || (chef_version[0].to_i == 12 && chef_version[1].to_i >= 20)
raise "FIPS Mode requested but not supported by this client"
end
CONFIG
@@ -175,8 +176,8 @@ class Chef
end
def start_chef
- # If the user doesn't have a client path configure, let bash use the PATH for what it was designed for
- client_path = @chef_config[:chef_client_path] || "chef-client"
+ # If the user doesn't have a client path @configure, let bash use the PATH for what it was designed for
+ client_path = @config[:chef_client_path] || "chef-client"
s = "#{client_path} -j /etc/chef/first-boot.json"
if @config[:verbosity] && @config[:verbosity] >= 3
s << " -l trace"
@@ -188,34 +189,17 @@ class Chef
s
end
- def knife_config
- @chef_config.key?(:knife) ? @chef_config[:knife] : {}
- end
-
#
# chef version string to fetch the latest current version from omnitruck
# If user is on X.Y.Z bootstrap will use the latest X release
# X here can be 10 or 11
def latest_current_chef_version_string
- installer_version_string = nil
- if @config[:prerelease]
- installer_version_string = ["-p"]
- else
- chef_version_string = if knife_config[:bootstrap_version]
- knife_config[:bootstrap_version]
- else
- Chef::VERSION.split(".").first
- end
-
- installer_version_string = ["-v", chef_version_string]
-
- # If bootstrapping a pre-release version add -p to the installer string
- if chef_version_string.split(".").length > 3
- installer_version_string << "-p"
- end
- end
-
- installer_version_string.join(" ")
+ chef_version_string = if @config[:bootstrap_version]
+ @config[:bootstrap_version]
+ else
+ Chef::VERSION.split(".").first
+ end
+ "-v #{chef_version_string}"
end
def first_boot
@@ -238,8 +222,8 @@ class Chef
# This string should contain both the commands necessary to both create the files, as well as their content
def trusted_certs_content
content = ""
- if @chef_config[:trusted_certs_dir]
- Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(@chef_config[:trusted_certs_dir]), "*.{crt,pem}")).each do |cert|
+ if @config[:trusted_certs_dir]
+ Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(@config[:trusted_certs_dir]), "*.{crt,pem}")).each do |cert|
content << "cat > /etc/chef/trusted_certs/#{File.basename(cert)} <<'EOP'\n" +
IO.read(File.expand_path(cert)) + "\nEOP\n"
end
@@ -249,8 +233,8 @@ class Chef
def client_d_content
content = ""
- if @chef_config[:client_d_dir] && File.exist?(@chef_config[:client_d_dir])
- root = Pathname(@chef_config[:client_d_dir])
+ if @config[:client_d_dir] && File.exist?(@config[:client_d_dir])
+ root = Pathname(@config[:client_d_dir])
root.find do |f|
relative = f.relative_path_from(root)
if f != root
@@ -266,7 +250,6 @@ class Chef
end
content
end
-
end
end
end
diff --git a/lib/chef/knife/core/windows_bootstrap_context.rb b/lib/chef/knife/core/windows_bootstrap_context.rb
index 1993a68ea8..dbc7595c3d 100644
--- a/lib/chef/knife/core/windows_bootstrap_context.rb
+++ b/lib/chef/knife/core/windows_bootstrap_context.rb
@@ -25,36 +25,25 @@ class Chef
# Instances of BootstrapContext are the context objects (i.e., +self+) for
# bootstrap templates. For backwards compatability, they +must+ set the
# following instance variables:
- # * @config - a hash of knife's config values
+ # * config - a hash of knife's config values
# * @run_list - the run list for the node to boostrap
#
class WindowsBootstrapContext < BootstrapContext
- def initialize(config, run_list, chef_config, secret = nil)
- @config = config
- @run_list = run_list
- @chef_config = chef_config
- @secret = secret
- # Compatibility with Chef 12 and Chef 11 versions
- begin
- # Pass along the secret parameter for Chef 12
- super(config, run_list, chef_config, secret)
- rescue ArgumentError
- # The Chef 11 base class only has parameters for initialize
- super(config, run_list, chef_config)
- end
+ def initialize(config, run_list, secret = nil)
+ super
end
def validation_key
- if File.exist?(File.expand_path(@chef_config[:validation_key]))
- IO.read(File.expand_path(@chef_config[:validation_key]))
+ if File.exist?(File.expand_path(config[:validation_key]))
+ IO.read(File.expand_path(config[:validation_key]))
else
false
end
end
def secret
- escape_and_echo(@config[:secret])
+ escape_and_echo(config[:secret])
end
def trusted_certs_script
@@ -63,20 +52,20 @@ class Chef
def config_content
client_rb = <<~CONFIG
- chef_server_url "#{@chef_config[:chef_server_url]}"
- validation_client_name "#{@chef_config[:validation_client_name]}"
+ chef_server_url "#{config[:chef_server_url]}"
+ validation_client_name "#{config[:validation_client_name]}"
file_cache_path "c:/chef/cache"
file_backup_path "c:/chef/backup"
cache_options ({:path => "c:/chef/cache/checksums", :skip_expires => true})
CONFIG
- if @config[:chef_node_name]
- client_rb << %Q{node_name "#{@config[:chef_node_name]}"\n}
+ if config[:chef_node_name]
+ client_rb << %Q{node_name "#{config[:chef_node_name]}"\n}
else
client_rb << "# Using default node name (fqdn)\n"
end
- if @chef_config[:config_log_level]
- client_rb << %Q{log_level :#{@chef_config[:config_log_level]}\n}
+ if config[:config_log_level]
+ client_rb << %Q{log_level :#{config[:config_log_level]}\n}
else
client_rb << "log_level :auto\n"
end
@@ -85,21 +74,21 @@ class Chef
# We configure :verify_api_cert only when it's overridden on the CLI
# or when specified in the knife config.
- if !@config[:node_verify_api_cert].nil? || knife_config.key?(:verify_api_cert)
- value = @config[:node_verify_api_cert].nil? ? knife_config[:verify_api_cert] : @config[:node_verify_api_cert]
+ if !config[:node_verify_api_cert].nil? || config.key?(:verify_api_cert)
+ value = config[:node_verify_api_cert].nil? ? config[:verify_api_cert] : config[:node_verify_api_cert]
client_rb << %Q{verify_api_cert #{value}\n}
end
# We configure :ssl_verify_mode only when it's overridden on the CLI
# or when specified in the knife config.
- if @config[:node_ssl_verify_mode] || knife_config.key?(:ssl_verify_mode)
- value = case @config[:node_ssl_verify_mode]
+ if config[:node_ssl_verify_mode] || config.key?(:ssl_verify_mode)
+ value = case config[:node_ssl_verify_mode]
when "peer"
:verify_peer
when "none"
:verify_none
when nil
- knife_config[:ssl_verify_mode]
+ config[:ssl_verify_mode]
else
nil
end
@@ -109,22 +98,22 @@ class Chef
end
end
- if @config[:ssl_verify_mode]
- client_rb << %Q{ssl_verify_mode :#{knife_config[:ssl_verify_mode]}\n}
+ if config[:ssl_verify_mode]
+ client_rb << %Q{ssl_verify_mode :#{config[:ssl_verify_mode]}\n}
end
- if knife_config[:bootstrap_proxy]
+ if config[:bootstrap_proxy]
client_rb << "\n"
- client_rb << %Q{http_proxy "#{knife_config[:bootstrap_proxy]}"\n}
- client_rb << %Q{https_proxy "#{knife_config[:bootstrap_proxy]}"\n}
- client_rb << %Q{no_proxy "#{knife_config[:bootstrap_no_proxy]}"\n} if knife_config[:bootstrap_no_proxy]
+ client_rb << %Q{http_proxy "#{config[:bootstrap_proxy]}"\n}
+ client_rb << %Q{https_proxy "#{config[:bootstrap_proxy]}"\n}
+ client_rb << %Q{no_proxy "#{config[:bootstrap_no_proxy]}"\n} if config[:bootstrap_no_proxy]
end
- if knife_config[:bootstrap_no_proxy]
- client_rb << %Q{no_proxy "#{knife_config[:bootstrap_no_proxy]}"\n}
+ if config[:bootstrap_no_proxy]
+ client_rb << %Q{no_proxy "#{config[:bootstrap_no_proxy]}"\n}
end
- if @config[:secret]
+ if config[:secret]
client_rb << %Q{encrypted_data_bag_secret "c:/chef/encrypted_data_bag_secret"\n}
end
@@ -136,7 +125,7 @@ class Chef
client_rb << <<~CONFIG
fips true
chef_version = ::Chef::VERSION.split(".")
- unless chef_version[0].to_i > 12 || (chef_version[0].to_i == 12 && chef_version[1].to_i >= 8)
+ unless chef_version[0].to_i > 12 || (chef_version[0].to_i == 12 && chef_version[1].to_i >= 20)
raise "FIPS Mode requested but not supported by this client"
end
CONFIG
@@ -146,18 +135,18 @@ class Chef
end
def get_log_location
- if @chef_config[:config_log_location].equal?(:win_evt)
- %Q{:#{@chef_config[:config_log_location]}\n}
- elsif @chef_config[:config_log_location].equal?(:syslog)
+ if config[:config_log_location].equal?(:win_evt)
+ %Q{:#{config[:config_log_location]}\n}
+ elsif config[:config_log_location].equal?(:syslog)
raise "syslog is not supported for log_location on Windows OS\n"
- elsif @chef_config[:config_log_location].equal?(STDOUT)
+ elsif config[:config_log_location].equal?(STDOUT)
"STDOUT\n"
- elsif @chef_config[:config_log_location].equal?(STDERR)
+ elsif config[:config_log_location].equal?(STDERR)
"STDERR\n"
- elsif @chef_config[:config_log_location].nil? || @chef_config[:config_log_location].empty?
+ elsif config[:config_log_location].nil? || config[:config_log_location].empty?
"STDOUT\n"
- elsif @chef_config[:config_log_location]
- %Q{"#{@chef_config[:config_log_location]}"\n}
+ elsif config[:config_log_location]
+ %Q{"#{config[:config_log_location]}"\n}
else
"STDOUT\n"
end
@@ -170,25 +159,13 @@ class Chef
end
def latest_current_windows_chef_version_query
- installer_version_string = nil
- if @config[:prerelease]
- installer_version_string = "&prerelease=true"
- else
- chef_version_string = if knife_config[:bootstrap_version]
- knife_config[:bootstrap_version]
- else
- Chef::VERSION.split(".").first
- end
-
- installer_version_string = "&v=#{chef_version_string}"
-
- # If bootstrapping a pre-release version add the prerelease query string
- if chef_version_string.split(".").length > 3
- installer_version_string << "&prerelease=true"
- end
- end
+ chef_version_string = if config[:bootstrap_version]
+ config[:bootstrap_version]
+ else
+ Chef::VERSION.split(".").first
+ end
- installer_version_string
+ "&v=#{chef_version_string}"
end
def win_wget
@@ -300,14 +277,14 @@ class Chef
# The default msi path has a number of url query parameters - we attempt to substitute
# such parameters in as long as they are provided by the template.
- if @config[:install].nil? || @config[:msi_url].empty?
+ if config[:install].nil? || config[:msi_url].empty?
url = "https://www.chef.io/chef/download?p=windows"
url += "&pv=#{machine_os}" unless machine_os.nil?
url += "&m=#{machine_arch}" unless machine_arch.nil?
url += "&DownloadContext=#{download_context}" unless download_context.nil?
url += latest_current_windows_chef_version_query
else
- @config[:msi_url]
+ config[:msi_url]
end
end
@@ -325,7 +302,7 @@ class Chef
private
def install_command(executor_quote)
- if @config[:install_as_service]
+ if config[:install_as_service]
"msiexec /qn /log #{executor_quote}%CHEF_CLIENT_MSI_LOG_PATH%#{executor_quote} /i #{executor_quote}%LOCAL_DESTINATION_MSI_PATH%#{executor_quote} ADDLOCAL=#{executor_quote}ChefClientFeature,ChefServiceFeature#{executor_quote}"
else
"msiexec /qn /log #{executor_quote}%CHEF_CLIENT_MSI_LOG_PATH%#{executor_quote} /i #{executor_quote}%LOCAL_DESTINATION_MSI_PATH%#{executor_quote}"
@@ -336,8 +313,8 @@ class Chef
# This string should contain both the commands necessary to both create the files, as well as their content
def trusted_certs_content
content = ""
- if @chef_config[:trusted_certs_dir]
- Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(@chef_config[:trusted_certs_dir]), "*.{crt,pem}")).each do |cert|
+ if config[:trusted_certs_dir]
+ Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(config[:trusted_certs_dir]), "*.{crt,pem}")).each do |cert|
content << "> #{bootstrap_directory}/trusted_certs/#{File.basename(cert)} (\n" +
escape_and_echo(IO.read(File.expand_path(cert))) + "\n)\n"
end
@@ -347,8 +324,8 @@ class Chef
def client_d_content
content = ""
- if @chef_config[:client_d_dir] && File.exist?(@chef_config[:client_d_dir])
- root = Pathname(@chef_config[:client_d_dir])
+ if config[:client_d_dir] && File.exist?(config[:client_d_dir])
+ root = Pathname(config[:client_d_dir])
root.find do |f|
relative = f.relative_path_from(root)
if f != root
diff --git a/spec/unit/knife/bootstrap_spec.rb b/spec/unit/knife/bootstrap_spec.rb
index 5be0999e37..1075e9dccc 100644
--- a/spec/unit/knife/bootstrap_spec.rb
+++ b/spec/unit/knife/bootstrap_spec.rb
@@ -51,13 +51,14 @@ describe Chef::Knife::Bootstrap do
end
end
- context "#render_template - when using the chef-full default template" do
+ context "#render_template - when using the chef-full default template", :focus do
let(:rendered_template) do
knife.merge_configs
knife.render_template
end
it "should render client.rb" do
+ puts rendered_template
expect(rendered_template).to match("cat > /etc/chef/client.rb <<'EOP'")
expect(rendered_template).to match("chef_server_url \"https://localhost:443\"")
expect(rendered_template).to match("validation_client_name \"chef-validator\"")
@@ -1777,27 +1778,37 @@ describe Chef::Knife::Bootstrap do
describe "#config_value" do
before do
- knife.config[:test_key_a] = "a from cli"
- knife.config[:test_key_b] = "b from cli"
- Chef::Config[:knife][:test_key_a] = "a from Chef::Config"
- Chef::Config[:knife][:test_key_c] = "c from Chef::Config"
- Chef::Config[:knife][:alt_test_key_c] = "alt c from Chef::Config"
+
+ # Make sure this is in classs.options, or else merge_configs won't see it
+ # since it's not a declared option
+ knife.class.options[:ssh_user] = knife.class.options[:connection_user]
+ knife.class.options[:winrm_user] = knife.class.options[:connection_user]
+
+ knife.config[:connection_protocol] = "connection_protocol from CLI"
+ knife.config[:connection_user] = "connection_user_from CLI"
+ knife.config[:password] = "password from CLI"
+
+ Chef::Config.knife.connection_protocol = "connection_protocol from Chef::Config"
+ Chef::Config.knife.ssh_user = "ssh user from Chef::Config"
+ Chef::Config.knife.winrm_user = "winrm user from Chef::Config"
+ knife.merge_configs
+
end
it "returns CLI value when key is only provided by the CLI" do
- expect(knife.config_value(:test_key_b)).to eq "b from cli"
+ expect(knife.config_value(:password)).to eq "password from CLI"
end
it "returns CLI value when key is provided by CLI and Chef::Config" do
- expect(knife.config_value(:test_key_a)).to eq "a from cli"
+ expect(knife.config_value(:connection_protocol)).to eq "connection_protocol from CLI"
end
- it "returns Chef::Config value whent he key is only provided by Chef::Config" do
- expect(knife.config_value(:test_key_c)).to eq "c from Chef::Config"
+ it "returns Chef::Config value when the key is only provided by Chef::Config" do
+ expect(knife.config_value(:ssh_user)).to eq "ssh user from Chef::Config"
end
it "returns the Chef::Config value from the alternative key when the CLI key is not set" do
- expect(knife.config_value(:test_key_c, :alt_test_key_c)).to eq "alt c from Chef::Config"
+ expect(knife.config_value(:bad_key, :winrm_user)).to eq "winrm user from Chef::Config"
end
it "returns the default value when the key is not provided by CLI or Chef::Config" do
diff --git a/spec/unit/knife/core/bootstrap_context_spec.rb b/spec/unit/knife/core/bootstrap_context_spec.rb
index 5aa176557f..bc09fdf2d9 100644
--- a/spec/unit/knife/core/bootstrap_context_spec.rb
+++ b/spec/unit/knife/core/bootstrap_context_spec.rb
@@ -26,9 +26,8 @@ describe Chef::Knife::Core::BootstrapContext do
Chef::Config[:fips] = false
end
- let(:config) { { foo: :bar, color: true } }
let(:run_list) { Chef::RunList.new("recipe[tmux]", "role[base]") }
- let(:chef_config) do
+ let(:config) do
{
config_log_level: "info",
config_log_location: "/tmp/log",
@@ -40,10 +39,10 @@ describe Chef::Knife::Core::BootstrapContext do
let(:secret) { nil }
- subject(:bootstrap_context) { described_class.new(config, run_list, chef_config, secret) }
+ subject(:bootstrap_context) { described_class.new(config, run_list, secret) }
it "initializes with Chef 11 parameters" do
- expect { described_class.new(config, run_list, chef_config) }.not_to raise_error
+ expect { described_class.new(config, run_list, config) }.not_to raise_error
end
it "runs chef with the first-boot.json with no environment specified" do
@@ -80,14 +79,14 @@ describe Chef::Knife::Core::BootstrapContext do
end
describe "alternate chef-client path" do
- let(:chef_config) { { chef_client_path: "/usr/local/bin/chef-client" } }
+ let(:config) { { chef_client_path: "/usr/local/bin/chef-client" } }
it "runs chef-client from another path when specified" do
expect(bootstrap_context.start_chef).to eq "/usr/local/bin/chef-client -j /etc/chef/first-boot.json"
end
end
describe "validation key path that contains a ~" do
- let(:chef_config) { { validation_key: "~/my.key" } }
+ let(:config) { { validation_key: "~/my.key" } }
it "reads the validation key when it contains a ~" do
expect(File).to receive(:exist?).with(File.expand_path("my.key", ENV["HOME"])).and_return(true)
expect(IO).to receive(:read).with(File.expand_path("my.key", ENV["HOME"]))
@@ -157,7 +156,7 @@ describe Chef::Knife::Core::BootstrapContext do
end
describe "when a bootstrap_version is specified" do
- let(:chef_config) do
+ let(:config) do
{
knife: { bootstrap_version: "11.12.4" },
}
@@ -169,7 +168,7 @@ describe Chef::Knife::Core::BootstrapContext do
end
describe "when a pre-release bootstrap_version is specified" do
- let(:chef_config) do
+ let(:config) do
{
knife: { bootstrap_version: "11.12.4.rc.0" },
}
@@ -193,7 +192,7 @@ describe Chef::Knife::Core::BootstrapContext do
end
describe "when configured in config" do
- let(:chef_config) do
+ let(:config) do
{
knife: { ssl_verify_mode: :verify_peer },
}
@@ -236,7 +235,7 @@ describe Chef::Knife::Core::BootstrapContext do
end
describe "when configured in config" do
- let(:chef_config) do
+ let(:config) do
{
knife: { verify_api_cert: :false },
}
@@ -272,49 +271,49 @@ describe Chef::Knife::Core::BootstrapContext do
describe "#config_log_location" do
context "when config_log_location is nil" do
- let(:chef_config) { { config_log_location: nil } }
+ let(:config) { { config_log_location: nil } }
it "sets the default config_log_location in the client.rb" do
expect(bootstrap_context.get_log_location).to eq "STDOUT"
end
end
context "when config_log_location is empty" do
- let(:chef_config) { { config_log_location: "" } }
+ let(:config) { { config_log_location: "" } }
it "sets the default config_log_location in the client.rb" do
expect(bootstrap_context.get_log_location).to eq "STDOUT"
end
end
context "when config_log_location is :win_evt" do
- let(:chef_config) { { config_log_location: :win_evt } }
+ let(:config) { { config_log_location: :win_evt } }
it "raise error when config_log_location is :win_evt " do
expect { bootstrap_context.get_log_location }.to raise_error("The value :win_evt is not supported for config_log_location on Linux Platforms \n")
end
end
context "when config_log_location is :syslog" do
- let(:chef_config) { { config_log_location: :syslog } }
+ let(:config) { { config_log_location: :syslog } }
it "sets the config_log_location value as :syslog in the client.rb" do
expect(bootstrap_context.get_log_location).to eq ":syslog"
end
end
context "When config_log_location is STDOUT" do
- let(:chef_config) { { config_log_location: STDOUT } }
+ let(:config) { { config_log_location: STDOUT } }
it "Sets the config_log_location value as STDOUT in the client.rb" do
expect(bootstrap_context.get_log_location).to eq "STDOUT"
end
end
context "when config_log_location is STDERR" do
- let(:chef_config) { { config_log_location: STDERR } }
+ let(:config) { { config_log_location: STDERR } }
it "sets the config_log_location value as STDERR in the client.rb" do
expect(bootstrap_context.get_log_location).to eq "STDERR"
end
end
context "when config_log_location is a path" do
- let(:chef_config) { { config_log_location: "/tmp/ChefLogFile" } }
+ let(:config) { { config_log_location: "/tmp/ChefLogFile" } }
it "sets the config_log_location path in the client.rb" do
expect(bootstrap_context.get_log_location).to eq "\"/tmp/ChefLogFile\""
end