Class: TheForemanProxmox::Proxmox
- Inherits:
-
ComputeResource
- Object
- ComputeResource
- TheForemanProxmox::Proxmox
show all
- Includes:
- ProxmoxComputeHelper
- Defined in:
- app/models/the_foreman_proxmox/proxmox.rb
Constant Summary
ProxmoxComputeHelper::GIGA, ProxmoxComputeHelper::KILO, ProxmoxComputeHelper::MEGA
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
#parse_cdrom, #parse_cpu, #parse_interface, #parse_interfaces, #parse_memory, #parse_vm, #parse_volume, #parse_volumes
Instance Attribute Details
#node ⇒ Object
Returns the value of attribute node.
29
30
31
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 29
def node
@node
end
|
Class Method Details
.model_name ⇒ Object
45
46
47
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 45
def self.model_name
ComputeResource.model_name
end
|
.provider_friendly_name ⇒ Object
37
38
39
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 37
def self.provider_friendly_name
"Proxmox"
end
|
Instance Method Details
#associated_host(vm) ⇒ Object
86
87
88
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 86
def associated_host(vm)
associate_by('mac', vm.mac)
end
|
#available_images ⇒ Object
96
97
98
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 96
def available_images
templates.collect { |template| OpenStruct.new(id: template.vmid) }
end
|
#bridges ⇒ Object
90
91
92
93
94
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 90
def bridges
node = network_client.nodes.all.first
bridges = node.networks.all(type: 'bridge')
bridges.sort_by(&:iface)
end
|
#capabilities ⇒ Object
41
42
43
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 41
def capabilities
[:build, :new_volume, :image]
end
|
#certs_to_store ⇒ Object
254
255
256
257
258
259
260
261
262
263
264
265
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 254
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
275
276
277
278
279
280
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 275
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
282
283
284
285
286
287
288
289
290
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 282
def console(uuid)
vm = find_vm_by_uuid(uuid)
if vm.config.type_console == 'vnc'
vnc_console = vm.start_console(websocket: 1)
WsProxy.start(:host => host, :host_port => vnc_console['port'], :password => vnc_console['ticket']).merge(:name => vm.name, :type => vm.config.type_console)
else
raise ::Foreman::Exception.new(N_("%s console is not supported at this time"), vm.config.type_console)
end
end
|
#create_vm(args = {}) ⇒ Object
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 166
def create_vm(args = {})
vmid = args[:vmid]
raise ::Foreman::Exception.new N_("invalid vmid=#{vmid}") unless node.servers.id_valid?(vmid)
image_id = args[:image_id]
node = get_cluster_node args
if image_id
logger.debug("create_vm(): clone #{image_id} in #{vmid}")
image = node.servers.get image_id
image.clone(vmid)
else
logger.debug("create_vm(): #{args}")
convert_sizes(args)
node.servers.create(parse_vm(args))
end
vm = find_vm_by_uuid(vmid)
vm
rescue => e
logger.warn "failed to create vm: #{e}"
destroy_vm vm.id if vm
raise e
end
|
#credentials_valid? ⇒ Boolean
49
50
51
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 49
def credentials_valid?
errors[:url].empty? && errors[:user].empty? && errors[:user].include?('@') && errors[:password].empty? && node
end
|
#editable_network_interfaces? ⇒ Boolean
213
214
215
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 213
def editable_network_interfaces?
true
end
|
#find_vm_by_uuid(uuid) ⇒ Object
188
189
190
191
192
193
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 188
def find_vm_by_uuid(uuid)
node.servers.get(uuid)
rescue Fog::Errors::Error => e
Foreman::Logging.exception("Failed retrieving proxmox vm by vmid=#{uuid}", e)
raise(ActiveRecord::RecordNotFound)
end
|
#host_compute_attrs(host) ⇒ Object
110
111
112
113
114
115
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 110
def host_compute_attrs(host)
super.tap do |attrs|
ostype = host.compute_attributes['config_attributes']['ostype']
raise Foreman::Exception.new("Operating system family #{host.operatingsystem.type} is not consistent with #{ostype}") unless compute_os_types(host).include?(ostype)
end
end
|
#host_interfaces_attrs(host) ⇒ Object
117
118
119
120
121
122
123
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 117
def host_interfaces_attrs(host)
host.interfaces.select(&:physical?).each.with_index.reduce({}) do |hash, (nic, index)|
raise ::Foreman::Exception.new N_("Identifier interface[#{index}] required.") if nic.identifier.empty?
raise ::Foreman::Exception.new N_("Invalid identifier interface[#{index}]. Must be net[n] with n integer >= 0") unless Fog::Proxmox::ControllerHelper.valid?(Fog::Compute::Proxmox::Interface::NAME,nic.identifier)
hash.merge(index.to_s => nic.compute_attributes.merge(id: nic.identifier, ip: nic.ip, ip6: nic.ip6))
end
end
|
#image_exists?(image) ⇒ Boolean
221
222
223
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 221
def image_exists?(image)
find_vm_by_uuid(image)
end
|
#isos(storage_id) ⇒ Object
81
82
83
84
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 81
def isos(storage_id)
storage = node.storages.find_by_id storage_id if storage_id
storage.volumes.list_by_content_type('iso').sort_by(&:volid) if storage
end
|
#new_interface(attr = {}) ⇒ Object
131
132
133
134
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 131
def new_interface(attr = {})
opts = interface_defaults.merge(attr.to_h).deep_symbolize_keys
Fog::Compute::Proxmox::Interface.new(opts)
end
|
#new_vm(attr = {}) ⇒ Object
160
161
162
163
164
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 160
def new_vm(attr = {})
vm = node.servers.new(vm_instance_defaults.merge(parse_vm(attr)))
logger.debug("new_vm() vm.config=#{vm.config.inspect}")
vm
end
|
#new_volume(attr = {}) ⇒ Object
125
126
127
128
129
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 125
def new_volume(attr = {})
opts = volume_defaults('scsi',1).merge(attr.to_h).deep_symbolize_keys
opts[:size] = opts[:size].to_s
Fog::Compute::Proxmox::Disk.new(opts)
end
|
#next_vmid ⇒ Object
238
239
240
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 238
def next_vmid
node.servers.next_id
end
|
#nodes ⇒ Object
61
62
63
64
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 61
def nodes
nodes = client.nodes.all
nodes.sort_by(&:node)
end
|
#pools ⇒ Object
66
67
68
69
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 66
def pools
pools = identity_client.pools.all
pools.sort_by(&:poolid)
end
|
#provided_attributes ⇒ Object
31
32
33
34
35
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 31
def provided_attributes
super.merge(
:mac => :mac
)
end
|
#save_vm(uuid, attr) ⇒ Object
225
226
227
228
229
230
231
232
233
234
235
236
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 225
def save_vm(uuid, attr)
vm = find_vm_by_uuid(uuid)
logger.debug("save_vm(): #{attr}")
templated = attr[:templated]
if (templated == '1' && !vm.templated?)
vm.template
else
merged = vm.config.attributes.merge!(parse_vm(attr).symbolize_keys).deep_symbolize_keys
filtered = merged.reject { |key,value| %w[node vmid].include?(key) || [:templated,:image_id].include?(key) || value.to_s.empty? }
vm.update(filtered)
end
end
|
#set_vm_interfaces_attributes(vm, vm_attrs) ⇒ Object
152
153
154
155
156
157
158
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 152
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
144
145
146
147
148
149
150
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 144
def set_vm_volumes_attributes(vm, vm_attrs)
if vm.config.respond_to?(:volumes)
volumes = vm.config.volumes || []
vm_attrs[:volumes_attributes] = Hash[volumes.each_with_index.map { |volume, idx| [idx.to_s, volume.attributes] }]
end
vm_attrs
end
|
#ssl_certs ⇒ Object
246
247
248
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 246
def ssl_certs
self.attrs[:ssl_certs]
end
|
#ssl_certs=(value) ⇒ Object
250
251
252
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 250
def ssl_certs=(value)
self.attrs[:ssl_certs] = value
end
|
#ssl_verify_peer ⇒ Object
267
268
269
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 267
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
271
272
273
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 271
def ssl_verify_peer=(value)
self.attrs[:ssl_verify_peer] = value
end
|
#storages ⇒ Object
71
72
73
74
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 71
def storages
storages = node.storages.list_by_content_type 'images'
storages.sort_by(&:storage)
end
|
#storages_isos ⇒ Object
76
77
78
79
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 76
def storages_isos
storages = node.storages.list_by_content_type 'iso'
storages.sort_by(&:storage)
end
|
#supports_update? ⇒ Boolean
195
196
197
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 195
def supports_update?
true
end
|
#template(vmid) ⇒ Object
106
107
108
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 106
def template(vmid)
find_vm_by_uuid(vmid)
end
|
#templates ⇒ Object
100
101
102
103
104
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 100
def templates
storage = storages.first
images = storage.volumes.list_by_content_type('images')
images.select { |image| image.templated? }
end
|
#test_connection(options = {}) ⇒ Object
53
54
55
56
57
58
59
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 53
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
199
200
201
202
203
204
205
206
207
208
209
210
211
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 199
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
217
218
219
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 217
def user_data_supported?
true
end
|
#vm_compute_attributes(vm) ⇒ Object
136
137
138
139
140
141
142
|
# File 'app/models/the_foreman_proxmox/proxmox.rb', line 136
def vm_compute_attributes(vm)
vm_attrs = vm.attributes rescue {}
vm_attrs = vm_attrs.reject{|k,v| k == :id }
vm_attrs = set_vm_volumes_attributes(vm, vm_attrs)
vm_attrs = set_vm_interfaces_attributes(vm, vm_attrs)
vm_attrs
end
|