knife-azure 1.8.7 → 1.9.0
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 +79 -81
- data/lib/azure/custom_errors.rb +34 -35
- data/lib/azure/helpers.rb +43 -44
- data/lib/azure/resource_management/ARM_deployment_template.rb +679 -678
- data/lib/azure/resource_management/ARM_interface.rb +513 -515
- data/lib/azure/resource_management/vnet_config.rb +43 -43
- data/lib/azure/resource_management/windows_credentials.rb +181 -184
- data/lib/azure/service_management/ASM_interface.rb +309 -317
- data/lib/azure/service_management/ag.rb +16 -16
- data/lib/azure/service_management/certificate.rb +30 -31
- data/lib/azure/service_management/connection.rb +31 -31
- data/lib/azure/service_management/deploy.rb +40 -38
- data/lib/azure/service_management/disk.rb +14 -10
- data/lib/azure/service_management/host.rb +28 -24
- data/lib/azure/service_management/image.rb +23 -22
- data/lib/azure/service_management/loadbalancer.rb +12 -12
- data/lib/azure/service_management/rest.rb +20 -19
- data/lib/azure/service_management/role.rb +274 -273
- data/lib/azure/service_management/storageaccount.rb +29 -25
- data/lib/azure/service_management/utility.rb +6 -7
- data/lib/azure/service_management/vnet.rb +44 -44
- data/lib/chef/knife/azure_ag_create.rb +18 -18
- data/lib/chef/knife/azure_ag_list.rb +3 -3
- data/lib/chef/knife/azure_base.rb +56 -56
- data/lib/chef/knife/azure_image_list.rb +8 -10
- data/lib/chef/knife/azure_internal-lb_create.rb +15 -15
- data/lib/chef/knife/azure_internal-lb_list.rb +3 -3
- data/lib/chef/knife/azure_server_create.rb +49 -50
- data/lib/chef/knife/azure_server_delete.rb +22 -24
- data/lib/chef/knife/azure_server_list.rb +4 -4
- data/lib/chef/knife/azure_server_show.rb +5 -5
- data/lib/chef/knife/azure_vnet_create.rb +17 -17
- data/lib/chef/knife/azure_vnet_list.rb +3 -3
- data/lib/chef/knife/azurerm_base.rb +58 -60
- data/lib/chef/knife/azurerm_server_create.rb +23 -22
- data/lib/chef/knife/azurerm_server_delete.rb +30 -34
- data/lib/chef/knife/azurerm_server_list.rb +42 -42
- data/lib/chef/knife/azurerm_server_show.rb +1 -1
- data/lib/chef/knife/bootstrap/bootstrap_options.rb +7 -8
- data/lib/chef/knife/bootstrap/bootstrapper.rb +65 -65
- data/lib/chef/knife/bootstrap/common_bootstrap_options.rb +3 -4
- data/lib/chef/knife/bootstrap_azure.rb +13 -13
- data/lib/chef/knife/bootstrap_azurerm.rb +106 -106
- data/lib/knife-azure/version.rb +2 -2
- metadata +43 -76
- data/lib/azure/resource_management/ARM_base.rb +0 -29
@@ -1,515 +1,513 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
23
|
-
require
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
include Azure::ARM::ARMDeploymentTemplate
|
30
|
-
include Azure::ARM::VnetConfig
|
31
|
-
|
32
|
-
include Azure::
|
33
|
-
include Azure::
|
34
|
-
|
35
|
-
include Azure::
|
36
|
-
include Azure::
|
37
|
-
|
38
|
-
include Azure::
|
39
|
-
include Azure::
|
40
|
-
|
41
|
-
include Azure::
|
42
|
-
include Azure::
|
43
|
-
|
44
|
-
attr_accessor :connection
|
45
|
-
|
46
|
-
def initialize(params = {})
|
47
|
-
if params[:azure_client_secret]
|
48
|
-
token_provider = MsRestAzure::ApplicationTokenProvider.new(params[:azure_tenant_id], params[:azure_client_id], params[:azure_client_secret])
|
49
|
-
else
|
50
|
-
token_provider = MsRest::StringTokenProvider.new(params[:token],params[:tokentype])
|
51
|
-
end
|
52
|
-
@credentials = MsRest::TokenCredentials.new(token_provider)
|
53
|
-
@azure_subscription_id = params[:azure_subscription_id]
|
54
|
-
super
|
55
|
-
end
|
56
|
-
|
57
|
-
def resource_management_client
|
58
|
-
@resource_management_client ||= begin
|
59
|
-
resource_management_client = ResourceManagementClient.new(@credentials)
|
60
|
-
resource_management_client.subscription_id = @azure_subscription_id
|
61
|
-
resource_management_client
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def compute_management_client
|
66
|
-
@compute_management_client ||= begin
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def list_images
|
90
|
-
end
|
91
|
-
|
92
|
-
def list_servers(resource_group_name = nil)
|
93
|
-
if resource_group_name.nil?
|
94
|
-
servers = compute_management_client.virtual_machines.list_all
|
95
|
-
else
|
96
|
-
servers = compute_management_client.virtual_machines.list(resource_group_name)
|
97
|
-
end
|
98
|
-
|
99
|
-
cols = [
|
100
|
-
rows =
|
101
|
-
|
102
|
-
servers.each do |server|
|
103
|
-
rows << server.name.to_s
|
104
|
-
rows << server.id.split(
|
105
|
-
rows << server.location.to_s
|
106
|
-
rows << begin
|
107
|
-
state = server.provisioning_state.to_s.downcase
|
108
|
-
case state
|
109
|
-
when
|
110
|
-
ui.color(state, :red)
|
111
|
-
when
|
112
|
-
ui.color(state, :green)
|
113
|
-
else
|
114
|
-
ui.color(state, :yellow)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
rows << server.storage_profile.os_disk.os_type.to_s
|
118
|
-
end
|
119
|
-
display_list(ui, cols, rows)
|
120
|
-
end
|
121
|
-
|
122
|
-
def delete_server(resource_group_name, vm_name)
|
123
|
-
server = compute_management_client.virtual_machines.get(resource_group_name, vm_name)
|
124
|
-
if server && server.name == vm_name
|
125
|
-
puts "\n\n"
|
126
|
-
msg_pair(ui,
|
127
|
-
msg_pair(ui,
|
128
|
-
msg_pair(ui,
|
129
|
-
puts "\n"
|
130
|
-
|
131
|
-
begin
|
132
|
-
ui.confirm(
|
133
|
-
rescue SystemExit # Need to handle this as confirming with N/n raises SystemExit exception
|
134
|
-
server = nil # Cleanup is implicitly performed in other cloud plugins
|
135
|
-
exit!
|
136
|
-
end
|
137
|
-
|
138
|
-
ui.info
|
139
|
-
|
140
|
-
begin
|
141
|
-
server_detail = compute_management_client.virtual_machines.delete(resource_group_name, vm_name)
|
142
|
-
end until server_detail.nil?
|
143
|
-
|
144
|
-
puts "\n"
|
145
|
-
ui.warn "Deleted server #{vm_name}"
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def show_server(name, resource_group)
|
150
|
-
server = find_server(resource_group, name)
|
151
|
-
if server
|
152
|
-
network_interface_name = server.network_profile.network_interfaces[0].id.split(
|
153
|
-
network_interface_data = network_resource_client.network_interfaces.get(resource_group, network_interface_name)
|
154
|
-
public_ip_id_data = network_interface_data.ip_configurations[0].public_ipaddress
|
155
|
-
unless public_ip_id_data.nil?
|
156
|
-
public_ip_name = public_ip_id_data.id.split(
|
157
|
-
public_ip_data = network_resource_client.public_ipaddresses.get(resource_group, public_ip_name)
|
158
|
-
else
|
159
|
-
public_ip_data = nil
|
160
|
-
end
|
161
|
-
|
162
|
-
details = Array.new
|
163
|
-
details << ui.color(
|
164
|
-
details << server.name
|
165
|
-
|
166
|
-
details << ui.color(
|
167
|
-
details << server.hardware_profile.vm_size
|
168
|
-
|
169
|
-
details << ui.color(
|
170
|
-
details << server.provisioning_state
|
171
|
-
|
172
|
-
details << ui.color(
|
173
|
-
details << server.location
|
174
|
-
|
175
|
-
details << ui.color(
|
176
|
-
details << server.storage_profile.image_reference.publisher
|
177
|
-
|
178
|
-
details << ui.color(
|
179
|
-
details << server.storage_profile.image_reference.offer
|
180
|
-
|
181
|
-
details << ui.color(
|
182
|
-
details << server.storage_profile.image_reference.sku
|
183
|
-
|
184
|
-
details << ui.color(
|
185
|
-
details << server.storage_profile.image_reference.version
|
186
|
-
|
187
|
-
details << ui.color(
|
188
|
-
details << server.storage_profile.os_disk.os_type
|
189
|
-
|
190
|
-
details << ui.color(
|
191
|
-
unless public_ip_data.nil?
|
192
|
-
details << public_ip_data.ip_address
|
193
|
-
else
|
194
|
-
details <<
|
195
|
-
end
|
196
|
-
|
197
|
-
details << ui.color(
|
198
|
-
unless public_ip_data.nil?
|
199
|
-
details << public_ip_data.dns_settings.fqdn
|
200
|
-
else
|
201
|
-
details <<
|
202
|
-
end
|
203
|
-
|
204
|
-
puts ui.list(details, :columns_across, 2)
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
def find_server(resource_group, name)
|
209
|
-
compute_management_client.virtual_machines.get(resource_group, name)
|
210
|
-
end
|
211
|
-
|
212
|
-
def virtual_machine_exist?(resource_group_name, vm_name)
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
end
|
243
|
-
|
244
|
-
def
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
end
|
258
|
-
|
259
|
-
def
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
## chef-client
|
299
|
-
color = :
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
)
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
template =
|
421
|
-
parameters =
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
vm_ext =
|
437
|
-
vm_ext.
|
438
|
-
vm_ext.
|
439
|
-
vm_ext.
|
440
|
-
vm_ext.
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
params[:
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
ui.error(
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
end
|
515
|
-
end
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright 2018 Chef Software, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require "azure/azure_interface"
|
19
|
+
require "azure/resource_management/ARM_deployment_template"
|
20
|
+
require "azure/resource_management/vnet_config"
|
21
|
+
require "azure_mgmt_resources"
|
22
|
+
require "azure_mgmt_compute"
|
23
|
+
require "azure_mgmt_storage"
|
24
|
+
require "azure_mgmt_network"
|
25
|
+
|
26
|
+
module Azure
|
27
|
+
class ResourceManagement
|
28
|
+
class ARMInterface < AzureInterface
|
29
|
+
include Azure::ARM::ARMDeploymentTemplate
|
30
|
+
include Azure::ARM::VnetConfig
|
31
|
+
|
32
|
+
include Azure::Resources::Mgmt::V2018_05_01
|
33
|
+
include Azure::Resources::Mgmt::V2018_05_01::Models
|
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
|
43
|
+
|
44
|
+
attr_accessor :connection
|
45
|
+
|
46
|
+
def initialize(params = {})
|
47
|
+
if params[:azure_client_secret]
|
48
|
+
token_provider = MsRestAzure::ApplicationTokenProvider.new(params[:azure_tenant_id], params[:azure_client_id], params[:azure_client_secret])
|
49
|
+
else
|
50
|
+
token_provider = MsRest::StringTokenProvider.new(params[:token], params[:tokentype])
|
51
|
+
end
|
52
|
+
@credentials = MsRest::TokenCredentials.new(token_provider)
|
53
|
+
@azure_subscription_id = params[:azure_subscription_id]
|
54
|
+
super
|
55
|
+
end
|
56
|
+
|
57
|
+
def resource_management_client
|
58
|
+
@resource_management_client ||= begin
|
59
|
+
resource_management_client = ResourceManagementClient.new(@credentials)
|
60
|
+
resource_management_client.subscription_id = @azure_subscription_id
|
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
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def list_images
|
90
|
+
end
|
91
|
+
|
92
|
+
def list_servers(resource_group_name = nil)
|
93
|
+
if resource_group_name.nil?
|
94
|
+
servers = compute_management_client.virtual_machines.list_all
|
95
|
+
else
|
96
|
+
servers = compute_management_client.virtual_machines.list(resource_group_name)
|
97
|
+
end
|
98
|
+
|
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.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)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
rows << server.storage_profile.os_disk.os_type.to_s
|
118
|
+
end
|
119
|
+
display_list(ui, cols, rows)
|
120
|
+
end
|
121
|
+
|
122
|
+
def delete_server(resource_group_name, vm_name)
|
123
|
+
server = compute_management_client.virtual_machines.get(resource_group_name, vm_name)
|
124
|
+
if server && server.name == vm_name
|
125
|
+
puts "\n\n"
|
126
|
+
msg_pair(ui, "VM Name", server.name)
|
127
|
+
msg_pair(ui, "VM Size", server.hardware_profile.vm_size)
|
128
|
+
msg_pair(ui, "VM OS", server.storage_profile.os_disk.os_type)
|
129
|
+
puts "\n"
|
130
|
+
|
131
|
+
begin
|
132
|
+
ui.confirm("Do you really want to delete this server")
|
133
|
+
rescue SystemExit # Need to handle this as confirming with N/n raises SystemExit exception
|
134
|
+
server = nil # Cleanup is implicitly performed in other cloud plugins
|
135
|
+
exit!
|
136
|
+
end
|
137
|
+
|
138
|
+
ui.info "Deleting .."
|
139
|
+
|
140
|
+
begin
|
141
|
+
server_detail = compute_management_client.virtual_machines.delete(resource_group_name, vm_name)
|
142
|
+
end until server_detail.nil?
|
143
|
+
|
144
|
+
puts "\n"
|
145
|
+
ui.warn "Deleted server #{vm_name}"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def show_server(name, resource_group)
|
150
|
+
server = find_server(resource_group, name)
|
151
|
+
if server
|
152
|
+
network_interface_name = server.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.ip_configurations[0].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
|
161
|
+
|
162
|
+
details = Array.new
|
163
|
+
details << ui.color("Server Name", :bold, :cyan)
|
164
|
+
details << server.name
|
165
|
+
|
166
|
+
details << ui.color("Size", :bold, :cyan)
|
167
|
+
details << server.hardware_profile.vm_size
|
168
|
+
|
169
|
+
details << ui.color("Provisioning State", :bold, :cyan)
|
170
|
+
details << server.provisioning_state
|
171
|
+
|
172
|
+
details << ui.color("Location", :bold, :cyan)
|
173
|
+
details << server.location
|
174
|
+
|
175
|
+
details << ui.color("Publisher", :bold, :cyan)
|
176
|
+
details << server.storage_profile.image_reference.publisher
|
177
|
+
|
178
|
+
details << ui.color("Offer", :bold, :cyan)
|
179
|
+
details << server.storage_profile.image_reference.offer
|
180
|
+
|
181
|
+
details << ui.color("Sku", :bold, :cyan)
|
182
|
+
details << server.storage_profile.image_reference.sku
|
183
|
+
|
184
|
+
details << ui.color("Version", :bold, :cyan)
|
185
|
+
details << server.storage_profile.image_reference.version
|
186
|
+
|
187
|
+
details << ui.color("OS Type", :bold, :cyan)
|
188
|
+
details << server.storage_profile.os_disk.os_type
|
189
|
+
|
190
|
+
details << ui.color("Public IP address", :bold, :cyan)
|
191
|
+
unless public_ip_data.nil?
|
192
|
+
details << public_ip_data.ip_address
|
193
|
+
else
|
194
|
+
details << " -- "
|
195
|
+
end
|
196
|
+
|
197
|
+
details << ui.color("FQDN", :bold, :cyan)
|
198
|
+
unless public_ip_data.nil? || public_ip_data.dns_settings.nil?
|
199
|
+
details << public_ip_data.dns_settings.fqdn
|
200
|
+
else
|
201
|
+
details << " -- "
|
202
|
+
end
|
203
|
+
|
204
|
+
puts ui.list(details, :columns_across, 2)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def find_server(resource_group, name)
|
209
|
+
compute_management_client.virtual_machines.get(resource_group, name)
|
210
|
+
end
|
211
|
+
|
212
|
+
def virtual_machine_exist?(resource_group_name, vm_name)
|
213
|
+
compute_management_client.virtual_machines.get(resource_group_name, vm_name)
|
214
|
+
true
|
215
|
+
rescue MsRestAzure::AzureOperationError => error
|
216
|
+
if error.body
|
217
|
+
err_json = JSON.parse(error.response.body)
|
218
|
+
if err_json["error"]["code"] == "ResourceNotFound"
|
219
|
+
return false
|
220
|
+
else
|
221
|
+
raise error
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def security_group_exist?(resource_group_name, security_group_name)
|
227
|
+
network_resource_client.network_security_groups.get(resource_group_name, security_group_name)
|
228
|
+
true
|
229
|
+
rescue MsRestAzure::AzureOperationError => error
|
230
|
+
if error.body
|
231
|
+
err_json = JSON.parse(error.response.body)
|
232
|
+
if err_json["error"]["code"] == "ResourceNotFound"
|
233
|
+
return false
|
234
|
+
else
|
235
|
+
raise error
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def resource_group_exist?(resource_group_name)
|
241
|
+
resource_management_client.resource_groups.check_existence(resource_group_name)
|
242
|
+
end
|
243
|
+
|
244
|
+
def platform(image_reference)
|
245
|
+
@platform ||= begin
|
246
|
+
if image_reference =~ /WindowsServer.*/
|
247
|
+
platform = "Windows"
|
248
|
+
else
|
249
|
+
platform = "Linux"
|
250
|
+
end
|
251
|
+
platform
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def parse_substatus_code(code, index)
|
256
|
+
code.split("/")[index]
|
257
|
+
end
|
258
|
+
|
259
|
+
def fetch_substatus(resource_group_name, virtual_machine_name, chef_extension_name)
|
260
|
+
substatuses = compute_management_client.virtual_machine_extensions.get(
|
261
|
+
resource_group_name,
|
262
|
+
virtual_machine_name,
|
263
|
+
chef_extension_name,
|
264
|
+
expand: "instanceView"
|
265
|
+
).instance_view.substatuses
|
266
|
+
|
267
|
+
return nil if substatuses.nil?
|
268
|
+
|
269
|
+
substatuses.each do |substatus|
|
270
|
+
if parse_substatus_code(substatus.code, 1) == "Chef Client run logs"
|
271
|
+
return substatus
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
nil
|
276
|
+
end
|
277
|
+
|
278
|
+
def fetch_chef_client_logs(resource_group_name, virtual_machine_name, chef_extension_name, fetch_process_start_time, fetch_process_wait_timeout = 30)
|
279
|
+
## fetch substatus field which contains the chef-client run logs ##
|
280
|
+
substatus = fetch_substatus(resource_group_name, virtual_machine_name, chef_extension_name)
|
281
|
+
|
282
|
+
unless substatus.nil?
|
283
|
+
## chef-client run logs becomes available ##
|
284
|
+
status = parse_substatus_code(substatus.code, 2)
|
285
|
+
message = substatus.message
|
286
|
+
|
287
|
+
puts "\n\n******** Please find the chef-client run details below ********\n\n"
|
288
|
+
print "----> chef-client run status: "
|
289
|
+
case status
|
290
|
+
when "succeeded"
|
291
|
+
## chef-client run succeeded ##
|
292
|
+
color = :green
|
293
|
+
when "failed"
|
294
|
+
## chef-client run failed ##
|
295
|
+
color = :red
|
296
|
+
when "transitioning"
|
297
|
+
## chef-client run did not complete within maximum timeout of 30 minutes ##
|
298
|
+
## fetch whatever logs available under the chef-client.log file ##
|
299
|
+
color = :yellow
|
300
|
+
end
|
301
|
+
puts "#{ui.color(status, color, :bold)}"
|
302
|
+
puts "----> chef-client run logs: "
|
303
|
+
puts "\n#{message}\n" ## message field of substatus contains the chef-client run logs ##
|
304
|
+
else
|
305
|
+
## unavailability of the substatus field indicates that chef-client run is not completed yet on the server ##
|
306
|
+
fetch_process_wait_time = ((Time.now - fetch_process_start_time) / 60).round
|
307
|
+
if fetch_process_wait_time <= fetch_process_wait_timeout
|
308
|
+
print "#{ui.color('.', :bold)}"
|
309
|
+
sleep 30
|
310
|
+
fetch_chef_client_logs(resource_group_name, virtual_machine_name, chef_extension_name, fetch_process_start_time, fetch_process_wait_timeout)
|
311
|
+
else
|
312
|
+
## wait time exceeded 30 minutes timeout ##
|
313
|
+
ui.error "\nchef-client run logs could not be fetched since fetch process exceeded wait timeout of #{fetch_process_wait_timeout} minutes.\n"
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
def create_server(params = {})
|
319
|
+
platform(params[:azure_image_reference_offer])
|
320
|
+
# resource group creation
|
321
|
+
if resource_group_exist?(params[:azure_resource_group_name])
|
322
|
+
ui.log("INFO:Resource Group #{params[:azure_resource_group_name]} already exist. Skipping its creation.")
|
323
|
+
ui.log("INFO:Adding new VM #{params[:azure_vm_name]} to this resource group.")
|
324
|
+
else
|
325
|
+
ui.log("Creating ResourceGroup....\n\n")
|
326
|
+
resource_group = create_resource_group(params)
|
327
|
+
Chef::Log.info("ResourceGroup creation successfull.")
|
328
|
+
Chef::Log.info("Resource Group name is: #{resource_group.name}")
|
329
|
+
Chef::Log.info("Resource Group ID is: #{resource_group.id}")
|
330
|
+
end
|
331
|
+
|
332
|
+
# virtual machine creation
|
333
|
+
if virtual_machine_exist?(params[:azure_resource_group_name], params[:azure_vm_name])
|
334
|
+
ui.log("INFO:Virtual Machine #{params[:azure_vm_name]} already exist under the Resource Group #{params[:azure_resource_group_name]}. Exiting for now.")
|
335
|
+
else
|
336
|
+
params[:chef_extension_version] = params[:chef_extension_version].nil? ? get_latest_chef_extension_version(params) : params[:chef_extension_version]
|
337
|
+
params[:vm_size] = params[:azure_vm_size]
|
338
|
+
params[:vnet_config] = create_vnet_config(
|
339
|
+
params[:azure_resource_group_name],
|
340
|
+
params[:azure_vnet_name],
|
341
|
+
params[:azure_vnet_subnet_name]
|
342
|
+
)
|
343
|
+
if params[:tcp_endpoints]
|
344
|
+
if @platform == "Windows"
|
345
|
+
params[:tcp_endpoints] = params[:tcp_endpoints] + ",3389"
|
346
|
+
else
|
347
|
+
params[:tcp_endpoints] = params[:tcp_endpoints] + ",22,16001"
|
348
|
+
end
|
349
|
+
random_no = rand(100..1000)
|
350
|
+
params[:azure_sec_group_name] = params[:azure_vm_name] + "_sec_grp_" + random_no.to_s
|
351
|
+
if security_group_exist?(params[:azure_resource_group_name], params[:azure_sec_group_name])
|
352
|
+
random_no = rand(100..1000)
|
353
|
+
params[:azure_sec_group_name] = params[:azure_vm_name] + "_sec_grp_" + random_no.to_s
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
ui.log("Creating Virtual Machine....")
|
358
|
+
deployment = create_virtual_machine_using_template(params)
|
359
|
+
ui.log("Virtual Machine creation successfull.") unless deployment.nil?
|
360
|
+
|
361
|
+
unless deployment.nil?
|
362
|
+
ui.log("Deployment name is: #{deployment.name}")
|
363
|
+
ui.log("Deployment ID is: #{deployment.id}")
|
364
|
+
deployment.properties.dependencies.each do |deploy|
|
365
|
+
if deploy.resource_type == "Microsoft.Compute/virtualMachines"
|
366
|
+
if params[:chef_extension_public_param][:extendedLogs] == "true"
|
367
|
+
print "\n\nWaiting for the first chef-client run on virtual machine #{deploy.resource_name}"
|
368
|
+
fetch_chef_client_logs(params[:azure_resource_group_name],
|
369
|
+
deploy.resource_name,
|
370
|
+
params[:chef_extension],
|
371
|
+
Time.now
|
372
|
+
)
|
373
|
+
end
|
374
|
+
|
375
|
+
ui.log("VM Details ...")
|
376
|
+
ui.log("-------------------------------")
|
377
|
+
ui.log("Virtual Machine name is: #{deploy.resource_name}")
|
378
|
+
ui.log("Virtual Machine ID is: #{deploy.id}")
|
379
|
+
show_server(deploy.resource_name, params[:azure_resource_group_name])
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
def vm_public_ip(params = {})
|
387
|
+
network_resource_client.public_ipaddresses.get(
|
388
|
+
params[:azure_resource_group_name],
|
389
|
+
params[:azure_vm_name]
|
390
|
+
).value!.body.properties.ip_address
|
391
|
+
end
|
392
|
+
|
393
|
+
def vm_default_port(params = {})
|
394
|
+
network_resource_client.network_security_groups.get(
|
395
|
+
params[:azure_resource_group_name],
|
396
|
+
params[:azure_vm_name]
|
397
|
+
).value!.body.properties.security_rules[0].properties.destination_port_range
|
398
|
+
end
|
399
|
+
|
400
|
+
def create_resource_group(params = {})
|
401
|
+
resource_group = ResourceGroup.new()
|
402
|
+
resource_group.name = params[:azure_resource_group_name]
|
403
|
+
resource_group.location = params[:azure_service_location]
|
404
|
+
|
405
|
+
begin
|
406
|
+
resource_group = resource_management_client.resource_groups.create_or_update(resource_group.name, resource_group)
|
407
|
+
rescue Exception => e
|
408
|
+
Chef::Log.error("Failed to create the Resource Group -- exception being rescued: #{e}")
|
409
|
+
common_arm_rescue_block(e)
|
410
|
+
end
|
411
|
+
|
412
|
+
resource_group
|
413
|
+
end
|
414
|
+
|
415
|
+
def create_virtual_machine_using_template(params)
|
416
|
+
template = create_deployment_template(params)
|
417
|
+
parameters = create_deployment_parameters(params, @platform)
|
418
|
+
|
419
|
+
deploy_prop = DeploymentProperties.new
|
420
|
+
deploy_prop.template = template
|
421
|
+
deploy_prop.parameters = parameters
|
422
|
+
deploy_prop.mode = "Incremental"
|
423
|
+
|
424
|
+
deploy_params = Deployment.new
|
425
|
+
deploy_params.properties = deploy_prop
|
426
|
+
|
427
|
+
deployment = resource_management_client.deployments.create_or_update(params[:azure_resource_group_name], "#{params[:azure_vm_name]}_deploy", deploy_params)
|
428
|
+
deployment
|
429
|
+
end
|
430
|
+
|
431
|
+
def create_vm_extension(params)
|
432
|
+
vm_ext = VirtualMachineExtension.new
|
433
|
+
vm_ext.name = params[:chef_extension]
|
434
|
+
vm_ext.location = params[:azure_service_location]
|
435
|
+
vm_ext.publisher = params[:chef_extension_publisher]
|
436
|
+
vm_ext.virtual_machine_extension_type = params[:chef_extension]
|
437
|
+
vm_ext.type_handler_version = params[:chef_extension_version].nil? ? get_latest_chef_extension_version(params) : params[:chef_extension_version]
|
438
|
+
vm_ext.auto_upgrade_minor_version = false
|
439
|
+
vm_ext.settings = params[:chef_extension_public_param]
|
440
|
+
vm_ext.protected_settings = params[:chef_extension_private_param]
|
441
|
+
begin
|
442
|
+
vm_extension = compute_management_client.virtual_machine_extensions.create_or_update(
|
443
|
+
params[:azure_resource_group_name],
|
444
|
+
params[:azure_vm_name],
|
445
|
+
vm_ext.name,
|
446
|
+
vm_ext
|
447
|
+
)
|
448
|
+
rescue Exception => error
|
449
|
+
Chef::Log.error("Failed to create the Virtual Machine Extension -- exception being rescued.")
|
450
|
+
common_arm_rescue_block(error)
|
451
|
+
end
|
452
|
+
|
453
|
+
vm_extension
|
454
|
+
end
|
455
|
+
|
456
|
+
def extension_already_installed?(server)
|
457
|
+
if server.resources
|
458
|
+
server.resources.each do |extension|
|
459
|
+
return true if extension.virtual_machine_extension_type == "ChefClient" || extension.virtual_machine_extension_type == "LinuxChefClient"
|
460
|
+
end
|
461
|
+
end
|
462
|
+
false
|
463
|
+
end
|
464
|
+
|
465
|
+
def get_latest_chef_extension_version(params)
|
466
|
+
ext_version = compute_management_client.virtual_machine_extension_images.list_versions(
|
467
|
+
params[:azure_service_location],
|
468
|
+
params[:chef_extension_publisher],
|
469
|
+
params[:chef_extension]).last.name
|
470
|
+
ext_version_split_values = ext_version.split(".")
|
471
|
+
ext_version = ext_version_split_values[0] + "." + ext_version_split_values[1]
|
472
|
+
ext_version
|
473
|
+
end
|
474
|
+
|
475
|
+
def delete_resource_group(resource_group_name)
|
476
|
+
ui.info "Resource group deletion takes some time. Please wait ..."
|
477
|
+
|
478
|
+
begin
|
479
|
+
server = resource_management_client.resource_groups.delete(resource_group_name)
|
480
|
+
end until server.nil?
|
481
|
+
puts "\n"
|
482
|
+
end
|
483
|
+
|
484
|
+
def common_arm_rescue_block(error)
|
485
|
+
if error.class == MsRestAzure::AzureOperationError && error.body
|
486
|
+
err_json = JSON.parse(error.response.body)
|
487
|
+
err_details = err_json["error"]["details"] if err_json["error"]
|
488
|
+
if err_details
|
489
|
+
err_details.each do |err|
|
490
|
+
begin
|
491
|
+
ui.error(JSON.parse(err["message"])["error"]["message"])
|
492
|
+
rescue JSON::ParserError => e
|
493
|
+
ui.error(err["message"])
|
494
|
+
end
|
495
|
+
end
|
496
|
+
else
|
497
|
+
ui.error(err_json["error"]["message"])
|
498
|
+
end
|
499
|
+
Chef::Log.debug(error.response.body)
|
500
|
+
else
|
501
|
+
begin
|
502
|
+
JSON.parse(error.message)
|
503
|
+
Chef::Log.debug("#{error.message}")
|
504
|
+
rescue JSON::ParserError => e
|
505
|
+
ui.error("#{error.message}")
|
506
|
+
end
|
507
|
+
ui.error("Something went wrong. Please use -VV option for more details.")
|
508
|
+
Chef::Log.debug("#{error.backtrace.join("\n")}")
|
509
|
+
end
|
510
|
+
end
|
511
|
+
end
|
512
|
+
end
|
513
|
+
end
|