Project

General

Profile

« Previous | Next » 

Revision 90ff2a3a

Added by Dmitri Dolguikh about 10 years ago

fixes #4381: dns records are being update after changes to host when dhcp is also present

View differences:

app/helpers/hosts_helper.rb
false
end
def has_dhcp_lease_errors? errors
errors.include?(:dhcp_lease_error)
end
def args_for_compute_resource_partial(host)
{ :arch => host.try(:architecture_id) || (params[:host] && params[:host][:architecture_id]),
:os => host.try(:operatingsystem_id) || (params[:host] && params[:host][:operatingsystem_id])
app/models/concerns/orchestration/dhcp.rb
extend ActiveSupport::Concern
included do
after_validation :queue_dhcp
after_validation :dhcp_conflict_detected?, :queue_dhcp
before_destroy :queue_dhcp_destroy
validate :ip_belongs_to_subnet?
end
......
def queue_dhcp
return unless (dhcp? or (old and old.dhcp?)) and orchestration_errors?
queue_remove_dhcp_conflicts if dhcp_conflict_detected?
queue_remove_dhcp_conflicts
new_record? ? queue_dhcp_create : queue_dhcp_update
end
......
end
def queue_remove_dhcp_conflicts
return unless dhcp? and errors.any? and errors.are_all_conflicts?
return unless overwrite?
return unless (dhcp? and overwrite?)
logger.debug "Scheduling DHCP conflicts removal"
queue.create(:name => _("DHCP conflicts removal for %s") % self, :priority => 5,
:action => [self, :del_dhcp_conflicts]) if dhcp_record and dhcp_record.conflicting?
......
def dhcp_conflict_detected?
# we can't do any dhcp based validations when our MAC address is defined afterwards (e.g. in vm creation)
return false if mac.blank? or name.blank?
# This is an expensive operation and we will only do it if the DNS validation failed. This will ensure
# that we report on both DNS and DHCP conflicts when we offer to remove collisions. It retrieves and
# caches the conflicting records so we must always do it when overwriting
return false unless (errors.any? and errors.are_all_conflicts?) or overwrite?
return false unless dhcp?
status = true
status = failure(_("DHCP records %s already exists") % dhcp_record.conflicts.to_sentence, nil, :conflict) if dhcp_record and dhcp_record.conflicting?
overwrite? ? errors.are_all_conflicts? : status
if dhcp_record and dhcp_record.conflicting? and (not overwrite?)
failure(_("DHCP records %s already exists") % dhcp_record.conflicts.to_sentence, nil, :conflict)
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
app/models/concerns/orchestration/dns.rb
status = true
status = failure(_("DNS A Records %s already exists") % dns_a_record.conflicts.to_sentence, nil, :conflict) if dns? and dns_a_record and dns_a_record.conflicting?
status &= failure(_("DNS PTR Records %s already exists") % dns_ptr_record.conflicts.to_sentence, nil, :conflict) if reverse_dns? and dns_ptr_record and dns_ptr_record.conflicting?
status
status = failure(_("DNS PTR Records %s already exists") % dns_ptr_record.conflicts.to_sentence, nil, :conflict) if reverse_dns? and dns_ptr_record and dns_ptr_record.conflicting?
not status #failure method returns 'false'
end
end
app/models/host/managed.rb
# handles all orchestration of smart proxies.
include Foreman::Renderer
include Orchestration
# Please note that the order of inclusion of DHCP and DNS orchestration modules is important,
# as DHCP validation code relies on DNS code being run first (but it's being run in the opposite order atm)
include Orchestration::DHCP
include Orchestration::DNS
include Orchestration::Compute
app/views/hosts/_dhcp_lease_errors.html.erb
<div id="host-conflicts-modal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title"><%= _('DHCP lease conflicts have been detected') %></h4>
</div>
<div class="modal-body">
<p><%= _('Please correct the error(s) below and submit your changes again.') %></p>
<div class="alert alert-warning alert-block base">
<% @host.errors.get(:dhcp_lease_error).each do |e| %>
<li><%= e %></li>
<% end %>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><%= _('ACK') %></button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
app/views/hosts/_form.html.erb
<%= javascript 'host_edit', 'compute_resource', 'lookup_keys'%>
<%= render "hosts/conflicts" if has_conflicts?(@host.errors) %>
<%= render "hosts/dhcp_lease_errors" if has_dhcp_lease_errors?(@host.errors) %>
<%= render "hosts/conflicts" if (!has_dhcp_lease_errors?(@host.errors) && has_conflicts?(@host.errors)) %>
<%= render "hosts/progress" %>
<% Taxonomy.as_taxonomy @organization , @location do %>
......
</div>
<%= f.hidden_field :overwrite? %>
<%= submit_or_cancel f, @host.overwrite?, :cancel_path => @host %>
<%= submit_or_cancel f, @host.overwrite?, :cancel_path => @host.new_record? || !@host.name_changed? ? @host : edit_host_path(@host.name_was) %>
<% end %>
<% end %>
lib/net/dhcp/record.rb
# Returns an array of record objects which are conflicting with our own
def conflicts
@conflicts ||= [proxy.record(network, mac), proxy.record(network, ip)].delete_if { |c| c == self }.compact
conflicts = [proxy.record(network, mac), proxy.record(network, ip)].delete_if { |c| c == self }.compact
@conflicts ||= conflicts.uniq {|c| c.attrs}
end
# Verifies that are record already exists on the dhcp server
......
self == proxy.record(network, mac)
end
def == other
attrs.values_at(:hostname, :mac, :ip, :network) == other.attrs.values_at(:hostname, :mac, :ip, :network)
end
def attrs
{ :hostname => hostname, :mac => mac, :ip => ip, :network => network,
:nextServer => nextServer, :filename => filename

Also available in: Unified diff