foreman_wreckingball 4.0.0 → 6.0.0
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 +4 -4
- data/README.md +3 -1
- data/Rakefile +2 -2
- data/app/controllers/foreman_wreckingball/hosts_controller.rb +30 -13
- data/app/helpers/{concerns/foreman_wreckingball/hosts_helper_extensions.rb → foreman_wreckingball/hosts_helper.rb} +1 -1
- data/app/helpers/foreman_wreckingball/hypervisors_helper.rb +2 -1
- data/app/helpers/foreman_wreckingball/statuses_helper.rb +9 -7
- data/app/jobs/update_hosts_vmware_facets.rb +3 -2
- data/app/lib/actions/foreman_wreckingball/bulk_remediate.rb +4 -1
- data/app/lib/actions/foreman_wreckingball/host/remediate_hardware_version.rb +3 -1
- data/app/lib/actions/foreman_wreckingball/host/remediate_spectre_v2.rb +3 -1
- data/app/lib/actions/foreman_wreckingball/host/remediate_vmware_operatingsystem.rb +14 -10
- data/app/lib/actions/foreman_wreckingball/vmware/schedule_vmware_sync.rb +1 -1
- data/app/lib/actions/foreman_wreckingball/vmware/sync_compute_resource.rb +2 -2
- data/app/lib/fog_extensions/foreman_wreckingball/vsphere/host.rb +2 -0
- data/app/lib/fog_extensions/foreman_wreckingball/vsphere/mock.rb +3 -1
- data/app/lib/fog_extensions/foreman_wreckingball/vsphere/real.rb +7 -2
- data/app/lib/fog_extensions/foreman_wreckingball/vsphere/server.rb +2 -0
- data/app/lib/vsphere_os_identifiers/data.yaml +7 -0
- data/app/models/concerns/foreman_wreckingball/compute_resource_extensions.rb +11 -5
- data/app/models/concerns/foreman_wreckingball/host_extensions.rb +9 -4
- data/app/models/concerns/foreman_wreckingball/vmware_facet_host_extensions.rb +42 -11
- data/app/models/concerns/foreman_wreckingball/vmware_hypervisor_facet_host_extensions.rb +6 -2
- data/app/models/foreman_wreckingball/cpu_hot_add_status.rb +1 -1
- data/app/models/foreman_wreckingball/hardware_version_status.rb +1 -1
- data/app/models/foreman_wreckingball/operatingsystem_status.rb +2 -0
- data/app/models/foreman_wreckingball/spectre_v2_status.rb +2 -2
- data/app/models/foreman_wreckingball/vmware_cluster.rb +14 -13
- data/app/models/foreman_wreckingball/vmware_facet.rb +18 -12
- data/app/models/foreman_wreckingball/vmware_hypervisor_facet.rb +3 -1
- data/app/services/foreman_wreckingball/vmware_cluster_importer.rb +7 -4
- data/app/services/foreman_wreckingball/vmware_hypervisor_importer.rb +44 -41
- data/app/views/foreman_wreckingball/hosts/_hosts.json.rabl +2 -2
- data/app/views/foreman_wreckingball/hosts/status_hosts.json.rabl +4 -4
- data/config/environments/production.rb +1 -1
- data/config/routes.rb +3 -2
- data/db/migrate/20181021111543_add_indexes_to_vmware_hypervisor_facets.rb +1 -1
- data/db/migrate/20240201094513_fix_wreckingball_settings_category_to_dsl.rb +13 -0
- data/lib/foreman_wreckingball/engine.rb +79 -87
- data/lib/foreman_wreckingball/scheduled_jobs.rb +1 -1
- data/lib/foreman_wreckingball/version.rb +1 -1
- data/lib/tasks/foreman_vmware_checks_tasks.rake +1 -21
- data/test/actions/foreman_wreckingball/bulk_remediate_test.rb +0 -1
- data/test/actions/foreman_wreckingball/host/refresh_vmware_facet_test.rb +6 -7
- data/test/actions/foreman_wreckingball/host/remediate_hardware_version_test.rb +6 -7
- data/test/actions/foreman_wreckingball/host/remediate_spectre_v2_test.rb +6 -7
- data/test/actions/foreman_wreckingball/host/remediate_vmware_operatingsystem_test.rb +8 -9
- data/test/actions/foreman_wreckingball/vmware/sync_compute_resource_test.rb +2 -2
- data/test/controllers/compute_resources_controller_test.rb +2 -2
- data/test/controllers/foreman_wreckingball/hosts_controller_test.rb +19 -18
- data/test/factories/foreman_wreckingball_factories.rb +10 -10
- data/test/integration/hosts_status_dashboard_test.rb +0 -4
- data/test/integration/hosts_status_managed_hosts_test.rb +4 -5
- data/test/models/compute_resources/vmware_test.rb +1 -1
- data/test/models/foreman_wreckingball/cpu_hot_add_status_test.rb +2 -2
- data/test/models/foreman_wreckingball/hardware_version_status_test.rb +3 -4
- data/test/models/foreman_wreckingball/operatingsystem_status_test.rb +5 -5
- data/test/models/foreman_wreckingball/spectre_v2_status_test.rb +4 -4
- data/test/models/foreman_wreckingball/tools_status_test.rb +2 -2
- data/test/models/foreman_wreckingball/vmware_facet_test.rb +10 -10
- data/test/models/foreman_wreckingball/vmware_hypervisor_facet_test.rb +4 -4
- data/test/models/host_test.rb +54 -52
- data/test/test_plugin_helper.rb +1 -1
- data/test/unit/foreman_wreckingball/access_permissions_test.rb +18 -0
- data/test/unit/foreman_wreckingball/vmware_cluster_importer_test.rb +6 -6
- data/test/unit/foreman_wreckingball/vmware_hypervisor_importer_test.rb +4 -4
- metadata +56 -40
- data/app/models/setting/wreckingball.rb +0 -26
@@ -63,6 +63,7 @@ module ForemanWreckingball
|
|
63
63
|
host&.vmware_facet
|
64
64
|
end
|
65
65
|
|
66
|
+
# rubocop:todo Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
66
67
|
def os_matches_identifier?
|
67
68
|
guest_id = host.vmware_facet.guest_id
|
68
69
|
vsphere_os = VsphereOsIdentifiers.lookup(guest_id)
|
@@ -75,5 +76,6 @@ module ForemanWreckingball
|
|
75
76
|
return false if vsphere_os.release && ![vsphere_os.release].flatten.include?(host.facts['os::release::full'])
|
76
77
|
true
|
77
78
|
end
|
79
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
78
80
|
end
|
79
81
|
end
|
@@ -14,7 +14,7 @@ module ForemanWreckingball
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.description
|
17
|
-
N_('In order to use hardware based branch target injection mitigation within virtual machines, Hypervisor-Assisted Guest Mitigation must be enabled.')
|
17
|
+
N_('In order to use hardware based branch target injection mitigation within virtual machines, Hypervisor-Assisted Guest Mitigation must be enabled.') # rubocop:disable Layout/LineLength
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.supports_remediate?
|
@@ -60,7 +60,7 @@ module ForemanWreckingball
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def relevant?(_options = {})
|
63
|
-
host
|
63
|
+
host&.vmware_facet && host.vmware_facet.hardware_version.present? && host.vmware_facet.cpu_features.any?
|
64
64
|
end
|
65
65
|
|
66
66
|
def guest_mitigation_enabled?
|
@@ -3,23 +3,24 @@
|
|
3
3
|
module ForemanWreckingball
|
4
4
|
class VmwareCluster < ApplicationRecord
|
5
5
|
has_many :vmware_hypervisor_facets,
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
has_many :hosts,
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
class_name: '::ForemanWreckingball::VmwareHypervisorFacet',
|
7
|
+
inverse_of: :vmware_cluster,
|
8
|
+
dependent: :nullify
|
9
|
+
has_many :hosts,
|
10
|
+
class_name: '::Host::Managed',
|
11
|
+
through: :vmware_hypervisor_facets,
|
12
|
+
inverse_of: :vmware_cluster,
|
13
|
+
dependent: :nullify
|
13
14
|
belongs_to :compute_resource,
|
14
|
-
|
15
|
+
inverse_of: :vmware_clusters
|
15
16
|
has_many :vmware_facets,
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
class_name: '::ForemanWreckingball::VmwareFacet',
|
18
|
+
inverse_of: :vmware_cluster,
|
19
|
+
dependent: :nullify
|
19
20
|
|
20
21
|
validates_lengths_from_database
|
21
22
|
|
22
|
-
validates :compute_resource, :
|
23
|
-
validates :name, :
|
23
|
+
validates :compute_resource, presence: true, allow_blank: false
|
24
|
+
validates :name, presence: true, allow_blank: false, uniqueness: { scope: :compute_resource }
|
24
25
|
end
|
25
26
|
end
|
@@ -4,23 +4,25 @@ module ForemanWreckingball
|
|
4
4
|
class VmwareFacet < ApplicationRecord
|
5
5
|
include Facets::Base
|
6
6
|
|
7
|
-
VALID_GUEST_STATUSES = [
|
7
|
+
VALID_GUEST_STATUSES = %i[toolsNotInstalled toolsNotRunning toolsOk toolsOld].freeze
|
8
8
|
|
9
|
-
enum :
|
9
|
+
enum tools_state: VALID_GUEST_STATUSES
|
10
10
|
|
11
|
-
VALID_POWER_STATES = [
|
12
|
-
enum :
|
11
|
+
VALID_POWER_STATES = %i[poweredOff poweredOn suspended].freeze
|
12
|
+
enum power_state: VALID_POWER_STATES
|
13
13
|
|
14
|
-
belongs_to :vmware_cluster,
|
15
|
-
|
14
|
+
belongs_to :vmware_cluster,
|
15
|
+
class_name: '::ForemanWreckingball::VmwareCluster',
|
16
|
+
inverse_of: :vmware_facets
|
16
17
|
|
17
|
-
has_many :vmware_hypervisor_facets,
|
18
|
-
|
19
|
-
|
18
|
+
has_many :vmware_hypervisor_facets,
|
19
|
+
class_name: '::ForemanWreckingball::VmwareHypervisorFacet',
|
20
|
+
through: :vmware_cluster,
|
21
|
+
inverse_of: :vmware_facets
|
20
22
|
|
21
23
|
validates_lengths_from_database
|
22
24
|
|
23
|
-
validates :host, :
|
25
|
+
validates :host, presence: true, allow_blank: false
|
24
26
|
|
25
27
|
serialize :cpu_features, JSON
|
26
28
|
|
@@ -37,11 +39,14 @@ module ForemanWreckingball
|
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
42
|
+
# rubocop:todo Metrics/AbcSize, Metrics/MethodLength
|
40
43
|
def refresh!
|
41
44
|
vm = host.compute_object
|
42
45
|
return unless vm
|
43
46
|
data_for_update = {
|
44
|
-
vmware_cluster: ::ForemanWreckingball::VmwareCluster.find_by(
|
47
|
+
vmware_cluster: ::ForemanWreckingball::VmwareCluster.find_by(
|
48
|
+
name: vm.cluster, compute_resource: host.compute_resource
|
49
|
+
),
|
45
50
|
cpus: vm.cpus,
|
46
51
|
corespersocket: vm.corespersocket,
|
47
52
|
memory_mb: vm.memory_mb,
|
@@ -50,11 +55,12 @@ module ForemanWreckingball
|
|
50
55
|
guest_id: vm.guest_id,
|
51
56
|
cpu_hot_add: vm.cpuHotAddEnabled,
|
52
57
|
hardware_version: vm.hardware_version,
|
53
|
-
cpu_features: []
|
58
|
+
cpu_features: [],
|
54
59
|
}
|
55
60
|
data_for_update[:cpu_features] = raw_vm_object.runtime.featureRequirement.map(&:key) if vm.ready?
|
56
61
|
update(data_for_update)
|
57
62
|
end
|
63
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
58
64
|
|
59
65
|
def refresh_statuses
|
60
66
|
::HostStatus.wreckingball_statuses.each { |status| host.get_status(status).refresh! }
|
@@ -8,7 +8,9 @@ module ForemanWreckingball
|
|
8
8
|
|
9
9
|
validates :host, presence: true, allow_blank: false
|
10
10
|
|
11
|
-
belongs_to :vmware_cluster,
|
11
|
+
belongs_to :vmware_cluster,
|
12
|
+
inverse_of: :vmware_hypervisor_facets,
|
13
|
+
class_name: '::ForemanWreckingball::VmwareCluster'
|
12
14
|
has_one :compute_resource, inverse_of: :vmware_hypervisor_facets, through: :vmware_cluster
|
13
15
|
has_many :vmware_facets, inverse_of: :vmware_hypervisor_facets, through: :vmware_cluster
|
14
16
|
|
@@ -14,18 +14,21 @@ module ForemanWreckingball
|
|
14
14
|
delete_removed_clusters
|
15
15
|
create_new_clusters
|
16
16
|
end
|
17
|
-
logger.info("Import clusters for '#{compute_resource}' completed. Added: #{counters[:added] || 0}, Updated: #{counters[:updated] || 0}, Deleted: #{counters[:deleted] || 0} clusters")
|
17
|
+
logger.info("Import clusters for '#{compute_resource}' completed. Added: #{counters[:added] || 0}, Updated: #{counters[:updated] || 0}, Deleted: #{counters[:deleted] || 0} clusters") # rubocop:disable Layout/LineLength
|
18
18
|
end
|
19
19
|
|
20
20
|
def delete_removed_clusters
|
21
|
-
counters[:deleted] =
|
21
|
+
counters[:deleted] =
|
22
|
+
::ForemanWreckingball::VmwareCluster.where(compute_resource: compute_resource)
|
23
|
+
.where.not(name: cluster_names)
|
24
|
+
.destroy_all
|
22
25
|
end
|
23
26
|
|
24
27
|
def create_new_clusters
|
25
|
-
existing_clusters = ::ForemanWreckingball::VmwareCluster.where(:
|
28
|
+
existing_clusters = ::ForemanWreckingball::VmwareCluster.where(compute_resource: compute_resource).pluck(:name)
|
26
29
|
clusters_to_create = cluster_names - existing_clusters
|
27
30
|
clusters_to_create.each do |cluster_name|
|
28
|
-
::ForemanWreckingball::VmwareCluster.create(:
|
31
|
+
::ForemanWreckingball::VmwareCluster.create(name: cluster_name, compute_resource: compute_resource)
|
29
32
|
end
|
30
33
|
counters[:added] = clusters_to_create.size
|
31
34
|
end
|
@@ -11,13 +11,12 @@ module ForemanWreckingball
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def import!
|
14
|
-
logger.info "Can not determine organization for compute resource #{compute_resource}."
|
15
14
|
compute_resource.refresh_cache
|
16
15
|
compute_resource.vmware_clusters.each do |cluster|
|
17
16
|
import_hypervisors(cluster)
|
18
17
|
delete_removed_hypervisors(cluster)
|
19
18
|
end
|
20
|
-
logger.info("Import hypervisors for '#{compute_resource}' completed. Added: #{counters[:added] || 0}, Updated: #{counters[:updated] || 0}, Deleted: #{counters[:deleted] || 0} hypervisors") # rubocop:disable
|
19
|
+
logger.info("Import hypervisors for '#{compute_resource}' completed. Added: #{counters[:added] || 0}, Updated: #{counters[:updated] || 0}, Deleted: #{counters[:deleted] || 0} hypervisors") # rubocop:disable Layout/LineLength
|
21
20
|
end
|
22
21
|
|
23
22
|
def import_hypervisors(cluster)
|
@@ -26,6 +25,7 @@ module ForemanWreckingball
|
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
28
|
+
# rubocop:todo Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
29
29
|
def import_hypervisor(cluster, hypervisor)
|
30
30
|
host = find_host_for_hypervisor(hypervisor)
|
31
31
|
|
@@ -33,10 +33,10 @@ module ForemanWreckingball
|
|
33
33
|
|
34
34
|
ipaddress6 = hypervisor.ipaddress6
|
35
35
|
ipaddress6 = nil if begin
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
IPAddr.new('fe80::/10').include?(ipaddress6)
|
37
|
+
rescue StandardError
|
38
|
+
false
|
39
|
+
end
|
40
40
|
|
41
41
|
hostname = hypervisor.hostname
|
42
42
|
domainname = hypervisor.domainname
|
@@ -52,65 +52,73 @@ module ForemanWreckingball
|
|
52
52
|
end
|
53
53
|
|
54
54
|
result = host.update(
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
59
|
-
:
|
60
|
-
:
|
61
|
-
:
|
62
|
-
:
|
63
|
-
:
|
64
|
-
:
|
65
|
-
:
|
66
|
-
:
|
67
|
-
:
|
55
|
+
name: hostname,
|
56
|
+
domain: ::Domain.where(name: domainname).first_or_create,
|
57
|
+
model: ::Model.where(name: hypervisor.model.strip).first_or_create,
|
58
|
+
ip: hypervisor.ipaddress,
|
59
|
+
ip6: ipaddress6,
|
60
|
+
vmware_hypervisor_facet_attributes: {
|
61
|
+
vmware_cluster: cluster,
|
62
|
+
cpu_cores: hypervisor.cpu_cores,
|
63
|
+
cpu_sockets: hypervisor.cpu_sockets,
|
64
|
+
cpu_threads: hypervisor.cpu_threads,
|
65
|
+
memory: hypervisor.memory,
|
66
|
+
uuid: hypervisor.uuid,
|
67
|
+
feature_capabilities: hypervisor.feature_capabilities,
|
68
68
|
}
|
69
69
|
)
|
70
70
|
if result
|
71
|
-
|
71
|
+
increment(counter)
|
72
72
|
else
|
73
73
|
logger.error "Failed to save host #{host}. Reason: #{host.errors.full_messages.to_sentence}"
|
74
74
|
end
|
75
75
|
end
|
76
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
76
77
|
|
77
78
|
def hypervisors(cluster)
|
78
|
-
@hypervisors[cluster.name.to_sym] ||= compute_resource.hypervisors(:
|
79
|
+
@hypervisors[cluster.name.to_sym] ||= compute_resource.hypervisors(cluster_id: cluster.name)
|
79
80
|
end
|
80
81
|
|
81
|
-
def find_host_for_hypervisor(hypervisor)
|
82
|
+
def find_host_for_hypervisor(hypervisor) # rubocop:disable Metrics/AbcSize
|
82
83
|
name = ::ForemanWreckingball::VmwareHypervisorFacet.sanitize_name(hypervisor.name)
|
83
|
-
hostname = ::ForemanWreckingball::VmwareHypervisorFacet.sanitize_name([hypervisor.hostname,
|
84
|
+
hostname = ::ForemanWreckingball::VmwareHypervisorFacet.sanitize_name([hypervisor.hostname,
|
85
|
+
hypervisor.domainname].join('.'))
|
84
86
|
hostname = nil if hostname.blank?
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
host
|
89
|
-
host ||= ::Host.find_by(:name => hostname) if hostname
|
90
|
-
host ||= ::Host.find_by(:name => name)
|
91
|
-
host ||= ::Host.find_by(:name => katello_name) if katello_name
|
92
|
-
host ||= ::Host.find_by(:name => katello_uuid) if katello_uuid
|
87
|
+
|
88
|
+
host = ::ForemanWreckingball::VmwareHypervisorFacet.find_by(uuid: hypervisor.uuid).try(:host)
|
89
|
+
host ||= ::Host.find_by(name: hostname) if hostname
|
90
|
+
host ||= ::Host.find_by(name: name)
|
93
91
|
host ||= create_host_for_hypervisor(hostname || name)
|
94
92
|
host
|
95
93
|
end
|
96
94
|
|
97
95
|
def create_host_for_hypervisor(name)
|
98
|
-
host = ::Host::Managed.new(
|
99
|
-
|
96
|
+
host = ::Host::Managed.new(
|
97
|
+
name: name,
|
98
|
+
organization: organization,
|
99
|
+
location: location,
|
100
|
+
managed: false,
|
101
|
+
enabled: false
|
102
|
+
)
|
100
103
|
host.save!
|
101
104
|
host
|
102
105
|
end
|
103
106
|
|
107
|
+
# rubocop:todo Metrics/AbcSize, Metrics/MethodLength
|
104
108
|
def delete_removed_hypervisors(cluster)
|
105
109
|
hypervisor_names = hypervisors(cluster).map(&:name)
|
106
110
|
hypervisor_uuids = hypervisors(cluster).map(&:uuid)
|
107
|
-
delete_query = ::ForemanWreckingball::VmwareHypervisorFacet.joins(:host)
|
111
|
+
delete_query = ::ForemanWreckingball::VmwareHypervisorFacet.joins(:host)
|
112
|
+
.where(vmware_cluster: cluster)
|
113
|
+
.where.not('hosts.name': hypervisor_names)
|
114
|
+
.where.not(uuid: hypervisor_uuids)
|
108
115
|
counters[:deleted] = if ActiveRecord::Base.connection.adapter_name.downcase.starts_with?('mysql')
|
109
|
-
::ForemanWreckingball::VmwareHypervisorFacet.where(:
|
116
|
+
::ForemanWreckingball::VmwareHypervisorFacet.where(id: delete_query.pluck(:id)).delete_all
|
110
117
|
else
|
111
118
|
delete_query.delete_all
|
112
119
|
end
|
113
120
|
end
|
121
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
114
122
|
|
115
123
|
def organization
|
116
124
|
compute_resource.organizations.first
|
@@ -120,14 +128,9 @@ module ForemanWreckingball
|
|
120
128
|
compute_resource.locations.first
|
121
129
|
end
|
122
130
|
|
123
|
-
def katello_hypervisor_hostname(hostname)
|
124
|
-
return unless organization
|
125
|
-
"virt-who-#{hostname}-#{organization.id}"
|
126
|
-
end
|
127
|
-
|
128
131
|
private
|
129
132
|
|
130
|
-
def
|
133
|
+
def increment(id)
|
131
134
|
counters[id] ||= 0
|
132
135
|
counters[id] += 1
|
133
136
|
end
|
@@ -22,7 +22,7 @@ node(:status) do |host|
|
|
22
22
|
id: status.id,
|
23
23
|
label: status.to_label,
|
24
24
|
icon_class: host_global_status_icon_class(status.to_global),
|
25
|
-
status_class: host_global_status_class(status.to_global)
|
25
|
+
status_class: host_global_status_class(status.to_global),
|
26
26
|
}
|
27
27
|
end
|
28
28
|
|
@@ -32,6 +32,6 @@ end) do
|
|
32
32
|
{
|
33
33
|
label: _('Remediate'),
|
34
34
|
title: _('Remediate Host OS'),
|
35
|
-
path: schedule_remediate_hosts_path
|
35
|
+
path: schedule_remediate_hosts_path,
|
36
36
|
}
|
37
37
|
end
|
@@ -6,8 +6,8 @@ node(:recordsTotal) { @count }
|
|
6
6
|
node(:recordsFiltered) { @count }
|
7
7
|
node(:data) do
|
8
8
|
partial 'foreman_wreckingball/hosts/_hosts', object: @hosts,
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
locals: {
|
10
|
+
host_association: @status.host_association,
|
11
|
+
supports_remediate: @status.supports_remediate?,
|
12
|
+
}
|
13
13
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require Rails.root.join('config
|
3
|
+
require Rails.root.join('config/environments/production.rb')
|
4
4
|
|
5
5
|
Foreman::Application.configure do
|
6
6
|
config.assets.js_compressor = Uglifier.new(harmony: true) if defined?(Uglifier)
|
data/config/routes.rb
CHANGED
@@ -2,12 +2,13 @@
|
|
2
2
|
|
3
3
|
Rails.application.routes.draw do
|
4
4
|
scope '/wreckingball' do
|
5
|
-
constraints(:
|
5
|
+
constraints(id: %r{[^/]+}) do
|
6
6
|
resources :hosts, controller: 'foreman_wreckingball/hosts', only: [] do
|
7
7
|
collection do
|
8
8
|
get :status_dashboard
|
9
9
|
get :status_managed_hosts_dashboard
|
10
|
-
get 'status_dashboard/hosts(/:status)', as: :ajax_status_dashboard, action: :status_hosts,
|
10
|
+
get 'status_dashboard/hosts(/:status)', as: :ajax_status_dashboard, action: :status_hosts,
|
11
|
+
defaults: { format: :json }
|
11
12
|
put :refresh_status_dashboard
|
12
13
|
get :schedule_remediate
|
13
14
|
post :submit_remediate
|
@@ -3,6 +3,6 @@
|
|
3
3
|
class AddIndexesToVmwareHypervisorFacets < ActiveRecord::Migration[5.1]
|
4
4
|
def change
|
5
5
|
add_index :vmware_hypervisor_facets, :uuid
|
6
|
-
add_index :vmware_hypervisor_facets, [
|
6
|
+
add_index :vmware_hypervisor_facets, %i[vmware_cluster_id uuid]
|
7
7
|
end
|
8
8
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FixWreckingballSettingsCategoryToDsl < ActiveRecord::Migration[6.0]
|
4
|
+
class MigrationSettings < ActiveRecord::Base
|
5
|
+
self.table_name = :settings
|
6
|
+
end
|
7
|
+
|
8
|
+
def up
|
9
|
+
MigrationSettings.where(category: 'Setting::Wreckingball').update_all(category: 'Setting') if column_exists?(
|
10
|
+
:settings, :category
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
@@ -12,14 +12,9 @@ module ForemanWreckingball
|
|
12
12
|
'ForemanWreckingball::OperatingsystemStatus',
|
13
13
|
'ForemanWreckingball::CpuHotAddStatus',
|
14
14
|
'ForemanWreckingball::SpectreV2Status',
|
15
|
-
'ForemanWreckingball::HardwareVersionStatus'
|
15
|
+
'ForemanWreckingball::HardwareVersionStatus',
|
16
16
|
].freeze
|
17
17
|
|
18
|
-
config.autoload_paths += Dir["#{config.root}/app/lib"]
|
19
|
-
config.autoload_paths += Dir["#{config.root}/app/services"]
|
20
|
-
config.autoload_paths += Dir["#{config.root}/app/models/concerns"]
|
21
|
-
config.autoload_paths += Dir["#{config.root}/app/helpers/concerns"]
|
22
|
-
|
23
18
|
initializer 'foreman_wreckingball.register_paths' do |_app|
|
24
19
|
::ForemanTasks.dynflow.config.eager_load_paths.concat(%W[#{ForemanWreckingball::Engine.root}/app/lib/actions])
|
25
20
|
end
|
@@ -31,79 +26,85 @@ module ForemanWreckingball
|
|
31
26
|
end
|
32
27
|
end
|
33
28
|
|
34
|
-
initializer 'foreman_wreckingball.
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
29
|
+
initializer 'foreman_wreckingball.register_plugin', before: :finisher_hook do |app|
|
30
|
+
app.reloader.to_prepare do
|
31
|
+
Foreman::Plugin.register :foreman_wreckingball do
|
32
|
+
requires_foreman '>= 3.13'
|
33
|
+
|
34
|
+
settings do
|
35
|
+
category :wreckingball, N_('Wreckingball') do
|
36
|
+
setting :min_vsphere_hardware_version,
|
37
|
+
type: :integer,
|
38
|
+
default: 13,
|
39
|
+
description: _('Minimum required Hardware version for vSphere VMs')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
automatic_assets(false)
|
44
|
+
precompile_assets(
|
45
|
+
[
|
46
|
+
'foreman_wreckingball/modal.js',
|
47
|
+
'foreman_wreckingball/status_hosts_table.js',
|
48
|
+
'foreman_wreckingball/status_managed_hosts_dashboard.js',
|
49
|
+
'foreman_wreckingball/status_row.js',
|
50
|
+
'foreman_wreckingball/status_hosts_table.css',
|
51
|
+
'foreman_wreckingball/status_managed_hosts_dashboard.css',
|
52
|
+
]
|
53
|
+
)
|
54
|
+
|
55
|
+
security_block :foreman_wreckingball do
|
56
|
+
permission :refresh_vmware_status_hosts, {
|
57
|
+
'foreman_wreckingball/hosts': %i[refresh_status_dashboard],
|
58
|
+
}, resource_type: 'Host'
|
59
|
+
permission :remediate_vmware_status_hosts, {
|
60
|
+
'foreman_wreckingball/hosts': %i[schedule_remediate submit_remediate],
|
61
|
+
}, resource_type: 'Host'
|
62
|
+
end
|
63
|
+
|
64
|
+
# Extend built in permissions
|
65
|
+
Foreman::AccessControl.permission(:view_hosts).actions.concat [
|
66
|
+
'foreman_wreckingball/hosts/status_dashboard',
|
67
|
+
'foreman_wreckingball/hosts/status_managed_hosts_dashboard',
|
68
|
+
'foreman_wreckingball/hosts/status_hosts',
|
56
69
|
]
|
57
|
-
)
|
58
|
-
|
59
|
-
security_block :foreman_wreckingball do
|
60
|
-
permission :refresh_vmware_status_hosts, {
|
61
|
-
:'foreman_wreckingball/hosts' => [:refresh_status_dashboard]
|
62
|
-
}, :resource_type => 'Host'
|
63
|
-
permission :remediate_vmware_status_hosts, {
|
64
|
-
:'foreman_wreckingball/hosts' => [:schedule_remediate, :submit_remediate]
|
65
|
-
}, :resource_type => 'Host'
|
66
|
-
end
|
67
70
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
71
|
+
menu :top_menu,
|
72
|
+
:wreckingball_status_dashboard,
|
73
|
+
url_hash: { controller: :'foreman_wreckingball/hosts', action: :status_dashboard },
|
74
|
+
caption: N_('VMware Status'),
|
75
|
+
parent: :hosts_menu,
|
76
|
+
after: :hosts
|
74
77
|
|
75
|
-
|
76
|
-
:caption => N_('VMware Status'),
|
77
|
-
:parent => :hosts_menu,
|
78
|
-
:after => :hosts
|
78
|
+
WRECKINGBALL_STATUSES.each { |status| register_custom_status(status.constantize) }
|
79
79
|
|
80
|
-
|
80
|
+
menu :top_menu,
|
81
|
+
:wreckingball_status_managed_hosts_dashboard,
|
82
|
+
url_hash: { controller: :'foreman_wreckingball/hosts', action: :status_managed_hosts_dashboard },
|
83
|
+
caption: N_('VMware Managed Status'),
|
84
|
+
parent: :monitor_menu,
|
85
|
+
after: :audits
|
81
86
|
|
82
|
-
|
83
|
-
caption: N_('VMware Managed Status'),
|
84
|
-
parent: :monitor_menu,
|
85
|
-
after: :audits
|
87
|
+
register_facet(ForemanWreckingball::VmwareFacet, :vmware_facet)
|
86
88
|
|
87
|
-
|
89
|
+
register_facet(ForemanWreckingball::VmwareHypervisorFacet, :vmware_hypervisor_facet)
|
88
90
|
|
89
|
-
|
91
|
+
add_controller_action_scope('HostsController', :index) { |base_scope| base_scope.includes(:vmware_facet) }
|
90
92
|
|
91
|
-
|
93
|
+
# extend host show page
|
94
|
+
extend_page('compute_resources/show') do |context|
|
95
|
+
context.add_pagelet :main_tabs,
|
96
|
+
name: N_('Hypervisors'),
|
97
|
+
partial: 'compute_resources/hypervisors_tab',
|
98
|
+
onlyif: proc { |cr| cr.provider_friendly_name == 'VMware' && cr.vmware_hypervisor_facets.any? }
|
99
|
+
end
|
92
100
|
|
93
|
-
|
94
|
-
|
95
|
-
context.add_pagelet :main_tabs,
|
96
|
-
:name => N_('Hypervisors'),
|
97
|
-
:partial => 'compute_resources/hypervisors_tab',
|
98
|
-
:onlyif => proc { |cr| cr.provider_friendly_name == 'VMware' && cr.vmware_hypervisor_facets.any? }
|
101
|
+
# add custom logger
|
102
|
+
logger :import, enabled: true
|
99
103
|
end
|
100
|
-
|
101
|
-
# add custom logger
|
102
|
-
logger :import, enabled: true
|
103
104
|
end
|
104
105
|
end
|
105
106
|
|
106
|
-
initializer 'foreman_wreckingball.dynflow_world', :
|
107
|
+
initializer 'foreman_wreckingball.dynflow_world', before: 'foreman_tasks.initialize_dynflow' do |_app|
|
107
108
|
::ForemanTasks.dynflow.require!
|
108
109
|
end
|
109
110
|
|
@@ -111,20 +112,19 @@ module ForemanWreckingball
|
|
111
112
|
config.to_prepare do
|
112
113
|
::HostStatus.extend(ForemanWreckingball::HostStatusExtensions)
|
113
114
|
|
114
|
-
::ComputeResource.
|
115
|
-
::Foreman::Model::Vmware.
|
116
|
-
::Host::Managed.
|
117
|
-
::Host::Managed.
|
118
|
-
::Host::Managed.
|
119
|
-
::
|
120
|
-
::
|
121
|
-
::Usergroup.send(:include, ForemanWreckingball::UsergroupExtensions)
|
115
|
+
::ComputeResource.include(ForemanWreckingball::ComputeResourceExtensions)
|
116
|
+
::Foreman::Model::Vmware.include(ForemanWreckingball::VmwareExtensions)
|
117
|
+
::Host::Managed.include(ForemanWreckingball::HostExtensions)
|
118
|
+
::Host::Managed.include(ForemanWreckingball::VmwareFacetHostExtensions)
|
119
|
+
::Host::Managed.include(ForemanWreckingball::VmwareHypervisorFacetHostExtensions)
|
120
|
+
::User.include(ForemanWreckingball::UserExtensions)
|
121
|
+
::Usergroup.include(ForemanWreckingball::UsergroupExtensions)
|
122
122
|
|
123
123
|
if ForemanWreckingball.fog_patches_required?
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
124
|
+
Fog::Vsphere::Compute::Host.include(FogExtensions::ForemanWreckingball::Vsphere::Host)
|
125
|
+
Fog::Vsphere::Compute::Server.include(FogExtensions::ForemanWreckingball::Vsphere::Server)
|
126
|
+
Fog::Vsphere::Compute::Real.include(FogExtensions::ForemanWreckingball::Vsphere::Real)
|
127
|
+
Fog::Vsphere::Compute::Mock.include(FogExtensions::ForemanWreckingball::Vsphere::Mock)
|
128
128
|
end
|
129
129
|
rescue StandardError => e
|
130
130
|
Rails.logger.warn "ForemanWreckingball: skipping engine hook (#{e})\n#{e.backtrace.join("\n")}"
|
@@ -142,17 +142,9 @@ module ForemanWreckingball
|
|
142
142
|
require 'fog/vsphere'
|
143
143
|
require 'fog/vsphere/compute'
|
144
144
|
require 'fog/vsphere/models/compute/host'
|
145
|
+
require 'fog/vsphere/models/compute/server'
|
145
146
|
true
|
146
147
|
rescue LoadError
|
147
148
|
false
|
148
149
|
end
|
149
|
-
|
150
|
-
def self.fog_vsphere_namespace
|
151
|
-
require 'fog/vsphere/version'
|
152
|
-
@fog_vsphere_namespace ||= if Gem::Version.new(Fog::Vsphere::VERSION) >= Gem::Version.new('3.0.0')
|
153
|
-
Fog::Vsphere::Compute
|
154
|
-
else
|
155
|
-
Fog::Compute::Vsphere
|
156
|
-
end
|
157
|
-
end
|
158
150
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# First, we check if there's a job already enqueued
|
4
|
-
pending_jobs = ::Foreman::Application.dynflow.world.persistence.find_execution_plans(filters: { :
|
4
|
+
pending_jobs = ::Foreman::Application.dynflow.world.persistence.find_execution_plans(filters: { state: 'scheduled' })
|
5
5
|
scheduled_job = pending_jobs.select do |job|
|
6
6
|
delayed_plan = ::Foreman::Application.dynflow.world.persistence.load_delayed_plan(job.id)
|
7
7
|
next if delayed_plan.blank?
|