foreman_azure_rm 1.3.1 → 2.0.0.pre1

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.
@@ -0,0 +1,95 @@
1
+ module ForemanAzureRM
2
+ class AzureRMCompute
3
+ attr_accessor :sdk
4
+ attr_accessor :azure_vm
5
+
6
+ delegate :name, to: :azure_vm, allow_nil: true
7
+
8
+ def initialize(azure_vm: ComputeModels::VirtualMachine.new, sdk: sdk)
9
+ @azure_vm = azure_vm
10
+ @sdk = sdk
11
+ end
12
+
13
+ def id
14
+ @azure_vm.id
15
+ end
16
+
17
+ def persisted?
18
+ !!identity && !!id
19
+ end
20
+
21
+ def vm_size
22
+ @azure_vm.hardware_profile.vm_size
23
+ end
24
+
25
+ def wait_for(_timeout = 0, _interval = 0, &block)
26
+ instance_eval(&block)
27
+ return true
28
+ end
29
+
30
+ def ready?
31
+ vm_status == 'running'
32
+ end
33
+
34
+ def state
35
+ vm_status
36
+ end
37
+
38
+ def vm_status
39
+ sdk.check_vm_status(@azure_vm.resource_group, name)
40
+ end
41
+
42
+ def network_interface_card_ids
43
+ nics = @azure_vm.network_profile.network_interfaces
44
+ nics.map(&:id)
45
+ end
46
+
47
+ def provisioning_ip_address
48
+ interfaces.each do |nic|
49
+ nic.ip_configurations.each do |configuration|
50
+ next unless configuration.primary
51
+ if configuration.public_ipaddress.present?
52
+ ip_id = configuration.public_ipaddress.id
53
+ ip_rg = ip_id.split('/')[4]
54
+ ip_name = ip_id.split('/')[-1]
55
+ public_ip = sdk.public_ip(ip_rg, ip_name)
56
+ return public_ip.ip_address
57
+ else
58
+ return configuration.private_ipaddress
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def interfaces
65
+ interfaces = []
66
+ unless network_interface_card_ids.nil?
67
+ network_interface_card_ids.each do |nic_id|
68
+ nic_rg = nic_id.split('/')[4]
69
+ nic_name = nic_id.split('/')[-1]
70
+ interfaces << sdk.vm_nic(nic_rg, nic_name)
71
+ end
72
+ end
73
+ interfaces
74
+ end
75
+
76
+ def interfaces=(setifaces)
77
+ @azure_vm.network_profile.network_interfaces = setifaces
78
+ end
79
+
80
+ def ip_addresses
81
+ []
82
+ end
83
+
84
+ def identity
85
+ @azure_vm.name
86
+ end
87
+
88
+ def identity=(setuuid)
89
+ @azure_vm.name = setuuid
90
+ end
91
+
92
+ def image_id
93
+ end
94
+ end
95
+ end
@@ -1,9 +1,8 @@
1
1
  <%= text_f f, :url, :label => _('Client ID'), :required => true %>
2
- <%= password_f f, :password, :label => _('Client Secret'), :required => true %>
2
+ <%= password_f f, :password, :label => _('Client Secret'), :keep_value => true, :required => true %>
3
3
  <%= text_f f, :user, :label => _('Subscription ID'), :required => true %>
4
- <%= text_f f, :uuid, :label => _('Tenant ID'), :required => true,
5
- :help_inline => link_to_function(
6
- _("Test Connection"), "testConnection(this)",
7
- :class => "btn btn-default",
8
- :'data-url' => test_connection_compute_resources_path) +
9
- hidden_spinner('', :id => 'test_connection_indicator').html_safe %>
4
+ <%= text_f f, :uuid, :label => _('Tenant ID'), :required => true %>
5
+
6
+ <div class="col-md-offset-2">
7
+ <%= test_connection_button_f(f, true) %>
8
+ </div>
@@ -5,13 +5,13 @@
5
5
  %>
6
6
 
7
7
  <script>
8
- function azure_rm_location_callback() {
9
- azure_rm_get_size_from_location();
10
- azure_rm_subnets_from_location();
8
+ function azure_rm_region_callback() {
9
+ azure_rm_get_size_from_region();
10
+ azure_rm_subnets_from_region();
11
11
  }
12
12
 
13
- function azure_rm_get_size_from_location() {
14
- var location = $('#azure_rm_location').val();
13
+ function azure_rm_get_size_from_region() {
14
+ var region = $('#azure_rm_region').val();
15
15
  var size_spinner = $('#azure_rm_size_spinner');
16
16
  var sizes = $('#azure_rm_size');
17
17
  var imageId = $('#azure_rm_image_id').val();
@@ -22,7 +22,7 @@
22
22
  }
23
23
  size_spinner.removeClass('hide');
24
24
  $.ajax({
25
- data: {"location_string": location, "image_id": imageId},
25
+ data: {"region_string": region, "image_id": imageId},
26
26
  type: 'get',
27
27
  url: '/azure_rm/sizes',
28
28
  complete: function () {
@@ -47,19 +47,19 @@
47
47
  });
48
48
  }
49
49
 
50
- function azure_rm_subnets_from_location() {
50
+ function azure_rm_subnets_from_region() {
51
51
  var imageId = $('#azure_rm_image_id').val();
52
52
  var subnets = $('#azure_rm_subnet');
53
- var location = $('#azure_rm_location').val();
53
+ var region = $('#azure_rm_region').val();
54
54
  if (typeof tfm == 'undefined') { // earlier than 1.13
55
55
  foreman.tools.showSpinner();
56
56
  } else {
57
57
  tfm.tools.showSpinner();
58
58
  }
59
59
  $.ajax({
60
- data: {"image_id": imageId, "location": location},
61
- type: "get",
62
- url: "/azure_rm/subnets",
60
+ data: {"image_id": imageId, "region": region},
61
+ type: 'get',
62
+ url: '/azure_rm/subnets',
63
63
  complete: function () {
64
64
  reloadOnAjaxComplete('#azure_rm_subnet');
65
65
  if (typeof tfm == 'undefined') { // earlier than 1.13
@@ -77,33 +77,39 @@
77
77
  subnets.empty();
78
78
  $.each(request_subnets, function () {
79
79
  //noinspection JSAnnotator
80
- subnets.append($("<option />").val(this.id).text(`${this.virtual_network_name} - ${this.name} (${this.address_prefix})`));
80
+ subnets.append($("<option />").val(this.id).text(`${this.id.split('/')[8]} - ${this.name} (${this.address_prefix})`));
81
81
  });
82
82
  }
83
83
  });
84
84
  }
85
85
  </script>
86
86
 
87
- <%= selectable_f f, :location, compute_resource.locations,
88
- { :include_blank => _('Please select an Azure region') },
89
- {
90
- :label => _('Azure Region'),
91
- :required => true,
92
- :id => 'azure_rm_location',
93
- :label_size => "col-md-2",
94
- :onchange => 'azure_rm_location_callback();',
95
- :help_inline => spinner_button_f(f, _('Reload Images, Sizes, vNets'),
96
- 'azure_rm_location_callback();',
97
- {
98
- :id => 'load_subnets_btn',
99
- :spinner_id => 'load_subnets_indicator',
100
- :class => 'btn-success',
101
- :spinner_class => 'spinner-inverse'
102
- })
103
- }
87
+ <% #This view has been modified and wraps the properties of azure_vm
88
+ # using fields_for rails method.
104
89
  %>
105
90
 
106
- <%= selectable_f f, :resource_group, resource_groups,
91
+ <%= f.fields_for :azure_vm do |vm_f| %>
92
+
93
+ <%= selectable_f vm_f, :location, compute_resource.regions,
94
+ { :include_blank => _('Please select an Azure region') },
95
+ {
96
+ :label => _('Azure Region'),
97
+ :required => true,
98
+ :id => 'azure_rm_region',
99
+ :label_size => "col-md-2",
100
+ :onchange => 'azure_rm_region_callback();',
101
+ :help_inline => spinner_button_f(f, _('Reload Images, Sizes, vNets'),
102
+ 'azure_rm_region_callback();',
103
+ {
104
+ :id => 'load_subnets_btn',
105
+ :spinner_id => 'load_subnets_indicator',
106
+ :class => 'btn-success',
107
+ :spinner_class => 'spinner-inverse'
108
+ })
109
+ }
110
+ %>
111
+
112
+ <%= selectable_f vm_f, :resource_group, resource_groups,
107
113
  { :include_blank => true },
108
114
  {
109
115
  :disabled => resource_groups.empty?,
@@ -111,87 +117,76 @@
111
117
  :required => true,
112
118
  :id => 'azure_rm_rg'
113
119
  }
114
- %>
120
+ %>
115
121
 
116
- <%= selectable_f f, :vm_size, [],
122
+ <%= selectable_f vm_f, :vm_size, [],
117
123
  { :include_blank => _('Please first select an Azure region') },
118
124
  {
119
125
  :label => _('VM Size'),
120
126
  :required => true,
121
127
  :id => 'azure_rm_size'
122
128
  }
123
- %>
129
+ %>
124
130
 
125
- <%= selectable_f f, :platform, %w(Linux Windows),
131
+ <%= selectable_f vm_f, :platform, %w(Linux Windows),
126
132
  {},
127
133
  {
128
134
  :label => _('Platform'),
129
135
  :required => true
130
136
  }
131
- %>
137
+ %>
132
138
 
133
- <%= text_f f, :username,
139
+ <%= text_f vm_f, :username,
134
140
  {
135
141
  :label => _('Username'),
136
142
  :required => true
137
143
  }
138
- %>
139
- <%= text_f f, :password,
144
+ %>
145
+
146
+ <%= password_f vm_f, :password,
140
147
  {
141
148
  :label => _('Password'),
142
- :required => true
149
+ :required => true,
150
+ :placeholder => "********"
143
151
  }
144
- %>
152
+ %>
145
153
 
146
- <%= textarea_f f, :ssh_key_data,
154
+ <%= textarea_f vm_f, :ssh_key_data,
147
155
  {
148
156
  :label => _('SSH Key')
149
157
  }
150
- %>
151
-
152
- <%= number_f f, :os_disk_size,
153
- {
154
- :class => "col-md-2",
155
- :label => _('OS Disk Size (GB)'), :label_size => "col-md-2",
156
- :required => true
157
- }
158
- %>
158
+ %>
159
159
 
160
- <%= checkbox_f f, :premium_os_disk,
160
+ <%= checkbox_f vm_f, :premium_os_disk,
161
161
  {
162
162
  :label => _('Premium OS Disk'), :label_size => "col-md-2"
163
163
  },
164
164
  'true',
165
165
  'false'
166
- %>
166
+ %>
167
167
 
168
- <%= selectable_f f, :os_disk_caching, %w(None ReadOnly ReadWrite),
168
+ <%= selectable_f vm_f, :os_disk_caching, %w(None ReadOnly ReadWrite),
169
169
  {},
170
170
  {
171
171
  :label => _('OS Disk Caching'),
172
172
  :required => true,
173
173
  :class => "col-md-2"
174
174
  }
175
- %>
176
-
177
- <%= text_f f, :puppet_master,
178
- {
179
- :label => _('Puppet Master'),
180
- :help_inline => _('For the Azure Puppet extension for Windows')
181
- }
182
- %>
175
+ %>
183
176
 
184
- <%= text_f f, :script_command,
177
+ <%= text_f vm_f, :script_command,
185
178
  {
186
- :label => _('Custom Script Command')
179
+ :label => _('Custom Script Command'),
180
+ :help_inline => _("To perform commands as root, prefix it with 'sudo'.")
187
181
  }
188
- %>
182
+ %>
189
183
 
190
- <%= text_f f, :script_uris,
184
+ <%= text_f vm_f, :script_uris,
191
185
  {
192
186
  :label => _('Comma seperated file URIs')
193
187
  }
194
- %>
188
+ %>
189
+ <% end %>
195
190
 
196
191
  <div id="image_selection">
197
192
  <%= select_f f, :image_id, images, :uuid, :name,
@@ -204,4 +199,4 @@
204
199
  :id => 'azure_rm_image_id'
205
200
  }
206
201
  %>
207
- </div>
202
+ </div>
@@ -13,8 +13,8 @@
13
13
  <tr>
14
14
  <td><%= link_to_if_authorized vm.name, hash_for_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => vm.identity).merge(:auth_object => @compute_resource, :authorizer => :authorizer) %></td>
15
15
  <td><%= vm.vm_size %></td>
16
- <td><%= vm.resource_group %></td>
17
- <td><%= vm.location %></td>
16
+ <td><%= vm.azure_vm.resource_group %></td>
17
+ <td><%= vm.azure_vm.location %></td>
18
18
  <td> <span <%= vm_power_class(vm.ready?) %>> <%= vm_state(vm) %> </span> </td>
19
19
  <td>
20
20
  <%= action_buttons(
@@ -26,4 +26,4 @@
26
26
  </td>
27
27
  </tr>
28
28
  <% end %>
29
- </table>
29
+ </table>
@@ -1,14 +1,26 @@
1
- <% title @vm.name %>
1
+ <% title @vm.azure_vm.name %>
2
2
  <div class='col-md-12'>
3
3
  <table class="<%= table_css_classes %>">
4
4
  <thead>
5
5
  <tr><th colspan="2"><%=_('Properties') %></th></tr>
6
6
  </thead>
7
7
  <tbody>
8
- <%= prop :id %>
9
- <%= prop :location %>
10
- <%= prop :vm_size %>
11
- <%= prop :platform %>
8
+ <tr>
9
+ <td>Id</td>
10
+ <td><%=@vm.id%></td>
11
+ </tr>
12
+ <tr>
13
+ <td>Location</td>
14
+ <td><%=@vm.azure_vm.location%></td>
15
+ </tr>
16
+ <tr>
17
+ <td>VM Size</td>
18
+ <td><%=@vm.vm_size%></td>
19
+ </tr>
20
+ <tr>
21
+ <td>Platform</td>
22
+ <td><%=@vm.azure_vm.storage_profile.os_disk.os_type%></td>
23
+ </tr>
12
24
  </tbody>
13
25
  </table>
14
26
  </div>
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Tests
4
+ namespace :test do
5
+ desc 'Test foreman_azure_rm'
6
+ Rake::TestTask.new(:foreman_azure_rm) do |t|
7
+ test_dir = File.join(File.dirname(__FILE__), '..', 'test')
8
+ t.libs << ['test', test_dir]
9
+ t.pattern = "#{test_dir}/**/*_test.rb"
10
+ t.verbose = true
11
+ t.warning = false
12
+ end
13
+ end
@@ -0,0 +1,141 @@
1
+ module ForemanAzureRM
2
+ Storage = Azure::Storage::Profiles::Latest::Mgmt
3
+ Network = Azure::Network::Profiles::Latest::Mgmt
4
+ Compute = Azure::Compute::Profiles::Latest::Mgmt
5
+ Resources = Azure::Resources::Profiles::Latest::Mgmt
6
+
7
+ StorageModels = Storage::Models
8
+ NetworkModels = Network::Models
9
+ ComputeModels = Compute::Models
10
+ ResourceModels = Resources::Models
11
+
12
+ class AzureSDKAdapter
13
+ def initialize(tenant, app_ident, secret_key, sub_id)
14
+ @tenant = tenant
15
+ @app_ident = app_ident
16
+ @secret_key = secret_key
17
+ @sub_id = sub_id
18
+ end
19
+
20
+ def resource_client
21
+ @resource_client ||= Resources::Client.new(azure_credentials)
22
+ end
23
+
24
+ def compute_client
25
+ @compute_client ||= Compute::Client.new(azure_credentials)
26
+ end
27
+
28
+ def network_client
29
+ @network_client ||= Network::Client.new(azure_credentials)
30
+ end
31
+
32
+ def storage_client
33
+ @storage_client ||= Storage::Client.new(azure_credentials)
34
+ end
35
+
36
+ def azure_credentials
37
+ provider = MsRestAzure::ApplicationTokenProvider.new(
38
+ @tenant,
39
+ @app_ident,
40
+ @secret_key)
41
+
42
+ credentials = MsRest::TokenCredentials.new(provider)
43
+
44
+ {
45
+ credentials: credentials,
46
+ subscription_id: @sub_id
47
+ }
48
+ end
49
+
50
+ def rgs
51
+ rgs = resource_client.resource_groups.list
52
+ rgs.map(&:name)
53
+ end
54
+
55
+ def vnets
56
+ network_client.virtual_networks.list_all
57
+ end
58
+
59
+ def subnets(resource_group, vnet_name)
60
+ network_client.subnets.list(resource_group, vnet_name)
61
+ end
62
+
63
+ def public_ip(rg_name, pip_name)
64
+ network_client.public_ipaddresses.get(rg_name, pip_name)
65
+ end
66
+
67
+ def vm_nic(rg_name,nic_name)
68
+ network_client.network_interfaces.get(rg_name, nic_name)
69
+ end
70
+
71
+ def list_vm_sizes(region)
72
+ stripped_region = region.gsub(/\s+/, '').downcase
73
+ compute_client.virtual_machine_sizes.list(stripped_region).value()
74
+ end
75
+
76
+ def list_vms(rg_name)
77
+ # List all VMs in a resource group
78
+ virtual_machines = compute_client.virtual_machines.list(rg_name)
79
+ end
80
+
81
+ def get_vm(rg_name, vm_name)
82
+ compute_client.virtual_machines.get(rg_name, vm_name)
83
+ end
84
+
85
+ def get_storage_accts
86
+ result = storage_client.storage_accounts.list
87
+ result.value
88
+ end
89
+
90
+ def create_or_update_vm(rg_name, vm_name, parameters)
91
+ compute_client.virtual_machines.create_or_update(rg_name, vm_name, parameters)
92
+ end
93
+
94
+ def create_or_update_vm_extensions(rg_name, vm_name, vm_extension_name, extension_params)
95
+ compute_client.virtual_machine_extensions.create_or_update(rg_name,
96
+ vm_name,
97
+ vm_extension_name,
98
+ extension_params)
99
+ end
100
+
101
+ def create_or_update_pip(rg_name, pip_name, parameters)
102
+ network_client.public_ipaddresses.create_or_update(rg_name, pip_name, parameters)
103
+ end
104
+
105
+ def create_or_update_nic(rg_name, nic_name, parameters)
106
+ network_client.network_interfaces.create_or_update(rg_name, nic_name, parameters)
107
+ end
108
+
109
+ def delete_pip(rg_name, pip_name)
110
+ network_client.public_ipaddresses.delete(rg_name, pip_name)
111
+ end
112
+
113
+ def delete_nic(rg_name, nic_name)
114
+ network_client.network_interfaces.delete(rg_name, nic_name)
115
+ end
116
+
117
+ def delete_vm(rg_name, vm_name)
118
+ compute_client.virtual_machines.delete(rg_name, vm_name)
119
+ end
120
+
121
+ def delete_disk(rg_name, osdisk_name)
122
+ compute_client.disks.delete(rg_name, osdisk_name)
123
+ end
124
+
125
+ def check_vm_status(rg_name, vm_name)
126
+ virtual_machine = compute_client.virtual_machines.get(rg_name, vm_name, expand:'instanceView')
127
+ get_status(virtual_machine)
128
+ end
129
+
130
+ def get_status(virtual_machine)
131
+ vm_statuses = virtual_machine.instance_view.statuses
132
+ vm_status = nil
133
+ vm_statuses.each do |status|
134
+ if status.code.include? 'PowerState'
135
+ vm_status = status.code.split('/')[1]
136
+ end
137
+ end
138
+ vm_status
139
+ end
140
+ end
141
+ end