foreman_azure_rm 1.3.1 → 2.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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