foreman_azure_rm 2.0.6 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -15
  3. data/app/helpers/azure_compute_resource_helper.rb +13 -0
  4. data/app/models/concerns/foreman_azure_rm/vm_extensions/managed_vm.rb +66 -28
  5. data/app/models/foreman_azure_rm/azure_rm.rb +83 -31
  6. data/app/models/foreman_azure_rm/azure_rm_compute.rb +34 -3
  7. data/app/views/compute_resources/form/_azurerm.html.erb +1 -5
  8. data/app/views/compute_resources_vms/form/azurerm/_base.html.erb +1 -1
  9. data/app/views/compute_resources_vms/form/azurerm/_volume.html.erb +20 -0
  10. data/app/views/compute_resources_vms/index/_azurerm.html.erb +12 -12
  11. data/app/views/images/form/_azurerm.html.erb +2 -2
  12. data/db/migrate/20200211073049_fix_case_azure_rm.rb +5 -0
  13. data/db/migrate/20200507103900_fix_image_uuid_prefix.rb +8 -0
  14. data/lib/foreman_azure_rm.rb +3 -0
  15. data/lib/foreman_azure_rm/azure_sdk_adapter.rb +68 -2
  16. data/lib/foreman_azure_rm/engine.rb +13 -0
  17. data/lib/foreman_azure_rm/version.rb +1 -1
  18. data/locale/Makefile +61 -0
  19. data/locale/action_names.rb +5 -0
  20. data/locale/ca/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  21. data/locale/ca/foreman_azure_rm.po +185 -0
  22. data/locale/cs_CZ/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  23. data/locale/cs_CZ/foreman_azure_rm.po +189 -0
  24. data/locale/de/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  25. data/locale/de/foreman_azure_rm.po +191 -0
  26. data/locale/en/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  27. data/locale/en/foreman_azure_rm.po +183 -0
  28. data/locale/en_GB/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  29. data/locale/en_GB/foreman_azure_rm.po +187 -0
  30. data/locale/es/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  31. data/locale/es/foreman_azure_rm.po +190 -0
  32. data/locale/foreman_azure_rm.pot +248 -0
  33. data/locale/fr/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  34. data/locale/fr/foreman_azure_rm.po +187 -0
  35. data/locale/gl/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  36. data/locale/gl/foreman_azure_rm.po +185 -0
  37. data/locale/it/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  38. data/locale/it/foreman_azure_rm.po +187 -0
  39. data/locale/ja/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  40. data/locale/ja/foreman_azure_rm.po +187 -0
  41. data/locale/ko/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  42. data/locale/ko/foreman_azure_rm.po +187 -0
  43. data/locale/nl_NL/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  44. data/locale/nl_NL/foreman_azure_rm.po +188 -0
  45. data/locale/pl/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  46. data/locale/pl/foreman_azure_rm.po +189 -0
  47. data/locale/pt_BR/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  48. data/locale/pt_BR/foreman_azure_rm.po +192 -0
  49. data/locale/ru/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  50. data/locale/ru/foreman_azure_rm.po +192 -0
  51. data/locale/sv_SE/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  52. data/locale/sv_SE/foreman_azure_rm.po +187 -0
  53. data/locale/zh_CN/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  54. data/locale/zh_CN/foreman_azure_rm.po +188 -0
  55. data/locale/zh_TW/LC_MESSAGES/foreman_azure_rm.mo +0 -0
  56. data/locale/zh_TW/foreman_azure_rm.po +187 -0
  57. metadata +59 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 910b1dd793ab445a40152db2f4613550f39d846cb53603da5a1b80cbd785f832
4
- data.tar.gz: ed13a2dd55819f1c12f6c572173108b300c6ac456ec9d788507b68cf171c0260
3
+ metadata.gz: 04afcc03f8710a4e02d4f540342ff9e1ec9188fc8c83734065eecc6956327341
4
+ data.tar.gz: 20b3d6cbfd6346270fb9fe335ae0ebde9181751ffd61b6c4bb98868cacf82ab4
5
5
  SHA512:
6
- metadata.gz: 8876efb62862f4d57684d620a91ee740459187e3e7b64cf35da8d12473fde4189902a8a88ec0bb6aca6c6f3785b79cb1973b12a2d2cf00f7b5ff15aa27a0a7c0
7
- data.tar.gz: 79b0e983f67fe039698c1ecb7ae2699435049d26aec02ed2389299492113c26e197e4366aac740bafd5e4b9251a18a7e3912fd65daf43628186c54cf83c78a26
6
+ metadata.gz: c6dc0580218a0bb8e37c734a669931d1fd6c02d37170b77d50a11afdaaee0c7675ee0cb3897eb8c05aa7e8d58af519a8e1b3e09521b6e1344a78cda1f5e3f456
7
+ data.tar.gz: 2aea8c30cc2c29bea406c17471bffbf029311616137e964564e236d1b8caee737f8afc644c5b6e52969f4a0eaff59d420bf4a0de7159229b424475e5797da6ba
data/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
  ```foreman_azure_rm``` adds [Microsoft Azure Resource Manager](http://azure.com/) as a compute resource for The Foreman
5
5
 
6
6
  * Website: [TheForeman.org](http://theforeman.org)
7
+ * ForemanAzureRm: [Plugin manual](https://theforeman.org/plugins/foreman_azure)
7
8
  * Support: [Foreman support](http://theforeman.org/support.html)
8
9
 
9
10
  ## Installation
@@ -12,25 +13,25 @@
12
13
 
13
14
  Add the following to bundler.d/Gemfile.local.rb in your Foreman installation directory (/usr/share/foreman by default)
14
15
 
15
- ```bash
16
+ ```console
16
17
  $ gem 'foreman_azure_rm'
17
18
  ```
18
19
 
19
20
  Or simply:
20
21
 
21
- ```bash
22
+ ```console
22
23
  $ echo "gem 'foreman_azure_rm'" > /usr/share/foreman/bundler.d/Gemfile.local.rb
23
24
  ```
24
25
 
25
26
  Then run `bundle install` from the same directory
26
27
 
27
28
  ### Package
28
- ```
29
+ ```console
29
30
  # yum install tfm-rubygem-foreman_azure_rm
30
31
  ```
31
32
 
32
33
  ### Foreman Installer
33
- ```
34
+ ```console
34
35
  # foreman-installer --enable-foreman-plugin-azure
35
36
  ```
36
37
 
@@ -44,7 +45,7 @@ git clone https://github.com/theforeman/foreman_azure_rm.git
44
45
  Add the following to bundler.d/Gemfile.local.rb in your Foreman development directory
45
46
 
46
47
  ```ruby
47
- $ gem 'foreman_azure_rm', :path => 'path to foreman_azure_rm directory'
48
+ gem 'foreman_azure_rm', :path => 'path to foreman_azure_rm directory'
48
49
  ```
49
50
 
50
51
  Then run `bundle install` from the same directory
@@ -54,10 +55,14 @@ Then run `bundle install` from the same directory
54
55
  * VM creation
55
56
  * Provisions using Finish and User data templates from Foreman
56
57
  * Supports cloud-config provisioning
57
- * Currently supports single NIC
58
- * Currently supports single default OS Disk
59
58
  * Currently supports only provisioning of Linux platforms
60
59
  * Provisioning using [Public Images](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/cli-ps-findimage)
60
+ * Provision using custom images
61
+ * Provision using shared image galleries
62
+ * Provision using RHEL byos images
63
+ * Multiple NICs support
64
+ * Support to add multiple data disks/volumes (standard or premium)
65
+ * VM Extension with Custom Script and File URIs support
61
66
  * Static or dynamic addresses on a per NIC basis
62
67
  * Limited extension support
63
68
  * Microsoft's custom script extension
@@ -71,21 +76,18 @@ Choose the **Azure Resource Manager provider**, and fill in all the fields. You
71
76
  That's it. You're now ready to create and manage Azure resources in your new Azure Resource Manager compute resource. You should see something like this in the Compute Resource page:
72
77
 
73
78
 
74
- ![](https://i.imgur.com/4ClZhTP.png)
79
+ ![](https://i.imgur.com/vsamP4G.png)
75
80
 
76
81
 
77
- ![](https://i.imgur.com/eFHucdb.png)
82
+ ![](https://i.imgur.com/Ag9tH55.png)
78
83
 
79
84
 
80
- ![](https://i.imgur.com/YjlRQIE.png)
85
+ ![](https://i.imgur.com/fNjlFci.png)
81
86
 
82
87
 
83
88
  ## Planned Features
84
- * Multiple NICs support
85
- * Support to add multiple data disks (standard or premium)
86
- * Provision using custom images
87
- * Provision using shared image galleries
88
- * Improved extension support
89
+ * Azure Gov Cloud Support
90
+ * Support for http_proxy
89
91
 
90
92
  ## Known Limitations
91
93
  * Please note that currently username is expected to be the same on both Virtual Machine tab for Host creation and during Image creation for Compute Resource. The password field for Image creation is optional.
@@ -0,0 +1,13 @@
1
+ module AzureComputeResourceHelper
2
+ def regions_list(azurerm_cr, f)
3
+ begin
4
+ regions = azurerm_cr.regions || []
5
+ rescue StandardError
6
+ #do nothing
7
+ regions = []
8
+ rescue Exception => ex
9
+ return information_box("Regions could not be loaded due to exception: #{ex}")
10
+ end
11
+ selectable_f(f, :url, regions, {}, {:label => _('Azure Region'), :disabled => regions.empty?, :required => true, :help_inline_permanent => load_button_f(f, regions.present?, _("Load Regions")) })
12
+ end
13
+ end
@@ -13,19 +13,7 @@ module ForemanAzureRm
13
13
  os_disk.name = "#{vm_name}-osdisk"
14
14
  os_disk.os_type = platform
15
15
  os_disk.create_option = ComputeModels::DiskCreateOptionTypes::FromImage
16
- os_disk.caching = if os_disk_caching.present?
17
- case os_disk_caching
18
- when 'None'
19
- ComputeModels::CachingTypes::None
20
- when 'ReadOnly'
21
- ComputeModels::CachingTypes::ReadOnly
22
- when 'ReadWrite'
23
- ComputeModels::CachingTypes::ReadWrite
24
- end
25
- else
26
- # ARM best practices stipulate RW caching on the OS disk
27
- ComputeModels::CachingTypes::ReadWrite
28
- end
16
+ os_disk.caching = disk_caching(os_disk_caching)
29
17
  managed_disk_params.storage_account_type = if premium_os_disk == 'true'
30
18
  ComputeModels::StorageAccountTypes::PremiumLRS
31
19
  else
@@ -33,10 +21,59 @@ module ForemanAzureRm
33
21
  end
34
22
  os_disk.managed_disk = managed_disk_params
35
23
  storage_profile.os_disk = os_disk
36
-
37
24
  storage_profile
38
25
  end
39
26
 
27
+ def disk_caching(disk_type_caching)
28
+ case disk_type_caching
29
+ when 'None'
30
+ ComputeModels::CachingTypes::None
31
+ when 'ReadOnly'
32
+ ComputeModels::CachingTypes::ReadOnly
33
+ when 'ReadWrite'
34
+ ComputeModels::CachingTypes::ReadWrite
35
+ when nil, ""
36
+ nil
37
+ else
38
+ raise RuntimeError, "Disk caching value must be either 'None', 'ReadOnly' or 'ReadWrite'."
39
+ end
40
+ end
41
+
42
+ def define_data_disks(vm_name, data_disks)
43
+ unless data_disks.nil?
44
+ disks = []
45
+ disk_count = 0
46
+ data_disks.each do |disk_num, attrs|
47
+ managed_data_disk = ComputeModels::ManagedDiskParameters.new
48
+ disk = ComputeModels::DataDisk.new
49
+ disk.name = "#{vm_name}-data-disk#{disk_count}"
50
+ disk.caching = disk_caching(attrs[:data_disk_caching])
51
+ disk.disk_size_gb = attrs[:disk_size_gb]
52
+ disk.create_option = ComputeModels::DiskCreateOption::Empty
53
+ disk.lun = disk_count + 1
54
+ disk.managed_disk = managed_data_disk
55
+ disk_count += 1
56
+ disks << disk
57
+ end
58
+ disks
59
+ end
60
+ end
61
+
62
+ def marketplace_image_plan(image)
63
+ image_type, image_id = image.split('://')
64
+ return nil unless image_type == 'marketplace' && image_id.include?('byos')
65
+ urn = image_id.split(':')
66
+ publisher = urn[0]
67
+ offer = urn[1]
68
+ sku = urn[2]
69
+ version = urn[3]
70
+ image_plan = ComputeModels::PurchasePlan.new
71
+ image_plan.publisher = publisher.downcase
72
+ image_plan.name = sku.downcase
73
+ image_plan.product = offer.downcase
74
+ image_plan
75
+ end
76
+
40
77
  def marketplace_image_reference(publisher, offer, sku, version)
41
78
  image_reference = ComputeModels::ImageReference.new
42
79
  image_reference.publisher = publisher
@@ -46,26 +83,25 @@ module ForemanAzureRm
46
83
  image_reference
47
84
  end
48
85
 
49
- def define_image(image_id)
50
- # If image UUID begins with / it is a custom managed image
51
- # Otherwise it is a marketplace URN
52
- unless image_id.start_with?('/')
86
+ def define_image(rg_name, image)
87
+ image_type, image_id = image.split('://')
88
+ case image_type
89
+ when 'marketplace'
53
90
  urn = image_id.split(':')
54
91
  publisher = urn[0]
55
92
  offer = urn[1]
56
93
  sku = urn[2]
57
94
  version = urn[3]
58
- image_id = nil
59
- end
60
-
61
- if image_id.nil?
62
- # For marketplace image
63
95
  image_reference = marketplace_image_reference(publisher, offer, sku, version)
96
+ when 'custom'
97
+ custom_image = sdk.get_custom_image(rg_name, image_id)
98
+ image_reference = ComputeModels::ImageReference.new
99
+ image_reference.id = custom_image.id
100
+ when 'gallery'
101
+ image_reference = ComputeModels::ImageReference.new
102
+ image_reference.id = sdk.fetch_gallery_image_id(rg_name, image_id)
64
103
  else
65
- # For custom managed image
66
- image_ref = ComputeModels::ImageReference.new
67
- image_ref.id = image_id
68
- image_reference = image_ref
104
+ image_reference = nil
69
105
  end
70
106
  image_reference
71
107
  end
@@ -188,8 +224,10 @@ module ForemanAzureRm
188
224
 
189
225
  def create_managed_virtual_machine(vm_hash)
190
226
  vm_params = initialize_vm(vm_hash)
227
+ vm_params.plan = marketplace_image_plan(vm_hash[:image_id])
191
228
  vm_params.network_profile = define_network_profile(vm_hash[:network_interface_card_ids])
192
- vm_params.storage_profile.image_reference = define_image(vm_hash[:image_id])
229
+ vm_params.storage_profile.image_reference = define_image(vm_hash[:resource_group], vm_hash[:image_id])
230
+ vm_params.storage_profile.data_disks = define_data_disks(vm_hash[:name], vm_hash[:data_disks])
193
231
  sdk.create_or_update_vm(vm_hash[:resource_group], vm_hash[:name], vm_params)
194
232
  end
195
233
 
@@ -12,12 +12,14 @@ module ForemanAzureRm
12
12
  alias_attribute :region, :url
13
13
  alias_attribute :tenant, :uuid
14
14
 
15
- validates :user, :password, :url, :uuid, :app_ident, :presence => true
15
+ validates :user, :password, :uuid, :app_ident, :presence => true
16
16
 
17
17
  has_one :key_pair, :foreign_key => :compute_resource_id, :dependent => :destroy
18
18
 
19
19
  before_create :test_connection, :setup_key_pair
20
20
 
21
+ validate :ensure_attributes_and_values
22
+
21
23
  class VMContainer
22
24
  attr_accessor :virtualmachines
23
25
  delegate :each, to: :virtualmachines
@@ -47,6 +49,15 @@ module ForemanAzureRm
47
49
  "#{name} (#{provider_friendly_name})"
48
50
  end
49
51
 
52
+ def ensure_attributes_and_values
53
+ validate_region
54
+ end
55
+
56
+ def validate_region
57
+ return unless regions.present?
58
+ errors.add(:region, "is not valid, must be lowercase eg. 'eastus'. No special characters allowed.") unless regions.collect(&:second).include?(region)
59
+ end
60
+
50
61
  def self.model_name
51
62
  ComputeResource.model_name
52
63
  end
@@ -56,44 +67,35 @@ module ForemanAzureRm
56
67
  end
57
68
 
58
69
  def capabilities
59
- [:image]
70
+ [:image, :new_volume]
60
71
  end
61
72
 
62
- def self.regions
63
- [
64
- ['West Europe', 'westeurope'],
65
- ['Central US', 'centralus'],
66
- ['South Central US', 'southcentralus'],
67
- ['North Central US', 'northcentralus'],
68
- ['West Central US', 'westcentralus'],
69
- ['East US', 'eastus'],
70
- ['East US 2', 'eastus2'],
71
- ['West US', 'westus'],
72
- ['West US 2', 'westus2']
73
- ]
73
+ def regions
74
+ return unless sub_id.present?
75
+ sdk.list_regions(sub_id).value.map { |loc| [loc.display_name, loc.name] }
74
76
  end
75
77
 
76
- validates :region, inclusion: { in: regions.collect(&:second),
77
- message: "%{value} must be lowercase eg. 'eastus'. No special characters allowed." }
78
-
79
78
  def resource_groups
80
79
  sdk.rgs
81
80
  end
82
81
 
83
82
  def test_connection(options = {})
84
- sdk.rgs.each do |rg|
85
- puts "#{rg}"
86
- end
87
- super(options)
83
+ super
84
+ errors[:user].empty? && errors[:password].empty? && errors[:uuid].empty? && errors[:app_ident].empty? && regions
85
+ rescue StandardError => e
86
+ errors[:base] << e.message
87
+ rescue Excon::Error::Socket => e
88
+ errors[:base] << e.message
88
89
  end
89
90
 
90
91
  def new_vm(args = {})
91
92
  return AzureRmCompute.new(sdk: sdk) if args.empty?
92
93
  opts = vm_instance_defaults.merge(args.to_h).deep_symbolize_keys
93
94
  # convert rails nested_attributes into a plain hash
94
- nested_args = opts.delete(:interfaces_attributes)
95
- opts[:interfaces] = nested_attributes_for(:interfaces, nested_args) if nested_args
96
-
95
+ [:interfaces, :volumes].each do |collection|
96
+ nested_args = opts.delete("#{collection}_attributes".to_sym)
97
+ opts[collection] = nested_attributes_for(collection, nested_args) if nested_args
98
+ end
97
99
  opts.reject! { |k, v| v.nil? }
98
100
 
99
101
  raw_vm = initialize_vm(location: region,
@@ -112,13 +114,54 @@ module ForemanAzureRm
112
114
  ifaces << new_interface(iface_attrs)
113
115
  end
114
116
  end
115
- AzureRmCompute.new(azure_vm: raw_vm ,sdk: sdk, resource_group: opts[:resource_group], nics: ifaces, script_command: opts[:script_command], script_uris: opts[:script_uris])
117
+
118
+ vols = opts.fetch(:volumes, []).map { |vols_attrs| new_volume(vols_attrs) } if opts[:volumes].present?
119
+
120
+ AzureRmCompute.new(azure_vm: raw_vm ,sdk: sdk, resource_group: opts[:resource_group], nics: ifaces, volumes: vols, script_command: opts[:script_command], script_uris: opts[:script_uris])
116
121
  end
117
122
 
118
123
  def provided_attributes
119
124
  super.merge({ :ip => :provisioning_ip_address })
120
125
  end
121
126
 
127
+ def image_exists?(image)
128
+ image_type, image_id = image.split('://')
129
+ case image_type
130
+ when 'marketplace'
131
+ begin
132
+ urn = image_id.split(':')
133
+ publisher = urn[0]
134
+ offer = urn[1]
135
+ sku = urn[2]
136
+ version = urn[3]
137
+ if version == "latest"
138
+ all_versions = sdk.list_versions(region, publisher, offer, sku).map(&:name)
139
+ return true if all_versions.any?
140
+ end
141
+ sdk.get_marketplace_image(region, publisher, offer, sku, version).present?
142
+ rescue StandardError => e
143
+ return false
144
+ end
145
+ when 'gallery'
146
+ gallery_images_list = sdk.list_resources(filter: "resourceType eq 'Microsoft.Compute/galleries/images'")
147
+ gallery_image = gallery_images_list.detect { |gal_img| gal_img.id.split('/')[-1] == image_id }
148
+ if gallery_image.present?
149
+ rg_name = gallery_image.id.split('/')[4]
150
+ gallery_name = gallery_image.name.split('/')[0]
151
+ image_versions = sdk.list_gallery_image_versions(rg_name, gallery_name, image_id)
152
+ target_regions = image_versions.map do |image_version|
153
+ image_version.publishing_profile.target_regions.map(&:name)
154
+ end.flatten.uniq.map { |tgt_reg| tgt_reg.gsub(/\s+/, '').downcase }
155
+ return true if target_regions.include? region
156
+ end
157
+ when 'custom'
158
+ custom_image = sdk.list_custom_images.detect { |custom_img| custom_img.name == image_id && custom_img.location == region }
159
+ return custom_image.present?
160
+ else
161
+ false
162
+ end
163
+ end
164
+
122
165
  def available_vnets(attr = {})
123
166
  virtual_networks
124
167
  end
@@ -151,6 +194,11 @@ module ForemanAzureRm
151
194
  true
152
195
  end
153
196
 
197
+ def new_volume(attrs = {})
198
+ args = { :disk_size_gb => 0, :data_disk_caching => "", 'persisted?' => false }.merge(attrs.to_h)
199
+ OpenStruct.new(args)
200
+ end
201
+
154
202
  def vm_sizes
155
203
  sdk.list_vm_sizes(region)
156
204
  end
@@ -161,7 +209,8 @@ module ForemanAzureRm
161
209
 
162
210
  def vm_instance_defaults
163
211
  super.deep_merge(
164
- interfaces: [new_interface]
212
+ interfaces: [new_interface],
213
+ volumes: [new_volume]
165
214
  )
166
215
  end
167
216
 
@@ -175,6 +224,10 @@ module ForemanAzureRm
175
224
  ifaces
176
225
  end
177
226
 
227
+ def vm_disks(vm)
228
+ vm.storage_profile.data_disks
229
+ end
230
+
178
231
  def vms(attrs = {})
179
232
  container = VMContainer.new
180
233
  # Load all vms of the region
@@ -239,6 +292,7 @@ module ForemanAzureRm
239
292
  image_id: args[:image_id],
240
293
  os_disk_caching: args[:os_disk_caching],
241
294
  premium_os_disk: args[:premium_os_disk],
295
+ data_disks: args[:volumes_attributes],
242
296
  custom_data: args[:user_data],
243
297
  script_command: args[:script_command],
244
298
  script_uris: args[:script_uris],
@@ -246,7 +300,7 @@ module ForemanAzureRm
246
300
  logger.debug "Virtual Machine #{args[:vm_name]} Created Successfully."
247
301
  create_vm_extension(region, args)
248
302
  # return the vm object using azure_vm
249
- AzureRmCompute.new(azure_vm: vm, sdk: sdk, resource_group: args[:resource_group], nics: vm_nics(vm), script_command: user_command, script_uris: args[:script_uris])
303
+ AzureRmCompute.new(azure_vm: vm, sdk: sdk, resource_group: args[:resource_group], nics: vm_nics(vm), volumes: vm_disks(vm), script_command: user_command, script_uris: args[:script_uris])
250
304
  rescue RuntimeError => e
251
305
  Foreman::Logging.exception('Unhandled AzureRm error', e)
252
306
  destroy_vm vm.id if vm
@@ -273,10 +327,8 @@ module ForemanAzureRm
273
327
  end
274
328
  end
275
329
  end
276
- if os_disk.present?
277
- sdk.delete_disk(rg_name, os_disk.name)
278
- end
279
-
330
+ sdk.delete_disk(rg_name, os_disk.name) if os_disk.present?
331
+ data_disks.each { |data_disk| sdk.delete_disk(rg_name, data_disk.name) } if data_disks.present?
280
332
  true
281
333
  rescue ActiveRecord::RecordNotFound
282
334
  logger.info "Could not find the selected vm."