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 +4 -4
- data/README.md +1 -1
- data/lib/kitchen/driver/{credentials.rb → azure_credentials.rb} +42 -25
- data/lib/kitchen/driver/azurerm.rb +142 -25
- data/templates/internal.erb +6 -2
- data/templates/public.erb +6 -2
- metadata +10 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 48df20f4bbd7b6087cfde1ec03770f559f0fbd45e01bc01834e95e95d8f9c3b6
|
|
4
|
+
data.tar.gz: 6cc4e949b4fbc6bf173664fb4ee5f7aa3eb9bcfa5254c70a6642767c53425ce6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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
|
-
#
|
|
6
|
+
# AzureCredentials
|
|
7
7
|
#
|
|
8
|
-
class
|
|
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
|
|
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
|
|
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:
|
|
43
|
-
base_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
|
|
54
|
-
case
|
|
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
|
|
73
|
-
case
|
|
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 "
|
|
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
|
-
|
|
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::
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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::
|
|
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
|
-
|
|
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
|
-
|
|
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
|
data/templates/internal.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": {
|
|
@@ -322,8 +324,10 @@
|
|
|
322
324
|
]
|
|
323
325
|
],
|
|
324
326
|
<%- end -%>
|
|
325
|
-
|
|
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
|
-
|
|
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.
|
|
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-
|
|
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.
|
|
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.
|