kitchen-azurerm 0.15.1 → 0.15.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '03965a2dd5197abe1ccce35906e33c7ba4dbf996c047b305b1d5b29abb3bc54c'
4
- data.tar.gz: 7d46770f6836c397717d6324d3af29bc57d4ce0ce87055decf8b21388aa326c1
3
+ metadata.gz: 48df20f4bbd7b6087cfde1ec03770f559f0fbd45e01bc01834e95e95d8f9c3b6
4
+ data.tar.gz: 6cc4e949b4fbc6bf173664fb4ee5f7aa3eb9bcfa5254c70a6642767c53425ce6
5
5
  SHA512:
6
- metadata.gz: 97e66a086d8565a6f2d4e7674dce0c527f2563465db2804d2de266b3e5eaf4d08f376704a6291cef68f0374d61803dfbc48a11c8c3704d3aa2fe9e019f975c43
7
- data.tar.gz: e63882365344c12bfface30030b4c6b32caf8c786cd39947047085cd40d23e1b8160b87a98c0647b1a41a4b1863de172e850903ce5e2ee81a490b7fc3acc25c8
6
+ metadata.gz: 71daccd76e78290d7c601b293d3e54c8a9fc4f1fd06a7d754d8dc0ea900c516424d05dbe50d1c5011a52862a5ac8a6f738cb183fd31ca280fe8637cf6fe3ba01
7
+ data.tar.gz: acadd9d7ea7152cac675428e0203a12d6d79b187d7ae4603be1795edbe3498c7b3ccffec5457f22e864bc1623b203d58ba666f522c3a1f65dd8331cdd70d6c79
data/README.md CHANGED
@@ -618,7 +618,7 @@ info: vm image list command OK
618
618
 
619
619
  ### Additional parameters that can be specified
620
620
 
621
- * Note that the ```driver``` section also takes a ```username``` and ```password``` parameter, the defaults if these are not specified are "azure" and "P2ssw0rd" respectively.
621
+ * Note that the ```driver``` section can also takes a ```username``` and ```password```. The default username is "azure" and the password is a randomly generated 12 character password that can be found in your local kitchen state file (typically .kitchen/<instance-name>.yml) if you require it for any reason.
622
622
 
623
623
  * The ```storage_account_type``` parameter defaults to 'Standard_LRS' and allows you to switch to premium storage (e.g. 'Premium_LRS')
624
624
 
@@ -3,15 +3,27 @@ require "inifile"
3
3
  module Kitchen
4
4
  module Driver
5
5
  #
6
- # Credentials
6
+ # AzureCredentials
7
7
  #
8
- class Credentials
8
+ class AzureCredentials
9
9
  CONFIG_PATH = "#{ENV["HOME"]}/.azure/credentials".freeze
10
10
 
11
+ #
12
+ # @return [String]
13
+ #
14
+ attr_reader :subscription_id
15
+
16
+ #
17
+ # @return [String]
18
+ #
19
+ attr_reader :environment
20
+
11
21
  #
12
22
  # Creates and initializes a new instance of the Credentials class.
13
23
  #
14
- def initialize
24
+ def initialize(subscription_id:, environment: "Azure")
25
+ @subscription_id = subscription_id
26
+ @environment = environment
15
27
  config_file = ENV["AZURE_CONFIG_FILE"] || File.expand_path(CONFIG_PATH)
16
28
  if File.file?(config_file)
17
29
  @credentials = IniFile.load(File.expand_path(config_file))
@@ -21,37 +33,47 @@ module Kitchen
21
33
  end
22
34
 
23
35
  #
24
- # Retrieves an object containing options and credentials for the given
25
- # subscription_id and azure_environment.
26
- #
27
- # @param subscription_id [String] The subscription_id to retrieve a token for
28
- # @param azure_environment [String] The azure_environment to use
36
+ # Retrieves an object containing options and credentials
29
37
  #
30
38
  # @return [Object] Object that can be supplied along with all Azure client requests.
31
39
  #
32
- def azure_options_for_subscription(subscription_id, azure_environment = "Azure")
33
- tenant_id = ENV["AZURE_TENANT_ID"] || @credentials[subscription_id]["tenant_id"]
34
- client_id = ENV["AZURE_CLIENT_ID"] || @credentials[subscription_id]["client_id"]
35
- client_secret = ENV["AZURE_CLIENT_SECRET"] || @credentials[subscription_id]["client_secret"]
36
- token_provider = ::MsRestAzure::ApplicationTokenProvider.new(tenant_id, client_id, client_secret, ad_settings_for_azure_environment(azure_environment))
40
+ def azure_options
37
41
  options = { tenant_id: tenant_id,
38
42
  client_id: client_id,
39
43
  client_secret: client_secret,
40
44
  subscription_id: subscription_id,
41
45
  credentials: ::MsRest::TokenCredentials.new(token_provider),
42
- active_directory_settings: ad_settings_for_azure_environment(azure_environment),
43
- base_url: endpoint_settings_for_azure_environment(azure_environment).resource_manager_endpoint_url }
46
+ active_directory_settings: ad_settings,
47
+ base_url: endpoint_settings.resource_manager_endpoint_url }
48
+
44
49
  options
45
50
  end
46
51
 
52
+ private
53
+
54
+ def tenant_id
55
+ ENV["AZURE_TENANT_ID"] || @credentials[subscription_id]["tenant_id"]
56
+ end
57
+
58
+ def client_id
59
+ ENV["AZURE_CLIENT_ID"] || @credentials[subscription_id]["client_id"]
60
+ end
61
+
62
+ def client_secret
63
+ ENV["AZURE_CLIENT_SECRET"] || @credentials[subscription_id]["client_secret"]
64
+ end
65
+
66
+ def token_provider
67
+ ::MsRestAzure::ApplicationTokenProvider.new(tenant_id, client_id, client_secret, ad_settings)
68
+ end
69
+
47
70
  #
48
71
  # Retrieves a [MsRestAzure::ActiveDirectoryServiceSettings] object representing the AD settings for the given cloud.
49
- # @param azure_environment [String] The Azure environment to retrieve settings for.
50
72
  #
51
73
  # @return [MsRestAzure::ActiveDirectoryServiceSettings] Settings to be used for subsequent requests
52
74
  #
53
- def ad_settings_for_azure_environment(azure_environment)
54
- case azure_environment.downcase
75
+ def ad_settings
76
+ case environment.downcase
55
77
  when "azureusgovernment"
56
78
  ::MsRestAzure::ActiveDirectoryServiceSettings.get_azure_us_government_settings
57
79
  when "azurechina"
@@ -65,12 +87,11 @@ module Kitchen
65
87
 
66
88
  #
67
89
  # Retrieves a [MsRestAzure::AzureEnvironment] object representing endpoint settings for the given cloud.
68
- # @param azure_environment [String] The Azure environment to retrieve settings for.
69
90
  #
70
91
  # @return [MsRestAzure::AzureEnvironment] Settings to be used for subsequent requests
71
92
  #
72
- def endpoint_settings_for_azure_environment(azure_environment)
73
- case azure_environment.downcase
93
+ def endpoint_settings
94
+ case environment.downcase
74
95
  when "azureusgovernment"
75
96
  ::MsRestAzure::AzureEnvironments::AzureUSGovernment
76
97
  when "azurechina"
@@ -81,10 +102,6 @@ module Kitchen
81
102
  ::MsRestAzure::AzureEnvironments::AzureCloud
82
103
  end
83
104
  end
84
-
85
- def self.singleton
86
- @credentials ||= Credentials.new
87
- end
88
105
  end
89
106
  end
90
107
  end
@@ -1,5 +1,5 @@
1
1
  require "kitchen"
2
- require_relative "credentials"
2
+ require_relative "azure_credentials"
3
3
  require "securerandom"
4
4
  require "azure_mgmt_resources"
5
5
  require "azure_mgmt_network"
@@ -9,6 +9,7 @@ require "fileutils"
9
9
  require "erb"
10
10
  require "ostruct"
11
11
  require "json"
12
+ require "faraday"
12
13
 
13
14
  module Kitchen
14
15
  module Driver
@@ -17,6 +18,7 @@ module Kitchen
17
18
  #
18
19
  class Azurerm < Kitchen::Driver::Base
19
20
  attr_accessor :resource_management_client
21
+ attr_accessor :network_management_client
20
22
 
21
23
  default_config(:azure_resource_group_prefix) do |_config|
22
24
  "kitchen-"
@@ -71,7 +73,7 @@ module Kitchen
71
73
  end
72
74
 
73
75
  default_config(:password) do |_config|
74
- "P2ssw0rd"
76
+ SecureRandom.base64(12)
75
77
  end
76
78
 
77
79
  default_config(:vm_name) do |_config|
@@ -190,6 +192,10 @@ module Kitchen
190
192
  ENV["AZURE_SUBSCRIPTION_ID"]
191
193
  end
192
194
 
195
+ default_config(:azure_api_retries) do |_config|
196
+ 5
197
+ end
198
+
193
199
  def create(state)
194
200
  state = validate_state(state)
195
201
  deployment_parameters = {
@@ -199,7 +205,6 @@ module Kitchen
199
205
  bootDiagnosticsEnabled: config[:boot_diagnostics_enabled],
200
206
  newStorageAccountName: "storage#{state[:uuid]}",
201
207
  adminUsername: state[:username],
202
- adminPassword: state[:password] || "P2ssw0rd",
203
208
  dnsNameForPublicIP: "kitchen-#{state[:uuid]}",
204
209
  vmName: state[:vm_name],
205
210
  systemAssignedIdentity: config[:system_assigned_identity],
@@ -209,6 +214,10 @@ module Kitchen
209
214
  vaultResourceGroup: config[:vault_resource_group],
210
215
  }
211
216
 
217
+ if instance.transport[:ssh_key].nil?
218
+ deployment_parameters["adminPassword"] = state[:password]
219
+ end
220
+
212
221
  if config[:subscription_id].to_s == ""
213
222
  raise "A subscription_id config value was not detected and kitchen-azurerm cannot continue. Please check your .kitchen.yml configuration. Exiting."
214
223
  end
@@ -255,7 +264,8 @@ module Kitchen
255
264
  deployment_parameters["imageVersion"] = image_version
256
265
  end
257
266
 
258
- options = Kitchen::Driver::Credentials.new.azure_options_for_subscription(config[:subscription_id], config[:azure_environment])
267
+ options = Kitchen::Driver::AzureCredentials.new(subscription_id: config[:subscription_id],
268
+ environment: config[:azure_environment]).azure_options
259
269
 
260
270
  debug "Azure environment: #{config[:azure_environment]}"
261
271
  @resource_management_client = ::Azure::Resources::Profiles::Latest::Mgmt::Client.new(options)
@@ -266,7 +276,7 @@ module Kitchen
266
276
  resource_group.tags = config[:resource_group_tags]
267
277
  begin
268
278
  info "Creating Resource Group: #{state[:azure_resource_group_name]}"
269
- resource_management_client.resource_groups.create_or_update(state[:azure_resource_group_name], resource_group)
279
+ create_resource_group(state[:azure_resource_group_name], resource_group)
270
280
  rescue ::MsRestAzure::AzureOperationError => operation_error
271
281
  error operation_error.body
272
282
  raise operation_error
@@ -277,17 +287,17 @@ module Kitchen
277
287
  if File.file?(config[:pre_deployment_template])
278
288
  pre_deployment_name = "pre-deploy-#{state[:uuid]}"
279
289
  info "Creating deployment: #{pre_deployment_name}"
280
- resource_management_client.deployments.begin_create_or_update_async(state[:azure_resource_group_name], pre_deployment_name, pre_deployment(config[:pre_deployment_template], config[:pre_deployment_parameters])).value!
290
+ create_deployment_async(state[:azure_resource_group_name], pre_deployment_name, pre_deployment(config[:pre_deployment_template], config[:pre_deployment_parameters])).value!
281
291
  follow_deployment_until_end_state(state[:azure_resource_group_name], pre_deployment_name)
282
292
  end
283
293
  deployment_name = "deploy-#{state[:uuid]}"
284
294
  info "Creating deployment: #{deployment_name}"
285
- resource_management_client.deployments.begin_create_or_update_async(state[:azure_resource_group_name], deployment_name, deployment(deployment_parameters)).value!
295
+ create_deployment_async(state[:azure_resource_group_name], deployment_name, deployment(deployment_parameters)).value!
286
296
  follow_deployment_until_end_state(state[:azure_resource_group_name], deployment_name)
287
297
  if File.file?(config[:post_deployment_template])
288
298
  post_deployment_name = "post-deploy-#{state[:uuid]}"
289
299
  info "Creating deployment: #{post_deployment_name}"
290
- resource_management_client.deployments.begin_create_or_update_async(state[:azure_resource_group_name], post_deployment_name, post_deployment(config[:post_deployment_template], config[:post_deployment_parameters])).value!
300
+ create_deployment_async(state[:azure_resource_group_name], post_deployment_name, post_deployment(config[:post_deployment_template], config[:post_deployment_parameters])).value!
291
301
  follow_deployment_until_end_state(state[:azure_resource_group_name], post_deployment_name)
292
302
  end
293
303
  rescue ::MsRestAzure::AzureOperationError => operation_error
@@ -302,17 +312,16 @@ module Kitchen
302
312
  end
303
313
  end
304
314
 
305
- network_management_client = ::Azure::Network::Profiles::Latest::Mgmt::Client.new(options)
315
+ @network_management_client = ::Azure::Network::Profiles::Latest::Mgmt::Client.new(options)
306
316
 
307
317
  if config[:vnet_id] == "" || config[:public_ip]
308
318
  # Retrieve the public IP from the resource group:
309
- result = network_management_client.public_ipaddresses.get(state[:azure_resource_group_name], "publicip")
319
+ result = get_public_ip(state[:azure_resource_group_name], "publicip")
310
320
  info "IP Address is: #{result.ip_address} [#{result.dns_settings.fqdn}]"
311
321
  state[:hostname] = result.ip_address
312
322
  else
313
323
  # Retrieve the internal IP from the resource group:
314
- network_interfaces = ::Azure::Network::Profiles::Latest::Mgmt::NetworkInterfaces.new(network_management_client)
315
- result = network_interfaces.get(state[:azure_resource_group_name], vmnic.to_s)
324
+ result = get_network_interface(state[:azure_resource_group_name], vmnic.to_s)
316
325
  info "IP Address is: #{result.ip_configurations[0].private_ipaddress}"
317
326
  state[:hostname] = result.ip_configurations[0].private_ipaddress
318
327
  end
@@ -475,7 +484,7 @@ module Kitchen
475
484
  until end_provisioning_state_reached
476
485
  list_outstanding_deployment_operations(resource_group, deployment_name)
477
486
  sleep config[:deployment_sleep]
478
- deployment_provisioning_state = deployment_state(resource_group, deployment_name)
487
+ deployment_provisioning_state = get_deployment_state(resource_group, deployment_name)
479
488
  end_provisioning_state_reached = end_provisioning_states.split(",").include?(deployment_provisioning_state)
480
489
  end
481
490
  info "Resource Template deployment reached end state of '#{deployment_provisioning_state}'."
@@ -483,7 +492,7 @@ module Kitchen
483
492
  end
484
493
 
485
494
  def show_failed_operations(resource_group, deployment_name)
486
- failed_operations = resource_management_client.deployment_operations.list(resource_group, deployment_name)
495
+ failed_operations = list_deployment_operations(resource_group, deployment_name)
487
496
  failed_operations.each do |val|
488
497
  resource_code = val.properties.status_code
489
498
  raise val.properties.status_message.inspect.to_s if resource_code != "OK"
@@ -492,7 +501,7 @@ module Kitchen
492
501
 
493
502
  def list_outstanding_deployment_operations(resource_group, deployment_name)
494
503
  end_operation_states = "Failed,Succeeded"
495
- deployment_operations = resource_management_client.deployment_operations.list(resource_group, deployment_name)
504
+ deployment_operations = list_deployment_operations(resource_group, deployment_name)
496
505
  deployment_operations.each do |val|
497
506
  resource_provisioning_state = val.properties.provisioning_state
498
507
  unless val.properties.target_resource.nil?
@@ -506,22 +515,18 @@ module Kitchen
506
515
  end
507
516
  end
508
517
 
509
- def deployment_state(resource_group, deployment_name)
510
- deployments = resource_management_client.deployments.get(resource_group, deployment_name)
511
- deployments.properties.provisioning_state
512
- end
513
-
514
518
  def destroy(state)
515
519
  return if state[:server_id].nil?
516
520
 
517
- options = Kitchen::Driver::Credentials.new.azure_options_for_subscription(state[:subscription_id], state[:azure_environment])
521
+ options = Kitchen::Driver::AzureCredentials.new(subscription_id: state[:subscription_id],
522
+ environment: state[:azure_environment]).azure_options
518
523
  @resource_management_client = ::Azure::Resources::Profiles::Latest::Mgmt::Client.new(options)
519
524
  if config[:destroy_resource_group_contents] == true
520
525
  info "Destroying individual resources within the Resource Group."
521
526
  empty_deployment_name = "empty-deploy-#{state[:uuid]}"
522
527
  begin
523
528
  info "Creating deployment: #{empty_deployment_name}"
524
- resource_management_client.deployments.begin_create_or_update_async(state[:azure_resource_group_name], empty_deployment_name, empty_deployment).value!
529
+ create_deployment_async(state[:azure_resource_group_name], empty_deployment_name, empty_deployment).value!
525
530
  follow_deployment_until_end_state(state[:azure_resource_group_name], empty_deployment_name)
526
531
  rescue ::MsRestAzure::AzureOperationError => operation_error
527
532
  error operation_error.body
@@ -536,7 +541,7 @@ module Kitchen
536
541
  info "Azure environment: #{state[:azure_environment]}"
537
542
  begin
538
543
  info "Destroying Resource Group: #{state[:azure_resource_group_name]}"
539
- resource_management_client.resource_groups.begin_delete(state[:azure_resource_group_name])
544
+ delete_resource_group_async(state[:azure_resource_group_name])
540
545
  info "Destroy operation accepted and will continue in the background."
541
546
  rescue ::MsRestAzure::AzureOperationError => operation_error
542
547
  error operation_error.body
@@ -638,10 +643,10 @@ module Kitchen
638
643
 
639
644
  def virtual_machine_deployment_template
640
645
  if config[:vnet_id] == ""
641
- virtual_machine_deployment_template_file("public.erb", vm_tags: vm_tag_string(config[:vm_tags]), use_managed_disks: config[:use_managed_disks], image_url: config[:image_url], existing_storage_account_blob_url: config[:existing_storage_account_blob_url], image_id: config[:image_id], existing_storage_account_container: config[:existing_storage_account_container], custom_data: config[:custom_data], os_disk_size_gb: config[:os_disk_size_gb], data_disks_for_vm_json: data_disks_for_vm_json, use_ephemeral_osdisk: config[:use_ephemeral_osdisk])
646
+ virtual_machine_deployment_template_file("public.erb", vm_tags: vm_tag_string(config[:vm_tags]), use_managed_disks: config[:use_managed_disks], image_url: config[:image_url], existing_storage_account_blob_url: config[:existing_storage_account_blob_url], image_id: config[:image_id], existing_storage_account_container: config[:existing_storage_account_container], custom_data: config[:custom_data], os_disk_size_gb: config[:os_disk_size_gb], data_disks_for_vm_json: data_disks_for_vm_json, use_ephemeral_osdisk: config[:use_ephemeral_osdisk], ssh_key: instance.transport[:ssh_key])
642
647
  else
643
648
  info "Using custom vnet: #{config[:vnet_id]}"
644
- virtual_machine_deployment_template_file("internal.erb", vnet_id: config[:vnet_id], subnet_id: config[:subnet_id], public_ip: config[:public_ip], vm_tags: vm_tag_string(config[:vm_tags]), use_managed_disks: config[:use_managed_disks], image_url: config[:image_url], existing_storage_account_blob_url: config[:existing_storage_account_blob_url], image_id: config[:image_id], existing_storage_account_container: config[:existing_storage_account_container], custom_data: config[:custom_data], os_disk_size_gb: config[:os_disk_size_gb], data_disks_for_vm_json: data_disks_for_vm_json, use_ephemeral_osdisk: config[:use_ephemeral_osdisk])
649
+ virtual_machine_deployment_template_file("internal.erb", vnet_id: config[:vnet_id], subnet_id: config[:subnet_id], public_ip: config[:public_ip], vm_tags: vm_tag_string(config[:vm_tags]), use_managed_disks: config[:use_managed_disks], image_url: config[:image_url], existing_storage_account_blob_url: config[:existing_storage_account_blob_url], image_id: config[:image_id], existing_storage_account_container: config[:existing_storage_account_container], custom_data: config[:custom_data], os_disk_size_gb: config[:os_disk_size_gb], data_disks_for_vm_json: data_disks_for_vm_json, use_ephemeral_osdisk: config[:use_ephemeral_osdisk], ssh_key: instance.transport[:ssh_key])
645
650
  end
646
651
  end
647
652
 
@@ -676,6 +681,118 @@ module Kitchen
676
681
  end
677
682
  end
678
683
  end
684
+
685
+ private
686
+
687
+ #
688
+ # Wrapper methods for the Azure API calls to retry the calls when getting timeouts.
689
+ #
690
+
691
+ def create_resource_group(resource_group_name, resource_group)
692
+ retries = config[:azure_api_retries]
693
+ begin
694
+ resource_management_client.resource_groups.create_or_update(resource_group_name, resource_group)
695
+ rescue Faraday::TimeoutError, Faraday::ClientError => exception
696
+ send_exception_message(exception, "while creating resource group '#{resource_group_name}'. #{retries} retries left.")
697
+ raise if retries == 0
698
+
699
+ retries -= 1
700
+ retry
701
+ end
702
+ end
703
+
704
+ def create_deployment_async(resource_group, deployment_name, deployment)
705
+ retries = config[:azure_api_retries]
706
+ begin
707
+ resource_management_client.deployments.begin_create_or_update_async(resource_group, deployment_name, deployment)
708
+ rescue Faraday::TimeoutError, Faraday::ClientError => exception
709
+ send_exception_message(exception, "while sending deployment creation request for deployment '#{deployment_name}'. #{retries} retries left.")
710
+ raise if retries == 0
711
+
712
+ retries -= 1
713
+ retry
714
+ end
715
+ end
716
+
717
+ def get_public_ip(resource_group_name, public_ip_name)
718
+ retries = config[:azure_api_retries]
719
+ begin
720
+ network_management_client.public_ipaddresses.get(resource_group_name, public_ip_name)
721
+ rescue Faraday::TimeoutError, Faraday::ClientError => exception
722
+ send_exception_message(exception, "while fetching public ip '#{public_ip_name}' for resource group '#{resource_group_name}'. #{retries} retries left.")
723
+ raise if retries == 0
724
+
725
+ retries -= 1
726
+ retry
727
+ end
728
+ end
729
+
730
+ def get_network_interface(resource_group_name, network_interface_name)
731
+ retries = config[:azure_api_retries]
732
+ begin
733
+ network_interfaces = ::Azure::Network::Profiles::Latest::Mgmt::NetworkInterfaces.new(network_management_client)
734
+ network_interfaces.get(resource_group_name, network_interface_name)
735
+ rescue Faraday::TimeoutError, Faraday::ClientError => exception
736
+ send_exception_message(exception, "while fetching network interface '#{network_interface_name}' for resource group '#{resource_group_name}'. #{retries} retries left.")
737
+ raise if retries == 0
738
+
739
+ retries -= 1
740
+ retry
741
+ end
742
+ end
743
+
744
+ def list_deployment_operations(resource_group, deployment_name)
745
+ retries = config[:azure_api_retries]
746
+ begin
747
+ resource_management_client.deployment_operations.list(resource_group, deployment_name)
748
+ rescue Faraday::TimeoutError, Faraday::ClientError => exception
749
+ send_exception_message(exception, "while listing deployment operations for deployment '#{deployment_name}'. #{retries} retries left.")
750
+ raise if retries == 0
751
+
752
+ retries -= 1
753
+ retry
754
+ end
755
+ end
756
+
757
+ def get_deployment_state(resource_group, deployment_name)
758
+ retries = config[:azure_api_retries]
759
+ begin
760
+ deployments = resource_management_client.deployments.get(resource_group, deployment_name)
761
+ deployments.properties.provisioning_state
762
+ rescue Faraday::TimeoutError, Faraday::ClientError => exception
763
+ send_exception_message(exception, "while retrieving state for deployment '#{deployment_name}'. #{retries} retries left.")
764
+ raise if retries == 0
765
+
766
+ retries -= 1
767
+ retry
768
+ end
769
+ end
770
+
771
+ def delete_resource_group_async(resource_group_name)
772
+ retries = config[:azure_api_retries]
773
+ begin
774
+ resource_management_client.resource_groups.begin_delete(resource_group_name)
775
+ rescue Faraday::TimeoutError, Faraday::ClientError => exception
776
+ send_exception_message(exception, "while sending resource group deletion request for '#{resource_group_name}'. #{retries} retries left.")
777
+ raise if retries == 0
778
+
779
+ retries -= 1
780
+ retry
781
+ end
782
+ end
783
+
784
+ def send_exception_message(exception, message)
785
+ if exception.is_a?(Faraday::TimeoutError)
786
+ header = "Timed out"
787
+ elsif exception.is_a?(Faraday::ClientError)
788
+ header = "Connection reset by peer"
789
+ else
790
+ # Unhandled exception, return early
791
+ info "Unrecognized exception type."
792
+ return
793
+ end
794
+ info "#{header} #{message}"
795
+ end
679
796
  end
680
797
  end
681
798
  end
@@ -26,12 +26,14 @@
26
26
  "description": "User name for the Virtual Machine."
27
27
  }
28
28
  },
29
+ <%- if ssh_key.nil? -%>
29
30
  "adminPassword": {
30
31
  "type": "securestring",
31
32
  "metadata": {
32
33
  "description": "Password for the Virtual Machine."
33
34
  }
34
35
  },
36
+ <%- end -%>
35
37
  "dnsNameForPublicIP": {
36
38
  "type": "string",
37
39
  "metadata": {
@@ -322,8 +324,10 @@
322
324
  ]
323
325
  ],
324
326
  <%- end -%>
325
- "adminUsername": "[parameters('adminUsername')]",
326
- "adminPassword": "[parameters('adminPassword')]"
327
+ <%- if ssh_key.nil? -%>
328
+ "adminPassword": "[parameters('adminPassword')]",
329
+ <%- end -%>
330
+ "adminUsername": "[parameters('adminUsername')]"
327
331
  },
328
332
  "storageProfile": {
329
333
  <%- if image_url.empty? and image_id.empty? -%>
data/templates/public.erb CHANGED
@@ -26,12 +26,14 @@
26
26
  "description": "User name for the Virtual Machine."
27
27
  }
28
28
  },
29
+ <%- if ssh_key.nil? -%>
29
30
  "adminPassword": {
30
31
  "type": "securestring",
31
32
  "metadata": {
32
33
  "description": "Password for the Virtual Machine."
33
34
  }
34
35
  },
36
+ <%- end -%>
35
37
  "dnsNameForPublicIP": {
36
38
  "type": "string",
37
39
  "metadata": {
@@ -341,8 +343,10 @@
341
343
  ]
342
344
  ],
343
345
  <%- end -%>
344
- "adminUsername": "[parameters('adminUsername')]",
345
- "adminPassword": "[parameters('adminPassword')]"
346
+ <%- if ssh_key.nil? -%>
347
+ "adminPassword": "[parameters('adminPassword')]",
348
+ <%- end -%>
349
+ "adminUsername": "[parameters('adminUsername')]"
346
350
  },
347
351
  "storageProfile": {
348
352
  <%- if image_url.empty? and image_id.empty? -%>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-azurerm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.1
4
+ version: 0.15.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stuart Preston
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-15 00:00:00.000000000 Z
11
+ date: 2020-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: azure_mgmt_network
@@ -54,22 +54,22 @@ dependencies:
54
54
  name: inifile
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
- - - ">="
58
- - !ruby/object:Gem::Version
59
- version: 3.0.0
60
57
  - - "~>"
61
58
  - !ruby/object:Gem::Version
62
59
  version: '3.0'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 3.0.0
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- version: 3.0.0
70
67
  - - "~>"
71
68
  - !ruby/object:Gem::Version
72
69
  version: '3.0'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 3.0.0
73
73
  - !ruby/object:Gem::Dependency
74
74
  name: sshkey
75
75
  requirement: !ruby/object:Gem::Requirement
@@ -141,8 +141,8 @@ extra_rdoc_files: []
141
141
  files:
142
142
  - LICENSE
143
143
  - README.md
144
+ - lib/kitchen/driver/azure_credentials.rb
144
145
  - lib/kitchen/driver/azurerm.rb
145
- - lib/kitchen/driver/credentials.rb
146
146
  - templates/empty.erb
147
147
  - templates/internal.erb
148
148
  - templates/public.erb
@@ -165,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
167
  requirements: []
168
- rubygems_version: 3.0.3
168
+ rubygems_version: 3.1.2
169
169
  signing_key:
170
170
  specification_version: 4
171
171
  summary: Test Kitchen driver for Azure Resource Manager.