foreman_hyperv 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rubocop.yml +22 -0
- data/.rubocop_todo.yml +20 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +14 -0
- data/Rakefile +10 -0
- data/app/assets/javascripts/compute_resources/hyperv/base.js +6 -0
- data/app/helpers/hyperv_helpers.rb +7 -0
- data/app/models/concerns/fog_extensions/hyperv/compute.rb +0 -0
- data/app/models/concerns/fog_extensions/hyperv/network_adapter.rb +29 -0
- data/app/models/concerns/fog_extensions/hyperv/server.rb +77 -0
- data/app/models/concerns/fog_extensions/hyperv/vhd.rb +12 -0
- data/app/models/foreman_hyperv/hyperv.rb +246 -0
- data/app/views/compute_resources/form/_hyperv.html.erb +7 -0
- data/app/views/compute_resources/show/_hyperv.html.erb +1 -0
- data/app/views/compute_resources_vms/form/hyperv/_base.html.erb +20 -0
- data/app/views/compute_resources_vms/form/hyperv/_network.html.erb +10 -0
- data/app/views/compute_resources_vms/form/hyperv/_volume.html.erb +5 -0
- data/app/views/compute_resources_vms/index/_hyperv.html.erb +25 -0
- data/app/views/compute_resources_vms/show/_hyperv.html.erb +25 -0
- data/foreman_hyperv.gemspec +27 -0
- data/lib/foreman_hyperv/engine.rb +35 -0
- data/lib/foreman_hyperv/version.rb +3 -0
- data/lib/foreman_hyperv.rb +4 -0
- data/test/foreman_hyperv_test.rb +11 -0
- data/test/test_helper.rb +4 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 095c817dd697a8c2bde70d4b2a4d4dad16eba039
|
4
|
+
data.tar.gz: 59761e7d008a15a913ee8951678c8467a5ed85ec
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 61ef39ff83c31aa3e9fd8b8a6c8151163b4eba692b8c54025c3ab0544e9c6b22990c44cdb5d71d7f3b81fe2ec5073def03354d513c0c8a6483ea3689724202f0
|
7
|
+
data.tar.gz: 35cc0657a3474aacb7033550580478fd4285599e290147fb95713f57c8a918b9f4fce48a7977d14574d39a7f21f74637be7dbc8e432497752e816cf0658a3bd7
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
inherit_from:
|
2
|
+
- .rubocop_todo.yml
|
3
|
+
|
4
|
+
Rails:
|
5
|
+
Enabled: true # always run the rails cops
|
6
|
+
|
7
|
+
# Don't enforce documentation
|
8
|
+
Style/Documentation:
|
9
|
+
Enabled: false
|
10
|
+
|
11
|
+
Style/HashSyntax:
|
12
|
+
Enabled: false
|
13
|
+
SupportedStyles:
|
14
|
+
- ruby19
|
15
|
+
- hash_rockets
|
16
|
+
|
17
|
+
# Force before_filter until upgrade to Rails 4
|
18
|
+
Rails/ActionFilter:
|
19
|
+
EnforcedStyle: filter
|
20
|
+
|
21
|
+
Metrics/MethodLength:
|
22
|
+
Max: 20
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# This configuration was generated by `rubocop --auto-gen-config`
|
2
|
+
# on 2015-05-21 16:13:17 +0300 using RuboCop version 0.26.1.
|
3
|
+
# The point is for the user to remove these configuration records
|
4
|
+
# one by one as the offenses are removed from the code base.
|
5
|
+
# Note that changes in the inspected code, or installation of new
|
6
|
+
# versions of RuboCop, may require this file to be generated again.
|
7
|
+
|
8
|
+
# Offense count: 11
|
9
|
+
# Configuration parameters: AllowURI, URISchemes.
|
10
|
+
Metrics/LineLength:
|
11
|
+
Max: 111
|
12
|
+
|
13
|
+
# Offense count: 8
|
14
|
+
Style/Documentation:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
# Offense count: 1
|
18
|
+
# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
|
19
|
+
Style/Next:
|
20
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Alexander Olofsson
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Foreman Hyper-V
|
2
|
+
|
3
|
+
Microsoft Hyper-V compute resource for Foreman
|
4
|
+
|
5
|
+
Uses the in-development `fog-hyperv` gem found [here](https://github.com/ace13/fog-hyperv).
|
6
|
+
|
7
|
+
## Contributing
|
8
|
+
|
9
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ace13/foreman_hyperv.
|
10
|
+
|
11
|
+
## License
|
12
|
+
|
13
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
14
|
+
|
data/Rakefile
ADDED
File without changes
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module FogExtensions
|
2
|
+
module Hyperv
|
3
|
+
module NetworkAdapter
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include ActionView::Helpers::NumberHelper
|
6
|
+
|
7
|
+
def to_s
|
8
|
+
name
|
9
|
+
end
|
10
|
+
|
11
|
+
def mac
|
12
|
+
m = mac_address
|
13
|
+
"#{m[0, 2]}:#{m[2, 2]}:#{m[4, 2]}:#{m[6, 2]}:#{m[8, 2]}:#{m[10, 2]}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def mac=(m)
|
17
|
+
self.mac_address = m.remove ':'
|
18
|
+
end
|
19
|
+
|
20
|
+
def network
|
21
|
+
switch_name
|
22
|
+
end
|
23
|
+
|
24
|
+
def network=(net)
|
25
|
+
self.switch_name = net
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module FogExtensions
|
2
|
+
module Hyperv
|
3
|
+
module Server
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include ActionView::Helpers::NumberHelper
|
6
|
+
|
7
|
+
attr_accessor :start
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
name
|
11
|
+
end
|
12
|
+
|
13
|
+
def folder_name
|
14
|
+
name.gsub(/[^0-9A-Za-z.\-]/, '_')
|
15
|
+
end
|
16
|
+
|
17
|
+
def mac(m = mac_addresses.first)
|
18
|
+
"#{m[0, 2]}:#{m[2, 2]}:#{m[4, 2]}:#{m[6, 2]}:#{m[8, 2]}:#{m[10, 2]}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def clean_mac_addresses
|
22
|
+
network_adapters.map { |n| mac(n.mac_address) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def interfaces
|
26
|
+
network_adapters
|
27
|
+
end
|
28
|
+
|
29
|
+
def volumes
|
30
|
+
vhds
|
31
|
+
end
|
32
|
+
|
33
|
+
def persisted?
|
34
|
+
identity.present?
|
35
|
+
end
|
36
|
+
|
37
|
+
def interfaces_attributes=(_attributes); end
|
38
|
+
|
39
|
+
def volumes_attributes=(_attributes); end
|
40
|
+
|
41
|
+
def secure_boot_enabled=(_); end
|
42
|
+
|
43
|
+
def secure_boot_enabled
|
44
|
+
return false if generation == 1
|
45
|
+
firmware.secure_boot == :On
|
46
|
+
end
|
47
|
+
|
48
|
+
def reset
|
49
|
+
restart(force: true)
|
50
|
+
end
|
51
|
+
|
52
|
+
def stop
|
53
|
+
requires :name, :computer_name
|
54
|
+
service.stop_vm options.merge(
|
55
|
+
name: name,
|
56
|
+
computer_name: computer_name,
|
57
|
+
force: true
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
def vm_description
|
62
|
+
format _('%{cpus} CPUs and %{ram} memory'),
|
63
|
+
cpus: processor_count,
|
64
|
+
ram: number_to_human_size(memory_startup)
|
65
|
+
end
|
66
|
+
|
67
|
+
def select_nic(fog_nics, nic)
|
68
|
+
nic_attrs = nic.compute_attributes
|
69
|
+
logger.debug "select_nic(#{fog_nics}, #{nic}[#{nic_attrs}])"
|
70
|
+
match = fog_nics.detect { |fn| fn.id == nic_attrs['id'] } # Check the id
|
71
|
+
match ||= fog_nics.detect { |fn| fn.name == nic_attrs['name'] } # Check the name
|
72
|
+
match ||= fog_nics.detect { |fn| fn.switch_name == nic_attrs['network'] } # Fall back to the switch
|
73
|
+
match
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,246 @@
|
|
1
|
+
module ForemanHyperv
|
2
|
+
class Hyperv < ::ComputeResource
|
3
|
+
validates :url, :user, :password, presence: true
|
4
|
+
|
5
|
+
def capabilities
|
6
|
+
[:build]
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.provider_friendly_name
|
10
|
+
'Hyper-V'
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.model_name
|
14
|
+
ComputeResource.model_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_connection(options = {})
|
18
|
+
super options
|
19
|
+
client.valid?
|
20
|
+
rescue Fog::Hyperv::Errors::ServiceError, ArgumentError, WinRM::WinRMAuthorizationError
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
def provided_attributes
|
25
|
+
super.merge(mac: :mac)
|
26
|
+
end
|
27
|
+
|
28
|
+
# TODO
|
29
|
+
def max_cpu_count
|
30
|
+
hypervisor.logical_processor_count
|
31
|
+
end
|
32
|
+
|
33
|
+
def max_memory
|
34
|
+
hypervisor.memory_capacity
|
35
|
+
end
|
36
|
+
|
37
|
+
def associated_host(vm)
|
38
|
+
associate_by('mac', vm.clean_mac_addresses)
|
39
|
+
end
|
40
|
+
|
41
|
+
def new_vm(attr = {})
|
42
|
+
vm = super
|
43
|
+
interfaces = nested_attributes_for :interfaces, attr[:interfaces_attributes]
|
44
|
+
interfaces.map { |i| vm.interfaces << new_interface(i) }
|
45
|
+
volumes = nested_attributes_for :volumes, attr[:volumes_attributes]
|
46
|
+
volumes.map { |v| vm.volumes << new_volume(v) }
|
47
|
+
vm
|
48
|
+
end
|
49
|
+
|
50
|
+
def stop_vm(uuid)
|
51
|
+
find_vm_by_uuid(uuid).stop force: true
|
52
|
+
end
|
53
|
+
|
54
|
+
def create_vm(args = {})
|
55
|
+
args = vm_instance_defaults.merge(args.to_hash.deep_symbolize_keys)
|
56
|
+
logger.debug "Creating a VM with arguments; #{args}"
|
57
|
+
pre_create = {
|
58
|
+
boot_device: 'NetworkAdapter',
|
59
|
+
generation: args[:generation].to_i,
|
60
|
+
memory_startup: args[:memory_startup].presence,
|
61
|
+
name: args[:name],
|
62
|
+
no_vhd: true
|
63
|
+
}
|
64
|
+
|
65
|
+
vm = client.servers.create pre_create
|
66
|
+
|
67
|
+
post_save = {
|
68
|
+
dynamic_memory_enabled: ActiveRecord::Type::Boolean.new.type_cast_from_user(args[:dynamic_memory_enabled]),
|
69
|
+
notes: args[:notes].presence,
|
70
|
+
processor_count: args[:processor_count].to_i
|
71
|
+
}
|
72
|
+
post_save.each do |k, v|
|
73
|
+
vm.send("#{k}=".to_sym, v)
|
74
|
+
end
|
75
|
+
|
76
|
+
vm.save if vm.dirty?
|
77
|
+
|
78
|
+
if vm.generation == 2 && !args[:secure_boot_enabled].nil?
|
79
|
+
f = vm.firmware
|
80
|
+
f.secure_boot = ActiveRecord::Type::Boolean.new.type_cast_from_user(args[:secure_boot_enabled]) ? :On : :Off
|
81
|
+
f.save if f.dirty?
|
82
|
+
end
|
83
|
+
|
84
|
+
create_interfaces(vm, args[:interfaces_attributes])
|
85
|
+
create_volumes(vm, args[:volumes_attributes])
|
86
|
+
|
87
|
+
vm
|
88
|
+
rescue StandardError => e
|
89
|
+
vm.stop turn_off: true
|
90
|
+
|
91
|
+
raise e
|
92
|
+
end
|
93
|
+
|
94
|
+
def save_vm(uuid, attr)
|
95
|
+
vm = find_vm_by_uuid(uuid)
|
96
|
+
logger.debug "Saving a VM with arguments; #{attr}"
|
97
|
+
attr.each do |k, v|
|
98
|
+
vm.send("#{k}=".to_sym, v) if vm.respond_to?("#{k}=".to_sym)
|
99
|
+
end
|
100
|
+
if vm.generation == 2 && !args[:secure_boot_enabled].nil?
|
101
|
+
f = vm.firmware
|
102
|
+
f.secure_boot = ActiveRecord::Type::Boolean.new.type_cast_from_user(args[:secure_boot_enabled]) ? :On : :Off
|
103
|
+
f.save if f.dirty?
|
104
|
+
end
|
105
|
+
update_interfaces(vm, attr[:interfaces_attributes])
|
106
|
+
update_volumes(vm, attr[:volumes_attributes])
|
107
|
+
vm.save if vm.dirty?
|
108
|
+
vm
|
109
|
+
end
|
110
|
+
|
111
|
+
def destroy_vm(uuid)
|
112
|
+
vm = find_vm_by_uuid(uuid)
|
113
|
+
vm.stop force: true if vm.ready?
|
114
|
+
vm.hard_drives.each do |hd|
|
115
|
+
hd.vhd.destroy if hd.path
|
116
|
+
end
|
117
|
+
# TODO: Remove the empty VM folder
|
118
|
+
vm.destroy
|
119
|
+
rescue ActiveRecord::RecordNotFound, Fog::Errors::NotFound
|
120
|
+
# if the VM does not exists, we don't really care.
|
121
|
+
true
|
122
|
+
end
|
123
|
+
|
124
|
+
def new_interface(attr = {})
|
125
|
+
client.network_adapters.new attr
|
126
|
+
end
|
127
|
+
|
128
|
+
def new_volume(attr = {})
|
129
|
+
client.vhds.new attr
|
130
|
+
end
|
131
|
+
|
132
|
+
def new_cdrom(attr = {})
|
133
|
+
client.dvd_drives.new attr
|
134
|
+
end
|
135
|
+
|
136
|
+
def editable_network_interfaces?
|
137
|
+
true
|
138
|
+
end
|
139
|
+
|
140
|
+
def switches
|
141
|
+
client.switches.all # _quick_query: true
|
142
|
+
end
|
143
|
+
|
144
|
+
def supports_update?
|
145
|
+
true
|
146
|
+
end
|
147
|
+
|
148
|
+
def available_hypervisors
|
149
|
+
client.hosts
|
150
|
+
end
|
151
|
+
|
152
|
+
def hypervisor
|
153
|
+
client.hosts.first
|
154
|
+
end
|
155
|
+
|
156
|
+
protected
|
157
|
+
|
158
|
+
def client
|
159
|
+
@client ||= Fog::Compute.new(
|
160
|
+
provider: :HyperV,
|
161
|
+
hyperv_endpoint: url,
|
162
|
+
hyperv_username: user,
|
163
|
+
hyperv_password: password
|
164
|
+
)
|
165
|
+
end
|
166
|
+
|
167
|
+
def vm_instance_defaults
|
168
|
+
super.merge(
|
169
|
+
generation: 1,
|
170
|
+
memory_startup: 512.megabytes,
|
171
|
+
processor_count: 1,
|
172
|
+
boot_device: 'NetworkAdapter'
|
173
|
+
)
|
174
|
+
end
|
175
|
+
|
176
|
+
def create_interfaces(vm, attrs)
|
177
|
+
vm.network_adapters.each(&:destroy)
|
178
|
+
|
179
|
+
interfaces = nested_attributes_for :interfaces, attrs
|
180
|
+
logger.debug "Building interfaces with: #{interfaces}"
|
181
|
+
interfaces.each do |iface|
|
182
|
+
nic = vm.network_adapters.create name: iface[:name], switch_name: iface[:network]
|
183
|
+
if iface[:mac]
|
184
|
+
nic.mac = iface[:mac]
|
185
|
+
nic.dynamic_mac_address_enabled = false
|
186
|
+
end
|
187
|
+
nic.save
|
188
|
+
end
|
189
|
+
|
190
|
+
# Populate the MAC addresses
|
191
|
+
vm.start
|
192
|
+
vm.stop turn_off: true
|
193
|
+
|
194
|
+
vm.network_adapters.reload
|
195
|
+
vm.network_adapters.each do |nic|
|
196
|
+
nic.dynamic_mac_address_enabled = false
|
197
|
+
nic.save if nic.dirty?
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def create_volumes(vm, attrs)
|
202
|
+
volumes = nested_attributes_for :volumes, attrs
|
203
|
+
logger.debug "Building volumes with: #{volumes}"
|
204
|
+
volumes.each do |vol|
|
205
|
+
vhd = vm.vhds.create path: vm.folder_name + '\\' + vol[:path], size: vol[:size]
|
206
|
+
vm.hard_drives.create path: vhd.path
|
207
|
+
end
|
208
|
+
vm.hard_drives.reload
|
209
|
+
end
|
210
|
+
|
211
|
+
def update_interfaces(vm, attrs)
|
212
|
+
interfaces = nested_attributes_for :interfaces, attrs
|
213
|
+
logger.debug "Updating interfaces with: #{interfaces}"
|
214
|
+
interfaces.each do |interface|
|
215
|
+
if interface[:id].blank? && interface[:_delete] != '1'
|
216
|
+
nic = vm.network_adapters.create interface
|
217
|
+
nic.dynamic_mac_address_enabled = false if nic.mac
|
218
|
+
nic.save
|
219
|
+
elsif interface[:id].present?
|
220
|
+
nic = vm.network_adapters.find { |n| n.id == interface[:id] }
|
221
|
+
if interface[:_delete] == '1'
|
222
|
+
nic.delete
|
223
|
+
else
|
224
|
+
interface.each do |k, v|
|
225
|
+
nic.send("#{k}=".to_sym, v)
|
226
|
+
end
|
227
|
+
nic.save if nic.dirty?
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def update_volumes(vm, attrs)
|
234
|
+
volumes = nested_attributes_for :volumes, attrs
|
235
|
+
logger.debug "Updating volumes with: #{volumes}"
|
236
|
+
volumes.each do |volume|
|
237
|
+
if volume[:_delete] == '1' && volume[:id].present?
|
238
|
+
hd = vm.hard_drives.get(path: volume[:path])
|
239
|
+
hd.vhd.destroy
|
240
|
+
hd.destroy
|
241
|
+
end
|
242
|
+
vm.hard_drives.create(path: volume[:path], size: volume[:size]) if volume[:id].blank?
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<%= text_f f, :url, label: _('WinRM Endpoint'), help_block: _('e.g. http://host.example.com:5985/wsman')%>
|
2
|
+
<%= text_f f, :user, label: _('User') %>
|
3
|
+
<%= password_f f, :password, label: _('Password') %>
|
4
|
+
|
5
|
+
<%= link_to_function _("Test Connection"), "testConnection(this)", :class => "btn + #{@compute_resource.test_connection.is_a?(FalseClass) ? "btn-default" : "btn-success"}", :'data-url' => test_connection_compute_resources_path %>
|
6
|
+
|
7
|
+
<%= hidden_spinner('', :id => 'test_connection_indicator') %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%# Placeholder %>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<%#= compute_specific_js(compute_resource, 'base') %>
|
2
|
+
<%= javascript_tag("$(document).on('ContentLoad', tfm.numFields.initAll)") %>
|
3
|
+
|
4
|
+
<%
|
5
|
+
generations = [ [1, 'Generation 1 (BIOS)'], [2, 'Generation 2 (UEFI)'] ]
|
6
|
+
%>
|
7
|
+
<%= select_f f, :generation, generations, :first, :last, {}, label: 'Generation', disabled: !new_host, onchange: 'hypervGenerationChange()' %>
|
8
|
+
<%= checkbox_f f, :secure_boot_enabled, { label: _('Use Secure Boot') }, 'true', 'false' %>
|
9
|
+
|
10
|
+
<%= counter_f f, :processor_count, label: _('CPUs'), label_size: 'col-md-2' %>
|
11
|
+
<%= byte_size_f f, :memory_startup, class: 'col-md-2', label: _('Memory') %>
|
12
|
+
<%= checkbox_f f, :dynamic_memory_enabled, { label: _('Use Dynamic Memory') }, 'true', 'false' %>
|
13
|
+
|
14
|
+
<% if new_host %>
|
15
|
+
<% checked = params[:host] && params[:host][:compute_attributes] && params[:host][:compute_attributes][:start] || '1' %>
|
16
|
+
<%= checkbox_f f, :start, { checked: (checked == '1'), help_inline: _("Power ON this machine"), label: _('Start'), label_size: "col-md-2"} if new_host && controller_name != "compute_attributes" %>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<%= textarea_f f, :notes, rows: '3', label: _('Notes') %>
|
20
|
+
<%= f.hidden_field :id %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%
|
2
|
+
networks = compute_resource.switches.map do |sw|
|
3
|
+
[ sw.name, "#{sw.name}#{sw.switch_type ? " (#{sw.switch_type})" : nil}" ]
|
4
|
+
end
|
5
|
+
%>
|
6
|
+
<%= text_f f, :name, :label => _('Name'), :label_size => 'col-md-3' %>
|
7
|
+
<%= select_f f, :network, networks, :first, :last,
|
8
|
+
{ include_blank: true },
|
9
|
+
{ label: _('Network switch'), :label_size => 'col-md-3' } %>
|
10
|
+
<%= f.hidden_field :id %>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<thead>
|
2
|
+
<tr>
|
3
|
+
<th><%= _('Name') -%></th>
|
4
|
+
<th><%= _('CPUs') -%></th>
|
5
|
+
<th><%= _('Memory') -%></th>
|
6
|
+
<th><%= _('Computer') -%></th>
|
7
|
+
<th><%= _('Power') -%></th>
|
8
|
+
<th><%= _('Actions') -%></th>
|
9
|
+
</tr>
|
10
|
+
</thead>
|
11
|
+
<tbody>
|
12
|
+
<% @vms.each do |vm| -%>
|
13
|
+
<tr>
|
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, :auth_action => 'view', :authorizer => authorizer) %></td>
|
15
|
+
<td><%= vm.processor_count %></td>
|
16
|
+
<td><%= number_to_human_size vm.memory_startup %></td>
|
17
|
+
<td><%= vm.computer_name %></td>
|
18
|
+
<td><span <%= vm_power_class(vm.ready?) %>><%= vm_state(vm) %></span></td>
|
19
|
+
<td>
|
20
|
+
<%= action_buttons(vm_power_action(vm, authorizer),
|
21
|
+
display_delete_if_authorized(hash_for_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => vm.identity).merge(:auth_object => @compute_resource, :authorizer => authorizer))) %>
|
22
|
+
</td>
|
23
|
+
</tr>
|
24
|
+
<% end -%>
|
25
|
+
</tbody>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<% title @vm.name %>
|
2
|
+
|
3
|
+
<div class='col-md-12'>
|
4
|
+
<table class="<%= table_css_classes %>">
|
5
|
+
<thead>
|
6
|
+
<tr><th colspan="2"><%=_('Properties') %></th></tr>
|
7
|
+
</thead>
|
8
|
+
<tbody>
|
9
|
+
<%= prop :id %>
|
10
|
+
<%#= prop :cluster %>
|
11
|
+
<%= prop :memory_startup %>
|
12
|
+
<% if @vm.dynamic_memory_enabled %>
|
13
|
+
<%= prop :memory_minimum %>
|
14
|
+
<%= prop :memory_maximum %>
|
15
|
+
<% end %>
|
16
|
+
<%= prop :public_ip_address %>
|
17
|
+
<%= prop :mac %>
|
18
|
+
<%= prop :processor_count %>
|
19
|
+
<%= prop :computer_name %>
|
20
|
+
<%= prop :status %>
|
21
|
+
<%= prop :state %>
|
22
|
+
<%= prop :notes %>
|
23
|
+
</tbody>
|
24
|
+
</table>
|
25
|
+
</div>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'foreman_hyperv/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'foreman_hyperv'
|
9
|
+
spec.version = ForemanHyperv::VERSION
|
10
|
+
spec.authors = ['Alexander Olofsson']
|
11
|
+
spec.email = ['alexander.olofsson@liu.se']
|
12
|
+
|
13
|
+
spec.summary = 'Hyper-V as a Compute Resource for Foreman'
|
14
|
+
spec.description = 'Hyper-V as a Compute Resource for Foreman'
|
15
|
+
spec.homepage = 'https://github.com/ace13/foreman_hyperv'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0")
|
19
|
+
spec.test_files = spec.files.grep(%r{^test\/})
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_runtime_dependency 'fog-hyperv', '~> 0.0.1'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.13'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
27
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ForemanHyperv
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
engine_name 'foreman_hyperv'
|
4
|
+
|
5
|
+
initializer 'foreman_hyperv.register_plugin', :before => :finisher_hook do
|
6
|
+
Foreman::Plugin.register :foreman_hyperv do
|
7
|
+
requires_foreman '>= 1.14'
|
8
|
+
compute_resource ForemanHyperv::Hyperv
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
initializer 'foreman_hyperv.assets.precompile' do |app|
|
13
|
+
app.config.assets.precompile += %w(compute_resources/hyperv/base.js)
|
14
|
+
end
|
15
|
+
|
16
|
+
config.to_prepare do
|
17
|
+
require 'fog/hyperv'
|
18
|
+
|
19
|
+
require 'fog/hyperv/models/compute/server'
|
20
|
+
require File.expand_path(
|
21
|
+
'../../../app/models/concerns/fog_extensions/hyperv/server', __FILE__)
|
22
|
+
Fog::Compute::Hyperv::Server.send(:include, FogExtensions::Hyperv::Server)
|
23
|
+
|
24
|
+
require 'fog/hyperv/models/compute/network_adapter'
|
25
|
+
require File.expand_path(
|
26
|
+
'../../../app/models/concerns/fog_extensions/hyperv/network_adapter', __FILE__)
|
27
|
+
Fog::Compute::Hyperv::NetworkAdapter.send(:include, FogExtensions::Hyperv::NetworkAdapter)
|
28
|
+
|
29
|
+
require 'fog/hyperv/models/compute/vhd'
|
30
|
+
require File.expand_path(
|
31
|
+
'../../../app/models/concerns/fog_extensions/hyperv/vhd', __FILE__)
|
32
|
+
Fog::Compute::Hyperv::Vhd.send(:include, FogExtensions::Hyperv::Vhd)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: foreman_hyperv
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexander Olofsson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-08-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fog-hyperv
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.0.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.13'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.13'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.0'
|
69
|
+
description: Hyper-V as a Compute Resource for Foreman
|
70
|
+
email:
|
71
|
+
- alexander.olofsson@liu.se
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rubocop.yml"
|
78
|
+
- ".rubocop_todo.yml"
|
79
|
+
- ".travis.yml"
|
80
|
+
- Gemfile
|
81
|
+
- LICENSE.txt
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- app/assets/javascripts/compute_resources/hyperv/base.js
|
85
|
+
- app/helpers/hyperv_helpers.rb
|
86
|
+
- app/models/concerns/fog_extensions/hyperv/compute.rb
|
87
|
+
- app/models/concerns/fog_extensions/hyperv/network_adapter.rb
|
88
|
+
- app/models/concerns/fog_extensions/hyperv/server.rb
|
89
|
+
- app/models/concerns/fog_extensions/hyperv/vhd.rb
|
90
|
+
- app/models/foreman_hyperv/hyperv.rb
|
91
|
+
- app/views/compute_resources/form/_hyperv.html.erb
|
92
|
+
- app/views/compute_resources/show/_hyperv.html.erb
|
93
|
+
- app/views/compute_resources_vms/form/hyperv/_base.html.erb
|
94
|
+
- app/views/compute_resources_vms/form/hyperv/_network.html.erb
|
95
|
+
- app/views/compute_resources_vms/form/hyperv/_volume.html.erb
|
96
|
+
- app/views/compute_resources_vms/index/_hyperv.html.erb
|
97
|
+
- app/views/compute_resources_vms/show/_hyperv.html.erb
|
98
|
+
- foreman_hyperv.gemspec
|
99
|
+
- lib/foreman_hyperv.rb
|
100
|
+
- lib/foreman_hyperv/engine.rb
|
101
|
+
- lib/foreman_hyperv/version.rb
|
102
|
+
- test/foreman_hyperv_test.rb
|
103
|
+
- test/test_helper.rb
|
104
|
+
homepage: https://github.com/ace13/foreman_hyperv
|
105
|
+
licenses:
|
106
|
+
- MIT
|
107
|
+
metadata: {}
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 2.6.12
|
125
|
+
signing_key:
|
126
|
+
specification_version: 4
|
127
|
+
summary: Hyper-V as a Compute Resource for Foreman
|
128
|
+
test_files:
|
129
|
+
- test/foreman_hyperv_test.rb
|
130
|
+
- test/test_helper.rb
|