forked from ManageIQ/manageiq
-
Notifications
You must be signed in to change notification settings - Fork 0
/
zone.rb
258 lines (205 loc) · 7.75 KB
/
zone.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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
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
257
258
class Zone < ApplicationRecord
validates_presence_of :name, :description
validates :name, :unique_within_region => true
serialize :settings, Hash
belongs_to :log_file_depot, :class_name => "FileDepot"
has_many :miq_servers
has_many :ext_management_systems
has_many :paused_ext_management_systems, :class_name => 'ExtManagementSystem', :inverse_of => :zone_before_pause
has_one :maintenance_zone_region, :class_name => 'MiqRegion', :inverse_of => :maintenance_zone
has_many :container_managers, :class_name => "ManageIQ::Providers::ContainerManager"
has_many :miq_schedules, :dependent => :destroy
has_many :providers
has_many :miq_queues, :dependent => :destroy, :foreign_key => :zone, :primary_key => :name
has_many :hosts, :through => :ext_management_systems
has_many :clustered_hosts, :through => :ext_management_systems
has_many :non_clustered_hosts, :through => :ext_management_systems
has_many :vms_and_templates, :through => :ext_management_systems
has_many :vms, :through => :ext_management_systems
has_many :miq_templates, :through => :ext_management_systems
has_many :ems_clusters, :through => :ext_management_systems
has_many :physical_servers, :through => :ext_management_systems
has_many :container_nodes, :through => :container_managers
has_many :container_groups, :through => :container_managers
has_many :container_replicators, :through => :container_managers
has_many :containers, :through => :container_managers
virtual_has_many :active_miq_servers, :class_name => "MiqServer"
before_destroy :check_zone_in_use_on_destroy
include AuthenticationMixin
include SupportsFeatureMixin
include Metric::CiMixin
include AggregationMixin
include ConfigurationManagementMixin
scope :visible, -> { where(:visible => true) }
default_value_for :visible, true
MAINTENANCE_ZONE_NAME_PREFIX = '__maintenance__'.freeze
def active_miq_servers
MiqServer.active_miq_servers.where(:zone_id => id)
end
def servers_for_settings_reload
miq_servers.where(:status => "started")
end
def find_master_server
active_miq_servers.detect(&:is_master?)
end
def self.create_maintenance_zone
if maintenance_zone.nil?
# 1) Create region, if not exists
MiqRegion.seed
# 2) Create Maintenance zone
threshold = 100 # avoiding infinite loop
zone = nil
(1..threshold).each do |idx|
zone = create(:name => "#{MAINTENANCE_ZONE_NAME_PREFIX}#{idx}",
:description => "Maintenance Zone",
:visible => false)
break if zone.valid?
end
# 3) Assign zone to region
if zone&.valid?
region = zone.miq_region
region&.maintenance_zone = zone
unless region&.save
_log.error("Saving Maintenance zone to region failed with: #{region&.errors&.messages.inspect}")
end
_log.info("Creating maintenance zone...")
else
_log.error("Maintenance zone not created in #{threshold} attempts")
end
end
end
def self.seed
create_maintenance_zone
create_with(:description => "Default Zone").find_or_create_by!(:name => 'default') do |_z|
_log.info("Creating default zone...")
end
end
def miq_region
MiqRegion.find_by(:region => region_id)
end
def assigned_roles
miq_servers.flat_map(&:assigned_roles).uniq.compact
end
def role_active?(role_name)
active_miq_servers.any? { |s| s.has_active_role?(role_name) }
end
def role_assigned?(role_name)
active_miq_servers.any? { |s| s.has_assigned_role?(role_name) }
end
def active_role_names
miq_servers.flat_map(&:active_role_names).uniq
end
def self.default_zone
in_my_region.find_by(:name => "default")
end
# Zone for paused providers (no servers in it), not visible by default
def self.maintenance_zone
MiqRegion.find_by(:region => my_region_number)&.maintenance_zone
end
def remote_cockpit_ws_miq_server
role_active?("cockpit_ws") ? miq_servers.find_by(:has_active_cockpit_ws => true) : nil
end
# The zone to use when inserting a record into MiqQueue
def self.determine_queue_zone(options)
if options.key?(:zone)
options[:zone] # return specified zone including nil (aka ANY zone)
elsif options[:role] && ServerRole.regional_role?(options[:role])
nil # ANY zone, will be limited by role
else
MiqServer.my_zone
end
end
def synchronize_logs(*args)
options = args.extract_options!
enabled = Settings.log.collection.include_automate_models_and_dialogs
active_miq_servers.each_with_index do |s, index|
# If enabled, export the automate domains and dialogs on the first active server
include_models_and_dialogs = enabled ? index.zero? : false
s.synchronize_logs(*args, options.merge(:include_automate_models_and_dialogs => include_models_and_dialogs))
end
end
def last_log_sync_on
miq_servers.inject(nil) do |d, s|
last = s.last_log_sync_on
d ||= last
d = last if last && last > d
d
end
end
def log_collection_active?
miq_servers.any?(&:log_collection_active?)
end
def log_collection_active_recently?(since = nil)
miq_servers.any? { |s| s.log_collection_active_recently?(since) }
end
def self.hosts_without_a_zone
Host.where(:ems_id => nil).to_a
end
def self.clusters_without_a_zone
EmsCluster.where(:ems_id => nil).to_a
end
def ems_infras
ext_management_systems.select { |e| e.kind_of?(EmsInfra) }
end
def ems_containers
ext_management_systems.select { |e| e.kind_of?(ManageIQ::Providers::ContainerManager) }
end
def ems_middlewares
ext_management_systems.select { |e| e.kind_of?(ManageIQ::Providers::MiddlewareManager) }
end
def middleware_servers
ems_middlewares.flat_map(&:middleware_servers)
end
def ems_datawarehouses
ext_management_systems.select { |e| e.kind_of?(ManageIQ::Providers::DatawarehouseManager) }
end
def ems_monitors
ext_management_systems.select { |e| e.kind_of?(ManageIQ::Providers::MonitoringManager) }
end
def ems_configproviders
ext_management_systems.select { |e| e.kind_of?(ManageIQ::Providers::ConfigurationManager) }
end
def ems_clouds
ext_management_systems.select { |e| e.kind_of?(EmsCloud) }
end
def ems_networks
ext_management_systems.select { |e| e.kind_of?(ManageIQ::Providers::NetworkManager) }
end
def availability_zones
MiqPreloader.preload(ems_clouds, :availability_zones)
ems_clouds.flat_map(&:availability_zones)
end
def self.vms_without_a_zone
Vm.where(:ems_id => nil).to_a
end
def storages
MiqPreloader.preload(self, :ext_management_systems => {:hosts => :storages})
ext_management_systems.flat_map(&:storages).uniq
end
def self.storages_without_a_zone
storage_without_hosts = Storage.includes(:hosts).where(:host_storages => {:storage_id => nil}).to_a
storage_without_ems = Host.where(:ems_id => nil).includes(:storages).flat_map(&:storages).uniq
storage_without_hosts + storage_without_ems
end
def display_name
name
end
def active?
miq_servers.any?(&:active?)
end
def any_started_miq_servers?
miq_servers.any?(&:started?)
end
def ntp_reload_queue
servers = active_miq_servers
return if servers.blank?
_log.info("Zone: [#{name}], Queueing ntp_reload for [#{servers.length}] active_miq_servers, ids: #{servers.collect(&:id)}")
servers.each(&:ntp_reload_queue)
end
protected
def check_zone_in_use_on_destroy
raise _("cannot delete default zone") if name == "default"
raise _("cannot delete maintenance zone") if self == miq_region&.maintenance_zone
raise _("zone name '%{name}' is used by a server") % {:name => name} unless miq_servers.blank?
end
end