knife-azure 4.0.0 → 5.0.1
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/lib/azure/azure_interface.rb +1 -1
- data/lib/azure/custom_errors.rb +1 -1
- data/lib/azure/helpers.rb +1 -1
- data/lib/azure/resource_management/ARM_deployment_template.rb +77 -22
- data/lib/azure/resource_management/ARM_interface.rb +115 -119
- data/lib/azure/resource_management/rest/arm_client.rb +208 -0
- data/lib/azure/resource_management/rest/environments.rb +89 -0
- data/lib/azure/resource_management/rest/errors.rb +57 -0
- data/lib/azure/resource_management/rest/http.rb +335 -0
- data/lib/azure/resource_management/rest/rest_object.rb +103 -0
- data/lib/azure/resource_management/rest/secure_connection.rb +57 -0
- data/lib/azure/resource_management/rest/token_provider.rb +125 -0
- data/lib/azure/resource_management/vnet_config.rb +4 -4
- data/lib/azure/resource_management/windows_credentials.rb +1 -1
- data/lib/chef/knife/azurerm_server_create.rb +21 -9
- data/lib/chef/knife/azurerm_server_delete.rb +1 -1
- data/lib/chef/knife/azurerm_server_list.rb +1 -1
- data/lib/chef/knife/azurerm_server_show.rb +1 -1
- data/lib/chef/knife/bootstrap/bootstrapper.rb +137 -4
- data/lib/chef/knife/bootstrap/common_bootstrap_options.rb +4 -6
- data/lib/chef/knife/bootstrap_azurerm.rb +1 -1
- data/lib/chef/knife/helpers/azurerm_base.rb +168 -7
- data/lib/knife-azure/version.rb +2 -2
- metadata +25 -70
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b2b0c8e7095b9f0880e4d35af2728b7c71119ef5fd22138cc4e5f6ad37ab467b
|
|
4
|
+
data.tar.gz: a853c153d5d15328a0026c84f91c552329e72c87dc5935c32760435f10bff6f9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 352cf2e4f22eaed979e964367e98e0e9c80a18e1b44352207f9bad659e8197a4355b4f9ff4393bd85248c5ffeceff672424902428385e17800aad36a8201600d
|
|
7
|
+
data.tar.gz: d9956696c10ce1e4c0a96d9d8d46826c8d4d8fe448778c274d1c658ac9485d136871f5843c7b952fbc92ba235ba784952a3241bc303b758ffc18af06c4d2a6fa
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#
|
|
2
|
-
# Copyright:: Copyright (c)
|
|
2
|
+
# Copyright:: Copyright (c) 2012-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
|
|
3
3
|
# License:: Apache License, Version 2.0
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
data/lib/azure/custom_errors.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#
|
|
2
|
-
# Copyright:: Copyright (c)
|
|
2
|
+
# Copyright:: Copyright (c) 2012-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
|
|
3
3
|
# License:: Apache License, Version 2.0
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
data/lib/azure/helpers.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#
|
|
2
2
|
# Author:: vasundhara.jagdale@clogeny.com
|
|
3
|
-
# Copyright:: Copyright (c)
|
|
3
|
+
# Copyright:: Copyright (c) 2012-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
|
|
4
4
|
# License:: Apache License, Version 2.0
|
|
5
5
|
#
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#
|
|
2
2
|
# Author:: Nimisha Sharad (nimisha.sharad@clogeny.com)
|
|
3
|
-
# Copyright:: Copyright (c)
|
|
3
|
+
# Copyright:: Copyright (c) 2012-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
|
|
4
4
|
# License:: Apache License, Version 2.0
|
|
5
5
|
#
|
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -94,8 +94,8 @@ module Azure::ARM
|
|
|
94
94
|
vmId = "[resourceId('Microsoft.Compute/virtualMachines', concat(variables('vmName'),copyIndex()))]"
|
|
95
95
|
depVm2 = "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'), copyIndex())]"
|
|
96
96
|
computerName = "[concat(variables('vmName'),copyIndex())]"
|
|
97
|
-
uri = "[concat('http://',variables('storageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',concat(variables('vmName'),copyIndex()),'.vhd')]"
|
|
98
97
|
netid = "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('nicName'), copyIndex()))]"
|
|
98
|
+
osDiskName = "[concat(variables('OSDiskName'),copyIndex())]"
|
|
99
99
|
|
|
100
100
|
# Extension Variables
|
|
101
101
|
extName = "[concat(variables('vmName'),copyIndex(),'/', variables('vmExtensionName'))]"
|
|
@@ -117,8 +117,8 @@ module Azure::ARM
|
|
|
117
117
|
vmId = "[resourceId('Microsoft.Compute/virtualMachines', variables('vmName'))]"
|
|
118
118
|
depVm2 = "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
|
|
119
119
|
computerName = "[variables('vmName')]"
|
|
120
|
-
uri = "[concat('http://',variables('storageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',variables('vmName'),'.vhd')]"
|
|
121
120
|
netid = "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
|
|
121
|
+
osDiskName = "[variables('OSDiskName')]"
|
|
122
122
|
|
|
123
123
|
# Extension Variables
|
|
124
124
|
extName = "[concat(variables('vmName'),'/', variables('vmExtensionName'))]"
|
|
@@ -252,12 +252,41 @@ module Azure::ARM
|
|
|
252
252
|
"description" => "Optional. Path to a client.rb file for use by the bootstrapped node.",
|
|
253
253
|
},
|
|
254
254
|
},
|
|
255
|
+
"CHEF_LICENSE" => {
|
|
256
|
+
"type" => "string",
|
|
257
|
+
"defaultValue" => "accept-no-persist",
|
|
258
|
+
"metadata" => {
|
|
259
|
+
"description" => "Optional. Chef Infra license acceptance value read and exported as an " \
|
|
260
|
+
"environment variable by the VM extension's own bootstrap script, so it also covers " \
|
|
261
|
+
"the extension's separate chef-apply cron-setup step (which does not read client_rb).",
|
|
262
|
+
},
|
|
263
|
+
},
|
|
255
264
|
"bootstrap_version" => {
|
|
256
265
|
"type" => "string",
|
|
257
266
|
"metadata" => {
|
|
258
267
|
"description" => "Optional. The version of Chef to install.",
|
|
259
268
|
},
|
|
260
269
|
},
|
|
270
|
+
"chef_license_key" => {
|
|
271
|
+
# securestring keeps this out of ARM deployment history/logs and the
|
|
272
|
+
# Azure Portal's deployment "Inputs" view (same treatment as
|
|
273
|
+
# adminPassword above). Per chef-partners/azure-chef-extension#413
|
|
274
|
+
# (version 1210.15.11.1, rolled out to all regions for both
|
|
275
|
+
# ChefClient and LinuxChefClient), the VM extension's install
|
|
276
|
+
# scripts now decrypt protectedSettings for this value and prefer
|
|
277
|
+
# it over the deprecated publicSettings location, so it is
|
|
278
|
+
# forwarded via the "protectedSettings" block below instead of
|
|
279
|
+
# plain "settings" - delivered to the VM CMS/PKCS7-encrypted and
|
|
280
|
+
# decrypted locally, the same treatment already given to
|
|
281
|
+
# validation_key/chef_server_crt/encrypted_data_bag_secret.
|
|
282
|
+
"type" => "securestring",
|
|
283
|
+
"metadata" => {
|
|
284
|
+
"description" => "Optional. Chef/Progress license key, forwarded to the VM extension's " \
|
|
285
|
+
"install.sh as chef_license_key so it can download Chef Infra Client from the licensed " \
|
|
286
|
+
"endpoints. When omitted, the extension falls back to the unlicensed omnitruck.chef.io " \
|
|
287
|
+
"download host with a warning.",
|
|
288
|
+
},
|
|
289
|
+
},
|
|
261
290
|
"custom_json_attr" => {
|
|
262
291
|
"type" => "string",
|
|
263
292
|
"metadata" => {
|
|
@@ -302,7 +331,6 @@ module Azure::ARM
|
|
|
302
331
|
},
|
|
303
332
|
},
|
|
304
333
|
"variables" => {
|
|
305
|
-
"storageAccountName" => "[concat(uniquestring(resourceGroup().id), '#{params[:azure_storage_account]}')]",
|
|
306
334
|
"imagePublisher" => "#{params[:azure_image_reference_publisher]}",
|
|
307
335
|
"imageOffer" => "#{params[:azure_image_reference_offer]}",
|
|
308
336
|
"OSDiskName" => "#{params[:azure_os_disk_name]}",
|
|
@@ -311,7 +339,6 @@ module Azure::ARM
|
|
|
311
339
|
"storageAccountType" => "#{params[:azure_storage_account_type]}",
|
|
312
340
|
"publicIPAddressName" => "#{params[:azure_vm_name]}",
|
|
313
341
|
"publicIPAddressType" => "Dynamic",
|
|
314
|
-
"vmStorageAccountContainerName" => "#{params[:azure_vm_name]}",
|
|
315
342
|
"vmName" => "#{params[:azure_vm_name]}",
|
|
316
343
|
"vmSize" => "#{params[:vm_size]}",
|
|
317
344
|
"virtualNetworkName" => "#{params[:vnet_config][:virtualNetworkName]}",
|
|
@@ -323,15 +350,12 @@ module Azure::ARM
|
|
|
323
350
|
"sshKeyPath" => "[concat('/home/',parameters('adminUserName'),'/.ssh/authorized_keys')]",
|
|
324
351
|
},
|
|
325
352
|
"resources" => [
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
"accountType" => "[variables('storageAccountType')]",
|
|
333
|
-
},
|
|
334
|
-
},
|
|
353
|
+
# NOTE: Managed disks are used for the OS disk below, so no separate
|
|
354
|
+
# Microsoft.Storage/storageAccounts resource is created here. Existing
|
|
355
|
+
# deployments created with an unmanaged-disk storage account continue to
|
|
356
|
+
# function as-is; this only affects new VM deployments. See Azure's
|
|
357
|
+
# migration guide if you want to move existing VMs to managed disks:
|
|
358
|
+
# https://docs.microsoft.com/en-us/azure/virtual-machines/windows/convert-unmanaged-to-managed-disks
|
|
335
359
|
{
|
|
336
360
|
"apiVersion" => "[variables('apiVersion')]",
|
|
337
361
|
"type" => "Microsoft.Network/publicIPAddresses",
|
|
@@ -391,7 +415,15 @@ module Azure::ARM
|
|
|
391
415
|
},
|
|
392
416
|
},
|
|
393
417
|
{
|
|
394
|
-
|
|
418
|
+
# NOTE: apiVersion "2020-12-01" is required, not just for managed disk
|
|
419
|
+
# support and managed boot diagnostics (both available since
|
|
420
|
+
# "2020-06-01", using Azure's managed-storage boot diagnostics instead
|
|
421
|
+
# of the storage account this template no longer creates), but also
|
|
422
|
+
# for the StandardSSD_ZRS/Premium_ZRS managed disk SKUs accepted by
|
|
423
|
+
# --azure-storage-account-type, which older API versions reject at
|
|
424
|
+
# deployment time. Don't switch this back to an older apiVersion
|
|
425
|
+
# without re-verifying managed disk, ZRS, and boot diagnostics support.
|
|
426
|
+
"apiVersion" => "2020-12-01",
|
|
395
427
|
"type" => "Microsoft.Compute/virtualMachines",
|
|
396
428
|
"name" => vmName,
|
|
397
429
|
"location" => "[resourceGroup().location]",
|
|
@@ -400,7 +432,6 @@ module Azure::ARM
|
|
|
400
432
|
"count" => "[parameters('numberOfInstances')]",
|
|
401
433
|
},
|
|
402
434
|
"dependsOn" => [
|
|
403
|
-
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
|
|
404
435
|
depVm2,
|
|
405
436
|
],
|
|
406
437
|
"properties" => {
|
|
@@ -430,12 +461,12 @@ module Azure::ARM
|
|
|
430
461
|
"version" => "[parameters('imageVersion')]",
|
|
431
462
|
},
|
|
432
463
|
"osDisk" => {
|
|
433
|
-
"name" =>
|
|
434
|
-
"vhd" => {
|
|
435
|
-
"uri" => uri,
|
|
436
|
-
},
|
|
464
|
+
"name" => osDiskName,
|
|
437
465
|
"caching" => "ReadWrite",
|
|
438
466
|
"createOption" => "FromImage",
|
|
467
|
+
"managedDisk" => {
|
|
468
|
+
"storageAccountType" => "[variables('storageAccountType')]",
|
|
469
|
+
},
|
|
439
470
|
},
|
|
440
471
|
},
|
|
441
472
|
"networkProfile" => {
|
|
@@ -447,8 +478,11 @@ module Azure::ARM
|
|
|
447
478
|
},
|
|
448
479
|
"diagnosticsProfile" => {
|
|
449
480
|
"bootDiagnostics" => {
|
|
481
|
+
# Managed boot diagnostics: no storageUri is provided (or needed)
|
|
482
|
+
# since apiVersion 2020-12-01+ provisions Azure-managed storage
|
|
483
|
+
# for boot diagnostics automatically, instead of the storage
|
|
484
|
+
# account this template no longer creates.
|
|
450
485
|
"enabled" => "true",
|
|
451
|
-
"storageUri" => "[concat('http://',variables('storageAccountName'),'.blob.core.windows.net')]",
|
|
452
486
|
},
|
|
453
487
|
},
|
|
454
488
|
},
|
|
@@ -486,11 +520,17 @@ module Azure::ARM
|
|
|
486
520
|
"hints" => hints_json,
|
|
487
521
|
"client_rb" => "[parameters('client_rb')]",
|
|
488
522
|
"custom_json_attr" => "[parameters('custom_json_attr')]",
|
|
523
|
+
"CHEF_LICENSE" => "[parameters('CHEF_LICENSE')]",
|
|
489
524
|
},
|
|
490
525
|
"protectedSettings" => {
|
|
491
526
|
"validation_key" => "[parameters('validation_key')]",
|
|
492
527
|
"chef_server_crt" => "[parameters('chef_server_crt')]",
|
|
493
528
|
"encrypted_data_bag_secret" => "[parameters('encrypted_data_bag_secret')]",
|
|
529
|
+
# Per chef-partners/azure-chef-extension#413 (version
|
|
530
|
+
# 1210.15.11.1, rolled out to all regions), the extension's
|
|
531
|
+
# install scripts decrypt this from protectedSettings and
|
|
532
|
+
# prefer it over the deprecated publicSettings location.
|
|
533
|
+
"chef_license_key" => "[parameters('chef_license_key')]",
|
|
494
534
|
},
|
|
495
535
|
},
|
|
496
536
|
},
|
|
@@ -501,8 +541,17 @@ module Azure::ARM
|
|
|
501
541
|
set_val = {
|
|
502
542
|
"name" => "[parameters('availabilitySetName')]",
|
|
503
543
|
"type" => "Microsoft.Compute/availabilitySets",
|
|
504
|
-
|
|
544
|
+
# NOTE: variables('apiVersion') ("2015-06-15") is intentionally not used
|
|
545
|
+
# here. That old API version (and the absence of an explicit "Aligned"
|
|
546
|
+
# sku) creates a classic (unmanaged-disk-only) availability set, which
|
|
547
|
+
# Azure rejects VMs with managed OS disks from joining. Managed-disk
|
|
548
|
+
# compatible ("Aligned") availability sets require apiVersion
|
|
549
|
+
# 2016-04-30-preview or later plus this explicit sku.
|
|
550
|
+
"apiVersion" => "2020-12-01",
|
|
505
551
|
"location" => "[resourceGroup().location]",
|
|
552
|
+
"sku" => {
|
|
553
|
+
"name" => "Aligned",
|
|
554
|
+
},
|
|
506
555
|
"properties" => {
|
|
507
556
|
"platformFaultDomainCount" => "[parameters('availabilitySetPlatformFaultDomainCount')]",
|
|
508
557
|
"platformUpdateDomainCount" => "[parameters('availabilitySetPlatformUpdateDomainCount')]",
|
|
@@ -644,6 +693,12 @@ module Azure::ARM
|
|
|
644
693
|
"client_rb" => {
|
|
645
694
|
"value" => "#{params[:chef_extension_public_param][:client_rb]}",
|
|
646
695
|
},
|
|
696
|
+
"CHEF_LICENSE" => {
|
|
697
|
+
"value" => "#{params[:chef_extension_public_param][:CHEF_LICENSE]}",
|
|
698
|
+
},
|
|
699
|
+
"chef_license_key" => {
|
|
700
|
+
"value" => "#{params[:chef_extension_private_param][:chef_license_key]}",
|
|
701
|
+
},
|
|
647
702
|
"bootstrap_version" => {
|
|
648
703
|
"value" => "#{params[:chef_extension_public_param][:bootstrap_options][:bootstrap_version]}",
|
|
649
704
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#
|
|
2
|
-
# Copyright:: Copyright (c)
|
|
2
|
+
# Copyright:: Copyright (c) 2012-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
|
|
3
3
|
# License:: Apache License, Version 2.0
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -18,10 +18,11 @@
|
|
|
18
18
|
require_relative "../azure_interface"
|
|
19
19
|
require_relative "ARM_deployment_template"
|
|
20
20
|
require_relative "vnet_config"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
require_relative "rest/environments"
|
|
22
|
+
require_relative "rest/errors"
|
|
23
|
+
require_relative "rest/token_provider"
|
|
24
|
+
require_relative "rest/http"
|
|
25
|
+
require_relative "rest/arm_client"
|
|
25
26
|
|
|
26
27
|
module Azure
|
|
27
28
|
class ResourceManagement
|
|
@@ -29,60 +30,23 @@ module Azure
|
|
|
29
30
|
include Azure::ARM::ARMDeploymentTemplate
|
|
30
31
|
include Azure::ARM::VnetConfig
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
include Azure::Compute::Mgmt::V2018_06_01
|
|
36
|
-
include Azure::Compute::Mgmt::V2018_06_01::Models
|
|
37
|
-
|
|
38
|
-
include Azure::Storage::Mgmt::V2018_07_01
|
|
39
|
-
include Azure::Storage::Mgmt::V2018_07_01::Models
|
|
40
|
-
|
|
41
|
-
include Azure::Network::Mgmt::V2018_08_01
|
|
42
|
-
include Azure::Network::Mgmt::V2018_08_01::Models
|
|
33
|
+
# Backwards-compatible alias so existing rescue clauses and consumers can
|
|
34
|
+
# keep referring to a single error type for Azure API failures.
|
|
35
|
+
OperationError = Azure::ResourceManagement::Rest::OperationError
|
|
43
36
|
|
|
44
37
|
attr_accessor :connection
|
|
45
38
|
|
|
46
39
|
def initialize(params = {})
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
else
|
|
50
|
-
MsRest::StringTokenProvider.new(params[:token], params[:tokentype])
|
|
51
|
-
end
|
|
52
|
-
@credentials = MsRest::TokenCredentials.new(token_provider)
|
|
40
|
+
@environment = Azure::ResourceManagement::Rest::Environments.from_name(params[:azure_environment])
|
|
41
|
+
@token_provider = Azure::ResourceManagement::Rest::TokenProvider.new(params, @environment)
|
|
53
42
|
@azure_subscription_id = params[:azure_subscription_id]
|
|
54
43
|
super
|
|
55
44
|
end
|
|
56
45
|
|
|
57
|
-
def
|
|
58
|
-
@
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
resource_management_client
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def compute_management_client
|
|
66
|
-
@compute_management_client ||= begin
|
|
67
|
-
compute_management_client = ComputeManagementClient.new(@credentials)
|
|
68
|
-
compute_management_client.subscription_id = @azure_subscription_id
|
|
69
|
-
compute_management_client
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def storage_management_client
|
|
74
|
-
@storage_management_client ||= begin
|
|
75
|
-
storage_management_client = StorageManagementClient.new(@credentials)
|
|
76
|
-
storage_management_client.subscription_id = @azure_subscription_id
|
|
77
|
-
storage_management_client
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def network_resource_client
|
|
82
|
-
@network_resource_client ||= begin
|
|
83
|
-
network_resource_client = NetworkManagementClient.new(@credentials)
|
|
84
|
-
network_resource_client.subscription_id = @azure_subscription_id
|
|
85
|
-
network_resource_client
|
|
46
|
+
def arm_client
|
|
47
|
+
@arm_client ||= begin
|
|
48
|
+
http = Azure::ResourceManagement::Rest::Http.new(@token_provider, environment: @environment)
|
|
49
|
+
Azure::ResourceManagement::Rest::ArmClient.new(@azure_subscription_id, http, @environment)
|
|
86
50
|
end
|
|
87
51
|
end
|
|
88
52
|
|
|
@@ -90,9 +54,9 @@ module Azure
|
|
|
90
54
|
|
|
91
55
|
def list_servers(resource_group_name = nil)
|
|
92
56
|
servers = if resource_group_name.nil?
|
|
93
|
-
|
|
57
|
+
arm_client.list_all_virtual_machines
|
|
94
58
|
else
|
|
95
|
-
|
|
59
|
+
arm_client.list_virtual_machines(resource_group_name)
|
|
96
60
|
end
|
|
97
61
|
|
|
98
62
|
cols = ["VM Name", "Resource Group Name", "Location", "Provisioning State", "OS Type"]
|
|
@@ -119,7 +83,7 @@ module Azure
|
|
|
119
83
|
end
|
|
120
84
|
|
|
121
85
|
def delete_server(resource_group_name, vm_name)
|
|
122
|
-
server =
|
|
86
|
+
server = arm_client.get_virtual_machine(resource_group_name, vm_name)
|
|
123
87
|
if server && server.name == vm_name
|
|
124
88
|
puts "\n\n"
|
|
125
89
|
msg_pair(ui, "VM Name", server.name)
|
|
@@ -136,9 +100,7 @@ module Azure
|
|
|
136
100
|
|
|
137
101
|
ui.info "Deleting .."
|
|
138
102
|
|
|
139
|
-
|
|
140
|
-
server_detail = compute_management_client.virtual_machines.delete(resource_group_name, vm_name)
|
|
141
|
-
end until server_detail.nil?
|
|
103
|
+
arm_client.delete_virtual_machine(resource_group_name, vm_name)
|
|
142
104
|
|
|
143
105
|
puts "\n"
|
|
144
106
|
ui.warn "Deleted server #{vm_name}"
|
|
@@ -149,13 +111,13 @@ module Azure
|
|
|
149
111
|
server = find_server(resource_group, name)
|
|
150
112
|
if server
|
|
151
113
|
network_interface_name = server.network_profile.network_interfaces[0].id.split("/")[-1]
|
|
152
|
-
network_interface_data =
|
|
114
|
+
network_interface_data = arm_client.get_network_interface(resource_group, network_interface_name)
|
|
153
115
|
public_ip_id_data = network_interface_data.ip_configurations[0].public_ipaddress
|
|
154
116
|
if public_ip_id_data.nil?
|
|
155
117
|
public_ip_data = nil
|
|
156
118
|
else
|
|
157
119
|
public_ip_name = public_ip_id_data.id.split("/")[-1]
|
|
158
|
-
public_ip_data =
|
|
120
|
+
public_ip_data = arm_client.get_public_ip_address(resource_group, public_ip_name)
|
|
159
121
|
end
|
|
160
122
|
|
|
161
123
|
details = []
|
|
@@ -205,13 +167,13 @@ module Azure
|
|
|
205
167
|
end
|
|
206
168
|
|
|
207
169
|
def find_server(resource_group, name)
|
|
208
|
-
|
|
170
|
+
arm_client.get_virtual_machine(resource_group, name)
|
|
209
171
|
end
|
|
210
172
|
|
|
211
173
|
def virtual_machine_exist?(resource_group_name, vm_name)
|
|
212
|
-
|
|
174
|
+
arm_client.get_virtual_machine(resource_group_name, vm_name)
|
|
213
175
|
true
|
|
214
|
-
rescue
|
|
176
|
+
rescue OperationError => e
|
|
215
177
|
if e.body
|
|
216
178
|
err_json = JSON.parse(e.response.body)
|
|
217
179
|
if err_json["error"]["code"] == "ResourceNotFound"
|
|
@@ -223,9 +185,9 @@ module Azure
|
|
|
223
185
|
end
|
|
224
186
|
|
|
225
187
|
def security_group_exist?(resource_group_name, security_group_name)
|
|
226
|
-
|
|
188
|
+
arm_client.get_network_security_group(resource_group_name, security_group_name)
|
|
227
189
|
true
|
|
228
|
-
rescue
|
|
190
|
+
rescue OperationError => e
|
|
229
191
|
if e.body
|
|
230
192
|
err_json = JSON.parse(e.response.body)
|
|
231
193
|
if err_json["error"]["code"] == "ResourceNotFound"
|
|
@@ -236,8 +198,30 @@ module Azure
|
|
|
236
198
|
end
|
|
237
199
|
end
|
|
238
200
|
|
|
201
|
+
# Returns the sku name (e.g. "Aligned") of an existing availability set, nil if it
|
|
202
|
+
# exists but is a legacy "Classic" set (which has no sku property at all), or the
|
|
203
|
+
# :not_found symbol if it doesn't exist yet. Used to detect the case where a caller
|
|
204
|
+
# reuses an existing Classic availability set name: since Azure availability set
|
|
205
|
+
# SKUs are immutable once created, redeploying it as "Aligned" (required for managed
|
|
206
|
+
# disks) would fail remotely with a cryptic ARM error instead of the actionable one
|
|
207
|
+
# raised in validate_params!.
|
|
208
|
+
def existing_availability_set_sku(resource_group_name, availability_set_name)
|
|
209
|
+
availability_set = arm_client.get_availability_set(resource_group_name, availability_set_name)
|
|
210
|
+
availability_set.sku && availability_set.sku.name
|
|
211
|
+
rescue OperationError => e
|
|
212
|
+
if e.body
|
|
213
|
+
err_json = JSON.parse(e.response.body)
|
|
214
|
+
# ResourceNotFound: the resource group exists but the availability set doesn't.
|
|
215
|
+
# ResourceGroupNotFound: the resource group itself doesn't exist yet (e.g. when
|
|
216
|
+
# creating a VM + availability set together in a brand-new resource group).
|
|
217
|
+
# Both mean "no existing availability set to conflict with".
|
|
218
|
+
return :not_found if %w{ResourceNotFound ResourceGroupNotFound}.include?(err_json["error"]["code"])
|
|
219
|
+
end
|
|
220
|
+
raise e
|
|
221
|
+
end
|
|
222
|
+
|
|
239
223
|
def resource_group_exist?(resource_group_name)
|
|
240
|
-
|
|
224
|
+
arm_client.resource_group_exist?(resource_group_name)
|
|
241
225
|
end
|
|
242
226
|
|
|
243
227
|
def platform(image_reference)
|
|
@@ -256,7 +240,7 @@ module Azure
|
|
|
256
240
|
end
|
|
257
241
|
|
|
258
242
|
def fetch_substatus(resource_group_name, virtual_machine_name, chef_extension_name)
|
|
259
|
-
substatuses =
|
|
243
|
+
substatuses = arm_client.get_vm_extension(
|
|
260
244
|
resource_group_name,
|
|
261
245
|
virtual_machine_name,
|
|
262
246
|
chef_extension_name,
|
|
@@ -381,27 +365,12 @@ module Azure
|
|
|
381
365
|
end
|
|
382
366
|
end
|
|
383
367
|
|
|
384
|
-
def vm_public_ip(params = {})
|
|
385
|
-
network_resource_client.public_ipaddresses.get(
|
|
386
|
-
params[:azure_resource_group_name],
|
|
387
|
-
params[:azure_vm_name]
|
|
388
|
-
).value!.body.properties.ip_address
|
|
389
|
-
end
|
|
390
|
-
|
|
391
|
-
def vm_default_port(params = {})
|
|
392
|
-
network_resource_client.network_security_groups.get(
|
|
393
|
-
params[:azure_resource_group_name],
|
|
394
|
-
params[:azure_vm_name]
|
|
395
|
-
).value!.body.properties.security_rules[0].properties.destination_port_range
|
|
396
|
-
end
|
|
397
|
-
|
|
398
368
|
def create_resource_group(params = {})
|
|
399
|
-
resource_group = ResourceGroup.new
|
|
400
|
-
resource_group.name = params[:azure_resource_group_name]
|
|
401
|
-
resource_group.location = params[:azure_service_location]
|
|
402
|
-
|
|
403
369
|
begin
|
|
404
|
-
resource_group =
|
|
370
|
+
resource_group = arm_client.create_resource_group(
|
|
371
|
+
params[:azure_resource_group_name],
|
|
372
|
+
params[:azure_service_location]
|
|
373
|
+
)
|
|
405
374
|
rescue Exception => e
|
|
406
375
|
Chef::Log.error("Failed to create the Resource Group -- exception being rescued: #{e}")
|
|
407
376
|
common_arm_rescue_block(e)
|
|
@@ -414,33 +383,38 @@ module Azure
|
|
|
414
383
|
template = create_deployment_template(params)
|
|
415
384
|
parameters = create_deployment_parameters(params)
|
|
416
385
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
386
|
+
deployment_body = {
|
|
387
|
+
"properties" => {
|
|
388
|
+
"template" => template,
|
|
389
|
+
"parameters" => parameters,
|
|
390
|
+
"mode" => "Incremental",
|
|
391
|
+
},
|
|
392
|
+
}
|
|
424
393
|
|
|
425
|
-
|
|
394
|
+
arm_client.create_deployment(params[:azure_resource_group_name], "#{params[:azure_vm_name]}_deploy", deployment_body)
|
|
426
395
|
end
|
|
427
396
|
|
|
428
397
|
def create_vm_extension(params)
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
398
|
+
extension_name = params[:chef_extension]
|
|
399
|
+
extension_body = {
|
|
400
|
+
"name" => extension_name,
|
|
401
|
+
"location" => params[:azure_service_location],
|
|
402
|
+
"properties" => {
|
|
403
|
+
"publisher" => params[:chef_extension_publisher],
|
|
404
|
+
"type" => extension_name,
|
|
405
|
+
"typeHandlerVersion" => params[:chef_extension_version].nil? ? get_latest_chef_extension_version(params) : params[:chef_extension_version],
|
|
406
|
+
"autoUpgradeMinorVersion" => false,
|
|
407
|
+
"settings" => params[:chef_extension_public_param],
|
|
408
|
+
"protectedSettings" => params[:chef_extension_private_param],
|
|
409
|
+
},
|
|
410
|
+
}
|
|
411
|
+
|
|
438
412
|
begin
|
|
439
|
-
vm_extension =
|
|
413
|
+
vm_extension = arm_client.create_vm_extension(
|
|
440
414
|
params[:azure_resource_group_name],
|
|
441
415
|
params[:azure_vm_name],
|
|
442
|
-
|
|
443
|
-
|
|
416
|
+
extension_name,
|
|
417
|
+
extension_body
|
|
444
418
|
)
|
|
445
419
|
rescue Exception => e
|
|
446
420
|
Chef::Log.error("Failed to create the Virtual Machine Extension -- exception being rescued.")
|
|
@@ -453,14 +427,21 @@ module Azure
|
|
|
453
427
|
def extension_already_installed?(server)
|
|
454
428
|
if server.resources
|
|
455
429
|
server.resources.each do |extension|
|
|
456
|
-
|
|
430
|
+
# Azure returns the extension handler name (ChefClient/LinuxChefClient)
|
|
431
|
+
# as the nested properties.type field, not a top-level
|
|
432
|
+
# virtual_machine_extension_type attribute -- that name was an
|
|
433
|
+
# artifact of the retired azure_mgmt_compute SDK's generated
|
|
434
|
+
# model, which doesn't exist on the raw ARM JSON this REST
|
|
435
|
+
# client wraps.
|
|
436
|
+
extension_type = extension.properties && extension.properties.type
|
|
437
|
+
return true if extension_type == "ChefClient" || extension_type == "LinuxChefClient"
|
|
457
438
|
end
|
|
458
439
|
end
|
|
459
440
|
false
|
|
460
441
|
end
|
|
461
442
|
|
|
462
443
|
def get_latest_chef_extension_version(params)
|
|
463
|
-
ext_version =
|
|
444
|
+
ext_version = arm_client.list_vm_extension_versions(
|
|
464
445
|
params[:azure_service_location],
|
|
465
446
|
params[:chef_extension_publisher],
|
|
466
447
|
params[:chef_extension]
|
|
@@ -472,24 +453,39 @@ module Azure
|
|
|
472
453
|
def delete_resource_group(resource_group_name)
|
|
473
454
|
ui.info "Resource group deletion takes some time. Please wait ..."
|
|
474
455
|
|
|
475
|
-
|
|
476
|
-
server = resource_management_client.resource_groups.delete(resource_group_name)
|
|
477
|
-
end until server.nil?
|
|
456
|
+
arm_client.delete_resource_group(resource_group_name)
|
|
478
457
|
puts "\n"
|
|
479
458
|
end
|
|
480
459
|
|
|
481
460
|
def common_arm_rescue_block(error)
|
|
482
|
-
if error.
|
|
483
|
-
err_json =
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
461
|
+
if error.is_a?(OperationError) && error.body
|
|
462
|
+
err_json = begin
|
|
463
|
+
JSON.parse(error.response.body)
|
|
464
|
+
rescue JSON::ParserError, TypeError
|
|
465
|
+
nil
|
|
466
|
+
end
|
|
467
|
+
unless err_json.is_a?(Hash)
|
|
468
|
+
ui.error(error.message)
|
|
469
|
+
Chef::Log.debug(error.response.body)
|
|
470
|
+
return
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
arm_error = err_json["error"]
|
|
474
|
+
if arm_error.is_a?(Hash)
|
|
475
|
+
err_details = arm_error["details"]
|
|
476
|
+
if err_details
|
|
477
|
+
err_details.each do |err|
|
|
478
|
+
ui.error(JSON.parse(err["message"])["error"]["message"])
|
|
479
|
+
rescue JSON::ParserError => e
|
|
480
|
+
ui.error(err["message"])
|
|
481
|
+
end
|
|
482
|
+
else
|
|
483
|
+
ui.error(arm_error["message"])
|
|
490
484
|
end
|
|
491
485
|
else
|
|
492
|
-
|
|
486
|
+
# OAuth token endpoint errors are flat: the "error" value is a
|
|
487
|
+
# string code and the human-readable text is in "error_description".
|
|
488
|
+
ui.error(err_json["error_description"] || arm_error || error.message)
|
|
493
489
|
end
|
|
494
490
|
Chef::Log.debug(error.response.body)
|
|
495
491
|
else
|