ridley 0.9.1 → 0.10.0.rc1

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.
Files changed (51) hide show
  1. data/.gitignore +1 -0
  2. data/.ruby-version +1 -0
  3. data/Guardfile +1 -1
  4. data/README.md +1 -1
  5. data/bootstrappers/{omnibus.erb → unix_omnibus.erb} +20 -5
  6. data/bootstrappers/windows_omnibus.erb +133 -0
  7. data/lib/ridley.rb +4 -1
  8. data/lib/ridley/bootstrap_bindings.rb +5 -0
  9. data/lib/ridley/bootstrap_bindings/unix_template_binding.rb +112 -0
  10. data/lib/ridley/bootstrap_bindings/windows_template_binding.rb +221 -0
  11. data/lib/ridley/bootstrapper.rb +14 -22
  12. data/lib/ridley/bootstrapper/context.rb +53 -162
  13. data/lib/ridley/chef.rb +0 -1
  14. data/lib/ridley/chef/cookbook.rb +0 -9
  15. data/lib/ridley/client.rb +12 -1
  16. data/lib/ridley/errors.rb +1 -0
  17. data/lib/ridley/host_connector.rb +76 -0
  18. data/lib/ridley/{ssh → host_connector}/response.rb +1 -1
  19. data/lib/ridley/{ssh → host_connector}/response_set.rb +11 -11
  20. data/lib/ridley/host_connector/ssh.rb +58 -0
  21. data/lib/ridley/host_connector/ssh/worker.rb +99 -0
  22. data/lib/ridley/host_connector/winrm.rb +55 -0
  23. data/lib/ridley/host_connector/winrm/worker.rb +126 -0
  24. data/lib/ridley/mixin/bootstrap_binding.rb +88 -0
  25. data/lib/ridley/resource.rb +1 -1
  26. data/lib/ridley/resources/client_resource.rb +7 -0
  27. data/lib/ridley/resources/node_resource.rb +9 -4
  28. data/lib/ridley/sandbox_uploader.rb +1 -7
  29. data/lib/ridley/version.rb +1 -1
  30. data/ridley.gemspec +1 -0
  31. data/spec/unit/ridley/bootstrap_bindings/unix_template_binding_spec.rb +102 -0
  32. data/spec/unit/ridley/bootstrap_bindings/windows_template_binding_spec.rb +118 -0
  33. data/spec/unit/ridley/bootstrapper/context_spec.rb +19 -106
  34. data/spec/unit/ridley/bootstrapper_spec.rb +2 -12
  35. data/spec/unit/ridley/client_spec.rb +20 -2
  36. data/spec/unit/ridley/{ssh → host_connector}/response_set_spec.rb +17 -17
  37. data/spec/unit/ridley/host_connector/ssh/worker_spec.rb +15 -0
  38. data/spec/unit/ridley/{ssh_spec.rb → host_connector/ssh_spec.rb} +5 -5
  39. data/spec/unit/ridley/host_connector/winrm/worker_spec.rb +41 -0
  40. data/spec/unit/ridley/host_connector/winrm_spec.rb +47 -0
  41. data/spec/unit/ridley/host_connector_spec.rb +102 -0
  42. data/spec/unit/ridley/mixin/bootstrap_binding_spec.rb +56 -0
  43. data/spec/unit/ridley/sandbox_uploader_spec.rb +1 -28
  44. metadata +53 -25
  45. data/.rbenv-version +0 -1
  46. data/lib/ridley/chef/chefignore.rb +0 -76
  47. data/lib/ridley/ssh.rb +0 -56
  48. data/lib/ridley/ssh/worker.rb +0 -87
  49. data/spec/fixtures/chefignore +0 -8
  50. data/spec/unit/ridley/chef/chefignore_spec.rb +0 -40
  51. data/spec/unit/ridley/ssh/worker_spec.rb +0 -13
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  *.sw[op]
19
+ .DS_Store
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p392
data/Guardfile CHANGED
@@ -12,7 +12,7 @@ guard 'yard', stdout: '/dev/null', stderr: '/dev/null' do
12
12
  watch(%r{ext/.+\.c})
13
13
  end
14
14
 
15
- guard 'rspec', cli: "--color --drb --format Fuubar", all_on_start: false, all_after_pass: false do
15
+ guard 'rspec', cli: "--color --drb --format Fuubar --tag ~type:acceptance", all_on_start: false, all_after_pass: false do
16
16
  watch(%r{^spec/unit/.+_spec\.rb$})
17
17
  watch(%r{^spec/acceptance/.+_spec\.rb$})
18
18
 
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  [![Gem Version](https://badge.fury.io/rb/ridley.png)](http://badge.fury.io/rb/ridley)
3
3
  [![Build Status](https://secure.travis-ci.org/RiotGames/ridley.png?branch=master)](http://travis-ci.org/RiotGames/ridley)
4
4
  [![Dependency Status](https://gemnasium.com/RiotGames/ridley.png?travis)](https://gemnasium.com/RiotGames/ridley)
5
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/RiotGames/ridley)
5
+ [![Code Climate](https://codeclimate.com/github/RiotGames/ridley.png)](https://codeclimate.com/github/RiotGames/ridley)
6
6
 
7
7
  A reliable Chef API client with a clean syntax
8
8
 
@@ -10,17 +10,32 @@ exists() {
10
10
  fi
11
11
  }
12
12
 
13
- install_sh="http://opscode.com/chef/install.sh"
14
- version_string="-v <%= chef_version %>"
13
+ install_chef() {
14
+ install_sh="http://opscode.com/chef/install.sh"
15
+ proxy_string="<%= "--proxy=on " if bootstrap_proxy %>"
16
+
17
+ if [[ $requested_chef_version != "" ]]; then
18
+ version_string="-v $requested_chef_version"
19
+ else
20
+ version_string=""
21
+ fi
15
22
 
16
- if ! exists /usr/bin/chef-client; then
17
23
  if exists wget; then
18
- bash <(wget <%= "--proxy=on " if bootstrap_proxy %> ${install_sh} -O -) ${version_string}
24
+ bash <(wget ${proxy_string} ${install_sh} -O -) ${version_string}
19
25
  else
20
26
  if exists curl; then
21
- bash <(curl -L <%= "--proxy=on " if bootstrap_proxy %> ${install_sh}) ${version_string}
27
+ bash <(curl -L ${proxy_string} ${install_sh}) ${version_string}
22
28
  fi
23
29
  fi
30
+ }
31
+
32
+ requested_chef_version="<%= chef_version %>"
33
+ installed_chef_version="$(which chef-client &>/dev/null && chef-client -v | cut -f 2 -d " ")"
34
+
35
+ if [[ ! $installed_chef_version ]]; then
36
+ install_chef
37
+ elif [[ ($requested_chef_version != "") && ($installed_chef_version != $requested_chef_version) ]]; then
38
+ install_chef
24
39
  fi
25
40
 
26
41
  mkdir -p /etc/chef
@@ -0,0 +1,133 @@
1
+ @echo off
2
+
3
+ rem Author:: Kyle Allan (<kallan@riotgames.com>)
4
+ rem Original Author:
5
+ rem
6
+ rem Author:: Seth Chisamore (<schisam@oopscode.com>)
7
+ rem Copyright:: Copyright (c) 2011 Opscode, Inc.
8
+ rem License:: Apache License, Version 2.0
9
+ rem
10
+ rem Licensed under the Apache License, Version 2.0 (the "License");
11
+ rem you may not use this file except in compliance with the License.
12
+ rem You may obtain a copy of the License at
13
+ rem
14
+ rem http://www.apache.org/licenses/LICENSE-2.0
15
+ rem
16
+ rem Unless required by applicable law or agreed to in writing, software
17
+ rem distributed under the License is distributed on an "AS IS" BASIS,
18
+ rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ rem See the License for the specific language governing permissions and
20
+ rem limitations under the License.
21
+ rem
22
+
23
+ setlocal
24
+
25
+ <%= "SETX HTTP_PROXY \"#{bootstrap_proxy}\"" if bootstrap_proxy %>
26
+ mkdir <%= bootstrap_directory %>
27
+
28
+ > <%= bootstrap_directory %>\wget.vbs (
29
+ <%= windows_wget_vb %>
30
+ )
31
+
32
+ > <%= bootstrap_directory %>\wget.ps1 (
33
+ <%= windows_wget_powershell %>
34
+ )
35
+
36
+ rem Determine the version and the architecture
37
+
38
+ FOR /F "tokens=1-8 delims=.[] " %%A IN ('ver') DO (
39
+ set WinMajor=%%D
40
+ set WinMinor=%%E
41
+ set WinBuild=%%F
42
+ )
43
+
44
+ goto Version%WinMajor%.%WinMinor%
45
+
46
+ rem If this is an unknown version of windows set the default
47
+ set MACHINE_OS=2008r2
48
+ goto architecture
49
+
50
+ :Version6.0
51
+ set MACHINE_OS=2008
52
+ goto architecture
53
+
54
+ :Version5.2
55
+ set MACHINE_OS=2003r2
56
+ goto architecture
57
+
58
+ :Version6.1
59
+ set MACHINE_OS=2008r2
60
+ goto architecture
61
+
62
+ :Version6.2
63
+ set MACHINE_OS=2012
64
+ goto architecture
65
+
66
+ :architecture
67
+
68
+ goto Architecture%PROCESSOR_ARCHITECTURE%
69
+
70
+ rem If this is an unknown architecture set the default
71
+ set MACHINE_ARCH=i686
72
+ goto install
73
+
74
+ :Architecturex86
75
+ set MACHINE_ARCH=i686
76
+ goto install
77
+
78
+ :Architectureamd64
79
+ set MACHINE_ARCH=x86_64
80
+ goto install
81
+
82
+ :install
83
+ rem Install Chef using chef-client MSI installer
84
+
85
+ set "VERSION_STRING=<%= chef_version %>"
86
+ set "REMOTE_SOURCE_MSI_URL=https://www.opscode.com/chef/download?p=windows&pv=%MACHINE_OS%&m=%MACHINE_ARCH%&v=%VERSION_STRING%"
87
+ set "LOCAL_DESTINATION_MSI_PATH=<%= local_download_path %>"
88
+ set "FALLBACK_QUERY_STRING=&DownloadContext=PowerShell"
89
+
90
+ cscript /nologo <%= bootstrap_directory %>\wget.vbs /url:"%REMOTE_SOURCE_MSI_URL%" /path:"%LOCAL_DESTINATION_MSI_PATH%"
91
+
92
+ rem Work around issues found in Windows Server 2012 around job objects not respecting WSMAN memory quotas
93
+ rem that cause the MSI download process to exceed the quota even when it is increased by administrators.
94
+ rem Retry the download using a more memory-efficient mechanism that only works if PowerShell is available.
95
+ if ERRORLEVEL 1 (
96
+ echo Warning: Failed to download "%REMOTE_SOURCE_MSI_URL%" to "%LOCAL_DESTINATION_MSI_PATH%"
97
+ echo Warning: Retrying download with PowerShell if available
98
+ if EXIST "%LOCAL_DESTINATION_MSI_PATH%" del /f /q "%LOCAL_DESTINATION_MSI_PATH%"
99
+ powershell -ExecutionPolicy Unrestricted -NoProfile -NonInteractive "& '<%= bootstrap_directory %>\wget.ps1' '%REMOTE_SOURCE_MSI_URL%%FALLBACK_QUERY_STRING%' '%LOCAL_DESTINATION_MSI_PATH%'"
100
+
101
+ if NOT ERRORLEVEL 1 (
102
+ echo Download succeeded
103
+ ) else (
104
+ echo Failed to download "%REMOTE_SOURCE_MSI_URL%"
105
+ echo Subsequent attempt to install the downloaded MSI is likely to fail
106
+ )
107
+ )
108
+
109
+ <%= install_chef %>
110
+
111
+ endlocal
112
+
113
+ > <%= bootstrap_directory %>\validation.pem (
114
+ <%= validation_key %>
115
+ )
116
+
117
+ <% if encrypted_data_bag_secret -%>
118
+ > <%= bootstrap_directory %>\encrypted_data_bag_secret (
119
+ <%= encrypted_data_bag_secret %>
120
+ )
121
+ <% end -%>
122
+
123
+ > <%= bootstrap_directory %>\client.rb (
124
+ <%= chef_config %>
125
+ )
126
+
127
+ > <%= bootstrap_directory %>\first-boot.json (
128
+ <%= first_boot %>
129
+ )
130
+
131
+ <%= set_path %>
132
+
133
+ <%= chef_run %>
data/lib/ridley.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # Requiring winrm here because of https://github.com/WinRb/WinRM/issues/39
2
+ require 'winrm'
1
3
  require 'chozo'
2
4
  require 'celluloid'
3
5
  require 'faraday'
@@ -34,7 +36,7 @@ module Ridley
34
36
  autoload :Mixin, 'ridley/mixin'
35
37
  autoload :Resource, 'ridley/resource'
36
38
  autoload :SandboxUploader, 'ridley/sandbox_uploader'
37
- autoload :SSH, 'ridley/ssh'
39
+ autoload :HostConnector, 'ridley/host_connector'
38
40
 
39
41
  class << self
40
42
  extend Forwardable
@@ -62,5 +64,6 @@ end
62
64
 
63
65
  Celluloid.logger = Ridley.logger
64
66
 
67
+ require 'ridley/bootstrap_bindings'
65
68
  require 'ridley/middleware'
66
69
  require 'ridley/resources'
@@ -0,0 +1,5 @@
1
+ require 'ridley/mixin/bootstrap_binding'
2
+
3
+ Dir["#{File.dirname(__FILE__)}/bootstrap_bindings/*.rb"].sort.each do |path|
4
+ require "ridley/bootstrap_bindings/#{File.basename(path, '.rb')}"
5
+ end
@@ -0,0 +1,112 @@
1
+ #
2
+ # Ridley::UnixTemplateBinding
3
+ # Represents a binding that will be evaluated as an ERB template. When bootstrapping
4
+ # nodes, an instance of this class represents the customizable and necessary configurations
5
+ # need by the Host in order to install and connect to Chef. By default, this class will be used
6
+ # when SSH is the best way to connect to the node.
7
+ #
8
+ # @author Kyle Allan <kallan@riotgames.com>
9
+ #
10
+ module Ridley
11
+ class UnixTemplateBinding
12
+
13
+ include Ridley::BootstrapBinding
14
+
15
+ attr_reader :sudo
16
+ attr_reader :hints
17
+
18
+ # @option options [String] :validator_client
19
+ # @option options [String] :validator_path
20
+ # filepath to the validator used to bootstrap the node (required)
21
+ # @option options [String] :bootstrap_proxy (nil)
22
+ # URL to a proxy server to bootstrap through
23
+ # @option options [String] :encrypted_data_bag_secret_path (nil)
24
+ # filepath on your host machine to your organizations encrypted data bag secret
25
+ # @option options [Hash] :hints (Hash.new)
26
+ # a hash of Ohai hints to place on the bootstrapped node
27
+ # @option options [Hash] :attributes (Hash.new)
28
+ # a hash of attributes to use in the first Chef run
29
+ # @option options [Array] :run_list (Array.new)
30
+ # an initial run list to bootstrap with
31
+ # @option options [String] :chef_version (nil)
32
+ # version of Chef to install on the node
33
+ # @option options [String] :environment ('_default')
34
+ # environment to join the node to
35
+ # @option options [Boolean] :sudo (true)
36
+ # bootstrap with sudo (default: true)
37
+ # @option options [String] :template ('unix_omnibus')
38
+ # bootstrap template to use
39
+ def initialize(options = {})
40
+ options = self.class.default_options.merge(options)
41
+ options[:template] ||= default_template
42
+ self.class.validate_options(options)
43
+
44
+ @template_file = options[:template]
45
+ @bootstrap_proxy = options[:bootstrap_proxy]
46
+ @chef_version = options[:chef_version]
47
+ @sudo = options[:sudo]
48
+ @validator_path = options[:validator_path]
49
+ @encrypted_data_bag_secret_path = options[:encrypted_data_bag_secret_path]
50
+ @hints = options[:hints]
51
+ @server_url = options[:server_url]
52
+ @validator_client = options[:validator_client]
53
+ @node_name = options[:node_name]
54
+ @attributes = options[:attributes]
55
+ @run_list = options[:run_list]
56
+ @environment = options[:environment]
57
+ end
58
+
59
+ # @return [String]
60
+ def boot_command
61
+ cmd = template.evaluate(self)
62
+
63
+ if sudo
64
+ cmd = "sudo #{cmd}"
65
+ end
66
+
67
+ cmd
68
+ end
69
+
70
+ # @return [String]
71
+ def chef_config
72
+ body = <<-CONFIG
73
+ log_level :info
74
+ log_location STDOUT
75
+ chef_server_url "#{server_url}"
76
+ validation_client_name "#{validator_client}"
77
+ CONFIG
78
+
79
+ if node_name.present?
80
+ body << %Q{node_name "#{node_name}"\n}
81
+ else
82
+ body << "# Using default node name (fqdn)\n"
83
+ end
84
+
85
+ if bootstrap_proxy.present?
86
+ body << %Q{http_proxy "#{bootstrap_proxy}"\n}
87
+ body << %Q{https_proxy "#{bootstrap_proxy}"\n}
88
+ end
89
+
90
+ if encrypted_data_bag_secret.present?
91
+ body << %Q{encrypted_data_bag_secret "#{bootstrap_directory}/encrypted_data_bag_secret"\n}
92
+ end
93
+
94
+ body
95
+ end
96
+
97
+ # @return [String]
98
+ def bootstrap_directory
99
+ "/etc/chef"
100
+ end
101
+
102
+ # @return [String]
103
+ def chef_run
104
+ "chef-client -j #{bootstrap_directory}/first-boot.json -E #{environment}"
105
+ end
106
+
107
+ # @return [String]
108
+ def default_template
109
+ templates_path.join('unix_omnibus.erb').to_s
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,221 @@
1
+ #
2
+ # Ridley::WindowsTemplateBinding
3
+ # Represents a binding that will be evaluated as an ERB template. When bootstrapping
4
+ # nodes, an instance of this class represents the customizable and necessary configurations
5
+ # need by the Host in order to install and connect to Chef. By default, this class will be used
6
+ # when WinRM is the best way to connect to the node.
7
+ #
8
+ # @author Kyle Allan <kallan@riotgames.com>
9
+ #
10
+ # Windows Specific code written by Seth Chisamore (<schisamo@opscode.com>) in knife-windows
11
+ # https://github.com/opscode/knife-windows/blob/3b8886ddcfb928ca0958cd05b22f8c3d78bee86e/lib/chef/knife/bootstrap/windows-chef-client-msi.erb
12
+ # https://github.com/opscode/knife-windows/blob/78d38bbed358ac20107fc2b5b427f4b5e52e5cb2/lib/chef/knife/core/windows_bootstrap_context.rb
13
+ module Ridley
14
+ class WindowsTemplateBinding
15
+
16
+ include Ridley::BootstrapBinding
17
+
18
+ attr_reader :template_file
19
+
20
+ # @option options [String] :validator_client
21
+ # @option options [String] :validator_path
22
+ # filepath to the validator used to bootstrap the node (required)
23
+ # @option options [String] :bootstrap_proxy (nil)
24
+ # URL to a proxy server to bootstrap through
25
+ # @option options [String] :encrypted_data_bag_secret_path (nil)
26
+ # filepath on your host machine to your organizations encrypted data bag secret
27
+ # @option options [Hash] :hints (Hash.new)
28
+ # a hash of Ohai hints to place on the bootstrapped node
29
+ # @option options [Hash] :attributes (Hash.new)
30
+ # a hash of attributes to use in the first Chef run
31
+ # @option options [Array] :run_list (Array.new)
32
+ # an initial run list to bootstrap with
33
+ # @option options [String] :chef_version (nil)
34
+ # version of Chef to install on the node
35
+ # @option options [String] :environment ('_default')
36
+ # environment to join the node to
37
+ # @option options [Boolean] :sudo (true)
38
+ # bootstrap with sudo (default: true)
39
+ # @option options [String] :template ('windows_omnibus')
40
+ # bootstrap template to use
41
+ def initialize(options)
42
+ options = self.class.default_options.merge(options)
43
+ options[:template] ||= default_template
44
+ self.class.validate_options(options)
45
+
46
+ @template_file = options[:template]
47
+ @bootstrap_proxy = options[:bootstrap_proxy]
48
+ @chef_version = options[:chef_version] ? options[:chef_version] : "latest"
49
+ @validator_path = options[:validator_path]
50
+ @encrypted_data_bag_secret_path = options[:encrypted_data_bag_secret_path]
51
+ @server_url = options[:server_url]
52
+ @validator_client = options[:validator_client]
53
+ @node_name = options[:node_name]
54
+ @attributes = options[:attributes]
55
+ @run_list = options[:run_list]
56
+ @environment = options[:environment]
57
+ end
58
+
59
+ # @return [String]
60
+ def boot_command
61
+ template.evaluate(self)
62
+ end
63
+
64
+ # @return [String]
65
+ def chef_config
66
+ body = <<-CONFIG
67
+ log_level :info
68
+ log_location STDOUT
69
+ chef_server_url "#{server_url}"
70
+ validation_client_name "#{validator_client}"
71
+ CONFIG
72
+
73
+ if node_name.present?
74
+ body << %Q{node_name "#{node_name}"\n}
75
+ else
76
+ body << "# Using default node name (fqdn)\n"
77
+ end
78
+
79
+ if bootstrap_proxy.present?
80
+ body << %Q{http_proxy "#{bootstrap_proxy}"\n}
81
+ body << %Q{https_proxy "#{bootstrap_proxy}"\n}
82
+ end
83
+
84
+ if encrypted_data_bag_secret.present?
85
+ body << %Q{encrypted_data_bag_secret "#{bootstrap_directory}\\encrypted_data_bag_secret"\n}
86
+ end
87
+
88
+ escape_and_echo(body)
89
+ end
90
+
91
+ # @return [String]
92
+ def bootstrap_directory
93
+ "C:\\chef"
94
+ end
95
+
96
+ # @return [String]
97
+ def validation_key
98
+ escape_and_echo(IO.read(File.expand_path(validator_path)).chomp)
99
+ rescue Errno::ENOENT
100
+ raise Errors::ValidatorNotFound, "Error bootstrapping: Validator not found at '#{validator_path}'"
101
+ end
102
+
103
+ # @return [String]
104
+ def chef_run
105
+ "chef-client -j #{bootstrap_directory}\\first-boot.json -E #{environment}"
106
+ end
107
+
108
+ # @return [String]
109
+ def default_template
110
+ templates_path.join('windows_omnibus.erb').to_s
111
+ end
112
+
113
+ # @return [String]
114
+ def encrypted_data_bag_secret
115
+ return unless encrypted_data_bag_secret_path
116
+
117
+ escape_and_echo(IO.read(encrypted_data_bag_secret_path).chomp)
118
+ rescue Errno::ENOENT
119
+ raise Errors::EncryptedDataBagSecretNotFound, "Error bootstrapping: Encrypted data bag secret provided but not found at '#{encrypted_data_bag_secret_path}'"
120
+ end
121
+
122
+ # Implements a Visual Basic script that attempts a simple
123
+ # 'wget' to download the Chef msi
124
+ #
125
+ # @return [String]
126
+ def windows_wget_vb
127
+ win_wget = <<-WGET
128
+ url = WScript.Arguments.Named("url")
129
+ path = WScript.Arguments.Named("path")
130
+ proxy = null
131
+ Set objXMLHTTP = CreateObject("MSXML2.ServerXMLHTTP")
132
+ Set wshShell = CreateObject( "WScript.Shell" )
133
+ Set objUserVariables = wshShell.Environment("USER")
134
+
135
+ 'http proxy is optional
136
+ 'attempt to read from HTTP_PROXY env var first
137
+ On Error Resume Next
138
+
139
+ If NOT (objUserVariables("HTTP_PROXY") = "") Then
140
+ proxy = objUserVariables("HTTP_PROXY")
141
+
142
+ 'fall back to named arg
143
+ ElseIf NOT (WScript.Arguments.Named("proxy") = "") Then
144
+ proxy = WScript.Arguments.Named("proxy")
145
+ End If
146
+
147
+ If NOT isNull(proxy) Then
148
+ 'setProxy method is only available on ServerXMLHTTP 6.0+
149
+ Set objXMLHTTP = CreateObject("MSXML2.ServerXMLHTTP.6.0")
150
+ objXMLHTTP.setProxy 2, proxy
151
+ End If
152
+
153
+ On Error Goto 0
154
+
155
+ objXMLHTTP.open "GET", url, false
156
+ objXMLHTTP.send()
157
+ If objXMLHTTP.Status = 200 Then
158
+ Set objADOStream = CreateObject("ADODB.Stream")
159
+ objADOStream.Open
160
+ objADOStream.Type = 1
161
+ objADOStream.Write objXMLHTTP.ResponseBody
162
+ objADOStream.Position = 0
163
+ Set objFSO = Createobject("Scripting.FileSystemObject")
164
+ If objFSO.Fileexists(path) Then objFSO.DeleteFile path
165
+ Set objFSO = Nothing
166
+ objADOStream.SaveToFile path
167
+ objADOStream.Close
168
+ Set objADOStream = Nothing
169
+ End if
170
+ Set objXMLHTTP = Nothing
171
+ WGET
172
+ escape_and_echo(win_wget)
173
+ end
174
+
175
+ # Implements a Powershell script that attempts a simple
176
+ # 'wget' to download the Chef msi
177
+ #
178
+ # @return [String]
179
+ def windows_wget_powershell
180
+ win_wget_ps = <<-WGET_PS
181
+ param(
182
+ [String] $remoteUrl,
183
+ [String] $localPath
184
+ )
185
+
186
+ $webClient = new-object System.Net.WebClient;
187
+
188
+ $webClient.DownloadFile($remoteUrl, $localPath);
189
+ WGET_PS
190
+
191
+ escape_and_echo(win_wget_ps)
192
+ end
193
+
194
+ # @return [String]
195
+ def install_chef
196
+ 'msiexec /qb /i "%LOCAL_DESTINATION_MSI_PATH%"'
197
+ end
198
+
199
+ # @return [String]
200
+ def first_boot
201
+ escape_and_echo(MultiJson.encode attributes.merge(run_list: run_list))
202
+ end
203
+
204
+ # @return [String]
205
+ def set_path
206
+ "SET \"PATH=%PATH%;C:\\ruby\\bin;C:\\opscode\\chef\\bin;C:\\opscode\\chef\\embedded\\bin\"\n"
207
+ end
208
+
209
+ # @return [String]
210
+ def local_download_path
211
+ "%TEMP%\\chef-client-#{chef_version}.msi"
212
+ end
213
+
214
+ # escape WIN BATCH special chars
215
+ # and prefixes each line with an
216
+ # echo
217
+ def escape_and_echo(file_contents)
218
+ file_contents.gsub(/^(.*)$/, 'echo.\1').gsub(/([(<|>)^])/, '^\1')
219
+ end
220
+ end
221
+ end