knife-windows 0.5.12 → 0.5.14.rc.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
4
+ - 2.0.0
5
+
6
+ script: bundle exec rake spec
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in knife-windows.gemspec
4
4
  gemspec
@@ -7,4 +7,5 @@ group :test do
7
7
  gem "rspec"
8
8
  gem "ruby-wmi"
9
9
  gem "chef"
10
+ gem 'rake'
10
11
  end
data/README.rdoc CHANGED
@@ -118,7 +118,7 @@ For development and testing purposes, unencrypted traffic with Basic authenticat
118
118
 
119
119
  = CONTRIBUTING:
120
120
 
121
- Please file bugs against the KNIFE_WINDOWS project at http://tickets.opscode.com/browse/KNIFE_WINDOWS
121
+ Please file bugs against the KNIFE_WINDOWS project at http://tickets.opscode.com/browse/knife
122
122
 
123
123
  More information on the contribution process for Opscode projects can be found at: http://wiki.opscode.com/display/chef/How+to+Contribute
124
124
  = LICENSE:
@@ -0,0 +1,20 @@
1
+ Feature: Ensure that the help works as designed
2
+ In order to test the help via CLI
3
+ As an Operator
4
+ I want to run the CLI with different arguments
5
+
6
+ Scenario: Running the windows sub-command shows available commands
7
+ When I run `knife windows`
8
+ And the output should contain "Available windows subcommands: (for details, knife SUB-COMMAND --help)\n\n** WINDOWS COMMANDS **\nknife bootstrap windows winrm FQDN (options)\nknife bootstrap windows ssh FQDN (options)\nknife winrm QUERY COMMAND (options)"
9
+
10
+ Scenario: Running the windows sub-command shows available commands
11
+ When I run `knife windows --help`
12
+ And the output should contain "Available windows subcommands: (for details, knife SUB-COMMAND --help)\n\n** WINDOWS COMMANDS **\nknife bootstrap windows winrm FQDN (options)\nknife bootstrap windows ssh FQDN (options)\nknife winrm QUERY COMMAND (options)"
13
+
14
+ Scenario: Running the windows sub-command shows available commands
15
+ When I run `knife windows help`
16
+ And the output should contain "Available windows subcommands: (for details, knife SUB-COMMAND --help)\n\n** WINDOWS COMMANDS **\nknife bootstrap windows winrm FQDN (options)\nknife bootstrap windows ssh FQDN (options)\nknife winrm QUERY COMMAND (options)"
17
+
18
+ Scenario: Running the knife command shows available windows command"
19
+ When I run `knife`
20
+ And the output should contain "** WINDOWS COMMANDS **\nknife bootstrap windows winrm FQDN (options)\nknife bootstrap windows ssh FQDN (options)\nknife winrm QUERY COMMAND (options)"
@@ -0,0 +1,5 @@
1
+ require 'aruba/cucumber'
2
+
3
+ Before do
4
+ @aruba_timeout_seconds = 5
5
+ end
@@ -16,10 +16,21 @@
16
16
  @rem limitations under the License.
17
17
  @rem
18
18
 
19
- @setlocal
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
20
23
 
21
24
  <%= "SETX HTTP_PROXY \"#{knife_config[:bootstrap_proxy]}\"" if knife_config[:bootstrap_proxy] %>
22
- mkdir <%= bootstrap_directory %>
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
+ )
23
34
 
24
35
  > <%= bootstrap_directory %>\wget.vbs (
25
36
  <%= win_wget %>
@@ -31,36 +42,54 @@ mkdir <%= bootstrap_directory %>
31
42
 
32
43
  @rem Determine the version and the architecture
33
44
 
34
- FOR /F "tokens=1-8 delims=.[] " %%A IN ('ver') DO (
45
+ @FOR /F "tokens=1-8 delims=.[] " %%A IN ('ver') DO (
35
46
  @set WinMajor=%%D
36
47
  @set WinMinor=%%E
37
48
  @set WinBuild=%%F
38
49
  )
39
50
 
51
+ @echo Detected Windows Version %WinMajor%.%WinMinor% Build %WinBuild%
52
+
53
+ @set LATEST_OS_VERSION_MAJOR=6
54
+ @set LATEST_OS_VERSION_MINOR=3
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
+
40
61
  goto Version%WinMajor%.%WinMinor%
41
62
 
63
+ :VersionUnknown
42
64
  @rem If this is an unknown version of windows set the default
43
65
  @set MACHINE_OS=2008r2
44
- goto architecture
66
+ @echo Warning: Unknown version of Windows, assuming default of Windows %MACHINE_OS%
67
+ goto architecture_select
45
68
 
46
69
  :Version6.0
47
70
  @set MACHINE_OS=2008
48
- goto architecture
71
+ goto architecture_select
49
72
 
50
73
  :Version5.2
51
74
  @set MACHINE_OS=2003r2
52
- goto architecture
75
+ goto architecture_select
53
76
 
54
77
  :Version6.1
55
78
  @set MACHINE_OS=2008r2
56
- goto architecture
79
+ goto architecture_select
57
80
 
58
81
  :Version6.2
59
82
  @set MACHINE_OS=2012
60
- goto architecture
83
+ goto architecture_select
84
+
85
+ @rem Currently Windows Server 2012 R2 is treated as equivalent to Windows Server 2012
86
+ :Version6.3
87
+ goto Version6.2
61
88
 
62
- :architecture
89
+ :architecture_select
90
+ goto Architecture%PROCESSOR_ARCHITEW6432%
63
91
 
92
+ :Architecture
64
93
  goto Architecture%PROCESSOR_ARCHITECTURE%
65
94
 
66
95
  @rem If this is an unknown architecture set the default
@@ -78,37 +107,79 @@ goto install
78
107
  :install
79
108
  @rem Install Chef using chef-client MSI installer
80
109
 
81
- @set "REMOTE_SOURCE_MSI_URL=https://www.opscode.com/chef/download?p=windows&pv=%MACHINE_OS%&m=%MACHINE_ARCH%"
110
+ <% url="https://www.opscode.com/chef/download?p=windows&pv=%MACHINE_OS%&m=%MACHINE_ARCH%" -%>
111
+ <% url += "&v=#{@config[:bootstrap_version]}" if @config.key? :bootstrap_version -%>
112
+ @set "REMOTE_SOURCE_MSI_URL=<%= url %>"
82
113
  @set "LOCAL_DESTINATION_MSI_PATH=<%= local_download_path %>"
83
114
  @set "FALLBACK_QUERY_STRING=&DownloadContext=PowerShell"
84
115
 
116
+ @rem Clear any pre-existing downloads
117
+ @echo Checking for existing downloaded package at "%LOCAL_DESTINATION_MSI_PATH%"
118
+ @if EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
119
+ @echo Found existing downloaded package, deleting.
120
+ @del /f /q "%LOCAL_DESTINATION_MSI_PATH%"
121
+ @if ERRORLEVEL 1 (
122
+ echo Warning: Failed to delete pre-existing package with status code !ERRORLEVEL! > "&2"
123
+ )
124
+ ) else (
125
+ echo No existing downloaded packages to delete.
126
+ )
127
+
128
+ @echo Attempting to download client package using cscript...
85
129
  cscript /nologo <%= bootstrap_directory %>\wget.vbs /url:"%REMOTE_SOURCE_MSI_URL%" /path:"%LOCAL_DESTINATION_MSI_PATH%"
86
130
 
87
131
  @rem Work around issues found in Windows Server 2012 around job objects not respecting WSMAN memory quotas
88
132
  @rem that cause the MSI download process to exceed the quota even when it is increased by administrators.
89
133
  @rem Retry the download using a more memory-efficient mechanism that only works if PowerShell is available.
90
- @if ERRORLEVEL 1 (
91
- echo Warning: Failed to download "%REMOTE_SOURCE_MSI_URL%" to "%LOCAL_DESTINATION_MSI_PATH%"
92
- echo Warning: Retrying download with PowerShell if available
93
- if EXIST "%LOCAL_DESTINATION_MSI_PATH%" del /f /q "%LOCAL_DESTINATION_MSI_PATH%"
94
- @powershell -ExecutionPolicy Unrestricted -NoProfile -NonInteractive "& '<%= bootstrap_directory %>\wget.ps1' '%REMOTE_SOURCE_MSI_URL%%FALLBACK_QUERY_STRING%' '%LOCAL_DESTINATION_MSI_PATH%'"
95
-
96
- if NOT ERRORLEVEL 1 (
97
- echo Download succeeded
134
+ @set DOWNLOAD_ERROR_STATUS=!ERRORLEVEL!
135
+ @if ERRORLEVEL 1 (
136
+ @echo Failed cscript download with status code !DOWNLOAD_ERROR_STATUS! > "&2"
137
+ @if !DOWNLOAD_ERROR_STATUS!==0 set DOWNLOAD_ERROR_STATUS=2
138
+ ) else (
139
+ @rem Sometimes the error level is not set even when the download failed,
140
+ @rem so check for the file to be sure it is there -- if it's not, we'll retry
141
+ @if NOT EXIST "%LOCAL_DESTINATION_MSI_PATH%" (
142
+ echo Failed download: download completed, but downloaded file not found > "&2"
143
+ set DOWNLOAD_ERROR_STATUS=2
98
144
  ) else (
99
- echo Failed to download "%REMOTE_SOURCE_MSI_URL%"
100
- echo Subsequent attempt to install the downloaded MSI is likely to fail
145
+ echo Download via cscript succeeded.
101
146
  )
102
147
  )
103
148
 
149
+ @if NOT %DOWNLOAD_ERROR_STATUS%==0 (
150
+ @echo Warning: Failed to download "%REMOTE_SOURCE_MSI_URL%" to "%LOCAL_DESTINATION_MSI_PATH%"
151
+ @echo Warning: Retrying download with PowerShell if available...
152
+
153
+ @if EXIST "%LOCAL_DESTINATION_MSI_PATH%" del /f /q "%LOCAL_DESTINATION_MSI_PATH%"
154
+
155
+ @set powershell_download=powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -command "& '<%= bootstrap_directory %>\wget.ps1' '%REMOTE_SOURCE_MSI_URL%%FALLBACK_QUERY_STRING%' '%LOCAL_DESTINATION_MSI_PATH%'"
156
+ @echo !powershell_download!
157
+ @call !powershell_download!
158
+ @if NOT ERRORLEVEL 1 (
159
+ echo Download via PowerShell succeeded.
160
+ ) else (
161
+ echo Failed to download "%REMOTE_SOURCE_MSI_URL%" with status code !ERRORLEVEL!. > "&2"
162
+ echo Exiting without bootstrapping due to download failure. > "&2"
163
+ exit /b 1
164
+ )
165
+ )
166
+
167
+ @echo Starting bootstrap with downloaded client package
168
+
104
169
  <%= install_chef %>
105
170
 
106
171
  @endlocal
107
172
 
173
+ @echo off
174
+ echo Writing validation key...
175
+
108
176
  > <%= bootstrap_directory %>\validation.pem (
109
177
  <%= validation_key %>
110
178
  )
111
179
 
180
+ echo Validation key written.
181
+ @echo on
182
+
112
183
  <% if @config[:encrypted_data_bag_secret] -%>
113
184
  > <%= bootstrap_directory %>\encrypted_data_bag_secret (
114
185
  <%= encrypted_data_bag_secret %>
@@ -120,7 +191,7 @@ cscript /nologo <%= bootstrap_directory %>\wget.vbs /url:"%REMOTE_SOURCE_MSI_URL
120
191
  )
121
192
 
122
193
  > <%= bootstrap_directory %>\first-boot.json (
123
- <%= run_list %>
194
+ <%= first_boot %>
124
195
  )
125
196
 
126
197
  <%= start_chef %>
@@ -18,6 +18,7 @@
18
18
 
19
19
  require 'chef/knife'
20
20
  require 'chef/encrypted_data_bag_item'
21
+ require 'chef/knife/core/windows_bootstrap_context'
21
22
 
22
23
  class Chef
23
24
  class Knife
@@ -53,6 +54,11 @@ class Chef
53
54
  :description => "The proxy server for the node being bootstrapped",
54
55
  :proc => Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p }
55
56
 
57
+ option :bootstrap_no_proxy,
58
+ :long => "--bootstrap-no-proxy ",
59
+ :description => "Avoid a proxy server for the given addresses",
60
+ :proc => Proc.new { |np| Chef::Config[:knife][:bootstrap_no_proxy] = np }
61
+
56
62
  option :distro,
57
63
  :short => "-d DISTRO",
58
64
  :long => "--distro DISTRO",
@@ -71,6 +77,13 @@ class Chef
71
77
  :proc => lambda { |o| o.split(",") },
72
78
  :default => []
73
79
 
80
+ option :first_boot_attributes,
81
+ :short => "-j JSON_ATTRIBS",
82
+ :long => "--json-attributes",
83
+ :description => "A JSON string to be added to the first run of chef-client",
84
+ :proc => lambda { |o| JSON.parse(o) },
85
+ :default => {}
86
+
74
87
  option :encrypted_data_bag_secret,
75
88
  :short => "-s SECRET",
76
89
  :long => "--secret ",
@@ -136,7 +149,7 @@ class Chef
136
149
  # we have to run the remote commands in 2047 char chunks
137
150
  create_bootstrap_bat_command do |command_chunk, chunk_num|
138
151
  begin
139
- run_command("cmd.exe /C echo \"Rendering '#{bootstrap_bat_file}' chunk #{chunk_num}\" && #{command_chunk}")
152
+ run_command("cmd.exe /C echo \"Rendering #{bootstrap_bat_file} chunk #{chunk_num}\" && #{command_chunk}")
140
153
  rescue SystemExit => e
141
154
  raise unless e.success?
142
155
  end
@@ -167,7 +180,7 @@ class Chef
167
180
  end
168
181
 
169
182
  def bootstrap_bat_file
170
- @bootstrap_bat_file ||= "%TEMP%\\bootstrap-#{Process.pid}-#{Time.now.to_i}.bat"
183
+ @bootstrap_bat_file ||= "\"%TEMP%\\bootstrap-#{Process.pid}-#{Time.now.to_i}.bat\""
171
184
  end
172
185
 
173
186
  def locate_config_value(key)
@@ -69,6 +69,7 @@ CONFIG
69
69
  client_rb << "\n"
70
70
  client_rb << %Q{http_proxy "#{knife_config[:bootstrap_proxy]}"\n}
71
71
  client_rb << %Q{https_proxy "#{knife_config[:bootstrap_proxy]}"\n}
72
+ client_rb << %Q{no_proxy "#{knife_config[:bootstrap_no_proxy]}"\n} if knife_config[:bootstrap_no_proxy]
72
73
  end
73
74
 
74
75
  if @config[:encrypted_data_bag_secret]
@@ -83,10 +84,6 @@ CONFIG
83
84
  start_chef << "chef-client -c c:/chef/client.rb -j c:/chef/first-boot.json -E #{bootstrap_environment}\n"
84
85
  end
85
86
 
86
- def run_list
87
- escape_and_echo({ "run_list" => @run_list }.to_json)
88
- end
89
-
90
87
  def win_wget
91
88
  win_wget = <<-WGET
92
89
  url = WScript.Arguments.Named("url")
@@ -152,7 +149,7 @@ WGET_PS
152
149
  end
153
150
 
154
151
  def install_chef
155
- install_chef = 'msiexec /qb /i "%LOCAL_DESTINATION_MSI_PATH%"'
152
+ install_chef = 'msiexec /qn /i "%LOCAL_DESTINATION_MSI_PATH%"'
156
153
  end
157
154
 
158
155
  def bootstrap_directory
@@ -163,6 +160,11 @@ WGET_PS
163
160
  local_download_path = "%TEMP%\\chef-client-latest.msi"
164
161
  end
165
162
 
163
+ def first_boot
164
+ first_boot_attributes_and_run_list = (@config[:first_boot_attributes] || {}).merge(:run_list => @run_list)
165
+ escape_and_echo(first_boot_attributes_and_run_list.to_json)
166
+ end
167
+
166
168
  # escape WIN BATCH special chars
167
169
  # and prefixes each line with an
168
170
  # echo
@@ -0,0 +1,34 @@
1
+ #
2
+ # Author:: Chirag Jog (<chirag@clogeny.com>)
3
+ # Copyright:: Copyright (c) 2013 Opscode, 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'
20
+ require 'chef/knife/winrm'
21
+ require 'chef/knife/bootstrap_windows_ssh'
22
+ require 'chef/knife/bootstrap_windows_winrm'
23
+
24
+ class Chef
25
+ class Knife
26
+ class WindowsHelper < Knife
27
+
28
+ banner "#{BootstrapWindowsWinrm.banner}\n" +
29
+ "#{BootstrapWindowsSsh.banner}\n" +
30
+ "#{Winrm.banner}"
31
+ end
32
+ end
33
+ end
34
+
@@ -75,6 +75,26 @@ class Chef
75
75
 
76
76
  end
77
77
 
78
+ # TODO: Copied from Knife::Core:GenericPresenter. Should be extracted
79
+ def extract_nested_value(data, nested_value_spec)
80
+ nested_value_spec.split(".").each do |attr|
81
+ if data.nil?
82
+ nil # don't get no method error on nil
83
+ elsif data.respond_to?(attr.to_sym)
84
+ data = data.send(attr.to_sym)
85
+ elsif data.respond_to?(:[])
86
+ data = data[attr]
87
+ else
88
+ data = begin
89
+ data.send(attr.to_sym)
90
+ rescue NoMethodError
91
+ nil
92
+ end
93
+ end
94
+ end
95
+ ( !data.kind_of?(Array) && data.respond_to?(:to_hash) ) ? data.to_hash : data
96
+ end
97
+
78
98
  def configure_session
79
99
  list = case config[:manual]
80
100
  when true
@@ -84,7 +104,7 @@ class Chef
84
104
  q = Chef::Search::Query.new
85
105
  @action_nodes = q.search(:node, @name_args[0])[0]
86
106
  @action_nodes.each do |item|
87
- i = format_for_display(item)[config[:attribute]]
107
+ i = extract_nested_value(item, config[:attribute])
88
108
  r.push(i) unless i.nil?
89
109
  end
90
110
  r
@@ -1,6 +1,6 @@
1
1
  module Knife
2
2
  module Windows
3
- VERSION = "0.5.12"
3
+ VERSION = "0.5.14.rc.0"
4
4
  MAJOR, MINOR, TINY = VERSION.split('.')
5
5
  end
6
6
  end
@@ -50,6 +50,9 @@ describe 'Knife::Windows::Core msi download functionality for knife Windows winr
50
50
  # Location to which the download script will be modified to write
51
51
  # the downloaded msi
52
52
  @local_file_download_destination = "#{@temp_directory}/chef-client-latest.msi"
53
+
54
+ source_code_directory = File.dirname(__FILE__)
55
+ @template_file_path ="#{source_code_directory}/../../lib/chef/knife/bootstrap/windows-chef-client-msi.erb"
53
56
  end
54
57
 
55
58
  after(:all) do
@@ -64,7 +67,8 @@ describe 'Knife::Windows::Core msi download functionality for knife Windows winr
64
67
  @mock_bootstrap_context = Chef::Knife::Core::WindowsBootstrapContext.new({ }, nil, { })
65
68
 
66
69
  # Stub the bootstrap context and prevent config related sections
67
- # to be populated, chef installation and first chef run
70
+ # from being populated, i.e. chef installation and first chef
71
+ # run sections
68
72
  @mock_bootstrap_context.stub(:validation_key).and_return("echo.validation_key")
69
73
  @mock_bootstrap_context.stub(:encrypted_data_bag_secret).and_return("echo.encrypted_data_bag_secret")
70
74
  @mock_bootstrap_context.stub(:config_content).and_return("echo.config_content")
@@ -72,7 +76,7 @@ describe 'Knife::Windows::Core msi download functionality for knife Windows winr
72
76
  @mock_bootstrap_context.stub(:run_list).and_return("echo.run_list")
73
77
  @mock_bootstrap_context.stub(:install_chef).and_return("echo.echo install_chef_command")
74
78
 
75
- # Change the directorires where bootstrap files will be created
79
+ # Change the directories where bootstrap files will be created
76
80
  @mock_bootstrap_context.stub(:bootstrap_directory).and_return(@temp_directory.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR))
77
81
  @mock_bootstrap_context.stub(:local_download_path).and_return(@local_file_download_destination.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR))
78
82
 
@@ -87,14 +91,15 @@ describe 'Knife::Windows::Core msi download functionality for knife Windows winr
87
91
  it "downloads the chef-client MSI during winrm bootstrap" do
88
92
  clean_test_case
89
93
 
90
- bootstrap_context = Chef::Knife::BootstrapWindowsWinrm.new([ "127.0.0.1" ])
94
+ winrm_bootstrapper = Chef::Knife::BootstrapWindowsWinrm.new([ "127.0.0.1" ])
95
+ winrm_bootstrapper.config[:template_file] = @template_file_path
91
96
 
92
97
  # Execute the commands locally that would normally be executed via WinRM
93
- bootstrap_context.stub(:run_command) do |command|
98
+ winrm_bootstrapper.stub(:run_command) do |command|
94
99
  system(command)
95
100
  end
96
101
 
97
- bootstrap_context.run
102
+ winrm_bootstrapper.run
98
103
 
99
104
  # Download should succeed
100
105
  download_succeeded?.should == true
@@ -105,7 +110,7 @@ describe 'Knife::Windows::Core msi download functionality for knife Windows winr
105
110
  File.exists?(@local_file_download_destination) && ! File.zero?(@local_file_download_destination)
106
111
  end
107
112
 
108
- # Remove file artifiacts generated by individual test cases
113
+ # Remove file artifacts generated by individual test cases
109
114
  def clean_test_case
110
115
  if File.exists?(@local_file_download_destination)
111
116
  File.delete(@local_file_download_destination)
@@ -0,0 +1,91 @@
1
+ #
2
+ # Author:: Chirag Jog (<chirag@clogeny.com>)
3
+ # Copyright:: Copyright (c) 2013 Chirag Jog
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
+ TEMPLATE_FILE = File.expand_path(File.dirname(__FILE__)) + "/../../../lib/chef/knife/bootstrap/windows-chef-client-msi.erb"
20
+
21
+ require 'spec_helper'
22
+
23
+ describe "While Windows Bootstrapping" do
24
+ context "the default Windows bootstrapping template" do
25
+ bootstrap = Chef::Knife::BootstrapWindowsWinrm.new
26
+ bootstrap.config[:template_file] = TEMPLATE_FILE
27
+
28
+ template = bootstrap.load_template
29
+ template_file_lines = template.split('\n')
30
+ it "should download Platform specific MSI" do
31
+ download_url=template_file_lines.find {|l| l.include?("url=")}
32
+ download_url.include?("%MACHINE_OS%") && download_url.include?("%MACHINE_ARCH%")
33
+ end
34
+ it "should download specific version of MSI if supplied" do
35
+ download_url_ext= template_file_lines.find {|l| l.include?("url +=")}
36
+ download_url_ext.include?("[:bootstrap_version]")
37
+ end
38
+ end
39
+ end
40
+
41
+ describe Chef::Knife::BootstrapWindowsWinrm do
42
+ before(:all) do
43
+ @original_config = Chef::Config.hash_dup
44
+ @original_knife_config = Chef::Config[:knife].dup
45
+ end
46
+
47
+ after(:all) do
48
+ Chef::Config.configuration = @original_config
49
+ Chef::Config[:knife] = @original_knife_config
50
+ end
51
+
52
+ before(:each) do
53
+ Chef::Log.logger = Logger.new(StringIO.new)
54
+ @knife = Chef::Knife::BootstrapWindowsWinrm.new
55
+ # Merge default settings in.
56
+ @knife.merge_configs
57
+ @knife.config[:template_file] = TEMPLATE_FILE
58
+ @stdout = StringIO.new
59
+ @knife.ui.stub(:stdout).and_return(@stdout)
60
+ @stderr = StringIO.new
61
+ @knife.ui.stub(:stderr).and_return(@stderr)
62
+ end
63
+
64
+ describe "specifying no_proxy with various entries" do
65
+ subject(:knife) { described_class.new }
66
+ let(:options){ ["--bootstrap-proxy", "", "--bootstrap-no-proxy", setting] }
67
+ let(:template_file) { TEMPLATE_FILE }
68
+ let(:rendered_template) do
69
+ knife.instance_variable_set("@template_file", template_file)
70
+ knife.parse_options(options)
71
+ # Avoid referencing a validation keyfile we won't find during #render_template
72
+ template_string = knife.read_template.gsub(/^.*[Vv]alidation_key.*$/, '')
73
+ knife.render_template(template_string)
74
+ end
75
+
76
+ context "via --bootstrap-no-proxy" do
77
+ let(:setting) { "api.opscode.com" }
78
+
79
+ it "renders the client.rb with a single FQDN no_proxy entry" do
80
+ rendered_template.should match(%r{.*no_proxy\s*\"api.opscode.com\".*})
81
+ end
82
+ end
83
+ context "via --bootstrap-no-proxy multiple" do
84
+ let(:setting) { "api.opscode.com,172.16.10.*" }
85
+
86
+ it "renders the client.rb with comma-separated FQDN and wildcard IP address no_proxy entries" do
87
+ rendered_template.should match(%r{.*no_proxy\s*"api.opscode.com,172.16.10.\*".*})
88
+ end
89
+ end
90
+ end
91
+ end
@@ -40,6 +40,7 @@ describe Chef::Knife::Winrm do
40
40
  @node_bar = Chef::Node.new
41
41
  @node_bar.automatic_attrs[:fqdn] = "bar.example.org"
42
42
  @node_bar.automatic_attrs[:ipaddress] = "10.0.0.2"
43
+ @node_bar.automatic_attrs[:ec2][:public_hostname] = "somewhere.com"
43
44
  end
44
45
 
45
46
  describe "#configure_session" do
@@ -49,6 +50,7 @@ describe Chef::Knife::Winrm do
49
50
 
50
51
  context "when there are some hosts found but they do not have an attribute to connect with" do
51
52
  before do
53
+ @knife.config[:manual] = false
52
54
  @query.stub!(:search).and_return([[@node_foo, @node_bar]])
53
55
  @node_foo.automatic_attrs[:fqdn] = nil
54
56
  @node_bar.automatic_attrs[:fqdn] = nil
@@ -61,5 +63,20 @@ describe Chef::Knife::Winrm do
61
63
  @knife.configure_session
62
64
  end
63
65
  end
66
+
67
+ context "when there are nested attributes" do
68
+ before do
69
+ @knife.config[:manual] = false
70
+ @query.stub!(:search).and_return([[@node_foo, @node_bar]])
71
+ Chef::Search::Query.stub!(:new).and_return(@query)
72
+ end
73
+
74
+ it "should use nested attributes (KNIFE-276)" do
75
+ @knife.config[:attribute] = "ec2.public_hostname"
76
+ @knife.stub!(:session_from_list)
77
+ @knife.configure_session
78
+
79
+ end
80
+ end
64
81
  end
65
82
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-windows
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.12
5
- prerelease:
4
+ version: 0.5.14.rc.0
5
+ prerelease: 7
6
6
  platform: ruby
7
7
  authors:
8
8
  - Seth Chisamore
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-25 00:00:00.000000000 Z
12
+ date: 2013-10-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: em-winrm
@@ -39,11 +39,14 @@ extra_rdoc_files:
39
39
  files:
40
40
  - .gitignore
41
41
  - .rspec
42
+ - .travis.yml
42
43
  - CHANGELOG
43
44
  - Gemfile
44
45
  - LICENSE
45
46
  - README.rdoc
46
47
  - Rakefile
48
+ - features/knife_help.feature
49
+ - features/support/env.rb
47
50
  - knife-windows.gemspec
48
51
  - lib/chef/knife/bootstrap/windows-chef-client-msi.erb
49
52
  - lib/chef/knife/bootstrap/windows-shell.erb
@@ -51,11 +54,13 @@ files:
51
54
  - lib/chef/knife/bootstrap_windows_ssh.rb
52
55
  - lib/chef/knife/bootstrap_windows_winrm.rb
53
56
  - lib/chef/knife/core/windows_bootstrap_context.rb
57
+ - lib/chef/knife/windows_helper.rb
54
58
  - lib/chef/knife/winrm.rb
55
59
  - lib/chef/knife/winrm_base.rb
56
60
  - lib/knife-windows/version.rb
57
61
  - spec/functional/bootstrap_download_spec.rb
58
62
  - spec/spec_helper.rb
63
+ - spec/unit/knife/bootstrap_template_spec.rb
59
64
  - spec/unit/knife/winrm_spec.rb
60
65
  homepage: https://github.com/opscode/knife-windows
61
66
  licenses: []
@@ -72,14 +77,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
72
77
  required_rubygems_version: !ruby/object:Gem::Requirement
73
78
  none: false
74
79
  requirements:
75
- - - ! '>='
80
+ - - ! '>'
76
81
  - !ruby/object:Gem::Version
77
- version: '0'
82
+ version: 1.3.1
78
83
  requirements: []
79
84
  rubyforge_project:
80
- rubygems_version: 1.8.21
85
+ rubygems_version: 1.8.23
81
86
  signing_key:
82
87
  specification_version: 3
83
88
  summary: Plugin that adds functionality to Chef's Knife CLI for configuring/interacting
84
89
  with nodes running Microsoft Windows
85
- test_files: []
90
+ test_files:
91
+ - features/knife_help.feature
92
+ - features/support/env.rb
93
+ - spec/functional/bootstrap_download_spec.rb
94
+ - spec/spec_helper.rb
95
+ - spec/unit/knife/bootstrap_template_spec.rb
96
+ - spec/unit/knife/winrm_spec.rb