knife-azure 1.6.0 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +201 -201
- data/README.md +37 -654
- data/lib/azure/resource_management/ARM_deployment_template.rb +87 -50
- data/lib/azure/resource_management/ARM_interface.rb +236 -516
- data/lib/azure/resource_management/vnet_config.rb +254 -0
- data/lib/azure/resource_management/windows_credentials.rb +109 -61
- data/lib/azure/service_management/ASM_interface.rb +17 -1
- data/lib/azure/service_management/certificate.rb +37 -13
- data/lib/azure/service_management/connection.rb +0 -0
- data/lib/azure/service_management/deploy.rb +0 -0
- data/lib/azure/service_management/disk.rb +0 -0
- data/lib/azure/service_management/host.rb +0 -0
- data/lib/azure/service_management/image.rb +0 -0
- data/lib/azure/service_management/rest.rb +0 -0
- data/lib/azure/service_management/role.rb +0 -0
- data/lib/azure/service_management/utility.rb +0 -0
- data/lib/chef/knife/azure_base.rb +100 -0
- data/lib/chef/knife/azure_image_list.rb +0 -0
- data/lib/chef/knife/azure_server_create.rb +0 -98
- data/lib/chef/knife/azure_server_delete.rb +0 -0
- data/lib/chef/knife/azure_server_list.rb +0 -0
- data/lib/chef/knife/azure_server_show.rb +0 -0
- data/lib/chef/knife/azurerm_base.rb +42 -9
- data/lib/chef/knife/azurerm_server_create.rb +31 -24
- data/lib/chef/knife/azurerm_server_delete.rb +1 -10
- data/lib/chef/knife/azurerm_server_list.rb +5 -1
- data/lib/chef/knife/azurerm_server_show.rb +5 -1
- data/lib/chef/knife/bootstrap/bootstrap_options.rb +12 -18
- data/lib/chef/knife/bootstrap/bootstrapper.rb +34 -15
- data/lib/chef/knife/bootstrap/common_bootstrap_options.rb +21 -24
- data/lib/chef/knife/bootstrap_azure.rb +58 -0
- data/lib/chef/knife/bootstrap_azurerm.rb +40 -50
- data/lib/knife-azure/version.rb +1 -1
- metadata +27 -12
@@ -36,6 +36,45 @@ module Azure::ARM
|
|
36
36
|
hints_json
|
37
37
|
end
|
38
38
|
|
39
|
+
def tcp_ports(tcp_ports, vm_name)
|
40
|
+
tcp_ports = tcp_ports.split(",")
|
41
|
+
sec_grp_json =
|
42
|
+
{
|
43
|
+
"apiVersion" => "[variables('apiVersion')]",
|
44
|
+
"type" => "Microsoft.Network/networkSecurityGroups",
|
45
|
+
"name" => "[variables('secgrpname')]",
|
46
|
+
"location" => "[resourceGroup().location]",
|
47
|
+
"properties" => {
|
48
|
+
"securityRules" => [
|
49
|
+
]
|
50
|
+
}
|
51
|
+
}
|
52
|
+
#Security Rule priority can be set between 100 and 4096
|
53
|
+
rule_no = 300
|
54
|
+
incremental=0
|
55
|
+
for port in tcp_ports
|
56
|
+
rule_no = rule_no + 2
|
57
|
+
sec_grp_json["properties"]["securityRules"].push(
|
58
|
+
{
|
59
|
+
"name" => vm_name + '_rule_' + incremental.to_s,
|
60
|
+
"properties"=> {
|
61
|
+
"description" => "Port Provided by user",
|
62
|
+
"protocol" => "Tcp",
|
63
|
+
"sourcePortRange" => "*",
|
64
|
+
"destinationPortRange" => port,
|
65
|
+
"sourceAddressPrefix" => "*",
|
66
|
+
"destinationAddressPrefix" => "*",
|
67
|
+
"access" => "Allow",
|
68
|
+
"priority" => rule_no,
|
69
|
+
"direction" => "Inbound"
|
70
|
+
}
|
71
|
+
}
|
72
|
+
)
|
73
|
+
incremental=incremental+1
|
74
|
+
end
|
75
|
+
sec_grp_json
|
76
|
+
end
|
77
|
+
|
39
78
|
def create_deployment_template(params)
|
40
79
|
if params[:chef_extension_public_param][:bootstrap_options][:chef_node_name]
|
41
80
|
chef_node_name = "[concat(parameters('chef_node_name'),copyIndex())]"
|
@@ -62,6 +101,7 @@ module Azure::ARM
|
|
62
101
|
# Extension Variables
|
63
102
|
extName = "[concat(variables('vmName'),copyIndex(),'/', variables('vmExtensionName'))]"
|
64
103
|
depExt = "[concat('Microsoft.Compute/virtualMachines/', variables('vmName'), copyIndex())]"
|
104
|
+
|
65
105
|
else
|
66
106
|
# publicIPAddresses Resource Variables
|
67
107
|
publicIPAddressName = "[variables('publicIPAddressName')]"
|
@@ -85,6 +125,11 @@ module Azure::ARM
|
|
85
125
|
depExt = "[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]"
|
86
126
|
end
|
87
127
|
|
128
|
+
# NetworkSecurityGroups Resource Variables
|
129
|
+
sec_grp_name = "[variables('secgrpname')]"
|
130
|
+
sec_grp = "[concat('Microsoft.Network/networkSecurityGroups/', variables('secgrpname'))]"
|
131
|
+
sec_grp_id = "[resourceId('Microsoft.Network/networkSecurityGroups/', variables('secgrpname'))]"
|
132
|
+
|
88
133
|
resource_ids = {}
|
89
134
|
hint_names = params[:chef_extension_public_param][:hints]
|
90
135
|
|
@@ -176,24 +221,6 @@ module Azure::ARM
|
|
176
221
|
"metadata"=> {
|
177
222
|
"description"=> "Optional Run List to Execute"
|
178
223
|
}
|
179
|
-
},
|
180
|
-
"autoUpdateClient" => {
|
181
|
-
"type" => "string",
|
182
|
-
"metadata" => {
|
183
|
-
"description" => "Optional Flag for auto update"
|
184
|
-
}
|
185
|
-
},
|
186
|
-
"deleteChefConfig" => {
|
187
|
-
"type" => "string",
|
188
|
-
"metadata" => {
|
189
|
-
"description" => "Optional Flag for deleteChefConfig"
|
190
|
-
}
|
191
|
-
},
|
192
|
-
"uninstallChefClient" => {
|
193
|
-
"type" => "string",
|
194
|
-
"metadata" => {
|
195
|
-
"description" => "Optional Flag for uninstallChefClient"
|
196
|
-
}
|
197
224
|
},
|
198
225
|
"chef_node_name" => {
|
199
226
|
"type" => "string",
|
@@ -270,16 +297,15 @@ module Azure::ARM
|
|
270
297
|
"imageOffer"=> "#{params[:azure_image_reference_offer]}",
|
271
298
|
"OSDiskName"=> "#{params[:azure_os_disk_name]}",
|
272
299
|
"nicName"=> "#{params[:azure_vm_name]}",
|
273
|
-
"addressPrefix"=> "10.0.0.0/16",
|
274
300
|
"subnetName"=> "#{params[:azure_vnet_subnet_name]}",
|
275
|
-
"subnetPrefix"=> "10.0.0.0/24",
|
276
301
|
"storageAccountType"=> "#{params[:azure_storage_account_type]}",
|
277
302
|
"publicIPAddressName"=> "#{params[:azure_vm_name]}",
|
278
303
|
"publicIPAddressType"=> "Dynamic",
|
279
304
|
"vmStorageAccountContainerName"=> "#{params[:azure_vm_name]}",
|
280
305
|
"vmName"=> "#{params[:azure_vm_name]}",
|
281
306
|
"vmSize"=> "#{params[:vm_size]}",
|
282
|
-
"virtualNetworkName"=> "#{params[:
|
307
|
+
"virtualNetworkName"=> "#{params[:vnet_config][:virtualNetworkName]}",
|
308
|
+
"secgrpname" => "#{params[:azure_sec_group_name]}",
|
283
309
|
"vnetID"=> "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
|
284
310
|
"subnetRef"=> "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]",
|
285
311
|
"apiVersion"=> "2015-06-15",
|
@@ -319,18 +345,9 @@ module Azure::ARM
|
|
319
345
|
"location"=> "[resourceGroup().location]",
|
320
346
|
"properties"=> {
|
321
347
|
"addressSpace"=> {
|
322
|
-
"addressPrefixes"=> [
|
323
|
-
"[variables('addressPrefix')]"
|
324
|
-
]
|
348
|
+
"addressPrefixes"=> params[:vnet_config][:addressPrefixes]
|
325
349
|
},
|
326
|
-
"subnets"=> [
|
327
|
-
{
|
328
|
-
"name"=> "[variables('subnetName')]",
|
329
|
-
"properties"=> {
|
330
|
-
"addressPrefix"=> "[variables('subnetPrefix')]"
|
331
|
-
}
|
332
|
-
}
|
333
|
-
]
|
350
|
+
"subnets"=> params[:vnet_config][:subnets]
|
334
351
|
}
|
335
352
|
},
|
336
353
|
{
|
@@ -440,6 +457,7 @@ module Azure::ARM
|
|
440
457
|
"publisher" => "#{params[:chef_extension_publisher]}",
|
441
458
|
"type" => "#{params[:chef_extension]}",
|
442
459
|
"typeHandlerVersion" => "#{params[:chef_extension_version]}",
|
460
|
+
"autoUpgradeMinorVersion" => "#{params[:auto_upgrade_minor_version]}",
|
443
461
|
"settings" => {
|
444
462
|
"bootstrap_options" => {
|
445
463
|
"chef_node_name" => chef_node_name,
|
@@ -448,13 +466,9 @@ module Azure::ARM
|
|
448
466
|
"bootstrap_version" => "[parameters('bootstrap_version')]",
|
449
467
|
"node_ssl_verify_mode" => "[parameters('node_ssl_verify_mode')]",
|
450
468
|
"node_verify_api_cert" => "[parameters('node_verify_api_cert')]",
|
451
|
-
"encrypted_data_bag_secret" => "[parameters('encrypted_data_bag_secret')]",
|
452
469
|
"bootstrap_proxy" => "[parameters('bootstrap_proxy')]"
|
453
470
|
},
|
454
471
|
"runlist" => "[parameters('runlist')]",
|
455
|
-
"autoUpdateClient" => "[parameters('autoUpdateClient')]",
|
456
|
-
"deleteChefConfig" => "[parameters('deleteChefConfig')]",
|
457
|
-
"uninstallChefClient" => "[parameters('uninstallChefClient')]",
|
458
472
|
"validation_key_format" => "[parameters('validation_key_format')]",
|
459
473
|
"hints" => hints_json,
|
460
474
|
"client_rb" => "[parameters('client_rb')]",
|
@@ -462,14 +476,46 @@ module Azure::ARM
|
|
462
476
|
},
|
463
477
|
"protectedSettings" => {
|
464
478
|
"validation_key" => "[parameters('validation_key')]",
|
465
|
-
"autoUpgradeMinorVersion" => "#{params[:auto_upgrade_minor_version]}",
|
466
479
|
"client_pem" => "[parameters('client_pem')]",
|
467
|
-
"chef_server_crt" => "[parameters('chef_server_crt')]"
|
480
|
+
"chef_server_crt" => "[parameters('chef_server_crt')]",
|
481
|
+
"encrypted_data_bag_secret" => "[parameters('encrypted_data_bag_secret')]"
|
468
482
|
}
|
469
483
|
}
|
470
484
|
}
|
471
485
|
]
|
472
486
|
}
|
487
|
+
|
488
|
+
if params[:tcp_endpoints]
|
489
|
+
sec_grp_json = tcp_ports(params[:tcp_endpoints], params[:azure_vm_name])
|
490
|
+
template['resources'].insert(1,sec_grp_json)
|
491
|
+
length = template['resources'].length.to_i - 1
|
492
|
+
for i in 0..length do
|
493
|
+
if template['resources'][i]['type'] == "Microsoft.Network/virtualNetworks"
|
494
|
+
template['resources'][i] = template['resources'][i].merge({"dependsOn" => [sec_grp]})
|
495
|
+
end
|
496
|
+
if template['resources'][i]['type'] == "Microsoft.Network/networkInterfaces"
|
497
|
+
template['resources'][i]['properties'] = template['resources'][i]['properties'].merge({"networkSecurityGroup" => {"id" => sec_grp_id}})
|
498
|
+
end
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
if params[:chef_extension_public_param][:extendedLogs] == "true"
|
503
|
+
template['resources'].each do |resource|
|
504
|
+
if resource['type'] == 'Microsoft.Compute/virtualMachines/extensions'
|
505
|
+
resource['properties']['settings']['extendedLogs'] = params[:chef_extension_public_param][:extendedLogs]
|
506
|
+
end
|
507
|
+
end
|
508
|
+
end
|
509
|
+
|
510
|
+
if params[:chef_extension_public_param][:chef_service_interval]
|
511
|
+
template['resources'].each do |resource|
|
512
|
+
if resource['type'] == 'Microsoft.Compute/virtualMachines/extensions'
|
513
|
+
resource['properties']['settings']['chef_service_interval'] = params[:chef_extension_public_param][:chef_service_interval]
|
514
|
+
end
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
template
|
473
519
|
end
|
474
520
|
|
475
521
|
def create_deployment_parameters(params, platform)
|
@@ -506,6 +552,9 @@ module Azure::ARM
|
|
506
552
|
"chef_server_crt" => {
|
507
553
|
"value" => "#{params[:chef_extension_private_param][:chef_server_crt]}"
|
508
554
|
},
|
555
|
+
"encrypted_data_bag_secret" => {
|
556
|
+
"value" => "#{params[:chef_extension_private_param][:encrypted_data_bag_secret]}"
|
557
|
+
},
|
509
558
|
"chef_server_url"=> {
|
510
559
|
"value" => "#{params[:chef_extension_public_param][:bootstrap_options][:chef_server_url]}"
|
511
560
|
},
|
@@ -518,24 +567,12 @@ module Azure::ARM
|
|
518
567
|
"node_verify_api_cert" => {
|
519
568
|
"value" => "#{params[:chef_extension_public_param][:bootstrap_options][:node_verify_api_cert]}"
|
520
569
|
},
|
521
|
-
"encrypted_data_bag_secret" => {
|
522
|
-
"value" => "#{params[:chef_extension_public_param][:bootstrap_options][:encrypted_data_bag_secret]}"
|
523
|
-
},
|
524
570
|
"bootstrap_proxy" => {
|
525
571
|
"value" => "#{params[:chef_extension_public_param][:bootstrap_options][:bootstrap_proxy]}"
|
526
572
|
},
|
527
573
|
"runlist" => {
|
528
574
|
"value" => "#{params[:chef_extension_public_param][:runlist]}"
|
529
575
|
},
|
530
|
-
"autoUpdateClient" => {
|
531
|
-
"value" => "#{params[:chef_extension_public_param][:autoUpdateClient]}"
|
532
|
-
},
|
533
|
-
"deleteChefConfig" => {
|
534
|
-
"value" => "#{params[:chef_extension_public_param][:deleteChefConfig]}"
|
535
|
-
},
|
536
|
-
"uninstallChefClient" => {
|
537
|
-
"value" => "#{params[:chef_extension_public_param][:uninstallChefClient]}"
|
538
|
-
},
|
539
576
|
"chef_node_name" => {
|
540
577
|
"value"=> "#{params[:chef_extension_public_param][:bootstrap_options][:chef_node_name]}"
|
541
578
|
},
|
@@ -16,6 +16,7 @@
|
|
16
16
|
require 'azure/azure_interface'
|
17
17
|
require 'azure/resource_management/ARM_base'
|
18
18
|
require 'azure/resource_management/ARM_deployment_template'
|
19
|
+
require 'azure/resource_management/vnet_config'
|
19
20
|
require 'azure_mgmt_resources'
|
20
21
|
require 'azure_mgmt_compute'
|
21
22
|
require 'azure_mgmt_storage'
|
@@ -26,6 +27,7 @@ module Azure
|
|
26
27
|
class ARMInterface < AzureInterface
|
27
28
|
include Azure::ARM::ARMBase
|
28
29
|
include Azure::ARM::ARMDeploymentTemplate
|
30
|
+
include Azure::ARM::VnetConfig
|
29
31
|
|
30
32
|
include Azure::ARM::Resources
|
31
33
|
include Azure::ARM::Resources::Models
|
@@ -88,59 +90,42 @@ module Azure
|
|
88
90
|
end
|
89
91
|
|
90
92
|
def list_servers(resource_group_name = nil)
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end
|
93
|
+
if resource_group_name.nil?
|
94
|
+
servers = compute_management_client.virtual_machines.list_all.value
|
95
|
+
else
|
96
|
+
servers = compute_management_client.virtual_machines.list(resource_group_name).value
|
97
|
+
end
|
97
98
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
rows
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
state
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
ui.color(state, :green)
|
115
|
-
else
|
116
|
-
ui.color(state, :yellow)
|
117
|
-
end
|
99
|
+
cols = ['VM Name', 'Resource Group Name', 'Location', 'Provisioning State', 'OS Type']
|
100
|
+
rows = []
|
101
|
+
|
102
|
+
servers.each do |server|
|
103
|
+
rows << server.name.to_s
|
104
|
+
rows << server.id.split('/')[4].downcase
|
105
|
+
rows << server.location.to_s
|
106
|
+
rows << begin
|
107
|
+
state = server.properties.provisioning_state.to_s.downcase
|
108
|
+
case state
|
109
|
+
when 'failed'
|
110
|
+
ui.color(state, :red)
|
111
|
+
when 'succeeded'
|
112
|
+
ui.color(state, :green)
|
113
|
+
else
|
114
|
+
ui.color(state, :yellow)
|
118
115
|
end
|
119
|
-
|
120
|
-
|
121
|
-
display_list(ui, cols, rows)
|
122
|
-
rescue => error
|
123
|
-
if error.class == MsRestAzure::AzureOperationError && error.body
|
124
|
-
if error.body['error']['code']
|
125
|
-
ui.error("#{error.body['error']['message']}")
|
126
|
-
else
|
127
|
-
ui.error(error.body)
|
128
|
-
end
|
129
|
-
else
|
130
|
-
ui.error("#{error.message}")
|
131
|
-
Chef::Log.debug("#{error.backtrace.join("\n")}")
|
132
|
-
end
|
133
|
-
exit
|
116
|
+
end
|
117
|
+
rows << server.properties.storage_profile.os_disk.os_type.to_s
|
134
118
|
end
|
119
|
+
display_list(ui, cols, rows)
|
135
120
|
end
|
136
121
|
|
137
122
|
def delete_server(resource_group_name, vm_name)
|
138
|
-
|
139
|
-
if
|
123
|
+
server = compute_management_client.virtual_machines.get(resource_group_name, vm_name)
|
124
|
+
if server && server.name == vm_name
|
140
125
|
puts "\n\n"
|
141
|
-
msg_pair(ui, 'VM Name',
|
142
|
-
msg_pair(ui, 'VM Size',
|
143
|
-
msg_pair(ui, 'VM OS',
|
126
|
+
msg_pair(ui, 'VM Name', server.name)
|
127
|
+
msg_pair(ui, 'VM Size', server.properties.hardware_profile.vm_size)
|
128
|
+
msg_pair(ui, 'VM OS', server.properties.storage_profile.os_disk.os_type)
|
144
129
|
puts "\n"
|
145
130
|
|
146
131
|
begin
|
@@ -153,9 +138,8 @@ module Azure
|
|
153
138
|
ui.info 'Deleting ..'
|
154
139
|
|
155
140
|
begin
|
156
|
-
|
157
|
-
|
158
|
-
end until promise.value!.body.nil?
|
141
|
+
server_detail = compute_management_client.virtual_machines.delete(resource_group_name, vm_name)
|
142
|
+
end until server_detail.value!.body.nil?
|
159
143
|
|
160
144
|
puts "\n"
|
161
145
|
ui.warn "Deleted server #{vm_name}"
|
@@ -163,90 +147,102 @@ module Azure
|
|
163
147
|
end
|
164
148
|
|
165
149
|
def show_server(name, resource_group)
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
end
|
178
|
-
|
179
|
-
details = Array.new
|
180
|
-
details << ui.color('Server Name', :bold, :cyan)
|
181
|
-
details << server.name
|
182
|
-
|
183
|
-
details << ui.color('Size', :bold, :cyan)
|
184
|
-
details << server.properties.hardware_profile.vm_size
|
150
|
+
server = find_server(resource_group, name)
|
151
|
+
if server
|
152
|
+
network_interface_name = server.properties.network_profile.network_interfaces[0].id.split('/')[-1]
|
153
|
+
network_interface_data = network_resource_client.network_interfaces.get(resource_group, network_interface_name)
|
154
|
+
public_ip_id_data = network_interface_data.properties.ip_configurations[0].properties.public_ipaddress
|
155
|
+
unless public_ip_id_data.nil?
|
156
|
+
public_ip_name = public_ip_id_data.id.split('/')[-1]
|
157
|
+
public_ip_data = network_resource_client.public_ipaddresses.get(resource_group, public_ip_name)
|
158
|
+
else
|
159
|
+
public_ip_data = nil
|
160
|
+
end
|
185
161
|
|
186
|
-
|
187
|
-
|
162
|
+
details = Array.new
|
163
|
+
details << ui.color('Server Name', :bold, :cyan)
|
164
|
+
details << server.name
|
188
165
|
|
189
|
-
|
190
|
-
|
166
|
+
details << ui.color('Size', :bold, :cyan)
|
167
|
+
details << server.properties.hardware_profile.vm_size
|
191
168
|
|
192
|
-
|
193
|
-
|
169
|
+
details << ui.color('Provisioning State', :bold, :cyan)
|
170
|
+
details << server.properties.provisioning_state
|
194
171
|
|
195
|
-
|
196
|
-
|
172
|
+
details << ui.color('Location', :bold, :cyan)
|
173
|
+
details << server.location
|
197
174
|
|
198
|
-
|
199
|
-
|
175
|
+
details << ui.color('Publisher', :bold, :cyan)
|
176
|
+
details << server.properties.storage_profile.image_reference.publisher
|
200
177
|
|
201
|
-
|
202
|
-
|
178
|
+
details << ui.color('Offer', :bold, :cyan)
|
179
|
+
details << server.properties.storage_profile.image_reference.offer
|
203
180
|
|
204
|
-
|
205
|
-
|
181
|
+
details << ui.color('Sku', :bold, :cyan)
|
182
|
+
details << server.properties.storage_profile.image_reference.sku
|
206
183
|
|
207
|
-
|
208
|
-
|
209
|
-
details << public_ip_data.properties.ip_address
|
210
|
-
else
|
211
|
-
details << ' -- '
|
212
|
-
end
|
184
|
+
details << ui.color('Version', :bold, :cyan)
|
185
|
+
details << server.properties.storage_profile.image_reference.version
|
213
186
|
|
214
|
-
|
215
|
-
|
216
|
-
details << public_ip_data.properties.dns_settings.fqdn
|
217
|
-
else
|
218
|
-
details << ' -- '
|
219
|
-
end
|
187
|
+
details << ui.color('OS Type', :bold, :cyan)
|
188
|
+
details << server.properties.storage_profile.os_disk.os_type
|
220
189
|
|
221
|
-
|
190
|
+
details << ui.color('Public IP address', :bold, :cyan)
|
191
|
+
unless public_ip_data.nil?
|
192
|
+
details << public_ip_data.properties.ip_address
|
193
|
+
else
|
194
|
+
details << ' -- '
|
222
195
|
end
|
223
|
-
rescue => error
|
224
|
-
puts "#{error.body["error"]["message"]}"
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
def find_server(resource_group, name)
|
229
|
-
begin
|
230
|
-
promise = compute_management_client.virtual_machines.get(resource_group, name)
|
231
|
-
result = promise.value!
|
232
196
|
|
233
|
-
|
234
|
-
|
197
|
+
details << ui.color('FQDN', :bold, :cyan)
|
198
|
+
unless public_ip_data.nil? or public_ip_data.properties.dns_settings.nil?
|
199
|
+
details << public_ip_data.properties.dns_settings.fqdn
|
235
200
|
else
|
236
|
-
|
201
|
+
details << ' -- '
|
237
202
|
end
|
238
|
-
|
239
|
-
ui.
|
203
|
+
|
204
|
+
puts ui.list(details, :columns_across, 2)
|
240
205
|
end
|
241
|
-
server
|
242
206
|
end
|
243
207
|
|
244
|
-
def
|
245
|
-
|
208
|
+
def find_server(resource_group, name)
|
209
|
+
compute_management_client.virtual_machines.get(resource_group, name)
|
246
210
|
end
|
247
211
|
|
212
|
+
def virtual_machine_exist?(resource_group_name, vm_name)
|
213
|
+
begin
|
214
|
+
compute_management_client.virtual_machines.get(resource_group_name, vm_name)
|
215
|
+
return true
|
216
|
+
rescue MsRestAzure::AzureOperationError => error
|
217
|
+
if error.body
|
218
|
+
err_json = JSON.parse(error.response.body)
|
219
|
+
if err_json['error']['code'] == "ResourceNotFound"
|
220
|
+
return false
|
221
|
+
else
|
222
|
+
raise error
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def security_group_exist?(resource_group_name, security_group_name)
|
229
|
+
begin
|
230
|
+
network_resource_client.network_security_groups.get(resource_group_name, security_group_name)
|
231
|
+
return true
|
232
|
+
rescue MsRestAzure::AzureOperationError => error
|
233
|
+
if error.body
|
234
|
+
err_json = JSON.parse(error.response.body)
|
235
|
+
if err_json['error']['code'] == "ResourceNotFound"
|
236
|
+
return false
|
237
|
+
else
|
238
|
+
raise error
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
248
244
|
def resource_group_exist?(resource_group_name)
|
249
|
-
resource_management_client.resource_groups.check_existence(resource_group_name)
|
245
|
+
resource_management_client.resource_groups.check_existence(resource_group_name)
|
250
246
|
end
|
251
247
|
|
252
248
|
def platform(image_reference)
|
@@ -260,6 +256,69 @@ module Azure
|
|
260
256
|
end
|
261
257
|
end
|
262
258
|
|
259
|
+
def parse_substatus_code(code, index)
|
260
|
+
code.split('/')[index]
|
261
|
+
end
|
262
|
+
|
263
|
+
def fetch_substatus(resource_group_name, virtual_machine_name, chef_extension_name)
|
264
|
+
substatuses = compute_management_client.virtual_machine_extensions.get(
|
265
|
+
resource_group_name,
|
266
|
+
virtual_machine_name,
|
267
|
+
chef_extension_name,
|
268
|
+
'instanceView'
|
269
|
+
).properties.instance_view.substatuses
|
270
|
+
|
271
|
+
return nil if substatuses.nil?
|
272
|
+
|
273
|
+
substatuses.each do |substatus|
|
274
|
+
if parse_substatus_code(substatus.code, 1) == 'Chef Client run logs'
|
275
|
+
return substatus
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
return nil
|
280
|
+
end
|
281
|
+
|
282
|
+
def fetch_chef_client_logs(resource_group_name, virtual_machine_name, chef_extension_name, fetch_process_start_time, fetch_process_wait_timeout = 30)
|
283
|
+
## fetch substatus field which contains the chef-client run logs ##
|
284
|
+
substatus = fetch_substatus(resource_group_name, virtual_machine_name, chef_extension_name)
|
285
|
+
|
286
|
+
unless substatus.nil?
|
287
|
+
## chef-client run logs becomes available ##
|
288
|
+
status = parse_substatus_code(substatus.code, 2)
|
289
|
+
message = substatus.message
|
290
|
+
|
291
|
+
puts "\n\n******** Please find the chef-client run details below ********\n\n"
|
292
|
+
print "----> chef-client run status: "
|
293
|
+
case status
|
294
|
+
when 'succeeded'
|
295
|
+
## chef-client run succeeded ##
|
296
|
+
color = :green
|
297
|
+
when 'failed'
|
298
|
+
## chef-client run failed ##
|
299
|
+
color = :red
|
300
|
+
when 'transitioning'
|
301
|
+
## chef-client run did not complete within maximum timeout of 30 minutes ##
|
302
|
+
## fetch whatever logs available under the chef-client.log file ##
|
303
|
+
color = :yellow
|
304
|
+
end
|
305
|
+
puts "#{ui.color(status, color, :bold)}"
|
306
|
+
puts "----> chef-client run logs: "
|
307
|
+
puts "\n#{message}\n" ## message field of substatus contains the chef-client run logs ##
|
308
|
+
else
|
309
|
+
## unavailability of the substatus field indicates that chef-client run is not completed yet on the server ##
|
310
|
+
fetch_process_wait_time = ((Time.now - fetch_process_start_time) / 60).round
|
311
|
+
if fetch_process_wait_time <= fetch_process_wait_timeout
|
312
|
+
print "#{ui.color('.', :bold)}"
|
313
|
+
sleep 30
|
314
|
+
fetch_chef_client_logs(resource_group_name, virtual_machine_name, chef_extension_name, fetch_process_start_time, fetch_process_wait_timeout)
|
315
|
+
else
|
316
|
+
## wait time exceeded 30 minutes timeout ##
|
317
|
+
ui.error "\nchef-client run logs could not be fetched since fetch process exceeded wait timeout of #{fetch_process_wait_timeout} minutes.\n"
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
263
322
|
def create_server(params = {})
|
264
323
|
platform(params[:azure_image_reference_offer])
|
265
324
|
# resource group creation
|
@@ -273,22 +332,50 @@ module Azure
|
|
273
332
|
Chef::Log.info("Resource Group name is: #{resource_group.name}")
|
274
333
|
Chef::Log.info("Resource Group ID is: #{resource_group.id}")
|
275
334
|
end
|
276
|
-
|
335
|
+
|
277
336
|
# virtual machine creation
|
278
337
|
if virtual_machine_exist?(params[:azure_resource_group_name], params[:azure_vm_name])
|
279
338
|
ui.log("INFO:Virtual Machine #{params[:azure_vm_name]} already exist under the Resource Group #{params[:azure_resource_group_name]}. Exiting for now.")
|
280
339
|
else
|
281
340
|
params[:chef_extension_version] = params[:chef_extension_version].nil? ? get_latest_chef_extension_version(params) : params[:chef_extension_version]
|
282
341
|
params[:vm_size] = get_vm_size(params[:azure_vm_size])
|
342
|
+
params[:vnet_config] = create_vnet_config(
|
343
|
+
params[:azure_resource_group_name],
|
344
|
+
params[:azure_vnet_name],
|
345
|
+
params[:azure_vnet_subnet_name]
|
346
|
+
)
|
347
|
+
if params[:tcp_endpoints]
|
348
|
+
if @platform == 'Windows'
|
349
|
+
params[:tcp_endpoints] = params[:tcp_endpoints] + ",3389"
|
350
|
+
else
|
351
|
+
params[:tcp_endpoints] = params[:tcp_endpoints] + ",22,16001"
|
352
|
+
end
|
353
|
+
random_no = rand(100..1000)
|
354
|
+
params[:azure_sec_group_name] = params[:azure_vm_name] + '_sec_grp_' + random_no.to_s
|
355
|
+
if security_group_exist?(params[:azure_resource_group_name], params[:azure_sec_group_name])
|
356
|
+
random_no = rand(100..1000)
|
357
|
+
params[:azure_sec_group_name] = params[:azure_vm_name] + '_sec_grp_' + random_no.to_s
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
283
361
|
ui.log("Creating Virtual Machine....")
|
284
362
|
deployment = create_virtual_machine_using_template(params)
|
285
363
|
ui.log("Virtual Machine creation successfull.") unless deployment.nil?
|
286
|
-
|
364
|
+
|
287
365
|
unless deployment.nil?
|
288
366
|
ui.log("Deployment name is: #{deployment.name}")
|
289
367
|
ui.log("Deployment ID is: #{deployment.id}")
|
290
368
|
deployment.properties.dependencies.each do |deploy|
|
291
369
|
if deploy.resource_type == "Microsoft.Compute/virtualMachines"
|
370
|
+
if params[:chef_extension_public_param][:extendedLogs] == "true"
|
371
|
+
print "\n\nWaiting for the first chef-client run on virtual machine #{deploy.resource_name}"
|
372
|
+
fetch_chef_client_logs(params[:azure_resource_group_name],
|
373
|
+
deploy.resource_name,
|
374
|
+
params[:chef_extension],
|
375
|
+
Time.now
|
376
|
+
)
|
377
|
+
end
|
378
|
+
|
292
379
|
ui.log("VM Details ...")
|
293
380
|
ui.log("-------------------------------")
|
294
381
|
ui.log("Virtual Machine name is: #{deploy.resource_name}")
|
@@ -300,32 +387,6 @@ module Azure
|
|
300
387
|
end
|
301
388
|
end
|
302
389
|
|
303
|
-
def vm_details(virtual_machine, vm_extension, params)
|
304
|
-
vm_details = OpenStruct.new
|
305
|
-
vm_details.publicipaddress = vm_public_ip(params)
|
306
|
-
|
307
|
-
if @platform == 'Windows'
|
308
|
-
vm_details.rdpport = vm_default_port(params)
|
309
|
-
else
|
310
|
-
vm_details.sshport = vm_default_port(params)
|
311
|
-
end
|
312
|
-
|
313
|
-
vm_details.id = virtual_machine.id
|
314
|
-
vm_details.name = virtual_machine.name
|
315
|
-
vm_details.locationname = params[:azure_service_location].gsub(/[ ]/,'').downcase
|
316
|
-
vm_details.ostype = virtual_machine.properties.storage_profile.os_disk.os_type
|
317
|
-
vm_details.provisioningstate = virtual_machine.properties.provisioning_state
|
318
|
-
vm_details.resources = OpenStruct.new
|
319
|
-
vm_details.resources.id = vm_extension.id
|
320
|
-
vm_details.resources.name = vm_extension.name
|
321
|
-
vm_details.resources.publisher = vm_extension.properties.publisher
|
322
|
-
vm_details.resources.type = vm_extension.properties.type
|
323
|
-
vm_details.resources.type_handler_version = vm_extension.properties.type_handler_version
|
324
|
-
vm_details.resources.provisioning_state = vm_extension.properties.provisioning_state
|
325
|
-
|
326
|
-
vm_details
|
327
|
-
end
|
328
|
-
|
329
390
|
def vm_public_ip(params = {})
|
330
391
|
network_resource_client.public_ipaddresses.get(
|
331
392
|
params[:azure_resource_group_name],
|
@@ -346,11 +407,10 @@ module Azure
|
|
346
407
|
resource_group.location = params[:azure_service_location]
|
347
408
|
|
348
409
|
begin
|
349
|
-
resource_group = resource_management_client.resource_groups.create_or_update(resource_group.name, resource_group)
|
410
|
+
resource_group = resource_management_client.resource_groups.create_or_update(resource_group.name, resource_group)
|
350
411
|
rescue Exception => e
|
351
412
|
Chef::Log.error("Failed to create the Resource Group -- exception being rescued: #{e.to_s}")
|
352
|
-
|
353
|
-
Chef::Log.debug("#{backtrace_message}")
|
413
|
+
common_arm_rescue_block(e)
|
354
414
|
end
|
355
415
|
|
356
416
|
resource_group
|
@@ -372,357 +432,6 @@ module Azure
|
|
372
432
|
deployment
|
373
433
|
end
|
374
434
|
|
375
|
-
def create_virtual_machine(params)
|
376
|
-
os_profile = OSProfile.new
|
377
|
-
os_profile.computer_name = params[:azure_vm_name]
|
378
|
-
os_profile.secrets = []
|
379
|
-
|
380
|
-
if @platform == 'Windows'
|
381
|
-
windows_config = WindowsConfiguration.new
|
382
|
-
windows_config.provision_vmagent = true
|
383
|
-
windows_config.enable_automatic_updates = true
|
384
|
-
|
385
|
-
os_profile.admin_username = params[:winrm_user]
|
386
|
-
os_profile.admin_password = params[:admin_password]
|
387
|
-
os_profile.windows_configuration = windows_config
|
388
|
-
else
|
389
|
-
linux_config = LinuxConfiguration.new
|
390
|
-
linux_config.disable_password_authentication = false
|
391
|
-
|
392
|
-
os_profile.admin_username = params[:ssh_user]
|
393
|
-
os_profile.admin_password = params[:ssh_password]
|
394
|
-
os_profile.linux_configuration = linux_config
|
395
|
-
end
|
396
|
-
|
397
|
-
hardware_profile = HardwareProfile.new
|
398
|
-
hardware_profile.vm_size = get_vm_size(params[:azure_vm_size])
|
399
|
-
|
400
|
-
vm_props = VirtualMachineProperties.new
|
401
|
-
vm_props.os_profile = os_profile
|
402
|
-
vm_props.hardware_profile = hardware_profile
|
403
|
-
vm_props.storage_profile = create_storage_profile(params)
|
404
|
-
vm_props.network_profile = create_network_profile(params)
|
405
|
-
|
406
|
-
vm_params = VirtualMachine.new
|
407
|
-
vm_params.name = params[:azure_vm_name]
|
408
|
-
vm_params.type = 'Microsoft.Compute/virtualMachines'
|
409
|
-
vm_params.properties = vm_props
|
410
|
-
vm_params.location = params[:azure_service_location]
|
411
|
-
|
412
|
-
begin
|
413
|
-
virtual_machine = compute_management_client.virtual_machines.create_or_update(params[:azure_resource_group_name], vm_params.name, vm_params).value!.body
|
414
|
-
rescue Exception => e
|
415
|
-
ui.log("Failed to create the virtual machine, use verbose mode for more details")
|
416
|
-
Chef::Log.error("Failed to create the Virtual Machine -- exception being rescued: #{e.to_s}")
|
417
|
-
backtrace_message = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
|
418
|
-
Chef::Log.debug("#{backtrace_message}")
|
419
|
-
end
|
420
|
-
|
421
|
-
virtual_machine
|
422
|
-
end
|
423
|
-
|
424
|
-
def create_storage_profile(params)
|
425
|
-
ui.log("Creating Storage Account.... \n\n ")
|
426
|
-
storage_account = create_storage_account(
|
427
|
-
params[:azure_storage_account],
|
428
|
-
params[:azure_service_location],
|
429
|
-
params[:azure_storage_account_type],
|
430
|
-
params[:azure_resource_group_name]
|
431
|
-
)
|
432
|
-
|
433
|
-
virtual_hard_disk = get_vhd(
|
434
|
-
params[:azure_storage_account],
|
435
|
-
params[:azure_os_disk_name]
|
436
|
-
)
|
437
|
-
|
438
|
-
ui.log("StorageAccount creation successfull.")
|
439
|
-
storage_profile = StorageProfile.new
|
440
|
-
storage_profile.image_reference = get_image_reference(
|
441
|
-
params[:azure_image_reference_publisher],
|
442
|
-
params[:azure_image_reference_offer],
|
443
|
-
params[:azure_image_reference_sku],
|
444
|
-
params[:azure_image_reference_version]
|
445
|
-
)
|
446
|
-
storage_profile.os_disk = get_os_disk(
|
447
|
-
virtual_hard_disk,
|
448
|
-
params[:azure_os_disk_name],
|
449
|
-
params[:azure_os_disk_caching],
|
450
|
-
params[:azure_os_disk_create_option]
|
451
|
-
)
|
452
|
-
|
453
|
-
storage_profile
|
454
|
-
end
|
455
|
-
|
456
|
-
def create_storage_account(storage_account_name, location, storage_account_type, resource_group_name)
|
457
|
-
storage_props = Azure::ARM::Storage::Models::StorageAccountPropertiesCreateParameters.new
|
458
|
-
storage_props.account_type = storage_account_type
|
459
|
-
|
460
|
-
storage_params = Azure::ARM::Storage::Models::StorageAccountCreateParameters.new
|
461
|
-
storage_params.location = location
|
462
|
-
storage_params.properties = storage_props
|
463
|
-
|
464
|
-
storage = storage_management_client.storage_accounts.create(resource_group_name, storage_account_name, storage_params).value!.body
|
465
|
-
storage
|
466
|
-
end
|
467
|
-
|
468
|
-
def get_vhd(storage_account_name, os_disk_name)
|
469
|
-
virtual_hard_disk = VirtualHardDisk.new
|
470
|
-
virtual_hard_disk.uri = "http://#{storage_account_name}.blob.core.windows.net/vhds/#{os_disk_name}.vhd"
|
471
|
-
virtual_hard_disk
|
472
|
-
end
|
473
|
-
|
474
|
-
def get_image_reference(publisher, offer, sku, version)
|
475
|
-
image_reference = ImageReference.new
|
476
|
-
image_reference.publisher = publisher
|
477
|
-
image_reference.offer = offer
|
478
|
-
image_reference.sku = sku
|
479
|
-
image_reference.version = version
|
480
|
-
image_reference
|
481
|
-
end
|
482
|
-
|
483
|
-
def get_os_disk(virtual_hard_disk, os_disk_name, os_disk_caching, os_disk_create_option)
|
484
|
-
os_disk = OSDisk.new
|
485
|
-
os_disk.name = os_disk_name
|
486
|
-
os_disk.vhd = virtual_hard_disk
|
487
|
-
os_disk.caching = os_disk_caching
|
488
|
-
os_disk.create_option = os_disk_create_option
|
489
|
-
os_disk
|
490
|
-
end
|
491
|
-
|
492
|
-
def vnet_exist?(resource_group_name, vnet_name)
|
493
|
-
begin
|
494
|
-
network_resource_client.virtual_networks.get(resource_group_name, vnet_name).value!.body
|
495
|
-
rescue
|
496
|
-
return false
|
497
|
-
end
|
498
|
-
end
|
499
|
-
|
500
|
-
def subnet_exist?(resource_group_name, vnet_name, subnet_name)
|
501
|
-
begin
|
502
|
-
network_resource_client.subnets.get(resource_group_name, vnet_name, subnet_name).value!.body
|
503
|
-
rescue
|
504
|
-
return false
|
505
|
-
end
|
506
|
-
end
|
507
|
-
|
508
|
-
def create_network_profile(params)
|
509
|
-
if vnet_exist?(params[:azure_resource_group_name], params[:azure_vnet_name])
|
510
|
-
vnet = network_resource_client.virtual_networks.get(params[:azure_resource_group_name], params[:azure_vnet_name]).value!.body
|
511
|
-
Chef::Log.info("Found existing vnet #{vnet.name}...")
|
512
|
-
else
|
513
|
-
ui.log("Creating VirtualNetwork....\n\n")
|
514
|
-
vnet = create_virtual_network(
|
515
|
-
params[:azure_resource_group_name],
|
516
|
-
params[:azure_vnet_name],
|
517
|
-
params[:azure_service_location]
|
518
|
-
)
|
519
|
-
Chef::Log.info("VirtualNetwork creation successfull.")
|
520
|
-
end
|
521
|
-
|
522
|
-
Chef::Log.info("Virtual Network name is: #{vnet.name}")
|
523
|
-
|
524
|
-
Chef::Log.info("Virtual Network ID is: #{vnet.id}")
|
525
|
-
|
526
|
-
if subnet_exist?(params[:azure_resource_group_name], vnet.name, params[:azure_vnet_subnet_name])
|
527
|
-
sbn = network_resource_client.subnets.get(params[:azure_resource_group_name], vnet.name, params[:azure_vnet_subnet_name]).value!.body
|
528
|
-
|
529
|
-
Chef::Log.info("Found subnet #{sbn.name} under virtual network #{vnet.name} ...")
|
530
|
-
|
531
|
-
else
|
532
|
-
ui.log("Creating Subnet....\n\n")
|
533
|
-
sbn = create_subnet(
|
534
|
-
params[:azure_resource_group_name],
|
535
|
-
params[:azure_vnet_subnet_name],
|
536
|
-
vnet
|
537
|
-
)
|
538
|
-
Chef::Log.info("Subnet creation successfull.")
|
539
|
-
end
|
540
|
-
|
541
|
-
Chef::Log.info("Subnet name is: #{sbn.name}")
|
542
|
-
Chef::Log.info("Subnet ID is: #{sbn.id}")
|
543
|
-
|
544
|
-
ui.log("Creating NetworkInterface....\n\n")
|
545
|
-
nic = create_network_interface(
|
546
|
-
params[:azure_resource_group_name],
|
547
|
-
params[:azure_vm_name],
|
548
|
-
params[:azure_service_location],
|
549
|
-
sbn
|
550
|
-
)
|
551
|
-
Chef::Log.info("NetworkInterface creation successfull.")
|
552
|
-
Chef::Log.info("Network Interface name is: #{nic.name}")
|
553
|
-
Chef::Log.info("Network Interface ID is: #{nic.id}")
|
554
|
-
|
555
|
-
network_profile = NetworkProfile.new
|
556
|
-
network_profile.network_interfaces = [nic]
|
557
|
-
network_profile
|
558
|
-
end
|
559
|
-
|
560
|
-
def create_virtual_network(resource_group_name, virtual_network_name, service_location)
|
561
|
-
address_space = AddressSpace.new
|
562
|
-
address_space.address_prefixes = ['10.0.0.0/16']
|
563
|
-
|
564
|
-
vnet_props = VirtualNetworkPropertiesFormat.new
|
565
|
-
vnet_props.address_space = address_space
|
566
|
-
|
567
|
-
vnet_params = VirtualNetwork.new
|
568
|
-
vnet_params.name = virtual_network_name
|
569
|
-
vnet_params.location = service_location
|
570
|
-
vnet_params.properties = vnet_props
|
571
|
-
|
572
|
-
begin
|
573
|
-
vnet = network_resource_client.virtual_networks.create_or_update(resource_group_name, vnet_params.name, vnet_params).value!.body
|
574
|
-
rescue Exception => e
|
575
|
-
Chef::Log.error("Failed to create the Virtual Network -- exception being rescued: #{e.to_s}")
|
576
|
-
backtrace_message = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
|
577
|
-
Chef::Log.debug("#{backtrace_message}")
|
578
|
-
end
|
579
|
-
vnet
|
580
|
-
end
|
581
|
-
|
582
|
-
def create_subnet(resource_group_name, subnet_name, virtual_network)
|
583
|
-
sbn_prop = SubnetPropertiesFormat.new
|
584
|
-
sbn_prop.address_prefix = '10.0.1.0/24'
|
585
|
-
|
586
|
-
sbn_params = Subnet.new
|
587
|
-
sbn_params.name = subnet_name
|
588
|
-
sbn_params.properties = sbn_prop
|
589
|
-
|
590
|
-
begin
|
591
|
-
sbn = network_resource_client.subnets.create_or_update(resource_group_name, virtual_network.name, sbn_params.name, sbn_params).value!.body
|
592
|
-
rescue Exception => e
|
593
|
-
Chef::Log.error("Failed to create the Subnet -- exception being rescued: #{e.to_s}")
|
594
|
-
backtrace_message = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
|
595
|
-
Chef::Log.debug("#{backtrace_message}")
|
596
|
-
end
|
597
|
-
sbn
|
598
|
-
end
|
599
|
-
|
600
|
-
def create_network_interface(resource_group_name, vm_name, service_location, subnet)
|
601
|
-
network_ip_configuration_properties = NetworkInterfaceIPConfigurationPropertiesFormat.new
|
602
|
-
network_ip_configuration_properties.private_ipallocation_method = 'Dynamic'
|
603
|
-
|
604
|
-
network_ip_configuration_properties.public_ipaddress = create_public_ip_config(
|
605
|
-
resource_group_name,
|
606
|
-
vm_name,
|
607
|
-
service_location
|
608
|
-
)
|
609
|
-
|
610
|
-
network_ip_configuration_properties.subnet = subnet
|
611
|
-
|
612
|
-
network_interface_ip_configuration = NetworkInterfaceIPConfiguration.new
|
613
|
-
network_interface_ip_configuration.properties = network_ip_configuration_properties
|
614
|
-
network_interface_ip_configuration.name = vm_name
|
615
|
-
|
616
|
-
network_interface_props_format = NetworkInterfacePropertiesFormat.new
|
617
|
-
network_interface_props_format.ip_configurations = [network_interface_ip_configuration]
|
618
|
-
network_interface_props_format.network_security_group = create_network_security_group(
|
619
|
-
resource_group_name,
|
620
|
-
vm_name,
|
621
|
-
service_location
|
622
|
-
)
|
623
|
-
|
624
|
-
network_interface = NetworkInterface.new
|
625
|
-
network_interface.location = service_location
|
626
|
-
network_interface.name = vm_name
|
627
|
-
network_interface.properties = network_interface_props_format
|
628
|
-
|
629
|
-
begin
|
630
|
-
nic = network_resource_client.network_interfaces.create_or_update(resource_group_name, network_interface.name, network_interface).value!.body
|
631
|
-
rescue Exception => e
|
632
|
-
Chef::Log.error("Failed to create the Network Interface -- exception being rescued: #{e.to_s}")
|
633
|
-
backtrace_message = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
|
634
|
-
Chef::Log.debug("#{backtrace_message}")
|
635
|
-
end
|
636
|
-
|
637
|
-
nic
|
638
|
-
end
|
639
|
-
|
640
|
-
def create_public_ip_config(resource_group_name, vm_name, service_location)
|
641
|
-
public_ip_props = PublicIPAddressPropertiesFormat.new
|
642
|
-
public_ip_props.public_ipallocation_method = 'Dynamic'
|
643
|
-
|
644
|
-
public_ip = PublicIPAddress.new
|
645
|
-
public_ip.name = vm_name
|
646
|
-
public_ip.location = service_location
|
647
|
-
public_ip.properties = public_ip_props
|
648
|
-
|
649
|
-
begin
|
650
|
-
public_ip_address = network_resource_client.public_ipaddresses.create_or_update(
|
651
|
-
resource_group_name,
|
652
|
-
public_ip.name,
|
653
|
-
public_ip
|
654
|
-
).value!.body
|
655
|
-
rescue Exception => e
|
656
|
-
Chef::Log.error("Failed to create the Public IP Address -- exception being rescued: #{e.to_s}")
|
657
|
-
backtrace_message = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
|
658
|
-
Chef::Log.debug("#{backtrace_message}")
|
659
|
-
end
|
660
|
-
|
661
|
-
public_ip_address
|
662
|
-
end
|
663
|
-
|
664
|
-
def create_network_security_group(resource_group_name, vm_name, service_location)
|
665
|
-
network_security_group_prop_format = NetworkSecurityGroupPropertiesFormat.new
|
666
|
-
network_security_group = NetworkSecurityGroup.new
|
667
|
-
network_security_group.name = vm_name
|
668
|
-
network_security_group.location = service_location
|
669
|
-
network_security_group.properties = network_security_group_prop_format
|
670
|
-
|
671
|
-
begin
|
672
|
-
nsg = network_resource_client.network_security_groups.create_or_update(
|
673
|
-
resource_group_name,
|
674
|
-
network_security_group.name,
|
675
|
-
network_security_group
|
676
|
-
).value!.body
|
677
|
-
rescue Exception => e
|
678
|
-
Chef::Log.error("Failed to create the Network Security Group -- exception being rescued: #{e.to_s}")
|
679
|
-
backtrace_message = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
|
680
|
-
Chef::Log.debug("#{backtrace_message}")
|
681
|
-
end
|
682
|
-
|
683
|
-
security_rules = []
|
684
|
-
if @platform == 'Windows'
|
685
|
-
security_rules << add_security_rule('3389', "RDP", 1000, resource_group_name, vm_name, network_security_group)
|
686
|
-
else
|
687
|
-
security_rules << add_security_rule("22", "SSH", 1000, resource_group_name, vm_name, network_security_group)
|
688
|
-
end
|
689
|
-
network_security_group_prop_format.default_security_rules = security_rules
|
690
|
-
|
691
|
-
nsg
|
692
|
-
end
|
693
|
-
|
694
|
-
def add_security_rule(port, description, priority, resource_group_name, vm_name, network_security_group)
|
695
|
-
security_rule_props = SecurityRulePropertiesFormat.new
|
696
|
-
security_rule_props.description = description
|
697
|
-
security_rule_props.destination_port_range = port
|
698
|
-
security_rule_props.protocol = "Tcp"
|
699
|
-
security_rule_props.source_port_range = "*"
|
700
|
-
security_rule_props.source_address_prefix = "*"
|
701
|
-
security_rule_props.destination_address_prefix = "*"
|
702
|
-
security_rule_props.access = "Allow"
|
703
|
-
security_rule_props.priority = priority
|
704
|
-
security_rule_props.direction = "Inbound"
|
705
|
-
|
706
|
-
security_rule = SecurityRule.new
|
707
|
-
security_rule.name = vm_name
|
708
|
-
security_rule.properties = security_rule_props
|
709
|
-
|
710
|
-
begin
|
711
|
-
security_rule = network_resource_client.security_rules.create_or_update(
|
712
|
-
resource_group_name,
|
713
|
-
network_security_group.name,
|
714
|
-
security_rule.name,
|
715
|
-
security_rule
|
716
|
-
).value!.body
|
717
|
-
rescue Exception => e
|
718
|
-
Chef::Log.error("Failed to create the Security Rule -- exception being rescued: #{e.to_s}")
|
719
|
-
backtrace_message = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
|
720
|
-
Chef::Log.debug("#{backtrace_message}")
|
721
|
-
end
|
722
|
-
|
723
|
-
security_rule
|
724
|
-
end
|
725
|
-
|
726
435
|
def create_vm_extension(params)
|
727
436
|
vm_ext_props = VirtualMachineExtensionProperties.new
|
728
437
|
vm_ext_props.publisher = params[:chef_extension_publisher]
|
@@ -731,12 +440,12 @@ module Azure
|
|
731
440
|
vm_ext_props.auto_upgrade_minor_version = false
|
732
441
|
vm_ext_props.settings = params[:chef_extension_public_param]
|
733
442
|
vm_ext_props.protected_settings = params[:chef_extension_private_param]
|
734
|
-
|
443
|
+
|
735
444
|
vm_ext = VirtualMachineExtension.new
|
736
445
|
vm_ext.name = params[:chef_extension]
|
737
446
|
vm_ext.location = params[:azure_service_location]
|
738
447
|
vm_ext.properties = vm_ext_props
|
739
|
-
|
448
|
+
|
740
449
|
begin
|
741
450
|
vm_extension = compute_management_client.virtual_machine_extensions.create_or_update(
|
742
451
|
params[:azure_resource_group_name],
|
@@ -744,22 +453,9 @@ module Azure
|
|
744
453
|
vm_ext.name,
|
745
454
|
vm_ext
|
746
455
|
).value!.body
|
747
|
-
rescue Exception =>
|
456
|
+
rescue Exception => error
|
748
457
|
Chef::Log.error("Failed to create the Virtual Machine Extension -- exception being rescued.")
|
749
|
-
|
750
|
-
if e.class == MsRestAzure::AzureOperationError && e.body
|
751
|
-
if e.body['error']['code'] == 'DeploymentFailed'
|
752
|
-
ui.error("#{error.body['error']['message']}")
|
753
|
-
else
|
754
|
-
ui.error(e.body)
|
755
|
-
end
|
756
|
-
else
|
757
|
-
ui.error("#{error.message}")
|
758
|
-
Chef::Log.debug("#{error.backtrace.join("\n")}")
|
759
|
-
end
|
760
|
-
|
761
|
-
backtrace_message = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
|
762
|
-
Chef::Log.debug("#{backtrace_message}")
|
458
|
+
common_arm_rescue_block(error)
|
763
459
|
end
|
764
460
|
|
765
461
|
vm_extension
|
@@ -776,7 +472,7 @@ module Azure
|
|
776
472
|
ext_version = compute_management_client.virtual_machine_extension_images.list_versions(
|
777
473
|
params[:azure_service_location],
|
778
474
|
params[:chef_extension_publisher],
|
779
|
-
params[:chef_extension]).
|
475
|
+
params[:chef_extension]).last.name
|
780
476
|
ext_version_split_values = ext_version.split(".")
|
781
477
|
ext_version = ext_version_split_values[0] + "." + ext_version_split_values[1]
|
782
478
|
ext_version
|
@@ -784,12 +480,36 @@ module Azure
|
|
784
480
|
|
785
481
|
def delete_resource_group(resource_group_name)
|
786
482
|
ui.info 'Resource group deletion takes some time. Please wait ...'
|
483
|
+
|
787
484
|
begin
|
788
|
-
|
789
|
-
|
790
|
-
end until promise.value!.body.nil?
|
485
|
+
server = resource_management_client.resource_groups.delete(resource_group_name)
|
486
|
+
end until server.value!.body.nil?
|
791
487
|
puts "\n"
|
792
488
|
end
|
489
|
+
|
490
|
+
def common_arm_rescue_block(error)
|
491
|
+
if error.class == MsRestAzure::AzureOperationError && error.body
|
492
|
+
err_json = JSON.parse(error.response.body)
|
493
|
+
err_details = err_json["error"]["details"] if err_json["error"]
|
494
|
+
if err_details
|
495
|
+
err_details.each do |err|
|
496
|
+
ui.error(JSON.parse(err["message"])["error"]["message"])
|
497
|
+
end
|
498
|
+
else
|
499
|
+
ui.error(err_json["error"]["message"])
|
500
|
+
end
|
501
|
+
Chef::Log.debug(error.response.body)
|
502
|
+
else
|
503
|
+
begin
|
504
|
+
JSON.parse(error.message)
|
505
|
+
Chef::Log.debug("#{error.message}")
|
506
|
+
rescue JSON::ParserError => e
|
507
|
+
ui.error("#{error.message}")
|
508
|
+
end
|
509
|
+
ui.error("Something went wrong. Please use -VV option for more details.")
|
510
|
+
Chef::Log.debug("#{error.backtrace.join("\n")}")
|
511
|
+
end
|
512
|
+
end
|
793
513
|
end
|
794
514
|
end
|
795
515
|
end
|