Class: ForemanFogProxmox::Proxmox
Constant Summary
ProxmoxContainerHelper::GIGA, ProxmoxContainerHelper::KILO, ProxmoxContainerHelper::MEGA
ProxmoxServerHelper::GIGA, ProxmoxServerHelper::KILO, ProxmoxServerHelper::MEGA
ProxmoxVmHelper::GIGA, ProxmoxVmHelper::KILO, ProxmoxVmHelper::MEGA
Class Method Summary
collapse
Instance Method Summary
collapse
#parse_container_cpu, #parse_container_interface, #parse_container_interfaces, #parse_container_memory, #parse_container_ostemplate, #parse_container_vm, #parse_container_volume, #parse_container_volumes
#parse_server_cdrom, #parse_server_cpu, #parse_server_interface, #parse_server_interfaces, #parse_server_memory, #parse_server_vm, #parse_server_volume, #parse_server_volumes
#add_cdrom_to_config_server, #convert_memory_size, #convert_sizes, #disk_to_cdrom, #mount_point_disk?, #object_to_config_hash, #parse_type_and_vmid, #remove_deletes, #server_disk?
Class Method Details
.model_name ⇒ Object
47
48
49
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 47
def self.model_name
ComputeResource.model_name
end
|
.provider_friendly_name ⇒ Object
39
40
41
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 39
def self.provider_friendly_name
"Proxmox"
end
|
Instance Method Details
#associated_host(vm) ⇒ Object
83
84
85
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 83
def associated_host(vm)
associate_by('mac', vm.mac)
end
|
#available_images ⇒ Object
93
94
95
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 93
def available_images
templates.collect { |template| OpenStruct.new(id: template.vmid) }
end
|
#bridges ⇒ Object
87
88
89
90
91
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 87
def bridges
node = network_client.nodes.find_by_id node_name
bridges = node.networks.all(type: 'any_bridge')
bridges.sort_by(&:iface)
end
|
#capabilities ⇒ Object
43
44
45
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 43
def capabilities
[:build, :new_volume, :image]
end
|
#certs_to_store ⇒ Object
343
344
345
346
347
348
349
350
351
352
353
354
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 343
def certs_to_store
return if ssl_certs.blank?
store = OpenSSL::X509::Store.new
ssl_certs.split(/(?=-----BEGIN)/).each do |cert|
x509_cert = OpenSSL::X509::Certificate.new cert
store.add_cert x509_cert
end
store
rescue => e
logger.error(e)
raise ::Foreman::Exception.new N_("Unable to store X509 certificates")
end
|
#connection_options ⇒ Object
364
365
366
367
368
369
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 364
def connection_options
opts = http_proxy ? {proxy: http_proxy.full_url} : {disable_proxy: 1}
opts.store(:ssl_verify_peer, ssl_verify_peer)
opts.store(:ssl_cert_store, certs_to_store) if Foreman::Cast.to_bool(ssl_verify_peer)
opts
end
|
#console(uuid) ⇒ Object
371
372
373
374
375
376
377
378
379
380
381
382
383
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 371
def console(uuid)
vm = find_vm_by_uuid(uuid)
type_console = vm.config.type_console
options = {}
options.store(:websocket, 1) if type_console == 'vnc'
begin
vnc_console = vm.start_console(options)
WsProxy.start(:host => host, :host_port => vnc_console['port'], :password => vnc_console['ticket']).merge(:name => vm.name, :type => type_console)
rescue => e
logger.error(e)
raise ::Foreman::Exception.new(_("%s console is not supported at this time") % type_console)
end
end
|
#create_vm(args = {}) ⇒ Object
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 226
def create_vm(args = {})
vmid = args[:vmid].to_i
type = args[:type]
raise ::Foreman::Exception.new N_("invalid vmid=%{vmid}") % { vmid: vmid } unless node.servers.id_valid?(vmid)
image_id = args[:image_id]
if image_id
logger.debug(_("create_vm(): clone %{image_id} in %{vmid}") % { image_id: image_id, vmid: vmid })
image = node.servers.get image_id
image.clone(vmid)
clone = node.servers.get vmid
clone.update(name: args[:name])
else
logger.debug(_("create_vm(): %{args}") % { args: args })
convert_sizes(args)
remove_deletes(args)
case type
when 'qemu'
node.servers.create(parse_server_vm(args))
when 'lxc'
hash = parse_container_vm(args)
hash = hash.merge(vmid: vmid)
node.containers.create(hash.reject { |key,_value| %w[ostemplate_storage ostemplate_file].include? key })
end
end
vm = find_vm_by_uuid("#{type}_#{vmid}")
vm
rescue => e
logger.warn(_("failed to create vm: %{e}") % { e: e })
destroy_vm vm.id if vm
raise e
end
|
#credentials_valid? ⇒ Boolean
51
52
53
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 51
def credentials_valid?
errors[:url].empty? && errors[:user].empty? && errors[:user].include?('@') && errors[:password].empty? && errors[:node_name].empty?
end
|
#editable_network_interfaces? ⇒ Boolean
289
290
291
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 289
def editable_network_interfaces?
true
end
|
#find_vm_by_uuid(uuid) ⇒ Object
258
259
260
261
262
263
264
265
266
267
268
269
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 258
def find_vm_by_uuid(uuid)
type, vmid = parse_type_and_vmid(uuid)
case type
when 'qemu'
node.servers.get(vmid)
when 'lxc'
node.containers.get(vmid)
end
rescue Fog::Errors::Error => e
Foreman::Logging.exception(_("Failed retrieving proxmox vm by vmid=%{vmid} and type=%{type}") % { vmid: vmid, type: type }, e)
raise(ActiveRecord::RecordNotFound)
end
|
#host_compute_attrs(host) ⇒ Object
109
110
111
112
113
114
115
116
117
118
119
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 109
def host_compute_attrs(host)
super.tap do |attrs|
ostype = host.compute_attributes['config_attributes']['ostype']
case host.compute_attributes['type']
when 'lxc'
host.compute_attributes['config_attributes'].store('hostname',host.name)
when 'qemu'
raise ::Foreman::Exception.new(_("Operating system family %{type} is not consistent with %{ostype}") % { type: host.operatingsystem.type, ostype: ostype }) unless compute_os_types(host).include?(ostype)
end
end
end
|
#host_interfaces_attrs(host) ⇒ Object
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 121
def host_interfaces_attrs(host)
host.interfaces.select(&:physical?).each.with_index.reduce({}) do |hash, (nic, index)|
nic.identifier = "net%{index}" % {index: index} if nic.identifier.empty?
raise ::Foreman::Exception.new _("Invalid identifier interface[%{index}]. Must be net[n] with n integer >= 0" % { index: index }) unless Fog::Proxmox::NicHelper.valid?(nic.identifier)
container = host.compute_attributes['type'] == 'lxc'
nic.compute_attributes['name'] = "eth%{index}" % {index: index} if container && nic.compute_attributes['name'].empty?
raise ::Foreman::Exception.new _("Invalid name interface[%{index}]. Must be eth[n] with n integer >= 0" % { index: index }) if container && !/^(eth)(\d+)$/.match?(nic.compute_attributes['name'])
nic_compute_attributes = nic.compute_attributes.merge(id: nic.identifier)
nic_compute_attributes.store(:ip, nic.ip) if (nic.ip && !nic.ip.empty?)
nic_compute_attributes.store(:ip6, nic.ip6) if (nic.ip6 && !nic.ip6.empty?)
hash.merge(index.to_s => nic_compute_attributes)
end
end
|
#image_exists?(image) ⇒ Boolean
297
298
299
300
301
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 297
def image_exists?(image)
vm = find_vm_by_uuid("qemu_#{image}")
vm = find_vm_by_uuid("lxc_#{image}") unless vm
vm!=nil
end
|
#images_by_storage(type = 'iso', storage_id) ⇒ Object
78
79
80
81
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 78
def images_by_storage(type = 'iso', storage_id)
storage = node.storages.find_by_id storage_id if storage_id
storage.volumes.list_by_content_type(type).sort_by(&:volid) if storage
end
|
#new_container_vm(attr = {}) ⇒ Object
214
215
216
217
218
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 214
def new_container_vm(attr = {})
vm = node.containers.new(vm_container_instance_defaults.merge(parse_container_vm(attr.merge(type: 'lxc'))))
logger.debug(_("new_container_vm() vm.config=%{config}") % { config: vm.config.inspect })
vm
end
|
#new_interface(attr = {}) ⇒ Object
161
162
163
164
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 161
def new_interface(attr = {})
opts = interface_server_defaults.merge(attr.to_h).deep_symbolize_keys
Fog::Compute::Proxmox::Interface.new(opts)
end
|
#new_server_vm(attr = {}) ⇒ Object
220
221
222
223
224
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 220
def new_server_vm(attr = {})
vm = node.servers.new(vm_server_instance_defaults.merge(parse_server_vm(attr.merge(type: 'qemu'))))
logger.debug(_("new_server_vm() vm.config=%{config}") % { config: vm.config.inspect })
vm
end
|
#new_vm(attr = {}) ⇒ Object
200
201
202
203
204
205
206
207
208
209
210
211
212
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 200
def new_vm(attr = {})
attr = ActiveSupport::HashWithIndifferentAccess.new(attr)
type = attr['type']
type = 'qemu' unless type
case type
when 'lxc'
vm = new_container_vm(attr)
when 'qemu'
vm = new_server_vm(attr)
end
logger.debug(_("new_vm() vm.config=%{config}") % { config: vm.config.inspect })
vm
end
|
#new_volume(attr = {}) ⇒ Object
137
138
139
140
141
142
143
144
145
146
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 137
def new_volume(attr = {})
type = attr['type']
type = 'qemu' unless type
case type
when 'lxc'
return new_volume_server(attr)
when 'qemu'
return new_volume_container(attr)
end
end
|
#new_volume_container(attr = {}) ⇒ Object
154
155
156
157
158
159
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 154
def new_volume_container(attr = {})
id = attr[:id]
opts = volume_container_defaults(id).merge(attr.to_h).deep_symbolize_keys
opts[:size] = opts[:size].to_s
Fog::Compute::Proxmox::Disk.new(opts)
end
|
#new_volume_server(attr = {}) ⇒ Object
148
149
150
151
152
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 148
def new_volume_server(attr = {})
opts = volume_server_defaults.merge(attr.to_h).deep_symbolize_keys
opts[:size] = opts[:size].to_s
Fog::Compute::Proxmox::Disk.new(opts)
end
|
#next_vmid ⇒ Object
319
320
321
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 319
def next_vmid
node.servers.next_id
end
|
#node ⇒ Object
331
332
333
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 331
def node
client.nodes.find_by_id node_name
end
|
#node_name ⇒ Object
323
324
325
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 323
def node_name
self.attrs[:node_name]
end
|
#node_name=(value) ⇒ Object
327
328
329
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 327
def node_name=(value)
self.attrs[:node_name] = value
end
|
#nodes ⇒ Object
63
64
65
66
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 63
def nodes
nodes = client.nodes.all if client
nodes.sort_by(&:node) if nodes
end
|
#pools ⇒ Object
68
69
70
71
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 68
def pools
pools = identity_client.pools.all
pools.sort_by(&:poolid)
end
|
#provided_attributes ⇒ Object
33
34
35
36
37
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 33
def provided_attributes
super.merge(
:mac => :mac
)
end
|
#save_vm(uuid, attr) ⇒ Object
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 303
def save_vm(uuid, attr)
type, vmid = parse_type_and_vmid(uuid)
attr = attr.merge(type: type, vmid: vmid)
vm = find_vm_by_uuid(uuid)
logger.debug(N_("save_vm(): %{attr}") % { attr: attr })
templated = attr[:templated]
if (templated == '1' && !vm.templated?)
vm.template
else
parsed_attr = vm.container? ? parse_container_vm(attr) : parse_server_vm(attr)
merged = vm.config.attributes.merge(parsed_attr.symbolize_keys).deep_symbolize_keys
filtered = merged.reject { |key,value| [:node,:vmid,:type,:templated,:image_id].include?(key) || value.to_s.empty? }
vm.update(filtered)
end
end
|
#set_vm_config_attributes(vm, vm_attrs) ⇒ Object
174
175
176
177
178
179
180
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 174
def set_vm_config_attributes(vm, vm_attrs)
if vm.respond_to?(:config)
config = vm.config.attributes.reject { |key,value| [:disks,:mount_points,:interfaces].include?(key) || value.to_s.empty?}
vm_attrs[:config_attributes] = config
end
vm_attrs
end
|
#set_vm_interfaces_attributes(vm, vm_attrs) ⇒ Object
188
189
190
191
192
193
194
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 188
def set_vm_interfaces_attributes(vm, vm_attrs)
if vm.config.respond_to?(:interfaces)
interfaces = vm.config.interfaces || []
vm_attrs[:interfaces_attributes] = Hash[interfaces.each_with_index.map { |interface, idx| [idx.to_s, interface.attributes] }]
end
vm_attrs
end
|
#set_vm_volumes_attributes(vm, vm_attrs) ⇒ Object
182
183
184
185
186
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 182
def set_vm_volumes_attributes(vm, vm_attrs)
volumes = vm.container? ? vm.config.mount_points : vm.config.disks || []
vm_attrs[:volumes_attributes] = Hash[volumes.each_with_index.map { |volume, idx| [idx.to_s, volume.attributes] }]
vm_attrs
end
|
#ssl_certs ⇒ Object
335
336
337
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 335
def ssl_certs
self.attrs[:ssl_certs]
end
|
#ssl_certs=(value) ⇒ Object
339
340
341
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 339
def ssl_certs=(value)
self.attrs[:ssl_certs] = value
end
|
#ssl_verify_peer ⇒ Object
356
357
358
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 356
def ssl_verify_peer
self.attrs[:ssl_verify_peer].blank? ? false : Foreman::Cast.to_bool(self.attrs[:ssl_verify_peer])
end
|
#ssl_verify_peer=(value) ⇒ Object
360
361
362
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 360
def ssl_verify_peer=(value)
self.attrs[:ssl_verify_peer] = value
end
|
#storages(type = 'images') ⇒ Object
73
74
75
76
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 73
def storages(type = 'images')
storages = node.storages.list_by_content_type type
storages.sort_by(&:storage)
end
|
#supports_update? ⇒ Boolean
271
272
273
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 271
def supports_update?
true
end
|
#template(vmid) ⇒ Object
103
104
105
106
107
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 103
def template(vmid)
vm = find_vm_by_uuid("qemu_#{vmid}")
vm = find_vm_by_uuid("lxc_#{vmid}") unless vm
vm
end
|
#templates ⇒ Object
97
98
99
100
101
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 97
def templates
storage = storages.first
images = storage.volumes.list_by_content_type('images')
images.select { |image| image.templated? }
end
|
#test_connection(options = {}) ⇒ Object
55
56
57
58
59
60
61
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 55
def test_connection(options = {})
super
credentials_valid?
rescue => e
errors[:base] << e.message
errors[:url] << e.message
end
|
#update_required?(old_attrs, new_attrs) ⇒ Boolean
275
276
277
278
279
280
281
282
283
284
285
286
287
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 275
def update_required?(old_attrs, new_attrs)
return true if super(old_attrs, new_attrs)
new_attrs[:interfaces_attributes].each do |key, interface|
return true if (interface[:id].blank? || interface[:_delete] == '1') && key != 'new_interfaces' end if new_attrs[:interfaces_attributes]
new_attrs[:volumes_attributes].each do |key, volume|
return true if (volume[:id].blank? || volume[:_delete] == '1') && key != 'new_volumes' end if new_attrs[:volumes_attributes]
false
end
|
#user_data_supported? ⇒ Boolean
293
294
295
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 293
def user_data_supported?
true
end
|
#vm_compute_attributes(vm) ⇒ Object
166
167
168
169
170
171
172
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 166
def vm_compute_attributes(vm)
vm_attrs = vm.attributes.reject { |key,value| [:config].include?(key) || value.to_s.empty? }
vm_attrs = set_vm_config_attributes(vm, vm_attrs)
vm_attrs = set_vm_volumes_attributes(vm, vm_attrs)
vm_attrs = set_vm_interfaces_attributes(vm, vm_attrs)
vm_attrs
end
|
#vms(opts = {}) ⇒ Object
196
197
198
|
# File 'app/models/foreman_fog_proxmox/proxmox.rb', line 196
def vms(opts = {})
node.servers
end
|