foreman_azure_rm 2.0.5 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +17 -15
- data/app/helpers/azure_compute_resource_helper.rb +13 -0
- data/app/models/concerns/foreman_azure_rm/vm_extensions/managed_vm.rb +67 -29
- data/app/models/foreman_azure_rm/azure_rm.rb +89 -33
- data/app/models/foreman_azure_rm/azure_rm_compute.rb +69 -2
- data/app/views/compute_resources/form/_azurerm.html.erb +1 -5
- data/app/views/compute_resources_vms/form/azurerm/_base.html.erb +4 -3
- data/app/views/compute_resources_vms/form/azurerm/_volume.html.erb +20 -0
- data/app/views/compute_resources_vms/index/_azurerm.html.erb +13 -13
- data/app/views/compute_resources_vms/show/_azurerm.html.erb +10 -6
- data/app/views/images/form/_azurerm.html.erb +2 -2
- data/db/migrate/20200211073049_fix_case_azure_rm.rb +5 -0
- data/db/migrate/20200507103900_fix_image_uuid_prefix.rb +8 -0
- data/lib/foreman_azure_rm.rb +3 -0
- data/lib/foreman_azure_rm/azure_sdk_adapter.rb +68 -2
- data/lib/foreman_azure_rm/engine.rb +13 -0
- data/lib/foreman_azure_rm/version.rb +1 -1
- data/locale/Makefile +61 -0
- data/locale/action_names.rb +5 -0
- data/locale/ca/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/ca/foreman_azure_rm.po +185 -0
- data/locale/cs_CZ/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/cs_CZ/foreman_azure_rm.po +189 -0
- data/locale/de/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/de/foreman_azure_rm.po +191 -0
- data/locale/en/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/en/foreman_azure_rm.po +183 -0
- data/locale/en_GB/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/en_GB/foreman_azure_rm.po +187 -0
- data/locale/es/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/es/foreman_azure_rm.po +190 -0
- data/locale/foreman_azure_rm.pot +248 -0
- data/locale/fr/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/fr/foreman_azure_rm.po +187 -0
- data/locale/gl/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/gl/foreman_azure_rm.po +185 -0
- data/locale/it/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/it/foreman_azure_rm.po +187 -0
- data/locale/ja/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/ja/foreman_azure_rm.po +187 -0
- data/locale/ko/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/ko/foreman_azure_rm.po +186 -0
- data/locale/nl_NL/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/nl_NL/foreman_azure_rm.po +187 -0
- data/locale/pl/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/pl/foreman_azure_rm.po +188 -0
- data/locale/pt_BR/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/pt_BR/foreman_azure_rm.po +190 -0
- data/locale/ru/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/ru/foreman_azure_rm.po +190 -0
- data/locale/sv_SE/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/sv_SE/foreman_azure_rm.po +187 -0
- data/locale/zh_CN/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/zh_CN/foreman_azure_rm.po +188 -0
- data/locale/zh_TW/LC_MESSAGES/foreman_azure_rm.mo +0 -0
- data/locale/zh_TW/foreman_azure_rm.po +187 -0
- metadata +59 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc75ad1df578bcc16ca37a67e323b1ff763ec6e6149db99a1056ae88c9248c5d
|
4
|
+
data.tar.gz: 3d8127cce9836f8f23c95947e5497b2c8f3c4d3fc10a7ad025c0d09fa805a06a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a213f22eb2b08b07fe28b803a33136a4d3a977eb46a4b95bf926f48189137efef13aacf37a4d81cf2f47c6d710e5ac8a73d5f498431d7a06d3bf6e4d7567380f
|
7
|
+
data.tar.gz: c361b566af6b568899c60942826a6db92e973da00ac4d6a8641a2c3592090ceaf87fe6a57414b3f260f486b70ebc84c98966da1802477987f816baa19c99a4c1
|
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
|
-
```
|
16
|
+
```console
|
16
17
|
$ gem 'foreman_azure_rm'
|
17
18
|
```
|
18
19
|
|
19
20
|
Or simply:
|
20
21
|
|
21
|
-
```
|
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
|
-
|
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/
|
79
|
+
![](https://i.imgur.com/vsamP4G.png)
|
75
80
|
|
76
81
|
|
77
|
-
![](https://i.imgur.com/
|
82
|
+
![](https://i.imgur.com/Ag9tH55.png)
|
78
83
|
|
79
84
|
|
80
|
-
![](https://i.imgur.com/
|
85
|
+
![](https://i.imgur.com/fNjlFci.png)
|
81
86
|
|
82
87
|
|
83
88
|
## Planned Features
|
84
|
-
*
|
85
|
-
* Support
|
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 =
|
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
|
-
else
|
25
|
-
# ARM best practices stipulate RW caching on the OS disk
|
26
|
-
ComputeModels::CachingTypes::ReadWrite
|
27
|
-
end
|
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(
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
urn =
|
86
|
+
def define_image(rg_name, image)
|
87
|
+
image_type, image_id = image.split('://')
|
88
|
+
case image_type
|
89
|
+
when 'marketplace'
|
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
|
-
vhd_path = nil
|
59
|
-
end
|
60
|
-
|
61
|
-
if vhd_path.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
|
-
|
66
|
-
image_ref = ComputeModels::ImageReference.new
|
67
|
-
image_ref.id = vhd_path
|
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[:
|
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, :
|
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
|
63
|
-
|
64
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|
-
|
95
|
-
|
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
|
-
|
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
|
@@ -207,10 +260,14 @@ module ForemanAzureRm
|
|
207
260
|
args[:vm_name] = args[:name].split('.')[0]
|
208
261
|
nics = create_nics(region, args)
|
209
262
|
if args[:password].present? && !args[:ssh_key_data].present?
|
263
|
+
# Any change to sudoers_cmd and formation of new
|
264
|
+
# args[:script_command] must be accordingly changed
|
265
|
+
# in script_command method in AzureRmCompute class
|
210
266
|
sudoers_cmd = "$echo #{args[:password]} | sudo -S echo '\"#{args[:username]}\" ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/waagent"
|
211
267
|
if args[:script_command].present?
|
212
268
|
# to run the script_cmd given through form as username
|
213
|
-
|
269
|
+
user_command = args[:script_command]
|
270
|
+
args[:script_command] = sudoers_cmd + " ; su - \"#{args[:username]}\" -c \"#{user_command}\""
|
214
271
|
else
|
215
272
|
args[:script_command] = sudoers_cmd
|
216
273
|
end
|
@@ -232,9 +289,10 @@ module ForemanAzureRm
|
|
232
289
|
disable_password_authentication: disable_password_auth,
|
233
290
|
network_interface_card_ids: nics.map(&:id),
|
234
291
|
platform: args[:platform],
|
235
|
-
|
292
|
+
image_id: args[:image_id],
|
236
293
|
os_disk_caching: args[:os_disk_caching],
|
237
294
|
premium_os_disk: args[:premium_os_disk],
|
295
|
+
data_disks: args[:volumes_attributes],
|
238
296
|
custom_data: args[:user_data],
|
239
297
|
script_command: args[:script_command],
|
240
298
|
script_uris: args[:script_uris],
|
@@ -242,7 +300,7 @@ module ForemanAzureRm
|
|
242
300
|
logger.debug "Virtual Machine #{args[:vm_name]} Created Successfully."
|
243
301
|
create_vm_extension(region, args)
|
244
302
|
# return the vm object using azure_vm
|
245
|
-
AzureRmCompute.new(azure_vm: vm, sdk: sdk, resource_group: args[:resource_group], nics: vm_nics(vm))
|
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])
|
246
304
|
rescue RuntimeError => e
|
247
305
|
Foreman::Logging.exception('Unhandled AzureRm error', e)
|
248
306
|
destroy_vm vm.id if vm
|
@@ -269,10 +327,8 @@ module ForemanAzureRm
|
|
269
327
|
end
|
270
328
|
end
|
271
329
|
end
|
272
|
-
if os_disk.present?
|
273
|
-
|
274
|
-
end
|
275
|
-
|
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?
|
276
332
|
true
|
277
333
|
rescue ActiveRecord::RecordNotFound
|
278
334
|
logger.info "Could not find the selected vm."
|