Project

General

Profile

« Previous | Next » 

Revision 14646e77

Added by Greg Sutcliffe about 10 years ago

Fixes #5637 - Don't raise lease conflicts when reading ad-hoc DHCP leases

View differences:

app/models/concerns/orchestration.rb
task.status = "conflict"
record_conflicts << e
failure e.message, nil, :conflict
#TODO: This is not a real error, but at the moment the proxy / foreman lacks better handling
# of the error instead of explode.
rescue Net::LeaseConflict => e
task.status = "failed"
failure _("DHCP has a lease at %s") % e, e.backtrace
rescue => e
task.status = "failed"
failure _("%{task} task failed with the following error: %{e}") % { :task => task.name, :e => e }, e.backtrace
app/models/concerns/orchestration/dhcp.rb
return true
end
false
rescue Net::LeaseConflict => e
failure(_("DHCP record %s conflicts with an existing reservation") % dhcp_record, nil, :dhcp_lease_error)
true
end
end
lib/net.rb
eval("self.#{k}= v") if self.respond_to?("#{k}=")
end if opts
raise Net::LeaseConflict.new("#{self.mac}/#{self.ip}") if opts['state']
self.logger ||= Rails.logger
raise "Must define a hostname" if hostname.blank?
raise "Must define a proxy" if proxy.nil?
raise "Must define a proxy" if proxy.nil?
end
def inspect
......
attr_accessor :type, :expected, :actual, :message
end
class LeaseConflict < RuntimeError; end
end
lib/net/dhcp/record.rb
def create
logger.info "Create DHCP reservation for #{to_s}"
begin
raise "Must define a hostname" if hostname.blank?
proxy.set network, attrs
rescue RestClient::Conflict
logger.warn "Conflicting DHCP reservation for #{to_s} detected"
......
end
def == other
attrs.values_at(:hostname, :mac, :ip, :network) == other.attrs.values_at(:hostname, :mac, :ip, :network)
if attrs[:hostname].blank?
# If we're converting an 'ad-hoc' lease created by a host booting outside of Foreman's knowledge,
# then :hostname will be blank on the incoming lease - if the ip/mac still match, then this
# isn't a conflict
attrs.values_at(:mac, :ip, :network) == other.attrs.values_at(:mac, :ip, :network)
else
# Otherwise, if a hostname is present, we want to check all 4 match before declaring a conflict
attrs.values_at(:hostname, :mac, :ip, :network) == other.attrs.values_at(:hostname, :mac, :ip, :network)
end
end
def attrs
lib/net/dns.rb
end
def create
raise "Must define a hostname" if hostname.blank?
logger.info "Add DNS #{type} record for #{to_s}"
end
lib/net/dns/ptr_record.rb
end
end
end
end
test/lib/net/dhcp_test.rb
assert_equal record1, record2
end
test "record should be equal if one record has no hostname" do
record1 = Net::DHCP::Record.new(:mac => "aa:bb:cc:dd:ee:ff",
:network => "127.0.0.0", :ip => "127.0.0.1", "proxy" => smart_proxies(:one))
record2 = Net::DHCP::Record.new(:hostname => "test", :mac => "aa:bb:cc:dd:ee:ff",
:network => "127.0.0.0", :ip => "127.0.0.1", "proxy" => smart_proxies(:one))
assert_equal record1, record2
end
test "record should not be equal if their attrs are not the same" do
record1 = Net::DHCP::Record.new(:hostname => "test1", :mac => "aa:bb:cc:dd:ee:ff",
:network => "127.0.0.0", :ip => "127.0.0.1", "proxy" => smart_proxies(:one))
record2 = Net::DHCP::Record.new(:hostname => "test2", :mac => "aa:bb:cc:dd:ee:ff",
:network => "127.0.0.0", :ip => "127.0.0.1", "proxy" => smart_proxies(:one))
refute_equal record1, record2
end
test "conflicts should be detected for mismatched records" do
proxy_lease = {"starts"=>"2014-05-09 11:55:21 UTC", "ends"=>"2014-05-09 12:05:21 UTC", "state"=>"active", "mac"=>"aa:bb:cc:dd:ee:ff", "subnet"=>"127.0.0.0/255.0.0.0", "ip"=>"127.0.0.1"}
ProxyAPI::Resource.any_instance.stubs(:get).returns("")
ProxyAPI::Resource.any_instance.stubs(:parse).returns(proxy_lease)
record1 = Net::DHCP::Record.new(:hostname => "test1", :mac => "aa:bb:cc:dd:ee:ff",
:network => "127.0.0.0", :ip => "127.0.0.2",
"proxy" => subnets(:one).dhcp_proxy)
assert record1.conflicts.present?
end
test "conflicts should be not detected for records with no hostname" do
proxy_lease = {"starts"=>"2014-05-09 11:55:21 UTC", "ends"=>"2014-05-09 12:05:21 UTC", "state"=>"active", "mac"=>"aa:bb:cc:dd:ee:ff", "subnet"=>"127.0.0.0/255.0.0.0", "ip"=>"127.0.0.1"}
ProxyAPI::Resource.any_instance.stubs(:get).returns("")
ProxyAPI::Resource.any_instance.stubs(:parse).returns(proxy_lease)
record1 = Net::DHCP::Record.new(:hostname => "test1", :mac => "aa:bb:cc:dd:ee:ff",
:network => "127.0.0.0", :ip => "127.0.0.1",
"proxy" => subnets(:one).dhcp_proxy)
assert record1.conflicts.empty?
end
end

Also available in: Unified diff