foreman_fog_proxmox 0.13.3 → 0.13.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15adca3cf1f65b7b543dcb24972d640c7cbd78ca11c6c7e657a1d1d0da2e250c
4
- data.tar.gz: 387a162262465681620bf37c69ecac793757b09b7b592cd1209ce97741748a17
3
+ metadata.gz: e42832dc77d338bb20585f27678bc2207c23a610f7c7b478f24f3791ca65a414
4
+ data.tar.gz: 1385bea7eed802496ae7ab85ca013e75dc0343a8a433a347d8811b59fd620cd0
5
5
  SHA512:
6
- metadata.gz: 1222697f1f9a8eba96c0f45156420e1437139b2e8927c31944bc8e78ce915ba37f52e595d3e25edc3ab56ebc96db09f27866677f256674681814909dd57cf9fa
7
- data.tar.gz: 0d1f4df3e6be994ef693df0d89755123fd440ed9d0eb2bdd660b10a8c55d0cf12bddd425bd0078fc9b1d5a2f14647a90ae7c8b01f9c0e3f6cd866d4f564933fc
6
+ metadata.gz: 91a262ffeb2b720fae01136cdcd158cd8c577702fafbea36d550eae859c6734f7a7ec1c390b39077852100d4507d9b3502bb7f3f1cb5c7d22c02cd7b012c51cf
7
+ data.tar.gz: 25512a916934966d9b5e66494f1b294c5b13d69ba326ed61170e330bff616111103984701a6311b150fb444dab3f0a48920c8debe193b7698a2ec43a0110cdd1
data/README.md CHANGED
@@ -34,6 +34,7 @@ You can support the plugin development via the following methods:
34
34
  |>=0.12 |>=6.1|>=0.11|>=2.0|>=2.5|
35
35
  |>=0.14 |>=6.2|=0.13.0|>=2.4|>=2.7|
36
36
  |>=0.14 |>=6.2|>=0.13.1|>=2.3|>=2.5|
37
+ |>=0.14 |>=6.2|>=0.14.0|>=2.5|>=2.5|
37
38
 
38
39
  ## Installation
39
40
 
@@ -47,10 +48,10 @@ See complete details in [plugin installation from gem](https://theforeman.org/pl
47
48
 
48
49
  Here is a Debian sample:
49
50
 
50
- * Install foreman [from OS packages](https://theforeman.org/manuals/1.19/index.html#3.3InstallFromPackages):
51
+ * Install foreman [from OS packages](https://theforeman.org/manuals/latest/index.html#3.3InstallFromPackages):
51
52
 
52
53
  ```shell
53
- sudo apt install -y foreman foreman-compute foreman-sqlite3 foreman-assets
54
+ sudo apt install -y foreman foreman-pgsql
54
55
  ```
55
56
 
56
57
  * Use only foreman user (**not root!**) `sudo -u foreman ...`
@@ -102,7 +103,21 @@ Then you can check plugin installation after login into your new foreman server
102
103
 
103
104
  Please see the Foreman manual for complete instructions:
104
105
 
105
- * [Foreman: How to Install a Plugin](http://theforeman.org/manuals/latest/index.html#6.1InstallaPlugin)
106
+ * [Foreman: How to Install a Plugin from package](https://theforeman.org/plugins/#2.Installation)
107
+
108
+ [Install from package](https://theforeman.org/plugins/#2.2Packageinstallation) is the easiest way to install the plugin. Choose the latest release plugins repository. If you don't find it in the same foreman release repository, get it from the `nightly` repository.
109
+
110
+ Then you can install it with the package manager, in Debian/Ubuntu:
111
+
112
+ ```shell
113
+ sudo apt-get install ruby-foreman-fog-proxmox
114
+ ```
115
+
116
+ and in Fedora/Redhat Linux:
117
+
118
+ ```shell
119
+ sudo dnf install rubygem-foreman_fog_proxmox
120
+ ```
106
121
 
107
122
  Redhat, CentOS or Fedora users should also [setup Selinux](https://projects.theforeman.org/projects/foreman/wiki/SELinux) to allow foreman and all its plugins to work.
108
123
 
@@ -113,7 +128,7 @@ Redhat, CentOS or Fedora users should also [setup Selinux](https://projects.thef
113
128
 
114
129
  ## Development
115
130
 
116
- ### Prerequisites
131
+ ### Dev prerequisites
117
132
 
118
133
  * You need a Proxmox VE 5.4+ server running.
119
134
  * You need ruby >= 2.5. You can install it with [asdf-vm](https://asdf-vm.com).
@@ -189,7 +204,7 @@ add these lines to each environment in config/database.yml:
189
204
 
190
205
  ```shell
191
206
  cp config/ignored_environments.yml.sample config/ignored_environments.yml
192
- docker run --name foreman-db -e POSTGRES_DB=foreman -e POSTGRES_USER=foreman -e POSTGRES_PASSWORD=foreman -p 5432:5432 -d postgres
207
+ docker run --name foreman-db -v foreman_data:/var/lib/postgresql/data -e POSTGRES_DB=foreman -e POSTGRES_USER=foreman -e POSTGRES_PASSWORD=foreman -p 5432:5432 -d postgres
193
208
  bundle exec bin/rake db:migrate
194
209
  # reboot if settings.NAME error in schema
195
210
  bundle exec bin/rake db:seed assets:precompile locale:pack webpack:compile
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Tristan Robert
4
+
5
+ # This file is part of ForemanFogProxmox.
6
+
7
+ # ForemanFogProxmox is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+
12
+ # ForemanFogProxmox is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ module ForemanFogProxmox
21
+ module ComputeResourcesVmsController
22
+ extend ActiveSupport::Concern
23
+ included do
24
+ prepend Overrides
25
+ end
26
+ module Overrides
27
+ def associate
28
+ if Host.for_vm_uuid(@compute_resource, @vm).any?
29
+ process_error(:error_msg => _("VM already associated with a host"), :redirect => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => proxmox_vm_id(@compute_resource, @vm)))
30
+ return
31
+ end
32
+ host = @compute_resource.associated_host(@vm) if @compute_resource.respond_to?(:associated_host)
33
+ if host.present?
34
+ host.associate!(@compute_resource, @vm)
35
+ process_success(:success_msg => _("VM associated to host %s") % host.name, :success_redirect => host_path(host))
36
+ else
37
+ process_error(:error_msg => _("No host found to associate this VM with"), :redirect => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => proxmox_vm_id(@compute_resource, @vm)))
38
+ end
39
+ end
40
+
41
+ def console
42
+ @console = @compute_resource.console proxmox_vm_id(@compute_resource, @vm)
43
+ render case @console[:type]
44
+ when 'spice'
45
+ 'hosts/console/spice'
46
+ when 'vnc'
47
+ 'hosts/console/vnc'
48
+ when 'vmrc'
49
+ 'hosts/console/vmrc'
50
+ else
51
+ 'hosts/console/log'
52
+ end
53
+ rescue StandardError => e
54
+ process_error :redirect => compute_resource_vm_path(@compute_resource, proxmox_vm_id(@compute_resource, @vm)), :error_msg => (_("Failed to set console: %s") % e), :object => @vm
55
+ end
56
+
57
+ private
58
+
59
+ def proxmox_vm_id(compute_resource, vm)
60
+ id = vm.identity
61
+ id = vm.unique_cluster_identity(compute_resource) if compute_resource.class == ForemanFogProxmox::Proxmox
62
+ id
63
+ end
64
+
65
+ def run_vm_action(action)
66
+ if @vm.send(action)
67
+ @vm.reload
68
+ success format(_("%<vm>s is now %<vm_state>s"), { :vm => @vm, :vm_state => @vm.state.capitalize })
69
+ else
70
+ error format(_("failed to %<action>s %<vm>s"), { :action => _(action), :vm => @vm })
71
+ end
72
+ redirect_back(:fallback_location => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => proxmox_vm_id(@compute_resource, @vm)))
73
+ # This should only rescue Fog::Errors, but Fog returns all kinds of errors...
74
+ rescue StandardError => e
75
+ error format(_("Error - %<message>s"), { :message => _(e.message) })
76
+ redirect_back(:fallback_location => compute_resource_vm_path(:compute_resource_id => params[:compute_resource_id], :id => proxmox_vm_id(@compute_resource, @vm)))
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Tristan Robert
4
+
5
+ # This file is part of ForemanFogProxmox.
6
+
7
+ # ForemanFogProxmox is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+
12
+ # ForemanFogProxmox is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ module ProxmoxComputeResourcesVmsHelper
21
+ def proxmox_vm_id(compute_resource, vm)
22
+ id = vm.identity
23
+ id = vm.unique_cluster_identity(compute_resource) if compute_resource.class == ForemanFogProxmox::Proxmox
24
+ id
25
+ end
26
+
27
+ def vm_host_action(vm)
28
+ host = Host.for_vm_uuid(@compute_resource, vm).first
29
+ return unless host
30
+
31
+ display_link_if_authorized(_("Host"), hash_for_host_path(:id => host), :class => 'btn btn-default')
32
+ end
33
+
34
+ def vm_power_action(vm, authorizer = nil)
35
+ opts = hash_for_power_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => proxmox_vm_id(@compute_resource, vm)).merge(:auth_object => @compute_resource, :permission => 'power_compute_resources_vms', :authorizer => authorizer)
36
+ html = power_action_html(vm)
37
+
38
+ display_link_if_authorized "Power #{action_string(vm)}", opts, html.merge(:method => :put)
39
+ end
40
+
41
+ def vm_associate_action(vm)
42
+ display_link_if_authorized(
43
+ _('Associate VM'),
44
+ hash_for_associate_compute_resource_vm_path(
45
+ :compute_resource_id => @compute_resource,
46
+ :id => proxmox_vm_id(@compute_resource, vm)
47
+ ).merge(
48
+ :auth_object => @compute_resource,
49
+ :permission => 'edit_compute_resources'),
50
+ :title => _('Associate VM to a Foreman host'),
51
+ :method => :put,
52
+ :class => 'btn btn-default'
53
+ )
54
+ end
55
+
56
+ def vm_import_action(vm, html_options = {})
57
+ @_linked_hosts_cache ||= Host.where(:compute_resource_id => @compute_resource.id).pluck(:uuid)
58
+ return if @_linked_hosts_cache.include?(proxmox_vm_id(@compute_resource, vm).to_s)
59
+
60
+ import_managed_link = display_link_if_authorized(
61
+ _('Import as managed Host'),
62
+ hash_for_import_compute_resource_vm_path(
63
+ :compute_resource_id => @compute_resource,
64
+ :id => proxmox_vm_id(@compute_resource, vm),
65
+ :type => 'managed'),
66
+ html_options
67
+ )
68
+ import_unmanaged_link = display_link_if_authorized(
69
+ _('Import as unmanaged Host'),
70
+ hash_for_import_compute_resource_vm_path(
71
+ :compute_resource_id => @compute_resource,
72
+ :id => proxmox_vm_id(@compute_resource, vm),
73
+ :type => 'unmanaged'),
74
+ html_options
75
+ )
76
+
77
+ import_managed_link + import_unmanaged_link
78
+ end
79
+
80
+ def vm_console_action(vm)
81
+ return unless vm.ready?
82
+
83
+ link_to_if_authorized(
84
+ _('Console'),
85
+ hash_for_console_compute_resource_vm_path.merge(
86
+ :auth_object => @compute_resource,
87
+ :id => proxmox_vm_id(@compute_resource, vm)
88
+ ),
89
+ {
90
+ :id => 'console-button',
91
+ :class => 'btn btn-info'
92
+ }
93
+ )
94
+ end
95
+
96
+ def vm_delete_action(vm, authorizer = nil)
97
+ display_delete_if_authorized(hash_for_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => proxmox_vm_id(@compute_resource, vm)).merge(:auth_object => @compute_resource, :authorizer => authorizer), :class => 'btn btn-danger')
98
+ end
99
+ end
@@ -23,8 +23,8 @@ module FogExtensions
23
23
  extend ActiveSupport::Concern
24
24
  attr_accessor :image_id, :templated, :ostemplate_storage, :ostemplate_file, :password, :start_after_create
25
25
 
26
- def unique_cluster_identity
27
- compute_resource.name + '_' + identity
26
+ def unique_cluster_identity(compute_resource)
27
+ compute_resource.id.to_s + '_' + identity
28
28
  end
29
29
 
30
30
  def start
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Tristan Robert
4
+
5
+ # This file is part of ForemanFogProxmox.
6
+
7
+ # ForemanFogProxmox is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+
12
+ # ForemanFogProxmox is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ module HostExt
21
+ module Proxmox
22
+ module Associator
23
+ extend ActiveSupport::Concern
24
+ included do
25
+ prepend Overrides
26
+ end
27
+ module Overrides
28
+ def associate!(cr, vm)
29
+ self.uuid = proxmox_vm_id(cr, vm)
30
+ self.compute_resource_id = cr.id
31
+ save!(:validate => false) # don't want to trigger callbacks
32
+ end
33
+
34
+ def proxmox_vm_id(compute_resource, vm)
35
+ id = vm.identity
36
+ id = vm.unique_cluster_identity(compute_resource) if compute_resource.class == ForemanFogProxmox::Proxmox
37
+ id
38
+ end
39
+ end
40
+
41
+ def for_vm_uuid(cr, vm)
42
+ where(:compute_resource_id => cr.id, :uuid => Array.wrap(vm).compact.map(cr.id.to_s + '_' + vm&.identity).map(&:to_s))
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Tristan Robert
4
+
5
+ # This file is part of ForemanFogProxmox.
6
+
7
+ # ForemanFogProxmox is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+
12
+ # ForemanFogProxmox is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ module HostExt
21
+ module Proxmox
22
+ module ForVm
23
+ extend ActiveSupport::Concern
24
+ module ClassMethods
25
+ def for_vm_uuid(cr, vm)
26
+ uuid = vm&.identity
27
+ uuid = cr.id.to_s + '_' + vm&.identity if cr.class == ForemanFogProxmox::Proxmox
28
+ where(:compute_resource_id => cr.id, :uuid => uuid)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -23,18 +23,26 @@ module Orchestration
23
23
  extend ActiveSupport::Concern
24
24
 
25
25
  def setComputeUpdate
26
- logger.info "Update Proxmox Compute instance for #{name}"
27
- final_compute_attributes = compute_attributes.merge(compute_resource.host_compute_attrs(self))
28
- logger.debug("setComputeUpdate: final_compute_attributes=#{final_compute_attributes}")
29
- compute_resource.save_vm uuid, final_compute_attributes
26
+ if compute_resource.class != ForemanFogProxmox::Proxmox
27
+ super
28
+ else
29
+ logger.info "Update Proxmox Compute instance for #{name}"
30
+ final_compute_attributes = compute_attributes.merge(compute_resource.host_compute_attrs(self))
31
+ logger.debug("setComputeUpdate: final_compute_attributes=#{final_compute_attributes}")
32
+ compute_resource.save_vm uuid, final_compute_attributes
33
+ end
30
34
  rescue StandardError => e
31
35
  failure format(_('Failed to update a compute %<compute_resource>s instance %<name>s: %<e>s'), :compute_resource => compute_resource, :name => name, :e => e), e
32
36
  end
33
37
 
34
38
  def delComputeUpdate
35
- logger.info "Undo Update Proxmox Compute instance for #{name}"
36
- final_compute_attributes = old.compute_attributes.merge(compute_resource.host_compute_attrs(old))
37
- compute_resource.save_vm uuid, final_compute_attributes
39
+ if compute_resource.class != ForemanFogProxmox::Proxmox
40
+ super
41
+ else
42
+ logger.info "Undo Update Proxmox Compute instance for #{name}"
43
+ final_compute_attributes = old.compute_attributes.merge(compute_resource.host_compute_attrs(old))
44
+ compute_resource.save_vm uuid, final_compute_attributes
45
+ end
38
46
  rescue StandardError => e
39
47
  failure format(_('Failed to undo update compute %<compute_resource>s instance %<name>s: %<e>s'), :compute_resource => compute_resource, :name => name, :e => e), e
40
48
  end
@@ -80,7 +88,9 @@ module Orchestration
80
88
  end
81
89
 
82
90
  def setComputeDetails
83
- if vm
91
+ if compute_resource.class != ForemanFogProxmox::Proxmox
92
+ super
93
+ elsif vm
84
94
  setVmDetails
85
95
  else
86
96
  failure format(_('failed to save %<name>s'), name: name)
@@ -64,6 +64,10 @@ module ForemanFogProxmox
64
64
  associate_by('mac', vm.mac)
65
65
  end
66
66
 
67
+ def associate_by(name, attributes)
68
+ Host.authorized(:view_hosts, Host).joins(:primary_interface).where(:nics => { :primary => true }).where("nics.#{name}" => attributes).readonly(false).first
69
+ end
70
+
67
71
  def ssl_certs
68
72
  attrs[:ssl_certs]
69
73
  end
@@ -27,9 +27,7 @@ module ForemanFogProxmox
27
27
  host.compute_attributes['config_attributes'].store('hostname', host.name)
28
28
  when 'qemu'
29
29
  host.compute_attributes['config_attributes'].store('name', host.name)
30
- unless compute_os_types(host).include?(ostype)
31
- raise ::Foreman::Exception, format(_('Operating system family %<type>s is not consistent with %<ostype>s'), type: host.operatingsystem.type, ostype: ostype)
32
- end
30
+ raise ::Foreman::Exception, format(_('Operating system family %<type>s is not consistent with %<ostype>s'), type: host.operatingsystem.type, ostype: ostype) unless compute_os_types(host).include?(ostype)
33
31
  end
34
32
  super
35
33
  end
@@ -50,9 +48,7 @@ module ForemanFogProxmox
50
48
  vm_attrs = vm_attrs.merge(vmid: vm.identity, node_id: vm.node_id, type: vm.type)
51
49
  if vm.respond_to?(:config)
52
50
  vm_attrs[:volumes_attributes] = Hash[vm.config.disks.each_with_index.map { |disk, idx| [idx.to_s, disk.attributes] }] if vm.config.respond_to?(:disks)
53
- if vm.config.respond_to?(:interfaces)
54
- vm_attrs[:interfaces_attributes] = Hash[vm.config.interfaces.each_with_index.map { |interface, idx| [idx.to_s, interface_compute_attributes(interface.attributes)] }]
55
- end
51
+ vm_attrs[:interfaces_attributes] = Hash[vm.config.interfaces.each_with_index.map { |interface, idx| [idx.to_s, interface_compute_attributes(interface.attributes)] }] if vm.config.respond_to?(:interfaces)
56
52
  vm_attrs[:config_attributes] = vm.config.attributes.reject do |key, value|
57
53
  not_config_key?(vm, key) || ForemanFogProxmox::Value.empty?(value.to_s) || Fog::Proxmox::DiskHelper.disk?(key.to_s) || Fog::Proxmox::NicHelper.nic?(key.to_s)
58
54
  end
@@ -31,8 +31,17 @@ module ForemanFogProxmox
31
31
  storage.volumes.list_by_content_type(type).sort_by(&:volid) if storage
32
32
  end
33
33
 
34
+ def template_name(template)
35
+ image = find_vm_by_uuid(template_uuid(template))
36
+ image&.name
37
+ end
38
+
39
+ def template_uuid(template)
40
+ id.to_s + '_' + template.vmid.to_s
41
+ end
42
+
34
43
  def available_images
35
- templates.collect { |template| OpenStruct.new(id: template.vmid.to_s) }
44
+ templates.collect { |template| OpenStruct.new(id: template_uuid(template), name: template_name(template)) }
36
45
  end
37
46
 
38
47
  def templates
@@ -44,15 +53,15 @@ module ForemanFogProxmox
44
53
  volumes.select(&:template?)
45
54
  end
46
55
 
47
- def template(vmid)
48
- find_vm_by_uuid(vmid)
56
+ def template(uuid)
57
+ find_vm_by_uuid(uuid)
49
58
  end
50
59
 
51
60
  def clone_from_image(image_id, args, vmid)
52
61
  logger.debug(format(_('create_vm(): clone %<image_id>s in %<vmid>s'), image_id: image_id, vmid: vmid))
53
62
  image = find_vm_by_uuid(image_id)
54
63
  image.clone(vmid)
55
- clone = find_vm_by_uuid(vmid)
64
+ clone = find_vm_by_uuid(id.to_s + '_' + vmid.to_s)
56
65
  options = {}
57
66
  options.store(:name, args[:name]) unless clone.container?
58
67
  options.store(:hostname, args[:name]) if clone.container?
@@ -18,6 +18,7 @@
18
18
  # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
20
  require 'fog/proxmox/helpers/ip_helper'
21
+ require 'net/validations'
21
22
 
22
23
  module ForemanFogProxmox
23
24
  module ProxmoxInterfaces
@@ -104,7 +105,7 @@ module ForemanFogProxmox
104
105
  def set_mac(nic_compute_attributes, mac, type)
105
106
  mac_attr_name = { 'qemu' => :macaddr, 'lxc' => :hwaddr }
106
107
  mac_key = mac_attr_name[type] || 'mac'
107
- nic_compute_attributes[mac_key] = mac
108
+ nic_compute_attributes[mac_key] = Net::Validations.normalize_mac(mac)
108
109
  end
109
110
 
110
111
  def host_interfaces_attrs(host)
@@ -56,8 +56,10 @@ module ForemanFogProxmox
56
56
 
57
57
  def destroy_vm(uuid)
58
58
  vm = find_vm_by_uuid(uuid)
59
- vm.stop if vm.ready?
60
- vm.destroy
59
+ unless vm.nil?
60
+ vm.stop if vm.ready?
61
+ vm.destroy
62
+ end
61
63
  rescue ActiveRecord::RecordNotFound
62
64
  # if the VM does not exists, we don't really care.
63
65
  true
@@ -166,9 +166,7 @@ module ForemanFogProxmox
166
166
  def convert_config_attributes(new_attr)
167
167
  config_attributes = new_attr[:config_attributes]
168
168
  config_attributes[:volumes_attributes] = Hash[config_attributes[:disks].each_with_index.map { |disk, idx| [idx.to_s, disk.attributes] }] if config_attributes.key?(:disks)
169
- if config_attributes.key?(:interfaces)
170
- config_attributes[:interfaces_attributes] = Hash[config_attributes[:interfaces].each_with_index.map { |interface, idx| [idx.to_s, interface_compute_attributes(interface.attributes)] }]
171
- end
169
+ config_attributes[:interfaces_attributes] = Hash[config_attributes[:interfaces].each_with_index.map { |interface, idx| [idx.to_s, interface_compute_attributes(interface.attributes)] }] if config_attributes.key?(:interfaces)
172
170
  config_attributes.delete_if { |key, _value| ['disks', 'interfaces'].include?(key) }
173
171
  end
174
172
 
@@ -181,7 +179,7 @@ module ForemanFogProxmox
181
179
  new_attr_type ||= type
182
180
  logger.debug(format(_('new_typed_vm(%<type>s): new_attr_type=%<new_attr_type>s'), type: type, new_attr_type: new_attr_type))
183
181
  logger.debug(format(_('new_typed_vm(%<type>s): new_attr=%<new_attr>s'), type: type, new_attr: new_attr))
184
- options = !new_attr.key?('vmid') || ForemanFogProxmox::Value.empty?(new_attr['vmid']) ? new_attr.merge(vm_typed_instance_defaults(type)).merge(type: type) : new_attr
182
+ options = !new_attr.key?('vmid') || ForemanFogProxmox::Value.empty?(new_attr['vmid']) ? vm_typed_instance_defaults(type).merge(new_attr).merge(type: type) : new_attr
185
183
  logger.debug(format(_('new_typed_vm(%<type>s): options=%<options>s'), type: type, options: options))
186
184
  vm_h = parse_typed_vm(options, type).deep_symbolize_keys
187
185
  logger.debug(format(_('new_typed_vm(%<type>s): vm_h=%<vm_h>s'), type: type, vm_h: vm_h))
@@ -43,9 +43,14 @@ module ForemanFogProxmox
43
43
  end
44
44
 
45
45
  # TODO: Pagination with filters
46
- def vms(_opts = {})
46
+ def vms(opts = {})
47
47
  vms = []
48
48
  nodes.each { |node| vms += node.servers.all + node.containers.all }
49
+ if opts.key?(:eager_loading) && opts[:eager_loading]
50
+ vms_eager = []
51
+ vms.each { |vm| vms_eager << vm.collection.get(vm.identity) }
52
+ vms = vms_eager
53
+ end
49
54
  ForemanFogProxmox::Vms.new(vms)
50
55
  end
51
56
 
@@ -22,7 +22,7 @@ module ForemanFogProxmox
22
22
  attr_reader :items
23
23
 
24
24
  def each
25
- @items.each
25
+ @items.each { |item| yield item }
26
26
  end
27
27
 
28
28
  # TODO: Pagination with filters
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Tristan Robert
4
+
5
+ # This file is part of ForemanFogProxmox.
6
+
7
+ # ForemanFogProxmox is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+
12
+ # ForemanFogProxmox is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ module ForemanFogProxmox
21
+ module ComputeResourceHostAssociator
22
+ extend ActiveSupport::Concern
23
+ included do
24
+ prepend Overrides
25
+ end
26
+ module Overrides
27
+ def associate_hosts
28
+ compute_resource.vms(:eager_loading => true).each do |vm|
29
+ associate_vm(vm) if Host.for_vm_uuid(compute_resource, vm).empty?
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -31,7 +31,7 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
31
31
  <tbody>
32
32
  <% @vms.each do |vm| -%>
33
33
  <tr>
34
- <td><%= link_to_if_authorized vm.name, hash_for_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => vm.identity) %></td>
34
+ <td><%= link_to_if_authorized vm.name, hash_for_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => vm.unique_cluster_identity(@compute_resource)) %></td>
35
35
  <td><%= vm.node_id %></td>
36
36
  <td><%= vm.type %></td>
37
37
  <td><%= vm.cpus %></td>
@@ -41,7 +41,7 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
41
41
  <td>
42
42
  <%= action_buttons(
43
43
  vm_power_action(vm, authorizer),
44
- 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))) %>
44
+ display_delete_if_authorized(hash_for_compute_resource_vm_path(:compute_resource_id => @compute_resource, :id => vm.unique_cluster_identity(@compute_resource)).merge(:auth_object => @compute_resource, :authorizer => authorizer))) %>
45
45
  </td>
46
46
  </tr>
47
47
  <% end -%>
@@ -26,6 +26,7 @@ module ForemanFogProxmox
26
26
  config.autoload_paths += Dir["#{config.root}/app/controllers/concerns"]
27
27
  config.autoload_paths += Dir["#{config.root}/app/helpers/concerns"]
28
28
  config.autoload_paths += Dir["#{config.root}/app/models/concerns"]
29
+ config.autoload_paths += Dir["#{config.root}/app/services/concerns"]
29
30
  config.autoload_paths += Dir["#{config.root}/app/overrides"]
30
31
  config.autoload_paths += Dir["#{config.root}/app/services"]
31
32
 
@@ -101,10 +102,14 @@ module ForemanFogProxmox
101
102
  Fog::Proxmox::Compute::ServerConfig.include FogExtensions::Proxmox::ServerConfig
102
103
  Fog::Proxmox::Compute::Interface.include FogExtensions::Proxmox::Interface
103
104
  Fog::Proxmox::Compute::Disk.include FogExtensions::Proxmox::Disk
104
- ::ComputeResourcesController.include ForemanFogProxmox::Controller::Parameters::ComputeResource
105
105
  Fog::Proxmox::Compute::Node.include FogExtensions::Proxmox::Node
106
+ ::ComputeResourcesController.include ForemanFogProxmox::Controller::Parameters::ComputeResource
107
+ ::ComputeResourcesVmsController.include ForemanFogProxmox::ComputeResourcesVmsController
106
108
  ::Host::Managed.include Orchestration::Proxmox::Compute
107
109
  ::Host::Managed.include HostExt::Proxmox::Interfaces
110
+ ::Host::Managed.include HostExt::Proxmox::Associator
111
+ ::Host::Base.include HostExt::Proxmox::ForVm
112
+ ::ComputeResourceHostAssociator.include ForemanFogProxmox::ComputeResourceHostAssociator
108
113
  end
109
114
  end
110
115
  end
@@ -18,5 +18,5 @@
18
18
  # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
20
  module ForemanFogProxmox
21
- VERSION = '0.13.3'
21
+ VERSION = '0.13.4'
22
22
  end
@@ -28,7 +28,7 @@ module ForemanFogProxmox
28
28
  before do
29
29
  @cr = FactoryBot.build_stubbed(:proxmox_cr)
30
30
  @args = { :name => 'name' }
31
- @image_id = 100
31
+ @image_id = @cr.id.to_s + '_' + 100.to_s
32
32
  @vmid = 101
33
33
  @image = mock('vm')
34
34
  @image.expects(:clone)
@@ -38,13 +38,13 @@ module ForemanFogProxmox
38
38
  it 'clones server from image' do
39
39
  @clone.expects(:update).with(:name => 'name')
40
40
  @clone.stubs(:container?).returns(false)
41
- @cr.stubs(:find_vm_by_uuid).with(@vmid).returns(@clone)
41
+ @cr.stubs(:find_vm_by_uuid).with(@cr.id.to_s + '_' + @vmid.to_s).returns(@clone)
42
42
  @cr.clone_from_image(@image_id, @args, @vmid)
43
43
  end
44
44
  it 'clones container from image' do
45
45
  @clone.stubs(:container?).returns(true)
46
46
  @clone.expects(:update).with(:hostname => 'name')
47
- @cr.stubs(:find_vm_by_uuid).with(@vmid).returns(@clone)
47
+ @cr.stubs(:find_vm_by_uuid).with(@cr.id.to_s + '_' + @vmid.to_s).returns(@clone)
48
48
  @cr.clone_from_image(@image_id, @args, @vmid)
49
49
  end
50
50
  end
@@ -48,7 +48,7 @@ module ForemanFogProxmox
48
48
 
49
49
  it 'sets server compute id with identifier, ip and ip6 and mac adress' do
50
50
  ip = '192.168.56.100'
51
- mac_address = '36:25:8C:53:0C:50'
51
+ mac_address = '36:25:8c:53:0c:50'
52
52
  ip6 = Array.new(4) { format('%<x>s', x: rand(16**4)) }.join(':') + '::1'
53
53
  physical_nic = FactoryBot.build(:nic_base_empty, :identifier => 'net0', :ip => ip, :ip6 => ip6, :mac => mac_address)
54
54
  host = FactoryBot.build(
@@ -117,7 +117,7 @@ module ForemanFogProxmox
117
117
 
118
118
  it 'sets container compute id with identifier, ip DHCP, mac adress and firewall' do
119
119
  ip = '192.168.56.100'
120
- mac_address = '36:25:8C:53:0C:50'
120
+ mac_address = '36:25:8c:53:0c:50'
121
121
  ip6 = '2001:0:1234::c1c0:abcd:876'
122
122
  firewall = '1'
123
123
  compute_attributes = { 'dhcp' => '1', 'ip6' => ip6, 'firewall' => firewall }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_fog_proxmox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.3
4
+ version: 0.13.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tristan Robert
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-03-18 00:00:00.000000000 Z
12
+ date: 2021-07-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: deface
@@ -100,11 +100,13 @@ files:
100
100
  - app/assets/javascripts/foreman_fog_proxmox/proxmox_volume.js
101
101
  - app/assets/javascripts/foreman_fog_proxmox/proxmox_volume_cdrom.js
102
102
  - app/assets/javascripts/foreman_fog_proxmox/proxmox_volume_cloudinit.js
103
+ - app/controllers/concerns/foreman_fog_proxmox/compute_resources_vms_controller.rb
103
104
  - app/controllers/concerns/foreman_fog_proxmox/controller/parameters/compute_resource.rb
104
105
  - app/controllers/foreman_fog_proxmox/compute_resources_controller.rb
105
106
  - app/helpers/node_dashboard_helper.rb
106
107
  - app/helpers/proxmox_compute_controllers_helper.rb
107
108
  - app/helpers/proxmox_compute_resources_helper.rb
109
+ - app/helpers/proxmox_compute_resources_vms_helper.rb
108
110
  - app/helpers/proxmox_compute_selectors_helper.rb
109
111
  - app/helpers/proxmox_form_helper.rb
110
112
  - app/helpers/proxmox_storages_helper.rb
@@ -121,6 +123,8 @@ files:
121
123
  - app/models/concerns/fog_extensions/proxmox/node.rb
122
124
  - app/models/concerns/fog_extensions/proxmox/server.rb
123
125
  - app/models/concerns/fog_extensions/proxmox/server_config.rb
126
+ - app/models/concerns/host_ext/proxmox/associator.rb
127
+ - app/models/concerns/host_ext/proxmox/for_vm.rb
124
128
  - app/models/concerns/host_ext/proxmox/interfaces.rb
125
129
  - app/models/concerns/orchestration/proxmox/compute.rb
126
130
  - app/models/foreman_fog_proxmox/options_select.rb
@@ -146,6 +150,7 @@ files:
146
150
  - app/overrides/compute_resources_vms/form/add_vm_type_to_volumes_edit.rb
147
151
  - app/overrides/compute_resources_vms/form/add_vm_type_to_volumes_new_volume.rb
148
152
  - app/overrides/compute_resources_vms/form/remove_new_vm_from_removable_layout.rb
153
+ - app/services/concerns/foreman_fog_proxmox/compute_resource_host_associator.rb
149
154
  - app/services/foreman_fog_proxmox/node_dashboard/data.rb
150
155
  - app/views/api/v2/compute_resources/proxmox.json.rabl
151
156
  - app/views/compute_resources/form/_proxmox.html.erb
@@ -237,7 +242,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
237
242
  - !ruby/object:Gem::Version
238
243
  version: '0'
239
244
  requirements: []
240
- rubygems_version: 3.2.3
245
+ rubygems_version: 3.2.22
241
246
  signing_key:
242
247
  specification_version: 4
243
248
  summary: Foreman plugin that adds Proxmox VE compute resource using fog-proxmox