knife-azure 1.6.0.rc.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +304 -8
  3. data/lib/azure/azure_interface.rb +81 -0
  4. data/lib/azure/custom_errors.rb +35 -0
  5. data/lib/azure/helpers.rb +44 -0
  6. data/lib/azure/resource_management/ARM_base.rb +29 -0
  7. data/lib/azure/resource_management/ARM_deployment_template.rb +561 -0
  8. data/lib/azure/resource_management/ARM_interface.rb +795 -0
  9. data/lib/azure/resource_management/windows_credentials.rb +136 -0
  10. data/lib/azure/service_management/ASM_interface.rb +301 -0
  11. data/lib/azure/{ag.rb → service_management/ag.rb} +2 -2
  12. data/lib/azure/{certificate.rb → service_management/certificate.rb} +2 -2
  13. data/lib/azure/service_management/connection.rb +102 -0
  14. data/lib/azure/{deploy.rb → service_management/deploy.rb} +8 -2
  15. data/lib/azure/{disk.rb → service_management/disk.rb} +2 -2
  16. data/lib/azure/{host.rb → service_management/host.rb} +2 -2
  17. data/lib/azure/{image.rb → service_management/image.rb} +2 -2
  18. data/lib/azure/{loadbalancer.rb → service_management/loadbalancer.rb} +4 -18
  19. data/lib/azure/{rest.rb → service_management/rest.rb} +15 -10
  20. data/lib/azure/{role.rb → service_management/role.rb} +174 -6
  21. data/lib/azure/{storageaccount.rb → service_management/storageaccount.rb} +2 -2
  22. data/lib/azure/{utility.rb → service_management/utility.rb} +0 -0
  23. data/lib/azure/{vnet.rb → service_management/vnet.rb} +2 -2
  24. data/lib/chef/knife/azure_ag_create.rb +3 -6
  25. data/lib/chef/knife/azure_ag_list.rb +2 -16
  26. data/lib/chef/knife/azure_base.rb +89 -22
  27. data/lib/chef/knife/azure_image_list.rb +3 -7
  28. data/lib/chef/knife/azure_internal-lb_create.rb +2 -5
  29. data/lib/chef/knife/azure_internal-lb_list.rb +2 -16
  30. data/lib/chef/knife/azure_server_create.rb +122 -501
  31. data/lib/chef/knife/azure_server_delete.rb +15 -38
  32. data/lib/chef/knife/azure_server_list.rb +2 -27
  33. data/lib/chef/knife/azure_server_show.rb +4 -60
  34. data/lib/chef/knife/azure_vnet_create.rb +2 -7
  35. data/lib/chef/knife/azure_vnet_list.rb +2 -17
  36. data/lib/chef/knife/azurerm_base.rb +228 -0
  37. data/lib/chef/knife/azurerm_server_create.rb +393 -0
  38. data/lib/chef/knife/azurerm_server_delete.rb +121 -0
  39. data/lib/chef/knife/azurerm_server_list.rb +18 -0
  40. data/lib/chef/knife/azurerm_server_show.rb +37 -0
  41. data/lib/chef/knife/bootstrap/bootstrap_options.rb +105 -0
  42. data/lib/chef/knife/bootstrap/bootstrapper.rb +343 -0
  43. data/lib/chef/knife/bootstrap/common_bootstrap_options.rb +116 -0
  44. data/lib/chef/knife/bootstrap_azure.rb +110 -0
  45. data/lib/chef/knife/bootstrap_azurerm.rb +116 -0
  46. data/lib/knife-azure/version.rb +1 -2
  47. metadata +132 -16
  48. data/lib/azure/connection.rb +0 -99
@@ -0,0 +1,393 @@
1
+ #
2
+ # Author:: Aliasgar Batterywala (aliasgar.batterywala@clogeny.com)
3
+ #
4
+ # Copyright:: Copyright (c) 2016 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'chef/knife/azurerm_base'
21
+ require 'securerandom'
22
+ require 'chef/knife/bootstrap/common_bootstrap_options'
23
+ require 'chef/knife/bootstrap/bootstrapper'
24
+
25
+ class Chef
26
+ class Knife
27
+ class AzurermServerCreate < Knife
28
+
29
+ include Knife::AzurermBase
30
+ include Knife::Bootstrap::CommonBootstrapOptions
31
+ include Knife::Bootstrap::Bootstrapper
32
+
33
+ banner "knife azurerm server create (options)"
34
+
35
+ attr_accessor :initial_sleep_delay
36
+
37
+ option :ssh_user,
38
+ :short => "-x USERNAME",
39
+ :long => "--ssh-user USERNAME",
40
+ :description => "The ssh username",
41
+ :default => "root"
42
+
43
+ option :ssh_password,
44
+ :short => "-P PASSWORD",
45
+ :long => "--ssh-password PASSWORD",
46
+ :description => "The ssh password"
47
+
48
+ option :ssh_port,
49
+ :long => "--ssh-port PORT",
50
+ :description => "The ssh port. Default is 22."
51
+
52
+ option :winrm_user,
53
+ :short => "-x USERNAME",
54
+ :long => "--winrm-user USERNAME",
55
+ :description => "The WinRM username",
56
+ :default => "Administrator",
57
+ :proc => Proc.new { |key| Chef::Config[:knife][:winrm_user] = key }
58
+
59
+ option :winrm_password,
60
+ :short => "-P PASSWORD",
61
+ :long => "--winrm-password PASSWORD",
62
+ :description => "The WinRM password",
63
+ :proc => Proc.new { |key| Chef::Config[:knife][:winrm_password] = key }
64
+
65
+ option :azure_storage_account,
66
+ :short => "-a NAME",
67
+ :long => "--azure-storage-account NAME",
68
+ :description => "Required for advanced server-create option.
69
+ A name for the storage account that is unique within Windows Azure. Storage account names must be
70
+ between 3 and 24 characters in length and use numbers and lower-case letters only.
71
+ This name is the DNS prefix name and can be used to access blobs, queues, and tables in the storage account.
72
+ For example: http://ServiceName.blob.core.windows.net/mycontainer/"
73
+
74
+ option :azure_storage_account_type,
75
+ :long => "--azure-storage-account-type TYPE",
76
+ :description => "Optional. One of the following account types (case-sensitive):
77
+ Standard_LRS (Standard Locally-redundant storage)
78
+ Standard_ZRS (Standard Zone-redundant storage)
79
+ Standard_GRS (Standard Geo-redundant storage)
80
+ Standard_RAGRS (Standard Read access geo-redundant storage)
81
+ Premium_LRS (Premium Locally-redundant storage)",
82
+ :default => 'Standard_GRS'
83
+
84
+ option :azure_vm_name,
85
+ :long => "--azure-vm-name NAME",
86
+ :description => "Required. Specifies the name for the virtual machine.
87
+ The name must be unique within the ResourceGroup.
88
+ The azure vm name cannot be more than 15 characters long"
89
+
90
+ option :azure_service_location,
91
+ :short => "-m LOCATION",
92
+ :long => "--azure-service-location LOCATION",
93
+ :description => "Required if not using an Affinity Group. Specifies the geographic location - the name of the data center location that is valid for your subscription.
94
+ Eg: westus, eastus, eastasia, southeastasia, northeurope, westeurope",
95
+ :proc => Proc.new { |lo| Chef::Config[:knife][:azure_service_location] = lo }
96
+
97
+ option :azure_os_disk_name,
98
+ :short => "-o DISKNAME",
99
+ :long => "--azure-os-disk-name DISKNAME",
100
+ :description => "Optional. Specifies the friendly name of the disk containing the guest OS image in the image repository."
101
+
102
+ option :azure_image_reference_publisher,
103
+ :long => "--azure-image-reference-publisher PUBLISHER_NAME",
104
+ :description => "Optional. Specifies the publisher of the image used to create the virtual machine.
105
+ eg. OpenLogic, Canonical, MicrosoftWindowsServer"
106
+
107
+ option :azure_image_reference_offer,
108
+ :long => "--azure-image-reference-offer OFFER",
109
+ :description => "Optional. Specifies the offer of the image used to create the virtual machine.
110
+ eg. CentOS, UbuntuServer, WindowsServer"
111
+
112
+ option :azure_image_reference_sku,
113
+ :long => "--azure-image-reference-sku SKU",
114
+ :description => "Optional. Specifies the SKU of the image used to create the virtual machine."
115
+
116
+ option :azure_image_reference_version,
117
+ :long => "--azure-image-reference-version VERSION",
118
+ :description => "Optional. Specifies the version of the image used to create the virtual machine.
119
+ Default value is 'latest'",
120
+ :default => 'latest'
121
+
122
+ option :azure_image_os_type,
123
+ :long => "--azure-image-os-type OSTYPE",
124
+ :description => "Optional. Specifies the image OS Type for which server needs to be created. Accepted values ubuntu|centos|rhel|debian|windows"
125
+
126
+ option :azure_vm_size,
127
+ :short => "-z SIZE",
128
+ :long => "--azure-vm-size SIZE",
129
+ :description => "Optional. Size of virtual machine (ExtraSmall, Small, Medium, Large, ExtraLarge)",
130
+ :default => 'Small',
131
+ :proc => Proc.new { |si| Chef::Config[:knife][:azure_vm_size] = si }
132
+
133
+ option :azure_vnet_name,
134
+ :long => "--azure-vnet-name VNET_NAME",
135
+ :description => "Optional. Specifies the virtual network name
136
+ If this is an existing vnet then it must exists under the current resource group identified by resource-group
137
+ If this is an existing vnet then vnet-subnet-name is required"
138
+
139
+ option :azure_vnet_subnet_name,
140
+ :long => "--azure-vnet-subnet-name VNET_SUBNET_NAME",
141
+ :description => "Optional. Specifies the virtual network subnet name."
142
+
143
+ option :identity_file,
144
+ :long => "--identity-file FILENAME",
145
+ :description => "SSH identity file for authentication, optional. It is the RSA private key path. Specify either ssh-password or identity-file"
146
+
147
+ option :thumbprint,
148
+ :long => "--thumbprint THUMBPRINT",
149
+ :description => "The thumprint of the ssl certificate"
150
+
151
+ option :cert_passphrase,
152
+ :long => "--cert-passphrase PASSWORD",
153
+ :description => "SSL Certificate Password"
154
+
155
+ option :cert_path,
156
+ :long => "--cert-path PATH",
157
+ :description => "SSL Certificate Path"
158
+
159
+ option :server_count,
160
+ :long => "--server-count COUNT",
161
+ :description => "Number of servers to create with same configuration.
162
+ Maximum count is 5. Default value is 1.",
163
+ :default => 1
164
+
165
+ option :ohai_hints,
166
+ :long => "--ohai-hints HINT_OPTIONS",
167
+ :description => "Hint option names to be set in Ohai configuration of the target node.
168
+ Supported values are: vm_name, public_fqdn and platform.
169
+ User can pass any comma separated combination of these values like 'vm_name,public_fqdn'.
170
+ Default value is 'default' which corresponds to the supported values list mentioned here.",
171
+ :default => 'default'
172
+
173
+ def run
174
+ $stdout.sync = true
175
+
176
+ validate_arm_keys!(
177
+ :azure_resource_group_name,
178
+ :azure_vm_name,
179
+ :azure_service_location
180
+ )
181
+
182
+ begin
183
+ validate_params!
184
+
185
+ set_default_image_reference!
186
+
187
+ ssh_override_winrm if !is_image_windows?
188
+
189
+ vm_details = service.create_server(create_server_def)
190
+ rescue => error
191
+ if error.class == MsRestAzure::AzureOperationError && error.body
192
+ if error.response.body['error']['code'] == 'DeploymentFailed'
193
+ ui.error("#{error.body['error']['message']}")
194
+ else
195
+ ui.error(error.response.body)
196
+ end
197
+ else
198
+ ui.error("#{error.message}")
199
+ end
200
+ Chef::Log.debug("#{error.backtrace.join("\n")}")
201
+ exit
202
+ end
203
+ end
204
+
205
+ def create_server_def
206
+ server_def = {
207
+ :azure_resource_group_name => locate_config_value(:azure_resource_group_name),
208
+ :azure_storage_account => locate_config_value(:azure_storage_account),
209
+ :azure_storage_account_type => locate_config_value(:azure_storage_account_type),
210
+ :azure_vm_name => locate_config_value(:azure_vm_name),
211
+ :azure_service_location => locate_config_value(:azure_service_location),
212
+ :azure_os_disk_name => locate_config_value(:azure_os_disk_name),
213
+ :azure_os_disk_caching => locate_config_value(:azure_os_disk_caching),
214
+ :azure_os_disk_create_option => locate_config_value(:azure_os_disk_create_option),
215
+ :azure_vm_size => locate_config_value(:azure_vm_size),
216
+ :azure_image_reference_publisher => locate_config_value(:azure_image_reference_publisher),
217
+ :azure_image_reference_offer => locate_config_value(:azure_image_reference_offer),
218
+ :azure_image_reference_sku => locate_config_value(:azure_image_reference_sku),
219
+ :azure_image_reference_version => locate_config_value(:azure_image_reference_version),
220
+ :winrm_user => locate_config_value(:winrm_user),
221
+ :azure_vnet_name => locate_config_value(:azure_vnet_name),
222
+ :azure_vnet_subnet_name => locate_config_value(:azure_vnet_subnet_name),
223
+ :ssl_cert_fingerprint => locate_config_value(:thumbprint),
224
+ :cert_path => locate_config_value(:cert_path),
225
+ :cert_password => locate_config_value(:cert_passphrase),
226
+ :vnet_subnet_address_prefix => locate_config_value(:vnet_subnet_address_prefix),
227
+ :server_count => locate_config_value(:server_count)
228
+ }
229
+
230
+ server_def[:azure_storage_account] = locate_config_value(:azure_vm_name) if server_def[:azure_storage_account].nil?
231
+ server_def[:azure_storage_account] = server_def[:azure_storage_account].gsub(/[!@#$%^&*()_-]/,'')
232
+
233
+ server_def[:azure_os_disk_name] = locate_config_value(:azure_vm_name) if server_def[:azure_os_disk_name].nil?
234
+ server_def[:azure_os_disk_name] = server_def[:azure_os_disk_name].gsub(/[!@#$%^&*()_-]/,'')
235
+
236
+ server_def[:azure_vnet_name] = locate_config_value(:azure_vm_name) if server_def[:azure_vnet_name].nil?
237
+ server_def[:azure_vnet_subnet_name] = locate_config_value(:azure_vm_name) if locate_config_value(:azure_vnet_subnet_name).nil? && locate_config_value(:azure_vnet_name).nil?
238
+
239
+ server_def[:chef_extension] = get_chef_extension_name
240
+ server_def[:chef_extension_publisher] = get_chef_extension_publisher
241
+ server_def[:chef_extension_version] = locate_config_value(:azure_chef_extension_version)
242
+ server_def[:chef_extension_public_param] = get_chef_extension_public_params
243
+ server_def[:chef_extension_private_param] = get_chef_extension_private_params
244
+ server_def[:auto_upgrade_minor_version] = false
245
+
246
+ if is_image_windows?
247
+ server_def[:admin_password] = locate_config_value(:winrm_password)
248
+ else
249
+ server_def[:ssh_user] = locate_config_value(:ssh_user)
250
+ server_def[:ssh_password] = locate_config_value(:ssh_password)
251
+ server_def[:disablePasswordAuthentication] = "false"
252
+ if locate_config_value(:identity_file)
253
+ server_def[:disablePasswordAuthentication] = "true"
254
+ server_def[:ssh_key] = File.read(locate_config_value(:identity_file))
255
+ end
256
+ end
257
+
258
+ server_def
259
+ end
260
+
261
+ def supported_ohai_hints
262
+ [
263
+ 'vm_name',
264
+ 'public_fqdn',
265
+ 'platform'
266
+ ]
267
+ end
268
+
269
+ def format_ohai_hints(ohai_hints)
270
+ ohai_hints = ohai_hints.split(',').each { |hint| hint.strip! }
271
+ ohai_hints.join(',')
272
+ end
273
+
274
+ def is_supported_ohai_hint?(hint)
275
+ supported_ohai_hints.any? { |supported_ohai_hint| hint.eql? supported_ohai_hint }
276
+ end
277
+
278
+ def validate_ohai_hints
279
+ hint_values = locate_config_value(:ohai_hints).split(',')
280
+ hint_values.each do |hint|
281
+ if ! is_supported_ohai_hint?(hint)
282
+ raise ArgumentError, "Ohai Hint name #{hint} passed is not supported. Please run the command help to see the list of supported values."
283
+ end
284
+ end
285
+ end
286
+
287
+ def validate_params!
288
+ if locate_config_value(:azure_vnet_name) && !locate_config_value(:azure_vnet_subnet_name)
289
+ raise ArgumentError, "When a --azure-vnet-name is specified, the --azure-vnet-subnet-name must also be specified."
290
+ end
291
+
292
+ if locate_config_value(:azure_vnet_subnet_name) && !locate_config_value(:azure_vnet_name)
293
+ raise ArgumentError, "When --azure-vnet-subnet-name is specified, the --azure-vnet-name must also be specified."
294
+ end
295
+
296
+ if is_image_windows?
297
+ if locate_config_value(:winrm_user).nil? || locate_config_value(:winrm_password).nil?
298
+ raise ArgumentError, "Please provide --winrm-user and --winrm-password options for Windows option."
299
+ end
300
+ end
301
+
302
+ if !is_image_windows?
303
+ if (locate_config_value(:azure_vm_name).match /^(?=.*[a-zA-Z-])([a-zA-z0-9-]{1,64})$/).nil?
304
+ raise ArgumentError, "VM name can only contain alphanumeric and hyphen(-) characters and maximun length cannot exceed 64 charachters."
305
+ end
306
+ elsif (locate_config_value(:azure_vm_name).match /^(?=.*[a-zA-Z-])([a-zA-z0-9-]{1,15})$/).nil?
307
+ raise ArgumentError, "VM name can only contain alphanumeric and hyphen(-) characters and maximun length cannot exceed 15 charachters."
308
+ end
309
+
310
+ if locate_config_value(:server_count).to_i > 5
311
+ raise ArgumentError, "Maximum allowed value of --server-count is 5."
312
+ end
313
+
314
+ config[:ohai_hints] = format_ohai_hints(locate_config_value(:ohai_hints))
315
+ validate_ohai_hints if ! locate_config_value(:ohai_hints).casecmp('default').zero?
316
+ end
317
+
318
+ private
319
+
320
+ def ssh_override_winrm
321
+ # unchanged ssh_user and changed winrm_user, override ssh_user
322
+ if locate_config_value(:ssh_user).eql?(options[:ssh_user][:default]) &&
323
+ !locate_config_value(:winrm_user).eql?(options[:winrm_user][:default])
324
+ config[:ssh_user] = locate_config_value(:winrm_user)
325
+ end
326
+
327
+ if locate_config_value(:ssh_password).nil? &&
328
+ !locate_config_value(:winrm_password).nil?
329
+ config[:ssh_password] = locate_config_value(:winrm_password)
330
+ end
331
+ end
332
+
333
+ def set_default_image_reference!
334
+ begin
335
+ if locate_config_value(:azure_image_os_type)
336
+ if (locate_config_value(:azure_image_reference_publisher) || locate_config_value(:azure_image_reference_offer))
337
+ # if azure_image_os_type is given and any of the other image reference parameters like publisher or offer are also given,
338
+ # raise error
339
+ raise ArgumentError, 'Please specify either --azure-image-os-type OR --azure-image-os-type with --azure-image-reference-sku or 4 image reference parameters i.e.
340
+ --azure-image-reference-publisher, --azure-image-reference-offer, --azure-image-reference-sku, --azure-image-reference-version."'
341
+ else
342
+ ## if azure_image_os_type is given (with or without azure-image-reference-sku) and other image reference parameters are not given,
343
+ # set default image reference parameters
344
+ case locate_config_value(:azure_image_os_type)
345
+ when "ubuntu"
346
+ config[:azure_image_reference_publisher] = "Canonical"
347
+ config[:azure_image_reference_offer] = "UbuntuServer"
348
+ config[:azure_image_reference_sku] = locate_config_value(:azure_image_reference_sku) ? locate_config_value(:azure_image_reference_sku) : "14.04.2-LTS"
349
+ when "centos"
350
+ config[:azure_image_reference_publisher] = "OpenLogic"
351
+ config[:azure_image_reference_offer] = "CentOS"
352
+ config[:azure_image_reference_sku] = locate_config_value(:azure_image_reference_sku) ? locate_config_value(:azure_image_reference_sku) : "7.1"
353
+ when "rhel"
354
+ config[:azure_image_reference_publisher] = "RedHat"
355
+ config[:azure_image_reference_offer] = "RHEL"
356
+ config[:azure_image_reference_sku] = locate_config_value(:azure_image_reference_sku) ? locate_config_value(:azure_image_reference_sku) : "7.2"
357
+ when "debian"
358
+ config[:azure_image_reference_publisher] = "credativ"
359
+ config[:azure_image_reference_offer] = "Debian"
360
+ config[:azure_image_reference_sku] = locate_config_value(:azure_image_reference_sku) ? locate_config_value(:azure_image_reference_sku) : "7"
361
+ when "windows"
362
+ config[:azure_image_reference_publisher] = "MicrosoftWindowsServer"
363
+ config[:azure_image_reference_offer] = "WindowsServer"
364
+ config[:azure_image_reference_sku] = locate_config_value(:azure_image_reference_sku) ? locate_config_value(:azure_image_reference_sku) : "2012-R2-Datacenter"
365
+ else
366
+ raise ArgumentError, 'Invalid value of --azure-image-os-type. Accepted values ubuntu|centos|windows'
367
+ end
368
+ end
369
+ else
370
+ if (locate_config_value(:azure_image_reference_publisher) && locate_config_value(:azure_image_reference_offer) && locate_config_value(:azure_image_reference_sku) && locate_config_value(:azure_image_reference_version))
371
+ # if azure_image_os_type is not given and other image reference parameters are given,
372
+ # do nothing
373
+ else
374
+ # if azure_image_os_type is not given and other image reference parameters are also not given,
375
+ # throw error for azure_image_os_type
376
+ validate_arm_keys!(:azure_image_os_type)
377
+ end
378
+ end
379
+ rescue => error
380
+ ui.error("#{error.message}")
381
+ Chef::Log.debug("#{error.backtrace.join("\n")}")
382
+ exit
383
+ end
384
+
385
+ # final verification for image reference parameters
386
+ validate_arm_keys!(:azure_image_reference_publisher,
387
+ :azure_image_reference_offer,
388
+ :azure_image_reference_sku,
389
+ :azure_image_reference_version)
390
+ end
391
+ end
392
+ end
393
+ end
@@ -0,0 +1,121 @@
1
+ #
2
+ # Author:: Barry Davis (barryd@jetstreamsoftware.com)
3
+ # Author:: Adam Jacob (<adam@opscode.com>)
4
+ # Author:: Seth Chisamore (<schisamo@opscode.com>)
5
+ # Copyright:: Copyright (c) 2009-2011 Opscode, Inc.
6
+ # License:: Apache License, Version 2.0
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+
21
+ require File.expand_path('../azure_base', __FILE__)
22
+
23
+ # These two are needed for the '--purge' deletion case
24
+ require 'chef/node'
25
+ require 'chef/api_client'
26
+
27
+ class Chef
28
+ class Knife
29
+ class AzurermServerDelete < Knife
30
+
31
+ include Knife::AzurermBase
32
+
33
+ banner "knife azurerm server delete SERVER [SERVER] (options)"
34
+
35
+ option :purge,
36
+ :short => "-P",
37
+ :long => "--purge",
38
+ :boolean => true,
39
+ :default => false,
40
+ :description => "Destroy corresponding node and client on the Chef Server, in addition to destroying the Windows Azure node itself. Assumes node and client have the same name as the server (if not, add the '--node-name' option)."
41
+
42
+ option :chef_node_name,
43
+ :short => "-N NAME",
44
+ :long => "--node-name NAME",
45
+ :description => "The name of the node and client to delete, if it differs from the server name. Only has meaning when used with the '--purge' option."
46
+
47
+ option :delete_resource_group,
48
+ :long => "--delete-resource-group",
49
+ :boolean => true,
50
+ :default => false,
51
+ :description => "Deletes corresponding resource group along with Vitual Machine."
52
+
53
+ # Extracted from Chef::Knife.delete_object, because it has a
54
+ # confirmation step built in... By specifying the '--purge'
55
+ # flag (and also explicitly confirming the server destruction!)
56
+ # the user is already making their intent known. It is not
57
+ # necessary to make them confirm two more times.
58
+
59
+ def destroy_item(klass, name, type_name)
60
+ begin
61
+ object = klass.load(name)
62
+ object.destroy
63
+ ui.warn("Deleted #{type_name} #{name}")
64
+ rescue Net::HTTPServerException
65
+ ui.warn("Could not find a #{type_name} named #{name} to delete!")
66
+ end
67
+ end
68
+
69
+ def run
70
+ begin
71
+ $stdout.sync = true
72
+ validate_arm_keys!(:azure_resource_group_name)
73
+
74
+ vm_name = @name_args[0]
75
+ resource_group_name = locate_config_value(:azure_resource_group_name)
76
+
77
+ if locate_config_value(:delete_resource_group)
78
+ ui.warn "Deleting resource group will delete all the virtual_machines inside it."
79
+ begin
80
+ ui.confirm('Do you really want to delete resource group')
81
+ rescue SystemExit # Need to handle this as confirming with N/n raises SystemExit exception
82
+ server = nil # Cleanup is implicitly performed in other cloud plugins
83
+ ui.warn "Resource group not deleted. Proceeding for server delete ..."
84
+ service.delete_server(locate_config_value(:azure_resource_group_name), vm_name)
85
+ exit
86
+ end
87
+
88
+ ui.info 'Deleting Resource Group '+resource_group_name+' and Virtual Machine '+vm_name+' ..'
89
+ service.delete_resource_group(locate_config_value(:azure_resource_group_name))
90
+ ui.warn "Deleted resource_group_name #{resource_group_name} and #{vm_name}"
91
+ else
92
+ service.delete_server(locate_config_value(:azure_resource_group_name), vm_name)
93
+ end
94
+
95
+ if config[:purge]
96
+ node_to_delete = config[:chef_node_name] || vm_name
97
+ if node_to_delete
98
+ destroy_item(Chef::Node, node_to_delete, 'node')
99
+ destroy_item(Chef::ApiClient, node_to_delete, 'client')
100
+ else
101
+ ui.warn("Node name to purge not provided. Corresponding client node will remain on Chef Server.")
102
+ end
103
+ else
104
+ ui.warn("Corresponding node and client for the #{vm_name} server were not deleted and remain registered with the Chef Server")
105
+ end
106
+ rescue => error
107
+ if error.class == MsRestAzure::AzureOperationError && error.body
108
+ if error.body['error']['code'] == 'ResourceNotFound'
109
+ ui.error("#{error.body['error']['message']}")
110
+ else
111
+ ui.error(error.body)
112
+ end
113
+ else
114
+ ui.error("#{error.message}")
115
+ Chef::Log.debug("#{error.backtrace.join("\n")}")
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end