knife-windows 1.9.6 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|