Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map server to zone in pods #19770

Merged
merged 4 commits into from
Jan 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/models/miq_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,8 @@ def is_recently_active?
end

def is_deleteable?
return true if MiqEnvironment::Command.is_podified?

if self.is_local?
message = N_("Cannot delete currently used %{log_message}") % {:log_message => format_short_log_msg}
@errors ||= ActiveModel::Errors.new(self)
Expand Down
27 changes: 24 additions & 3 deletions app/models/zone.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ class Zone < ApplicationRecord
has_many :containers, :through => :container_managers
virtual_has_many :active_miq_servers, :class_name => "MiqServer"

before_destroy :remove_servers_if_podified
before_destroy :check_zone_in_use_on_destroy
after_create :create_server_if_podified

include AuthenticationMixin

Expand Down Expand Up @@ -239,11 +241,30 @@ def ntp_reload_queue
servers.each(&:ntp_reload_queue)
end

def message_for_invalid_delete
return _("cannot delete default zone") if name == "default"
return _("cannot delete maintenance zone") if self == miq_region.maintenance_zone
return _("zone name '%{name}' is used by a server") % {:name => name} if miq_servers.present?
_("zone name '%{name}' is used by a provider") % {:name => name} if ext_management_systems.present?
end

protected

def remove_servers_if_podified
return unless MiqEnvironment::Command.is_podified?

miq_servers.destroy_all
end

def create_server_if_podified
return unless MiqEnvironment::Command.is_podified?
return if name == "default" || !visible

miq_servers.create!(:name => name)
end

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?
msg = message_for_invalid_delete
raise msg if msg
end
end
16 changes: 9 additions & 7 deletions spec/lib/workers/evm_server_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,21 @@
expect(subject.servers_to_monitor.first.id).to eq(MiqServer.first.id)

4.times { FactoryBot.create(:miq_server) }
expect(subject).to receive(:impersonate_server).exactly(4).times
expect(subject).to receive(:start_server).exactly(4).times

num_servers = MiqServer.count

# one for each new server
expect(subject).to receive(:impersonate_server).exactly(num_servers - 1).times
expect(subject).to receive(:start_server).exactly(num_servers - 1).times
subject.refresh_servers_to_monitor

expect(subject.servers_to_monitor.count).to eq(5)
expect(subject.servers_to_monitor.count).to eq(num_servers)
expect(subject.servers_to_monitor.map(&:id)).to match_array(MiqServer.all.map(&:id))
end

it "removes a server when it is removed from the database" do
server = FactoryBot.create(:miq_server)
expect(subject.servers_to_monitor.map(&:id)).to include(server.id)
expect(subject.servers_to_monitor.count).to eq(2)

monitor_server = subject.servers_to_monitor.find { |s| s.id == server.id }
expect(monitor_server).to receive(:shutdown)
Expand All @@ -75,7 +78,6 @@
subject.refresh_servers_to_monitor

expect(subject.servers_to_monitor.map(&:id)).not_to include(server.id)
expect(subject.servers_to_monitor.count).to eq(1)
end

# Note: this is a very important spec
Expand All @@ -86,8 +88,8 @@
initial_object_id = subject.servers_to_monitor.first.object_id

4.times { FactoryBot.create(:miq_server) }
expect(subject).to receive(:impersonate_server).exactly(4).times
expect(subject).to receive(:start_server).exactly(4).times
allow(subject).to receive(:impersonate_server)
allow(subject).to receive(:start_server)
subject.refresh_servers_to_monitor

new_objects = subject.servers_to_monitor.map(&:object_id)
Expand Down
10 changes: 5 additions & 5 deletions spec/models/miq_server/queue_management_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@

describe "#ntp_reload_queue" do
it "enqueues a message if the server is an appliance, but not a container" do
expect(MiqEnvironment::Command).to receive(:is_appliance?).and_return(true)
expect(MiqEnvironment::Command).to receive(:is_container?).and_return(false)
allow(MiqEnvironment::Command).to receive(:is_appliance?).and_return(true)
allow(MiqEnvironment::Command).to receive(:is_container?).and_return(false)

server.ntp_reload_queue

expect(ntp_reload_enqueued?).to be_truthy
end

it "doesn't enqueue a message if the server is not an appliance" do
expect(MiqEnvironment::Command).to receive(:is_appliance?).and_return(false)
allow(MiqEnvironment::Command).to receive(:is_appliance?).and_return(false)

server.ntp_reload_queue

expect(ntp_reload_enqueued?).to be_falsey
end

it "doesn't enqueue a message if the server is a container" do
expect(MiqEnvironment::Command).to receive(:is_appliance?).and_return(true)
expect(MiqEnvironment::Command).to receive(:is_container?).and_return(true)
allow(MiqEnvironment::Command).to receive(:is_appliance?).and_return(true)
allow(MiqEnvironment::Command).to receive(:is_container?).and_return(true)

server.ntp_reload_queue

Expand Down
7 changes: 7 additions & 0 deletions spec/models/miq_server_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@

expect(@miq_server.errors.full_messages.first).to match(/recently/)
end

it "doesn't enforce when podified" do
allow(MiqEnvironment::Command).to receive(:is_podified?).and_return(true)
allow(@miq_server).to receive(:is_local?).and_return(true)
@miq_server.last_heartbeat = 2.minutes.ago.utc
@miq_server.destroy!
end
end

context "#ntp_reload_queue" do
Expand Down
71 changes: 69 additions & 2 deletions spec/models/zone_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@

context "#ntp_reload_queue" do
it "queues a ntp reload for all active servers in the zone" do
expect(MiqEnvironment::Command).to receive(:is_appliance?).and_return(true)
expect(MiqEnvironment::Command).to receive(:is_container?).and_return(false)
allow(MiqEnvironment::Command).to receive(:is_appliance?).and_return(true)
allow(MiqEnvironment::Command).to receive(:is_container?).and_return(false)
zone = FactoryBot.create(:zone)
server_1 = FactoryBot.create(:miq_server, :zone => zone)
FactoryBot.create(:miq_server, :zone => zone, :status => "stopped")
Expand Down Expand Up @@ -203,6 +203,11 @@
described_class.seed
expect(described_class.maintenance_zone.visible).to eq(false)
end

it "cannot be destroyed" do
described_class.seed
expect { described_class.maintenance_zone.destroy! }.to raise_error(RuntimeError)
end
end

context "validate multi region" do
Expand All @@ -224,4 +229,66 @@
zone.destroy!
expect(MiqQueue.where(:zone => zone.name).count).to eq(0)
end

it "doesn't create a server for the zone when not podified" do
zone = FactoryBot.create(:zone)
expect(zone.miq_servers.count).to eq(0)
end

describe "#destroy" do
before { MiqRegion.seed }

it "fails for a zone with servers when not podified" do
zone = FactoryBot.create(:zone)
zone.miq_servers.create!(:name => "my_server")
expect { zone.destroy! }.to raise_error(RuntimeError)
end

it "fails for the default zone" do
described_class.seed
expect { described_class.default_zone.destroy! }.to raise_error(RuntimeError)
end

it "fails for a zone with a provider" do
zone = FactoryBot.create(:zone)
FactoryBot.create(:ext_management_system, :zone => zone)

expect { zone.destroy! }.to raise_error(RuntimeError)
end
end

context "when podified" do
before do
allow(MiqEnvironment::Command).to receive(:is_podified?).and_return(true)
end

describe ".create" do
it "automatically creates a server" do
zone = Zone.create!(:name => "my_zone", :description => "some zone")
expect(zone.miq_servers.count).to eq(1)

server = zone.miq_servers.first
expect(server.name).to eq("my_zone")
end

it "doesn't create a server for non-visible zones" do
zone = Zone.create!(:name => "my_zone", :description => "some zone", :visible => false)
expect(zone.miq_servers.count).to eq(0)
end

it "doesn't create a server for the default zone" do
zone = Zone.create!(:name => "default", :description => "Default Zone")
expect(zone.miq_servers.count).to eq(0)
end
end

it ".destroy deletes the server in the zone" do
MiqRegion.seed
zone = Zone.create!(:name => "my_zone", :description => "some zone")
server = zone.miq_servers.first
zone.destroy!

expect(MiqServer.find_by(:id => server.id)).to be_nil
end
end
end