forked from theforeman/foreman_virt_who_configure
-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.rb
206 lines (172 loc) · 6.71 KB
/
config.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
module ForemanVirtWhoConfigure
class Config < ActiveRecord::Base
PERMITTED_PARAMS = [
:interval, :organization_id, :compute_resource_id, :whitelist, :blacklist, :listing_mode, :hypervisor_id,
:hypervisor_type, :hypervisor_server, :hypervisor_username, :hypervisor_password, :debug,
:satellite_url, :proxy, :no_proxy, :name
]
include Authorizable
audited :except => [ :hypervisor_password, :last_report_at, :out_of_date_at ]
validates_lengths_from_database
UNLIMITED = 0
WHITELIST = 1
BLACKLIST = 2
FILTERING_MODES = {
UNLIMITED.to_s => N_('Unlimited'),
WHITELIST.to_s => N_('Whitelist'),
BLACKLIST.to_s => N_('Blacklist'),
}
WIZARD_STEPS = {
'general_information' => N_('General information'),
'schedule' => N_('Schedule'),
'connection' => N_('Connection')
}
HYPERVISOR_IDS = [ 'hostname', 'uuid', 'hwuuid' ]
HYPERVISOR_TYPES = {
'esx' => 'VMware vSphere / vCenter (esx)',
'rhevm' => 'Red Hat Virtualization Hypervisor (rhevm)',
# 'vdsm' => 'Red Hat Enterprise Linux Hypervisor (vdsm)',
'hyperv' => 'Microsoft Hyper-V (hyperv)',
'xen' => 'XenServer (xen)',
'libvirt' => 'libvirt'
}
HYPERVISOR_DEFAULT_TYPE = 'esx'
AVAILABLE_INTERVALS = {
'60' => N_('Every hour'),
'120' => N_('Every 2 hours'),
'240' => N_('Every 4 hours'),
'480' => N_('Every 8 hours'),
'720' => N_('Every 12 hours'),
}
DEFAULT_INTERVAL = 120
STATUSES = {
'ok' => N_('OK'),
'out_of_date' => N_('No change'),
'unknown' => N_('Unknown')
}
STATUS_DESCRIPTIONS = Hash.new(N_('Unknown configuration status, caused by unexpected conditions')).merge(
{
:unknown => N_('The configuration was not deployed yet or the virt-who was unable to report the status'),
:ok => N_('The virt-who report arrived within the interval'),
:out_of_date => N_('The virt-who report has not arrived within the interval, which indicates there was no change on hypervisor')
}
)
include Encryptable
encrypts :hypervisor_password
belongs_to :compute_resource
belongs_to :organization
# service user used by virt-who to report back
belongs_to :service_user
scoped_search :on => :interval, :complete_value => true
scoped_search :on => :name
scoped_search :on => :status, :complete_value => true, :only_explicit => true, :operators => ['= '], :ext_method => :search_by_status
scoped_search :on => :out_of_date_at, :complete_value => true, :only_explicit => true
scoped_search :on => :last_report_at, :complete_value => true, :only_explicit => true
# TODO add more related objects and attributes
# compatibility layer for 1.11 - pre strong params patch
if self.respond_to?(:attr_accessible)
attr_accessible(*PERMITTED_PARAMS)
end
after_create :create_service_user
after_destroy :destroy_service_user
validates :interval, :hypervisor_type, :hypervisor_server, :hypervisor_username, :hypervisor_password,
:satellite_url, :hypervisor_id, :organization_id, :name,
:presence => true
validates :hypervisor_type, :inclusion => HYPERVISOR_TYPES.keys
validates :hypervisor_id, :inclusion => HYPERVISOR_IDS
validates :interval, :inclusion => AVAILABLE_INTERVALS.keys.map(&:to_i)
validates :listing_mode, :inclusion => FILTERING_MODES.keys.map(&:to_i)
validates :whitelist, :presence => true, :if => Proc.new { |c| c.listing_mode.to_i == WHITELIST }
validates :blacklist, :presence => true, :if => Proc.new { |c| c.listing_mode.to_i == BLACKLIST }
validates_lengths_from_database
before_validation :remove_whitespaces
scope :out_of_date, ->(deadline = DateTime.now.utc) { where(["out_of_date_at < ?", deadline.utc.to_s(:db)]) }
scope :for_organization, ->(org) { org.nil? ? where(nil) : where(:organization_id => org) }
def self.search_by_status(key, operator, value)
condition = case value
when 'ok'
sanitize_sql_for_conditions([' out_of_date_at >= ? ', DateTime.now.utc.to_s(:db)])
when 'unknown'
sanitize_sql_for_conditions({:last_report_at => nil})
when 'out_of_date'
sanitize_sql_for_conditions([' out_of_date_at < ? ', DateTime.now.utc.to_s(:db)])
end
{ :conditions => condition }
end
def create_service_user
password = User.random_password
service_user = self.build_service_user
user = service_user.build_user
user.auth_source = AuthSourceHiddenWithAuthentication.default
user.password = password
user.login = "virt_who_reporter_#{self.id}"
user.organizations = [ self.organization ]
user.roles = [ Role.where(:name => 'Virt-who Reporter').first ]
user.valid? # to trigger password hashing
user.save!(:validate => false)
service_user.encrypted_password = password
service_user.save!
self.update_attribute :service_user_id, service_user.id
end
def destroy_service_user
# skip validation that prevents hidden user deletion
user = service_user.user
service_user.destroy
user.delete
end
# mapping of supported CR types
# case config.compute_resource
# when Foreman::Model::Libvirt
# 'libvirt'
# when Foreman::Model::Vmware
# 'esx'
# when Foreman::Model::Ovirt
# 'rhevm'
# else
# raise 'unsupported compute resource type'
# end
def humanized_interval
_("every %s hours") % (self.interval / 60)
end
def out_of_date?(deadline = DateTime.now.utc)
self.out_of_date_at.present? && self.out_of_date_at < deadline
end
def step_name(step_key)
_(WIZARD_STEPS[step_key])
end
def steps
WIZARD_STEPS.keys
end
def virt_who_config_file
generator = OutputGenerator.new(self)
if generator.ready_for_virt_who_output?
generator.virt_who_output
else
generator.missing_virt_who_input_messages.join("\n")
end
end
def virt_who_touch!
self.last_report_at = DateTime.now.utc
self.out_of_date_at = self.last_report_at + self.interval.minutes
self.save!
end
def status
case
when self.last_report_at.nil?
:unknown
when !self.out_of_date?
:ok
else
# out of date is currently considered ok too, virt-who does not send any report if there's no change on hypervisor
:out_of_date
end
end
def status_description
_(STATUS_DESCRIPTIONS[status])
end
private
def remove_whitespaces
satellite_url.strip! if satellite_url.present?
end
end
end