kitchen-azurerm 0.15.1 → 0.15.2

Sign up to get free protection for your applications and to get access to all the features.
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.