knife-azure 1.4.0 → 1.5.1.rc.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +40 -6
- data/lib/azure/role.rb +75 -7
- data/lib/chef/knife/azure_server_create.rb +45 -5
- data/lib/chef/knife/azure_server_show.rb +4 -0
- data/lib/knife-azure/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 835e340ce2d007e4dff24796002efd27cd9fdef0
|
4
|
+
data.tar.gz: f92a818b349d34acd9bf82101ab0731581aff5b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75c4aa892fd004fbad3afc464521414aa9f6486f382e9f29312b42302429161886562e04c7ae90a1969b04b46e943db0b969cc6296d020a1d821ed4747a96e9a
|
7
|
+
data.tar.gz: 59dbf6fbd46fd562597ba6b6c947b20a146b5f15dc111cb1abbe8fc8e88e85d75c4b688e94e5153b8b08ec63e8f3c260098e0fa4d3c4a29a19aab99c9fe59c1b
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@ via:
|
|
15
15
|
This plugin is distributed as a Ruby Gem. To install it, run:
|
16
16
|
|
17
17
|
gem install knife-azure
|
18
|
-
|
18
|
+
|
19
19
|
Depending on your system's configuration, you may need to run this command
|
20
20
|
with root/administrator privileges.
|
21
21
|
|
@@ -28,7 +28,7 @@ local file system location, and
|
|
28
28
|
then refer to the local file via an entry in your knife.rb:
|
29
29
|
|
30
30
|
knife[:azure_publish_settings_file] = "~/myazure.publishsettings"
|
31
|
-
|
31
|
+
|
32
32
|
Alternatively, all subcommands for this plugin will accept an
|
33
33
|
--azure-publish-settings-file option to allow you to specify the path to that
|
34
34
|
file with each command invocation.
|
@@ -43,7 +43,7 @@ location in your knife.rb:
|
|
43
43
|
|
44
44
|
# List images for use in creating new VM's:
|
45
45
|
$ knife azure image list
|
46
|
-
|
46
|
+
|
47
47
|
# List all VM's (including those not be managed by Chef)
|
48
48
|
$ knife azure server list
|
49
49
|
|
@@ -55,7 +55,7 @@ location in your knife.rb:
|
|
55
55
|
|
56
56
|
# Create and bootstrap an Windows VM through the Azure API --
|
57
57
|
# No winrm or ssh transport or Internet access required
|
58
|
-
$ knife azure server create --azure-dns-name MyNewServerName --azure-vm-size Medium -I a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-201412.01-en.us-127GB.vhd --azure-service-location 'West US' --winrm-user myuser --winrm-password 'mypassword' --bootstrap-protocol
|
58
|
+
$ knife azure server create --azure-dns-name MyNewServerName --azure-vm-size Medium -I a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-201412.01-en.us-127GB.vhd --azure-service-location 'West US' --winrm-user myuser --winrm-password 'mypassword' --bootstrap-protocol cloud-api
|
59
59
|
|
60
60
|
# Delete a server and purge it from the Chef server
|
61
61
|
$ knife azure server delete MyNewNode --purge -y
|
@@ -200,16 +200,32 @@ These options may also be configured from knife.rb, as in this example:
|
|
200
200
|
:kerberos_service The Kerberos service used for authentication
|
201
201
|
:ca_trust_file The Certificate Authority (CA) trust file used for SSL transport
|
202
202
|
|
203
|
+
#### Options to configure WinRM for Bootstrapping a Windows Node
|
204
|
+
Theses options are useful if you have long-running run-lists and if the chef run might use a lot of memory. In most cases people don't need to set these, but if they see certain timeout or memory related errors during bootstrap, particularly on Win2k8r2, it may make sense to move these beyond the default.
|
205
|
+
|
206
|
+
:winrm_max_timeout Set winrm max timeout in minutes
|
207
|
+
:winrm_max_memoryPerShell Set winrm max memory per shell in MB
|
208
|
+
|
209
|
+
Command:
|
210
|
+
knife azure server create
|
211
|
+
--azure-dns-name 'myserver'
|
212
|
+
--azure-source-image 'windows-2012-image-id'
|
213
|
+
--azure-service-location 'West US'
|
214
|
+
--winrm-user azure
|
215
|
+
--winrm-password 'azure@123'
|
216
|
+
--winrm-max-timeout 30
|
217
|
+
--winrm-max-memoryPerShell 400
|
218
|
+
|
203
219
|
#### Azure Windows Node Create
|
204
220
|
The quick create option requires the following options for a windows instance:
|
205
|
-
|
221
|
+
|
206
222
|
knife azure server create
|
207
223
|
--azure-publish-settings-file '/path/to/your/cert.publishsettingsfile'
|
208
224
|
--azure-dns-name 'myserverdnsname'
|
209
225
|
--azure-service-location 'West US'
|
210
226
|
--azure-source-image 'windows-2012-image-id'
|
211
227
|
--winrm-user 'jetstream'
|
212
|
-
--winrm-password 'jetstream@123'
|
228
|
+
--winrm-password 'jetstream@123'
|
213
229
|
--distro 'windows-chef-client-msi'
|
214
230
|
|
215
231
|
Sample knife.rb for bootstrapping Windows Node with basic authentication
|
@@ -221,6 +237,24 @@ Sample knife.rb for bootstrapping Windows Node with basic authentication
|
|
221
237
|
knife[:distro] = 'windows-chef-client-msi'
|
222
238
|
knife[:azure_source_image]='windows-2012-image-id'
|
223
239
|
|
240
|
+
#### `cloud-api` bootstrap feature
|
241
|
+
By specifying the value `cloud-api` for the `bootstrap_protocol` option of `knife azure server create` instead of `winrm` or `ssh`, Microsoft Azure will install Chef Client using its own internal mirror of Chef Client (it does not download it from Chef's Internet facing URL's as in the conventional winrm / ssh bootstrap). The process as a whole is asynchronous, so once the `knife azure server create` command has create the VM, full provisioning and Chef bootstrap will continue to occur even if the `knife` command is terminated before it completes.
|
242
|
+
|
243
|
+
In general, systems bootstrapped via `cloud-api` do not require incoming or outgoing Internet access.
|
244
|
+
|
245
|
+
knife azure server create
|
246
|
+
--azure-publish-settings-file '/path/to/your/cert.publishsettingsfile'
|
247
|
+
--azure-dns-name 'myserverdnsname'
|
248
|
+
--azure-service-location 'West US'
|
249
|
+
--azure-source-image 'windows-2012-image-id'
|
250
|
+
--winrm-user 'jetstream'
|
251
|
+
--winrm-password 'jetstream@123'
|
252
|
+
--bootstrap-protocol 'cloud-api'
|
253
|
+
--delete-chef-extension-config
|
254
|
+
|
255
|
+
`--delete-chef-extension-config` determines if Chef configuration files should be removed when Azure removes the Chef resource extension from the VM or not. This option is only valid for the 'cloud-api' bootstrap protocol. The default value is false. This is useful when `update` and `uninstall` commands are run for the extension on the VM created.
|
256
|
+
|
257
|
+
|
224
258
|
### Azure Server Delete Subcommand
|
225
259
|
Deletes an existing server in the currently configured Azure account. By
|
226
260
|
default, this does not delete the associated node and client objects from the
|
data/lib/azure/role.rb
CHANGED
@@ -172,7 +172,7 @@ class Azure
|
|
172
172
|
class Role
|
173
173
|
include AzureUtility
|
174
174
|
attr_accessor :connection, :name, :status, :size, :ipaddress, :publicipaddress
|
175
|
-
attr_accessor :sshport, :hostedservicename, :deployname
|
175
|
+
attr_accessor :sshport, :hostedservicename, :deployname, :thumbprint
|
176
176
|
attr_accessor :winrmport
|
177
177
|
attr_accessor :hostname, :tcpports, :udpports
|
178
178
|
|
@@ -187,6 +187,7 @@ class Azure
|
|
187
187
|
@hostname = xml_content(roleXML, 'HostName')
|
188
188
|
@hostedservicename = hostedservicename
|
189
189
|
@deployname = deployname
|
190
|
+
@thumbprint = fetch_thumbprint
|
190
191
|
@tcpports = Array.new
|
191
192
|
@udpports = Array.new
|
192
193
|
|
@@ -211,6 +212,12 @@ class Azure
|
|
211
212
|
end
|
212
213
|
end
|
213
214
|
end
|
215
|
+
|
216
|
+
def fetch_thumbprint
|
217
|
+
query_result = connection.query_azure("hostedservices/#{@hostedservicename}/deployments/#{@hostedservicename}/roles/#{@name}")
|
218
|
+
query_result.at_css("DefaultWinRmCertificateThumbprint").nil? ? '' : query_result.at_css("DefaultWinRmCertificateThumbprint").text
|
219
|
+
end
|
220
|
+
|
214
221
|
def setup(params)
|
215
222
|
builder = Nokogiri::XML::Builder.new do |xml|
|
216
223
|
xml.PersistentVMRole(
|
@@ -276,6 +283,62 @@ class Azure
|
|
276
283
|
}
|
277
284
|
end
|
278
285
|
xml.AdminUsername params[:winrm_user]
|
286
|
+
if params[:bootstrap_proto].downcase == 'winrm' && (params[:winrm_max_timeout] || params[:winrm_max_memoryPerShell])
|
287
|
+
xml.AdditionalUnattendContent {
|
288
|
+
xml.Passes {
|
289
|
+
xml.UnattendPass {
|
290
|
+
xml.PassName 'oobeSystem'
|
291
|
+
xml.Components {
|
292
|
+
xml.UnattendComponent {
|
293
|
+
xml.ComponentName 'Microsoft-Windows-Shell-Setup'
|
294
|
+
xml.ComponentSettings {
|
295
|
+
xml.ComponentSetting {
|
296
|
+
xml.SettingName 'AutoLogon'
|
297
|
+
xml.Content Base64.encode64(
|
298
|
+
Nokogiri::XML::Builder.new do |auto_logon_xml|
|
299
|
+
auto_logon_xml.AutoLogon {
|
300
|
+
auto_logon_xml.Username params[:winrm_user]
|
301
|
+
auto_logon_xml.Password {
|
302
|
+
auto_logon_xml.Value params[:admin_password]
|
303
|
+
auto_logon_xml.PlainText true
|
304
|
+
}
|
305
|
+
auto_logon_xml.LogonCount 1
|
306
|
+
auto_logon_xml.Enabled true
|
307
|
+
}
|
308
|
+
end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION)
|
309
|
+
).strip
|
310
|
+
}
|
311
|
+
xml.ComponentSetting {
|
312
|
+
xml.SettingName 'FirstLogonCommands'
|
313
|
+
xml.Content Base64.encode64(
|
314
|
+
Nokogiri::XML::Builder.new do |first_logon_xml|
|
315
|
+
first_logon_xml.FirstLogonCommands {
|
316
|
+
if params[:winrm_max_timeout]
|
317
|
+
first_logon_xml.SynchronousCommand('wcm:action' => 'add') {
|
318
|
+
first_logon_xml.Order 1
|
319
|
+
first_logon_xml.CommandLine "cmd.exe /c winrm set winrm/config @{MaxTimeoutms=\"#{params[:winrm_max_timeout]}\"}"
|
320
|
+
first_logon_xml.Description "Bump WinRM max timeout to #{params[:winrm_max_timeout]} milliseconds"
|
321
|
+
}
|
322
|
+
end
|
323
|
+
|
324
|
+
if params[:winrm_max_memoryPerShell]
|
325
|
+
first_logon_xml.SynchronousCommand('wcm:action' => 'add') {
|
326
|
+
first_logon_xml.Order 2
|
327
|
+
first_logon_xml.CommandLine "cmd.exe /c winrm set winrm/config/winrs @{MaxMemoryPerShellMB=\"#{params[:winrm_max_memoryPerShell]}\"}"
|
328
|
+
first_logon_xml.Description "Bump WinRM max memory per shell to #{params[:winrm_max_memoryPerShell]} MB"
|
329
|
+
}
|
330
|
+
end
|
331
|
+
}
|
332
|
+
end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION)
|
333
|
+
).strip
|
334
|
+
}
|
335
|
+
}
|
336
|
+
}
|
337
|
+
}
|
338
|
+
}
|
339
|
+
}
|
340
|
+
}
|
341
|
+
end
|
279
342
|
}
|
280
343
|
end
|
281
344
|
|
@@ -283,14 +346,18 @@ class Azure
|
|
283
346
|
xml.ConfigurationSetType 'NetworkConfiguration'
|
284
347
|
xml.InputEndpoints {
|
285
348
|
|
286
|
-
if params[:os_type] == 'Windows' and
|
349
|
+
if params[:os_type] == 'Windows' and params[:bootstrap_proto].downcase == 'winrm'
|
287
350
|
xml.InputEndpoint {
|
288
|
-
|
351
|
+
if params[:winrm_transport] == "ssl"
|
352
|
+
xml.LocalPort '5986'
|
353
|
+
else
|
354
|
+
xml.LocalPort '5985'
|
355
|
+
end
|
289
356
|
xml.Name 'WinRM'
|
290
357
|
xml.Port params[:port]
|
291
358
|
xml.Protocol 'TCP'
|
292
359
|
}
|
293
|
-
|
360
|
+
elsif params[:os_type] == 'Linux' and params[:bootstrap_proto].downcase == 'ssh'
|
294
361
|
xml.InputEndpoint {
|
295
362
|
xml.LocalPort '22'
|
296
363
|
xml.Name 'SSH'
|
@@ -344,9 +411,6 @@ class Azure
|
|
344
411
|
}
|
345
412
|
}
|
346
413
|
|
347
|
-
if params[:azure_availability_set]
|
348
|
-
xml.AvailabilitySetName params[:azure_availability_set]
|
349
|
-
end
|
350
414
|
# Azure resource extension support
|
351
415
|
if params[:bootstrap_proto] == 'cloud-api'
|
352
416
|
xml.ResourceExtensionReferences {
|
@@ -376,6 +440,10 @@ class Azure
|
|
376
440
|
}
|
377
441
|
end
|
378
442
|
|
443
|
+
if params[:azure_availability_set]
|
444
|
+
xml.AvailabilitySetName params[:azure_availability_set]
|
445
|
+
end
|
446
|
+
|
379
447
|
xml.Label Base64.encode64(params[:azure_vm_name]).strip
|
380
448
|
|
381
449
|
#OSVirtualHardDisk not required in case azure_source_image is a VMImage
|
@@ -40,7 +40,6 @@ class Chef
|
|
40
40
|
|
41
41
|
def load_winrm_deps
|
42
42
|
require 'winrm'
|
43
|
-
require 'em-winrm'
|
44
43
|
require 'chef/knife/winrm'
|
45
44
|
require 'chef/knife/bootstrap_windows_winrm'
|
46
45
|
end
|
@@ -198,7 +197,7 @@ class Chef
|
|
198
197
|
option :azure_vm_ready_timeout,
|
199
198
|
:long => "--azure-vm-ready-timeout TIMEOUT",
|
200
199
|
:description => "The number of minutes that knife-azure will wait for the virtual machine state to transition from 'provisioning' to 'ready'. Default is 15.",
|
201
|
-
:default => 15
|
200
|
+
:default => 15
|
202
201
|
|
203
202
|
option :auth_timeout,
|
204
203
|
:long => "--windows-auth-timeout MINUTES",
|
@@ -246,6 +245,22 @@ class Chef
|
|
246
245
|
:default => false,
|
247
246
|
:description => "Set this flag to enable auto chef client update in azure chef extension. This flag should be used with cloud-api bootstrap protocol only"
|
248
247
|
|
248
|
+
option :winrm_max_timeout,
|
249
|
+
:long => "--winrm-max-timeout MINUTES",
|
250
|
+
:description => "Set winrm max timeout in minutes"
|
251
|
+
|
252
|
+
option :winrm_max_memoryPerShell,
|
253
|
+
:long => "--winrm-max-memoryPerShell MB",
|
254
|
+
:description => "Set winrm max memory per shell in MB"
|
255
|
+
|
256
|
+
|
257
|
+
option :delete_chef_extension_config,
|
258
|
+
:long => "--delete-chef-extension-config",
|
259
|
+
:boolean => true,
|
260
|
+
:default => false,
|
261
|
+
:description => "Determines whether Chef configuration files removed when Azure removes the Chef resource extension from the VM. This option is only valid for the 'cloud-api' bootstrap protocol. The default is false."
|
262
|
+
|
263
|
+
|
249
264
|
def strip_non_ascii(string)
|
250
265
|
string.gsub(/[^0-9a-z ]/i, '')
|
251
266
|
end
|
@@ -479,6 +494,12 @@ class Chef
|
|
479
494
|
Chef::Log.info("validating...")
|
480
495
|
validate!
|
481
496
|
|
497
|
+
if (locate_config_value(:auto_update_client) || locate_config_value(:delete_chef_extension_config)) && (locate_config_value(:bootstrap_protocol) != 'cloud-api')
|
498
|
+
ui.error("--auto-update-client option works with --bootstrap-protocol cloud-api") if locate_config_value(:auto_update_client)
|
499
|
+
ui.error("--delete-chef-extension-config option works with --bootstrap-protocol cloud-api") if locate_config_value(:delete_chef_extension_config)
|
500
|
+
exit 1
|
501
|
+
end
|
502
|
+
|
482
503
|
ssh_override_winrm if %w(ssh cloud-api).include?(locate_config_value(:bootstrap_protocol)) and !is_image_windows?
|
483
504
|
|
484
505
|
Chef::Log.info("creating...")
|
@@ -622,6 +643,8 @@ class Chef
|
|
622
643
|
bootstrap.config[:winrm_authentication_protocol] = locate_config_value(:winrm_authentication_protocol)
|
623
644
|
bootstrap.config[:winrm_port] = port
|
624
645
|
bootstrap.config[:auth_timeout] = locate_config_value(:auth_timeout)
|
646
|
+
# Todo: we should skip cert generate in case when winrm_ssl_verify_mode=verify_none
|
647
|
+
bootstrap.config[:winrm_ssl_verify_mode] = locate_config_value(:winrm_ssl_verify_mode)
|
625
648
|
|
626
649
|
elsif locate_config_value(:bootstrap_protocol) == 'ssh'
|
627
650
|
bootstrap = Chef::Knife::BootstrapWindowsSsh.new
|
@@ -724,7 +747,9 @@ class Chef
|
|
724
747
|
:ssl_cert_fingerprint => locate_config_value(:thumbprint),
|
725
748
|
:cert_path => locate_config_value(:cert_path),
|
726
749
|
:cert_password => locate_config_value(:cert_passphrase),
|
727
|
-
:winrm_transport => locate_config_value(:winrm_transport)
|
750
|
+
:winrm_transport => locate_config_value(:winrm_transport),
|
751
|
+
:winrm_max_timeout => locate_config_value(:winrm_max_timeout).to_i * 60 * 1000, #converting minutes to milliseconds
|
752
|
+
:winrm_max_memoryPerShell => locate_config_value(:winrm_max_memoryPerShell)
|
728
753
|
}
|
729
754
|
# If user is connecting a new VM to an existing dns, then
|
730
755
|
# the VM needs to have a unique public port. Logic below takes care of this.
|
@@ -806,8 +831,12 @@ class Chef
|
|
806
831
|
|
807
832
|
# get latest version
|
808
833
|
def get_chef_extension_version
|
809
|
-
|
810
|
-
|
834
|
+
if locate_config_value(:azure_chef_extension_version)
|
835
|
+
Chef::Config[:knife][:azure_chef_extension_version]
|
836
|
+
else
|
837
|
+
extensions = @connection.query_azure("resourceextensions/#{get_chef_extension_publisher}/#{get_chef_extension_name}")
|
838
|
+
extensions.css("Version").max.text.split(".").first + ".*"
|
839
|
+
end
|
811
840
|
end
|
812
841
|
|
813
842
|
def get_chef_extension_public_params
|
@@ -815,6 +844,17 @@ class Chef
|
|
815
844
|
pub_config[:client_rb] = "chef_server_url \t #{Chef::Config[:chef_server_url].to_json}\nvalidation_client_name\t#{Chef::Config[:validation_client_name].to_json}"
|
816
845
|
pub_config[:runlist] = locate_config_value(:run_list).empty? ? "" : locate_config_value(:run_list).join(",").to_json
|
817
846
|
pub_config[:autoUpdateClient] = locate_config_value(:auto_update_client) ? "true" : "false"
|
847
|
+
pub_config[:deleteChefConfig] = locate_config_value(:delete_chef_extension_config) ? "true" : "false"
|
848
|
+
pub_config[:custom_json_attr] = locate_config_value(:json_attributes) || {}
|
849
|
+
|
850
|
+
# bootstrap attributes
|
851
|
+
pub_config[:bootstrap_options] = {}
|
852
|
+
pub_config[:bootstrap_options][:environment] = locate_config_value(:environment) if locate_config_value(:environment)
|
853
|
+
pub_config[:bootstrap_options][:chef_node_name] = config[:chef_node_name] if config[:chef_node_name]
|
854
|
+
pub_config[:bootstrap_options][:encrypted_data_bag_secret] = locate_config_value(:encrypted_data_bag_secret) if locate_config_value(:encrypted_data_bag_secret)
|
855
|
+
pub_config[:bootstrap_options][:chef_server_url] = Chef::Config[:chef_server_url] if Chef::Config[:chef_server_url]
|
856
|
+
pub_config[:bootstrap_options][:validation_client_name] = Chef::Config[:validation_client_name] if Chef::Config[:validation_client_name]
|
857
|
+
|
818
858
|
Base64.encode64(pub_config.to_json)
|
819
859
|
end
|
820
860
|
|
@@ -60,6 +60,10 @@ class Chef
|
|
60
60
|
end
|
61
61
|
details << ui.color('Public IP', :bold, :cyan)
|
62
62
|
details << role.publicipaddress
|
63
|
+
unless role.thumbprint.empty?
|
64
|
+
details << ui.color('Thumbprint', :bold, :cyan)
|
65
|
+
details << role.thumbprint
|
66
|
+
end
|
63
67
|
puts ui.list(details, :columns_across, 2)
|
64
68
|
if role.tcpports.length > 0 || role.udpports.length > 0
|
65
69
|
details.clear
|
data/lib/knife-azure/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-azure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.1.rc.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Barry Davis
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-05-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|