knife-windows 1.9.6 → 3.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/chef/knife/bootstrap_windows_base.rb +1 -259
- data/lib/chef/knife/bootstrap_windows_ssh.rb +10 -29
- data/lib/chef/knife/bootstrap_windows_winrm.rb +10 -56
- data/lib/chef/knife/windows_helper.rb +0 -1
- data/lib/knife-windows/version.rb +1 -1
- data/spec/assets/{win_template_rendered_with_bootstrap_install_command_on_12_5_client.txt → win_template_rendered_with_bootstrap_install_command_on_13_client.txt} +0 -0
- data/spec/spec_helper.rb +1 -27
- metadata +20 -26
- data/CHANGELOG.md +0 -176
- data/Gemfile +0 -13
- data/README.md +0 -431
- data/Rakefile +0 -21
- data/ci.gemfile +0 -16
- data/knife-windows.gemspec +0 -26
- data/lib/chef/knife/bootstrap/windows-chef-client-msi.erb +0 -259
- data/lib/chef/knife/core/windows_bootstrap_context.rb +0 -417
- data/lib/knife-windows/path_helper.rb +0 -242
- data/spec/functional/bootstrap_download_spec.rb +0 -239
- data/spec/unit/knife/bootstrap_options_spec.rb +0 -172
- data/spec/unit/knife/bootstrap_template_spec.rb +0 -139
- data/spec/unit/knife/bootstrap_windows_winrm_spec.rb +0 -410
- data/spec/unit/knife/core/windows_bootstrap_context_spec.rb +0 -292
data/Rakefile
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
Bundler::GemHelper.install_tasks
|
3
|
-
|
4
|
-
begin
|
5
|
-
require 'rspec/core/rake_task'
|
6
|
-
|
7
|
-
task :default => [:unit_spec, :functional_spec]
|
8
|
-
|
9
|
-
desc "Run all functional specs in spec directory"
|
10
|
-
RSpec::Core::RakeTask.new(:functional_spec) do |t|
|
11
|
-
t.pattern = 'spec/functional/**/*_spec.rb'
|
12
|
-
end
|
13
|
-
|
14
|
-
desc "Run all unit specs in spec directory"
|
15
|
-
RSpec::Core::RakeTask.new(:unit_spec) do |t|
|
16
|
-
t.pattern = 'spec/unit/**/*_spec.rb'
|
17
|
-
end
|
18
|
-
|
19
|
-
rescue LoadError
|
20
|
-
STDERR.puts "\n*** RSpec not available. (sudo) gem install rspec to run unit tests. ***\n\n"
|
21
|
-
end
|
data/ci.gemfile
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
source "https://rubygems.org"
|
2
|
-
|
3
|
-
# Specify your gem's dependencies in knife-windows.gemspec
|
4
|
-
gemspec
|
5
|
-
|
6
|
-
if ENV['CHEF_VERSION'] == 'master'
|
7
|
-
gem 'chef', github: 'chef/chef'
|
8
|
-
gem 'ohai', github: 'chef/ohai'
|
9
|
-
else
|
10
|
-
gem 'chef', ENV['CHEF_VERSION']
|
11
|
-
end
|
12
|
-
|
13
|
-
gem "rspec", '~> 3.0'
|
14
|
-
gem "ruby-wmi"
|
15
|
-
gem "httpclient"
|
16
|
-
gem 'rake'
|
data/knife-windows.gemspec
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
$:.push File.expand_path("../lib", __FILE__)
|
3
|
-
require "knife-windows/version"
|
4
|
-
|
5
|
-
Gem::Specification.new do |s|
|
6
|
-
s.name = "knife-windows"
|
7
|
-
s.version = Knife::Windows::VERSION
|
8
|
-
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["Seth Chisamore"]
|
10
|
-
s.email = ["schisamo@chef.io"]
|
11
|
-
s.license = "Apache-2.0"
|
12
|
-
s.homepage = "https://github.com/chef/knife-windows"
|
13
|
-
s.summary = %q{Plugin that adds functionality to Chef's Knife CLI for configuring/interacting with nodes running Microsoft Windows}
|
14
|
-
s.description = s.summary
|
15
|
-
|
16
|
-
s.required_ruby_version = ">= 1.9.1"
|
17
|
-
s.add_dependency "winrm", "~> 2.1"
|
18
|
-
s.add_dependency "winrm-elevated", "~> 1.0"
|
19
|
-
|
20
|
-
s.add_development_dependency 'pry'
|
21
|
-
|
22
|
-
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(\..*|DOC_CHANGES.md|VERSION|appveyor.yml|RELEASE_NOTES.md)}) }
|
23
|
-
s.test_files = `git ls-files -- spec/*`.split("\n")
|
24
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
25
|
-
s.require_paths = ["lib"]
|
26
|
-
end
|
@@ -1,259 +0,0 @@
|
|
1
|
-
@rem
|
2
|
-
@rem Author:: Seth Chisamore (<schisamo@chef.io>)
|
3
|
-
@rem Copyright:: Copyright (c) 2011-2017 Chef Software, Inc.
|
4
|
-
@rem License:: Apache License, Version 2.0
|
5
|
-
@rem
|
6
|
-
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
-
@rem you may not use this file except in compliance with the License.
|
8
|
-
@rem You may obtain a copy of the License at
|
9
|
-
@rem
|
10
|
-
@rem http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
@rem
|
12
|
-
@rem Unless required by applicable law or agreed to in writing, software
|
13
|
-
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
@rem See the License for the specific language governing permissions and
|
16
|
-
@rem limitations under the License.
|
17
|
-
@rem
|
18
|
-
|
19
|
-
@rem Use delayed environment expansion so that ERRORLEVEL can be evaluated with the
|
20
|
-
@rem !ERRORLEVEL! syntax which evaluates at execution of the line of script, not when
|
21
|
-
@rem the line is read. See help for the /E switch from cmd.exe /? .
|
22
|
-
@setlocal ENABLEDELAYEDEXPANSION
|
23
|
-
|
24
|
-
<%= "SETX HTTP_PROXY \"#{knife_config[:bootstrap_proxy]}\"" if knife_config[:bootstrap_proxy] %>
|
25
|
-
|
26
|
-
@set BOOTSTRAP_DIRECTORY=<%= bootstrap_directory %>
|
27
|
-
@echo Checking for existing directory "%BOOTSTRAP_DIRECTORY%"...
|
28
|
-
@if NOT EXIST %BOOTSTRAP_DIRECTORY% (
|
29
|
-
@echo Existing directory not found, creating.
|
30
|
-
@mkdir %BOOTSTRAP_DIRECTORY%
|
31
|
-
) else (
|
32
|
-
@echo Existing directory found, skipping creation.
|
33
|
-
)
|
34
|
-
|
35
|
-
> <%= bootstrap_directory %>\wget.vbs (
|
36
|
-
<%= win_wget %>
|
37
|
-
)
|
38
|
-
|
39
|
-
> <%= bootstrap_directory %>\wget.ps1 (
|
40
|
-
<%= win_wget_ps %>
|
41
|
-
)
|
42
|
-
|
43
|
-
@rem Determine the version and the architecture
|
44
|
-
|
45
|
-
@FOR /F "usebackq tokens=1-8 delims=.[] " %%A IN (`ver`) DO (
|
46
|
-
@set WinMajor=%%D
|
47
|
-
@set WinMinor=%%E
|
48
|
-
@set WinBuild=%%F
|
49
|
-
)
|
50
|
-
|
51
|
-
@echo Detected Windows Version %WinMajor%.%WinMinor% Build %WinBuild%
|
52
|
-
|
53
|
-
@set LATEST_OS_VERSION_MAJOR=10
|
54
|
-
@set LATEST_OS_VERSION_MINOR=1
|
55
|
-
|
56
|
-
@if /i %WinMajor% GTR %LATEST_OS_VERSION_MAJOR% goto VersionUnknown
|
57
|
-
@if /i %WinMajor% EQU %LATEST_OS_VERSION_MAJOR% (
|
58
|
-
@if /i %WinMinor% GTR %LATEST_OS_VERSION_MINOR% goto VersionUnknown
|
59
|
-
)
|
60
|
-
|
61
|
-
goto Version%WinMajor%.%WinMinor%
|
62
|
-
|
63
|
-
:VersionUnknown
|
64
|
-
@rem If this is an unknown version of windows set the default
|
65
|
-
@set MACHINE_OS=2012r2
|
66
|
-
@echo Warning: Unknown version of Windows, assuming default of Windows %MACHINE_OS%
|
67
|
-
goto architecture_select
|
68
|
-
|
69
|
-
:Version6.0
|
70
|
-
@set MACHINE_OS=2008
|
71
|
-
goto architecture_select
|
72
|
-
|
73
|
-
:Version5.2
|
74
|
-
@set MACHINE_OS=2003r2
|
75
|
-
goto architecture_select
|
76
|
-
|
77
|
-
:Version6.1
|
78
|
-
@set MACHINE_OS=2008r2
|
79
|
-
goto architecture_select
|
80
|
-
|
81
|
-
:Version6.2
|
82
|
-
@set MACHINE_OS=2012
|
83
|
-
goto architecture_select
|
84
|
-
|
85
|
-
@rem Currently Windows Server 2012 R2 is treated as equivalent to Windows Server 2012
|
86
|
-
:Version6.3
|
87
|
-
@set MACHINE_OS=2012r2
|
88
|
-
goto architecture_select
|
89
|
-
|
90
|
-
:Version10.0
|
91
|
-
@set MACHINE_OS=2016
|
92
|
-
goto architecture_select
|
93
|
-
|
94
|
-
@rem Currently Windows Server 2016 R2 is treated as equivalent to Windows Server 2016
|
95
|
-
:Version10.1
|
96
|
-
goto Version10.0
|
97
|
-
|
98
|
-
:architecture_select
|
99
|
-
<% if knife_config[:architecture] %>
|
100
|
-
@set MACHINE_ARCH=<%= knife_config[:architecture] %>
|
101
|
-
|
102
|
-
<% if knife_config[:architecture] == "x86_64" %>
|
103
|
-
IF "%PROCESSOR_ARCHITECTURE%"=="x86" IF not defined PROCESSOR_ARCHITEW6432 (
|
104
|
-
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"
|
105
|
-
echo Exiting without bootstrapping. > "&2"
|
106
|
-
exit /b 1
|
107
|
-
)
|
108
|
-
<% end %>
|
109
|
-
<% else %>
|
110
|
-
@set MACHINE_ARCH=x86_64
|
111
|
-
IF "%PROCESSOR_ARCHITECTURE%"=="x86" IF not defined PROCESSOR_ARCHITEW6432 @set MACHINE_ARCH=i686
|
112
|
-
<% end %>
|
113
|
-
goto install
|
114
|
-
|
115
|
-
:install
|
116
|
-
@rem If user has provided the custom installation command for chef-client then execute it
|
117
|
-
<% if @chef_config[:knife][:bootstrap_install_command] %>
|
118
|
-
<%= @chef_config[:knife][:bootstrap_install_command] %>
|
119
|
-
<% else %>
|
120
|
-
@rem Install Chef using chef-client MSI installer
|
121
|
-
|
122
|
-
@set "LOCAL_DESTINATION_MSI_PATH=<%= local_download_path %>"
|
123
|
-
@set "CHEF_CLIENT_MSI_LOG_PATH=%TEMP%\chef-client-msi%RANDOM%.log"
|
124
|
-
|
125
|
-
@rem Clear any pre-existing downloads
|
126
|
-
@echo Checking for existing downloaded package at "%LOCAL_DESTINATION_MSI_PATH%"
|
127
|
-
@if EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
|
128
|
-
@echo Found existing downloaded package, deleting.
|
129
|
-
@del /f /q "%LOCAL_DESTINATION_MSI_PATH%"
|
130
|
-
@if ERRORLEVEL 1 (
|
131
|
-
echo Warning: Failed to delete pre-existing package with status code !ERRORLEVEL! > "&2"
|
132
|
-
)
|
133
|
-
) else (
|
134
|
-
echo No existing downloaded packages to delete.
|
135
|
-
)
|
136
|
-
|
137
|
-
@rem If there is somehow a name collision, remove pre-existing log
|
138
|
-
@if EXIST "%CHEF_CLIENT_MSI_LOG_PATH%" del /f /q "%CHEF_CLIENT_MSI_LOG_PATH%"
|
139
|
-
|
140
|
-
@echo Attempting to download client package using PowerShell if available...
|
141
|
-
@set "REMOTE_SOURCE_MSI_URL=<%= msi_url('%MACHINE_OS%', '%MACHINE_ARCH%', 'PowerShell') %>"
|
142
|
-
@set powershell_download=powershell.exe -ExecutionPolicy Unrestricted -InputFormat None -NoProfile -NonInteractive -File <%= bootstrap_directory %>\wget.ps1 "%REMOTE_SOURCE_MSI_URL%" "%LOCAL_DESTINATION_MSI_PATH%"
|
143
|
-
@echo !powershell_download!
|
144
|
-
@call !powershell_download!
|
145
|
-
|
146
|
-
@set DOWNLOAD_ERROR_STATUS=!ERRORLEVEL!
|
147
|
-
|
148
|
-
@if ERRORLEVEL 1 (
|
149
|
-
@echo Failed PowerShell download with status code !DOWNLOAD_ERROR_STATUS! > "&2"
|
150
|
-
@if !DOWNLOAD_ERROR_STATUS!==0 set DOWNLOAD_ERROR_STATUS=2
|
151
|
-
) else (
|
152
|
-
@rem Sometimes the error level is not set even when the download failed,
|
153
|
-
@rem so check for the file to be sure it is there -- if it is not, we will retry
|
154
|
-
@if NOT EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
|
155
|
-
echo Failed download: download completed, but downloaded file not found > "&2"
|
156
|
-
set DOWNLOAD_ERROR_STATUS=2
|
157
|
-
) else (
|
158
|
-
echo Download via PowerShell succeeded.
|
159
|
-
)
|
160
|
-
)
|
161
|
-
|
162
|
-
@if NOT %DOWNLOAD_ERROR_STATUS%==0 (
|
163
|
-
@echo Warning: Failed to download "%REMOTE_SOURCE_MSI_URL%" to "%LOCAL_DESTINATION_MSI_PATH%"
|
164
|
-
@echo Warning: Retrying download with cscript ...
|
165
|
-
|
166
|
-
@if EXIST "%LOCAL_DESTINATION_MSI_PATH%" del /f /q "%LOCAL_DESTINATION_MSI_PATH%"
|
167
|
-
|
168
|
-
@set "REMOTE_SOURCE_MSI_URL=<%= msi_url('%MACHINE_OS%', '%MACHINE_ARCH%') %>"
|
169
|
-
cscript /nologo <%= bootstrap_directory %>\wget.vbs /url:"%REMOTE_SOURCE_MSI_URL%" /path:"%LOCAL_DESTINATION_MSI_PATH%"
|
170
|
-
|
171
|
-
@if NOT ERRORLEVEL 1 (
|
172
|
-
@rem Sometimes the error level is not set even when the download failed,
|
173
|
-
@rem so check for the file to be sure it is there.
|
174
|
-
@if NOT EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
|
175
|
-
echo Failed download: download completed, but downloaded file not found > "&2"
|
176
|
-
echo Exiting without bootstrapping due to download failure. > "&2"
|
177
|
-
exit /b 1
|
178
|
-
) else (
|
179
|
-
echo Download via cscript succeeded.
|
180
|
-
)
|
181
|
-
) else (
|
182
|
-
echo Failed to download "%REMOTE_SOURCE_MSI_URL%" with status code !ERRORLEVEL!. > "&2"
|
183
|
-
echo Exiting without bootstrapping due to download failure. > "&2"
|
184
|
-
exit /b 1
|
185
|
-
)
|
186
|
-
)
|
187
|
-
|
188
|
-
@echo Installing downloaded client package...
|
189
|
-
|
190
|
-
<%= install_chef %>
|
191
|
-
|
192
|
-
@if ERRORLEVEL 1 (
|
193
|
-
echo Chef-client package failed to install with status code !ERRORLEVEL!. > "&2"
|
194
|
-
echo See installation log for additional detail: %CHEF_CLIENT_MSI_LOG_PATH%. > "&2"
|
195
|
-
) else (
|
196
|
-
@echo Installation completed successfully
|
197
|
-
del /f /q "%CHEF_CLIENT_MSI_LOG_PATH%"
|
198
|
-
)
|
199
|
-
|
200
|
-
<% end %>
|
201
|
-
|
202
|
-
@endlocal
|
203
|
-
|
204
|
-
@echo off
|
205
|
-
|
206
|
-
<% if client_pem -%>
|
207
|
-
> <%= bootstrap_directory %>\client.pem (
|
208
|
-
<%= escape_and_echo(::File.read(::File.expand_path(client_pem))) %>
|
209
|
-
)
|
210
|
-
<% end -%>
|
211
|
-
|
212
|
-
echo Writing validation key...
|
213
|
-
|
214
|
-
<% if validation_key -%>
|
215
|
-
> <%= bootstrap_directory %>\validation.pem (
|
216
|
-
<%= escape_and_echo(validation_key) %>
|
217
|
-
)
|
218
|
-
<% end -%>
|
219
|
-
|
220
|
-
echo Validation key written.
|
221
|
-
@echo on
|
222
|
-
|
223
|
-
<% if @config[:secret] -%>
|
224
|
-
> <%= bootstrap_directory %>\encrypted_data_bag_secret (
|
225
|
-
<%= secret %>
|
226
|
-
)
|
227
|
-
<% end -%>
|
228
|
-
|
229
|
-
<% unless trusted_certs_script.empty? -%>
|
230
|
-
mkdir <%= bootstrap_directory %>\trusted_certs
|
231
|
-
<%= trusted_certs_script %>
|
232
|
-
<% end -%>
|
233
|
-
|
234
|
-
<%# Generate Ohai Hints -%>
|
235
|
-
<% unless @chef_config[:knife][:hints].nil? || @chef_config[:knife][:hints].empty? -%>
|
236
|
-
mkdir <%= bootstrap_directory %>\ohai\hints
|
237
|
-
|
238
|
-
<% @chef_config[:knife][:hints].each do |name, hash| -%>
|
239
|
-
> <%= bootstrap_directory %>\ohai\hints\<%= name %>.json (
|
240
|
-
<%= escape_and_echo(hash.to_json) %>
|
241
|
-
)
|
242
|
-
<% end -%>
|
243
|
-
<% end -%>
|
244
|
-
|
245
|
-
> <%= bootstrap_directory %>\client.rb (
|
246
|
-
<%= config_content %>
|
247
|
-
)
|
248
|
-
|
249
|
-
> <%= bootstrap_directory %>\first-boot.json (
|
250
|
-
<%= first_boot %>
|
251
|
-
)
|
252
|
-
|
253
|
-
<% unless client_d.empty? -%>
|
254
|
-
mkdir <%= bootstrap_directory %>\client.d
|
255
|
-
<%= client_d %>
|
256
|
-
<% end -%>
|
257
|
-
|
258
|
-
@echo Starting chef to bootstrap the node...
|
259
|
-
<%= start_chef %>
|
@@ -1,417 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
3
|
-
# Copyright:: Copyright (c) 2011-2016 Chef Software, Inc.
|
4
|
-
# License:: Apache License, Version 2.0
|
5
|
-
#
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
-
# you may not use this file except in compliance with the License.
|
8
|
-
# You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
# See the License for the specific language governing permissions and
|
16
|
-
# limitations under the License.
|
17
|
-
#
|
18
|
-
|
19
|
-
require 'chef/knife/core/bootstrap_context'
|
20
|
-
# Chef::Util::PathHelper in Chef 11 is a bit juvenile still
|
21
|
-
require 'knife-windows/path_helper'
|
22
|
-
# require 'chef/util/path_helper'
|
23
|
-
|
24
|
-
class Chef
|
25
|
-
class Knife
|
26
|
-
module Core
|
27
|
-
# Instances of BootstrapContext are the context objects (i.e., +self+) for
|
28
|
-
# bootstrap templates. For backwards compatability, they +must+ set the
|
29
|
-
# following instance variables:
|
30
|
-
# * @config - a hash of knife's config values
|
31
|
-
# * @run_list - the run list for the node to boostrap
|
32
|
-
#
|
33
|
-
class WindowsBootstrapContext < BootstrapContext
|
34
|
-
PathHelper = ::Knife::Windows::PathHelper
|
35
|
-
|
36
|
-
attr_accessor :client_pem
|
37
|
-
|
38
|
-
def initialize(config, run_list, chef_config, secret=nil)
|
39
|
-
@config = config
|
40
|
-
@run_list = run_list
|
41
|
-
@chef_config = chef_config
|
42
|
-
@secret = secret
|
43
|
-
# Compatibility with Chef 12 and Chef 11 versions
|
44
|
-
begin
|
45
|
-
# Pass along the secret parameter for Chef 12
|
46
|
-
super(config, run_list, chef_config, secret)
|
47
|
-
rescue ArgumentError
|
48
|
-
# The Chef 11 base class only has parameters for initialize
|
49
|
-
super(config, run_list, chef_config)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def validation_key
|
54
|
-
if File.exist?(File.expand_path(@chef_config[:validation_key]))
|
55
|
-
IO.read(File.expand_path(@chef_config[:validation_key]))
|
56
|
-
else
|
57
|
-
false
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def secret
|
62
|
-
escape_and_echo(@config[:secret])
|
63
|
-
end
|
64
|
-
|
65
|
-
def trusted_certs_script
|
66
|
-
@trusted_certs_script ||= trusted_certs_content
|
67
|
-
end
|
68
|
-
|
69
|
-
def config_content
|
70
|
-
client_rb = <<-CONFIG
|
71
|
-
chef_server_url "#{@chef_config[:chef_server_url]}"
|
72
|
-
validation_client_name "#{@chef_config[:validation_client_name]}"
|
73
|
-
file_cache_path "c:/chef/cache"
|
74
|
-
file_backup_path "c:/chef/backup"
|
75
|
-
cache_options ({:path => "c:/chef/cache/checksums", :skip_expires => true})
|
76
|
-
CONFIG
|
77
|
-
if @config[:chef_node_name]
|
78
|
-
client_rb << %Q{node_name "#{@config[:chef_node_name]}"\n}
|
79
|
-
else
|
80
|
-
client_rb << "# Using default node name (fqdn)\n"
|
81
|
-
end
|
82
|
-
|
83
|
-
if @chef_config[:config_log_level]
|
84
|
-
client_rb << %Q{log_level :#{@chef_config[:config_log_level]}\n}
|
85
|
-
else
|
86
|
-
client_rb << "log_level :info\n"
|
87
|
-
end
|
88
|
-
|
89
|
-
client_rb << "log_location #{get_log_location}"
|
90
|
-
|
91
|
-
# We configure :verify_api_cert only when it's overridden on the CLI
|
92
|
-
# or when specified in the knife config.
|
93
|
-
if !@config[:node_verify_api_cert].nil? || knife_config.has_key?(:verify_api_cert)
|
94
|
-
value = @config[:node_verify_api_cert].nil? ? knife_config[:verify_api_cert] : @config[:node_verify_api_cert]
|
95
|
-
client_rb << %Q{verify_api_cert #{value}\n}
|
96
|
-
end
|
97
|
-
|
98
|
-
# We configure :ssl_verify_mode only when it's overridden on the CLI
|
99
|
-
# or when specified in the knife config.
|
100
|
-
if @config[:node_ssl_verify_mode] || knife_config.has_key?(:ssl_verify_mode)
|
101
|
-
value = case @config[:node_ssl_verify_mode]
|
102
|
-
when "peer"
|
103
|
-
:verify_peer
|
104
|
-
when "none"
|
105
|
-
:verify_none
|
106
|
-
when nil
|
107
|
-
knife_config[:ssl_verify_mode]
|
108
|
-
else
|
109
|
-
nil
|
110
|
-
end
|
111
|
-
|
112
|
-
if value
|
113
|
-
client_rb << %Q{ssl_verify_mode :#{value}\n}
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
if @config[:ssl_verify_mode]
|
118
|
-
client_rb << %Q{ssl_verify_mode :#{knife_config[:ssl_verify_mode]}\n}
|
119
|
-
end
|
120
|
-
|
121
|
-
if knife_config[:bootstrap_proxy]
|
122
|
-
client_rb << "\n"
|
123
|
-
client_rb << %Q{http_proxy "#{knife_config[:bootstrap_proxy]}"\n}
|
124
|
-
client_rb << %Q{https_proxy "#{knife_config[:bootstrap_proxy]}"\n}
|
125
|
-
client_rb << %Q{no_proxy "#{knife_config[:bootstrap_no_proxy]}"\n} if knife_config[:bootstrap_no_proxy]
|
126
|
-
end
|
127
|
-
|
128
|
-
if knife_config[:bootstrap_no_proxy]
|
129
|
-
client_rb << %Q{no_proxy "#{knife_config[:bootstrap_no_proxy]}"\n}
|
130
|
-
end
|
131
|
-
|
132
|
-
if @config[:secret]
|
133
|
-
client_rb << %Q{encrypted_data_bag_secret "c:/chef/encrypted_data_bag_secret"\n}
|
134
|
-
end
|
135
|
-
|
136
|
-
unless trusted_certs_script.empty?
|
137
|
-
client_rb << %Q{trusted_certs_dir "c:/chef/trusted_certs"\n}
|
138
|
-
end
|
139
|
-
|
140
|
-
if Chef::Config[:fips]
|
141
|
-
client_rb << <<-CONFIG
|
142
|
-
fips true
|
143
|
-
chef_version = ::Chef::VERSION.split(".")
|
144
|
-
unless chef_version[0].to_i > 12 || (chef_version[0].to_i == 12 && chef_version[1].to_i >= 8)
|
145
|
-
raise "FIPS Mode requested but not supported by this client"
|
146
|
-
end
|
147
|
-
CONFIG
|
148
|
-
end
|
149
|
-
|
150
|
-
escape_and_echo(client_rb)
|
151
|
-
end
|
152
|
-
|
153
|
-
def get_log_location
|
154
|
-
if @chef_config[:config_log_location].equal?(:win_evt)
|
155
|
-
%Q{:#{@chef_config[:config_log_location]}\n}
|
156
|
-
elsif @chef_config[:config_log_location].equal?(:syslog)
|
157
|
-
raise "syslog is not supported for log_location on Windows OS\n"
|
158
|
-
elsif (@chef_config[:config_log_location].equal?(STDOUT))
|
159
|
-
"STDOUT\n"
|
160
|
-
elsif (@chef_config[:config_log_location].equal?(STDERR))
|
161
|
-
"STDERR\n"
|
162
|
-
elsif @chef_config[:config_log_location].nil? || @chef_config[:config_log_location].empty?
|
163
|
-
"STDOUT\n"
|
164
|
-
elsif @chef_config[:config_log_location]
|
165
|
-
%Q{"#{@chef_config[:config_log_location]}"\n}
|
166
|
-
else
|
167
|
-
"STDOUT\n"
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
def start_chef
|
172
|
-
bootstrap_environment_option = bootstrap_environment.nil? ? '' : " -E #{bootstrap_environment}"
|
173
|
-
start_chef = "SET \"PATH=%SystemRoot%\\system32;%SystemRoot%;%SystemRoot%\\System32\\Wbem;%SYSTEMROOT%\\System32\\WindowsPowerShell\\v1.0\\;C:\\ruby\\bin;C:\\opscode\\chef\\bin;C:\\opscode\\chef\\embedded\\bin\"\n"
|
174
|
-
start_chef << "chef-client -c c:/chef/client.rb -j c:/chef/first-boot.json#{bootstrap_environment_option}\n"
|
175
|
-
end
|
176
|
-
|
177
|
-
def latest_current_windows_chef_version_query
|
178
|
-
installer_version_string = nil
|
179
|
-
if @config[:prerelease]
|
180
|
-
installer_version_string = "&prerelease=true"
|
181
|
-
else
|
182
|
-
chef_version_string = if knife_config[:bootstrap_version]
|
183
|
-
knife_config[:bootstrap_version]
|
184
|
-
else
|
185
|
-
Chef::VERSION.split(".").first
|
186
|
-
end
|
187
|
-
|
188
|
-
installer_version_string = "&v=#{chef_version_string}"
|
189
|
-
|
190
|
-
# If bootstrapping a pre-release version add the prerelease query string
|
191
|
-
if chef_version_string.split(".").length > 3
|
192
|
-
installer_version_string << "&prerelease=true"
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
installer_version_string
|
197
|
-
end
|
198
|
-
|
199
|
-
def win_wget
|
200
|
-
# I tried my best to figure out how to properly url decode and switch / to \
|
201
|
-
# but this is VBScript - so I don't really care that badly.
|
202
|
-
win_wget = <<-WGET
|
203
|
-
url = WScript.Arguments.Named("url")
|
204
|
-
path = WScript.Arguments.Named("path")
|
205
|
-
proxy = null
|
206
|
-
'* Vaguely attempt to handle file:// scheme urls by url unescaping and switching all
|
207
|
-
'* / into \. Also assume that file:/// is a local absolute path and that file://<foo>
|
208
|
-
'* is possibly a network file path.
|
209
|
-
If InStr(url, "file://") = 1 Then
|
210
|
-
url = Unescape(url)
|
211
|
-
If InStr(url, "file:///") = 1 Then
|
212
|
-
sourcePath = Mid(url, Len("file:///") + 1)
|
213
|
-
Else
|
214
|
-
sourcePath = Mid(url, Len("file:") + 1)
|
215
|
-
End If
|
216
|
-
sourcePath = Replace(sourcePath, "/", "\\")
|
217
|
-
|
218
|
-
Set objFSO = CreateObject("Scripting.FileSystemObject")
|
219
|
-
If objFSO.Fileexists(path) Then objFSO.DeleteFile path
|
220
|
-
objFSO.CopyFile sourcePath, path, true
|
221
|
-
Set objFSO = Nothing
|
222
|
-
|
223
|
-
Else
|
224
|
-
Set objXMLHTTP = CreateObject("MSXML2.ServerXMLHTTP")
|
225
|
-
Set wshShell = CreateObject( "WScript.Shell" )
|
226
|
-
Set objUserVariables = wshShell.Environment("USER")
|
227
|
-
|
228
|
-
rem http proxy is optional
|
229
|
-
rem attempt to read from HTTP_PROXY env var first
|
230
|
-
On Error Resume Next
|
231
|
-
|
232
|
-
If NOT (objUserVariables("HTTP_PROXY") = "") Then
|
233
|
-
proxy = objUserVariables("HTTP_PROXY")
|
234
|
-
|
235
|
-
rem fall back to named arg
|
236
|
-
ElseIf NOT (WScript.Arguments.Named("proxy") = "") Then
|
237
|
-
proxy = WScript.Arguments.Named("proxy")
|
238
|
-
End If
|
239
|
-
|
240
|
-
If NOT isNull(proxy) Then
|
241
|
-
rem setProxy method is only available on ServerXMLHTTP 6.0+
|
242
|
-
Set objXMLHTTP = CreateObject("MSXML2.ServerXMLHTTP.6.0")
|
243
|
-
objXMLHTTP.setProxy 2, proxy
|
244
|
-
End If
|
245
|
-
|
246
|
-
On Error Goto 0
|
247
|
-
|
248
|
-
objXMLHTTP.open "GET", url, false
|
249
|
-
objXMLHTTP.send()
|
250
|
-
If objXMLHTTP.Status = 200 Then
|
251
|
-
Set objADOStream = CreateObject("ADODB.Stream")
|
252
|
-
objADOStream.Open
|
253
|
-
objADOStream.Type = 1
|
254
|
-
objADOStream.Write objXMLHTTP.ResponseBody
|
255
|
-
objADOStream.Position = 0
|
256
|
-
Set objFSO = Createobject("Scripting.FileSystemObject")
|
257
|
-
If objFSO.Fileexists(path) Then objFSO.DeleteFile path
|
258
|
-
Set objFSO = Nothing
|
259
|
-
objADOStream.SaveToFile path
|
260
|
-
objADOStream.Close
|
261
|
-
Set objADOStream = Nothing
|
262
|
-
End If
|
263
|
-
Set objXMLHTTP = Nothing
|
264
|
-
End If
|
265
|
-
WGET
|
266
|
-
escape_and_echo(win_wget)
|
267
|
-
end
|
268
|
-
|
269
|
-
def win_wget_ps
|
270
|
-
win_wget_ps = <<-WGET_PS
|
271
|
-
param(
|
272
|
-
[String] $remoteUrl,
|
273
|
-
[String] $localPath
|
274
|
-
)
|
275
|
-
|
276
|
-
$ProxyUrl = $env:http_proxy;
|
277
|
-
$webClient = new-object System.Net.WebClient;
|
278
|
-
|
279
|
-
if ($ProxyUrl -ne '') {
|
280
|
-
$WebProxy = New-Object System.Net.WebProxy($ProxyUrl,$true)
|
281
|
-
$WebClient.Proxy = $WebProxy
|
282
|
-
}
|
283
|
-
|
284
|
-
$webClient.DownloadFile($remoteUrl, $localPath);
|
285
|
-
WGET_PS
|
286
|
-
|
287
|
-
escape_and_echo(win_wget_ps)
|
288
|
-
end
|
289
|
-
|
290
|
-
def install_chef
|
291
|
-
# The normal install command uses regular double quotes in
|
292
|
-
# the install command, so request such a string from install_command
|
293
|
-
install_chef = install_command('"') + "\n" + fallback_install_task_command
|
294
|
-
end
|
295
|
-
|
296
|
-
def bootstrap_directory
|
297
|
-
bootstrap_directory = "C:\\chef"
|
298
|
-
end
|
299
|
-
|
300
|
-
def local_download_path
|
301
|
-
local_download_path = "%TEMP%\\chef-client-latest.msi"
|
302
|
-
end
|
303
|
-
|
304
|
-
def msi_url(machine_os=nil, machine_arch=nil, download_context=nil)
|
305
|
-
# The default msi path has a number of url query parameters - we attempt to substitute
|
306
|
-
# such parameters in as long as they are provided by the template.
|
307
|
-
|
308
|
-
if @config[:msi_url].nil? || @config[:msi_url].empty?
|
309
|
-
url = "https://www.chef.io/chef/download?p=windows"
|
310
|
-
url += "&pv=#{machine_os}" unless machine_os.nil?
|
311
|
-
url += "&m=#{machine_arch}" unless machine_arch.nil?
|
312
|
-
url += "&DownloadContext=#{download_context}" unless download_context.nil?
|
313
|
-
url += latest_current_windows_chef_version_query
|
314
|
-
else
|
315
|
-
@config[:msi_url]
|
316
|
-
end
|
317
|
-
end
|
318
|
-
|
319
|
-
def first_boot
|
320
|
-
escape_and_echo(super.to_json)
|
321
|
-
end
|
322
|
-
|
323
|
-
# escape WIN BATCH special chars
|
324
|
-
# and prefixes each line with an
|
325
|
-
# echo
|
326
|
-
def escape_and_echo(file_contents)
|
327
|
-
file_contents.gsub(/^(.*)$/, 'echo.\1').gsub(/([(<|>)^])/, '^\1')
|
328
|
-
end
|
329
|
-
|
330
|
-
private
|
331
|
-
|
332
|
-
def install_command(executor_quote)
|
333
|
-
if @config[:install_as_service]
|
334
|
-
"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}"
|
335
|
-
else
|
336
|
-
"msiexec /qn /log #{executor_quote}%CHEF_CLIENT_MSI_LOG_PATH%#{executor_quote} /i #{executor_quote}%LOCAL_DESTINATION_MSI_PATH%#{executor_quote}"
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
# Returns a string for copying the trusted certificates on the workstation to the system being bootstrapped
|
341
|
-
# This string should contain both the commands necessary to both create the files, as well as their content
|
342
|
-
def trusted_certs_content
|
343
|
-
content = ""
|
344
|
-
if @chef_config[:trusted_certs_dir]
|
345
|
-
Dir.glob(File.join(PathHelper.escape_glob_dir(@chef_config[:trusted_certs_dir]), "*.{crt,pem}")).each do |cert|
|
346
|
-
content << "> #{bootstrap_directory}/trusted_certs/#{File.basename(cert)} (\n" +
|
347
|
-
escape_and_echo(IO.read(File.expand_path(cert))) + "\n)\n"
|
348
|
-
end
|
349
|
-
end
|
350
|
-
content
|
351
|
-
end
|
352
|
-
|
353
|
-
def client_d_content
|
354
|
-
content = ""
|
355
|
-
if @chef_config[:client_d_dir] && File.exist?(@chef_config[:client_d_dir])
|
356
|
-
root = Pathname(@chef_config[:client_d_dir])
|
357
|
-
root.find do |f|
|
358
|
-
relative = f.relative_path_from(root)
|
359
|
-
if f != root
|
360
|
-
file_on_node = "#{bootstrap_directory}/client.d/#{relative}".gsub("/","\\")
|
361
|
-
if f.directory?
|
362
|
-
content << "mkdir #{file_on_node}\n"
|
363
|
-
else
|
364
|
-
content << "> #{file_on_node} (\n" +
|
365
|
-
escape_and_echo(IO.read(File.expand_path(f))) + "\n)\n"
|
366
|
-
end
|
367
|
-
end
|
368
|
-
end
|
369
|
-
end
|
370
|
-
content
|
371
|
-
end
|
372
|
-
|
373
|
-
def fallback_install_task_command
|
374
|
-
# This command will be executed by schtasks.exe in the batch
|
375
|
-
# code below. To handle tasks that contain arguments that
|
376
|
-
# need to be double quoted, schtasks allows the use of single
|
377
|
-
# quotes that will later be converted to double quotes
|
378
|
-
command = install_command('\'')
|
379
|
-
<<-EOH
|
380
|
-
@set MSIERRORCODE=!ERRORLEVEL!
|
381
|
-
@if ERRORLEVEL 1 (
|
382
|
-
@echo WARNING: Failed to install Chef Client MSI package in remote context with status code !MSIERRORCODE!.
|
383
|
-
@echo WARNING: This may be due to a defect in operating system update KB2918614: http://support.microsoft.com/kb/2918614
|
384
|
-
@set OLDLOGLOCATION="%CHEF_CLIENT_MSI_LOG_PATH%-fail.log"
|
385
|
-
@move "%CHEF_CLIENT_MSI_LOG_PATH%" "!OLDLOGLOCATION!" > NUL
|
386
|
-
@echo WARNING: Saving installation log of failure at !OLDLOGLOCATION!
|
387
|
-
@echo WARNING: Retrying installation with local context...
|
388
|
-
@schtasks /create /f /sc once /st 00:00:00 /tn chefclientbootstraptask /ru SYSTEM /rl HIGHEST /tr \"cmd /c #{command} & sleep 2 & waitfor /s %computername% /si chefclientinstalldone\"
|
389
|
-
|
390
|
-
@if ERRORLEVEL 1 (
|
391
|
-
@echo ERROR: Failed to create Chef Client installation scheduled task with status code !ERRORLEVEL! > "&2"
|
392
|
-
) else (
|
393
|
-
@echo Successfully created scheduled task to install Chef Client.
|
394
|
-
@schtasks /run /tn chefclientbootstraptask
|
395
|
-
@if ERRORLEVEL 1 (
|
396
|
-
@echo ERROR: Failed to execut Chef Client installation scheduled task with status code !ERRORLEVEL!. > "&2"
|
397
|
-
) else (
|
398
|
-
@echo Successfully started Chef Client installation scheduled task.
|
399
|
-
@echo Waiting for installation to complete -- this may take a few minutes...
|
400
|
-
waitfor chefclientinstalldone /t 600
|
401
|
-
if ERRORLEVEL 1 (
|
402
|
-
@echo ERROR: Timed out waiting for Chef Client package to install
|
403
|
-
) else (
|
404
|
-
@echo Finished waiting for Chef Client package to install.
|
405
|
-
)
|
406
|
-
@schtasks /delete /f /tn chefclientbootstraptask > NUL
|
407
|
-
)
|
408
|
-
)
|
409
|
-
) else (
|
410
|
-
@echo Successfully installed Chef Client package.
|
411
|
-
)
|
412
|
-
EOH
|
413
|
-
end
|
414
|
-
end
|
415
|
-
end
|
416
|
-
end
|
417
|
-
end
|