Skip to content

Commit def94bd

Browse files
authored
Merge pull request #23609 from kbrock/report_requires3_vm
Update Vm#find_all_by_mac_address_and_hostname_and_ipaddress
2 parents db84cd1 + e10f2ad commit def94bd

File tree

4 files changed

+143
-79
lines changed

4 files changed

+143
-79
lines changed

app/models/vm.rb

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -44,38 +44,6 @@ def enforce_single_service_parent?
4444
true
4545
end
4646

47-
def self.find_all_by_mac_address_and_hostname_and_ipaddress(mac_address, hostname, ipaddress)
48-
return [] if mac_address.blank? && hostname.blank? && ipaddress.blank?
49-
50-
include = [:vm_or_template]
51-
references = []
52-
conds = [["hardwares.vm_or_template_id IS NOT NULL"]]
53-
if mac_address
54-
conds[0] << "guest_devices.address = ?"
55-
conds << mac_address
56-
include << :nics
57-
references << :guest_devices
58-
end
59-
if hostname
60-
conds[0] << "networks.hostname = ?"
61-
conds << hostname
62-
include << :networks
63-
references << :networks
64-
end
65-
if ipaddress
66-
conds[0] << "networks.ipaddress = ?"
67-
conds << ipaddress
68-
include << :networks
69-
references << :networks
70-
end
71-
conds[0] = "(#{conds[0].join(" AND ")})"
72-
73-
Hardware.includes(include.uniq)
74-
.references(references.uniq)
75-
.where(conds)
76-
.map(&:vm_or_template).select { |vm| vm.kind_of?(Vm) }
77-
end
78-
7947
def running_processes
8048
pl = {}
8149
if (reason = unsupported_reason(:collect_running_processes))

lib/workers/evm_server.rb

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,15 +186,27 @@ def save_local_network_info
186186

187187
def set_local_server_vm
188188
if @current_server.vm_id.nil?
189-
vms = Vm.find_all_by_mac_address_and_hostname_and_ipaddress(@current_server.mac_address, @current_server.hostname, @current_server.ipaddress)
190-
if vms.length > 1
191-
_log.warn("Found multiple Vms that may represent this MiqServer: #{vms.collect(&:id).sort.inspect}")
192-
elsif vms.length == 1
193-
@current_server.update(:vm_id => vms.first.id)
189+
vm_ids = find_vms_by_mac_address_and_hostname_and_ipaddress(@current_server.mac_address, @current_server.hostname, @current_server.ipaddress).pluck(:id)
190+
if vm_ids.length > 1
191+
_log.warn("Found multiple Vms that may represent this MiqServer: #{vm_ids.sort.inspect}")
192+
elsif vm_ids.length == 1
193+
@current_server.update(:vm_id => vm_ids.first)
194194
end
195195
end
196196
end
197197

198+
def find_vms_by_mac_address_and_hostname_and_ipaddress(mac_address, hostname, ipaddress)
199+
return Vm.none if mac_address.blank? && hostname.blank? && ipaddress.blank?
200+
201+
scope = Vm
202+
# NOTE: nics are guest devices with an extra where()
203+
scope = scope.joins(:hardware => :nics).where(:guest_devices => {:address => mac_address}) if mac_address
204+
scope = scope.joins(:hardware => :networks).where(:networks => {:hostname => hostname}) if hostname
205+
scope = scope.joins(:hardware => :networks).where(:networks => {:ipaddress => ipaddress}) if ipaddress
206+
207+
scope
208+
end
209+
198210
def reset_server_runtime_info
199211
@current_server.update(
200212
:drb_uri => nil,

spec/lib/workers/evm_server_spec.rb

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,130 @@
188188
end
189189
end
190190
end
191+
192+
let(:hostname) { "ABCDEFG" }
193+
let(:address) { "AB:CD:EF:GH" }
194+
let(:vm1_network) { FactoryBot.create(:network, :hostname => hostname) }
195+
let(:vm2_network) { FactoryBot.create(:network) }
196+
let(:vm3_device) { FactoryBot.create(:guest_device, :address => address, :device_type => "ethernet") }
197+
let(:vm1) { FactoryBot.create(:vm_vmware, :hardware => FactoryBot.create(:hardware, :networks => [vm1_network])) }
198+
let(:vm2) { FactoryBot.create(:vm_vmware, :hardware => FactoryBot.create(:hardware, :networks => [vm2_network])) }
199+
let(:vm3) { FactoryBot.create(:vm_vmware, :hardware => FactoryBot.create(:hardware, :guest_devices => [vm3_device])) }
200+
201+
describe "#set_local_vserver_vm (private)" do
202+
let!(:miq_server) { EvmSpecHelper.local_miq_server }
203+
let(:evm_server) { EvmServer.new }
204+
205+
# Basically stock, just ensure podified environment doesn't modify this test.
206+
before { allow(evm_server).to receive(:servers_from_db).and_return([miq_server]) }
207+
208+
it "handles no matching servers" do
209+
vm1
210+
vm2
211+
212+
# sets evm_server.current_server
213+
evm_server.send(:impersonate_server, miq_server)
214+
evm_server.send(:set_local_server_vm)
215+
expect(miq_server.reload.vm_id).to eq(nil)
216+
end
217+
218+
it "finds local server (by mac_address)" do
219+
vm1
220+
vm2
221+
miq_server.update(:hostname => vm1_network.hostname)
222+
223+
evm_server.send(:impersonate_server, miq_server)
224+
evm_server.send(:set_local_server_vm)
225+
expect(miq_server.reload.vm_id).to eq(vm1.id)
226+
end
227+
228+
it "finds multiple servers" do
229+
vm1
230+
vm2
231+
vm3
232+
233+
miq_server.update(:hostname => vm1_network.hostname, :ipaddress => vm2_network.ipaddress)
234+
235+
evm_server.send(:impersonate_server, miq_server)
236+
evm_server.send(:set_local_server_vm)
237+
expect(miq_server.reload.vm_id).to eq(nil)
238+
end
239+
end
240+
241+
context "#find_vms_by_mac_address_and_hostname_and_ipaddress (private)" do
242+
subject { described_class.new }
243+
244+
it "mac_address" do
245+
vm1
246+
vm2
247+
vm3
248+
subject
249+
250+
expect do
251+
expect(subject.send(:find_vms_by_mac_address_and_hostname_and_ipaddress, address, nil, nil)).to eq([vm3])
252+
end.to make_database_queries(:count => 1)
253+
end
254+
255+
it "hostname" do
256+
vm1
257+
vm2
258+
subject
259+
260+
expect do
261+
expect(subject.send(:find_vms_by_mac_address_and_hostname_and_ipaddress, nil, hostname, nil)).to eq([vm1])
262+
end.to make_database_queries(:count => 1)
263+
end
264+
265+
it "ipaddress" do
266+
vm1
267+
vm2
268+
subject
269+
270+
expect do
271+
expect(subject.send(:find_vms_by_mac_address_and_hostname_and_ipaddress, nil, nil, vm1_network.ipaddress)).to eq([vm1])
272+
end.to make_database_queries(:count => 1)
273+
end
274+
275+
it "hostname and ipaddress" do
276+
vm1
277+
vm2
278+
subject
279+
280+
expect do
281+
expect(subject.send(:find_vms_by_mac_address_and_hostname_and_ipaddress, nil, vm1_network.hostname, vm1_network.ipaddress)).to eq([vm1])
282+
end.to make_database_queries(:count => 1)
283+
end
284+
285+
it "hostname and different ipaddress" do
286+
vm1
287+
vm2
288+
subject
289+
290+
expect do
291+
expect(subject.send(:find_vms_by_mac_address_and_hostname_and_ipaddress, nil, vm1_network.hostname, vm2_network.ipaddress)).to be_empty
292+
end.to make_database_queries(:count => 1)
293+
end
294+
295+
# vm must match both mac address and a hostname from a single server
296+
# not sure if that was the original intent, but how the code currently works
297+
it "mac address and different hostname" do
298+
vm1
299+
vm3
300+
subject
301+
302+
expect do
303+
expect(subject.send(:find_vms_by_mac_address_and_hostname_and_ipaddress, address, vm1_network.hostname, nil)).to be_empty
304+
end.to make_database_queries(:count => 1)
305+
end
306+
307+
it "returns an empty list when all are blank" do
308+
vm1
309+
subject
310+
311+
expect do
312+
expect(subject.send(:find_vms_by_mac_address_and_hostname_and_ipaddress, nil, nil, nil)).to eq([])
313+
expect(subject.send(:find_vms_by_mac_address_and_hostname_and_ipaddress, '', '', '')).to eq([])
314+
end.not_to make_database_queries
315+
end
316+
end
191317
end

spec/models/vm_spec.rb

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -48,48 +48,6 @@
4848
expect { vm.validate_native_console_support }.to raise_error MiqException::RemoteConsoleNotSupportedError
4949
end
5050

51-
context ".find_all_by_mac_address_and_hostname_and_ipaddress" do
52-
before do
53-
@hardware1 = FactoryBot.create(:hardware)
54-
@vm1 = FactoryBot.create(:vm_vmware, :hardware => @hardware1)
55-
56-
@hardware2 = FactoryBot.create(:hardware)
57-
@vm2 = FactoryBot.create(:vm_vmware, :hardware => @hardware2)
58-
end
59-
60-
it "mac_address" do
61-
address = "ABCDEFG"
62-
guest_device = FactoryBot.create(:guest_device, :address => address, :device_type => "ethernet")
63-
@hardware1.guest_devices << guest_device
64-
65-
expect(described_class.find_all_by_mac_address_and_hostname_and_ipaddress(address, nil, nil))
66-
.to eql([@vm1])
67-
end
68-
69-
it "hostname" do
70-
hostname = "ABCDEFG"
71-
network = FactoryBot.create(:network, :hostname => hostname)
72-
@hardware1.networks << network
73-
74-
expect(described_class.find_all_by_mac_address_and_hostname_and_ipaddress(nil, hostname, nil))
75-
.to eql([@vm1])
76-
end
77-
78-
it "ipaddress" do
79-
ipaddress = "127.0.0.1"
80-
network = FactoryBot.create(:network, :ipaddress => ipaddress)
81-
@hardware1.networks << network
82-
83-
expect(described_class.find_all_by_mac_address_and_hostname_and_ipaddress(nil, nil, ipaddress))
84-
.to eql([@vm1])
85-
end
86-
87-
it "returns an empty list when all are blank" do
88-
expect(described_class.find_all_by_mac_address_and_hostname_and_ipaddress(nil, nil, nil)).to eq([])
89-
expect(described_class.find_all_by_mac_address_and_hostname_and_ipaddress('', '', '')).to eq([])
90-
end
91-
end
92-
9351
context "with relationships of multiple types" do
9452
before do
9553
@rp = FactoryBot.create(:resource_pool, :name => "RP")

0 commit comments

Comments
 (0)