|
module Nic
|
|
class Interface < Base
|
|
attr_accessible :ip
|
|
|
|
validates :ip, :uniqueness => true, :format => {:with => Net::Validations::IP_REGEXP}, :allow_blank => true
|
|
|
|
validate :normalize_ip
|
|
|
|
validates :attached_to, :presence => true, :if => Proc.new { |o| o.virtual && o.instance_of?(Nic::Managed) && !o.bridge? }
|
|
|
|
attr_accessible :name, :subnet_id, :subnet, :domain_id, :domain
|
|
|
|
# Don't have to set a hostname for each interface, but it must be unique if it is set.
|
|
before_validation :copy_hostname_from_host, :if => Proc.new { |nic| nic.primary? && nic.hostname.blank? }
|
|
before_validation :normalize_name
|
|
|
|
validates :name, :uniqueness => {:scope => :domain_id},
|
|
:allow_nil => true,
|
|
:allow_blank => true,
|
|
:format => {:with => Net::Validations::HOST_REGEXP}
|
|
|
|
# aliases and vlans require identifiers so we can differentiate and properly configure them
|
|
validates :identifier, :presence => true, :if => Proc.new { |o| o.virtual? && o.managed? && o.instance_of?(Nic::Managed) }
|
|
validate :identifier_change, :on => :update
|
|
|
|
validate :alias_subnet
|
|
|
|
delegate :network, :to => :subnet
|
|
|
|
def vlanid
|
|
self.tag.blank? ? self.subnet.vlanid : self.tag
|
|
end
|
|
|
|
def bridge?
|
|
!!bridge
|
|
end
|
|
|
|
def bridge
|
|
attrs[:bridge]
|
|
end
|
|
|
|
def alias?
|
|
self.virtual? && self.identifier.present? && self.identifier.include?(':')
|
|
end
|
|
|
|
def fqdn_changed?
|
|
name_changed? || domain_id_changed?
|
|
end
|
|
|
|
def fqdn_was
|
|
domain_was = Domain.find(domain_id_was) unless domain_id_was.blank?
|
|
return name_was if name_was.blank? || domain_was.blank?
|
|
name_was.include?('.') ? name_was : "#{name_was}.#{domain_was}"
|
|
end
|
|
|
|
protected
|
|
|
|
# we don't allow changes to identifier which would change the interface type e.g. eth0 -> eth0,1 would make
|
|
# a vlan virtual interface from physical one
|
|
def identifier_change
|
|
old_value = self.identifier_was || ''
|
|
new_value = self.identifier || ''
|
|
|
|
%w(. :).each do |forbidden|
|
|
if old_value.include?(forbidden) != new_value.include?(forbidden)
|
|
errors.add(:identifier, _("Can't add or remove `%s` from identifier") % forbidden)
|
|
end
|
|
end
|
|
end
|
|
|
|
def alias_subnet
|
|
if self.managed? && self.alias? && self.subnet && self.subnet.boot_mode != Subnet::BOOT_MODES[:static]
|
|
errors.add(:subnet_id, _('subnet boot mode is not %s' % _(Subnet::BOOT_MODES[:static])))
|
|
end
|
|
end
|
|
|
|
def normalize_ip
|
|
self.ip = Net::Validations.normalize_ip(ip)
|
|
end
|
|
|
|
# ensure that host name is fqdn
|
|
# if the user inputted short name, the domain name will be appended
|
|
# this is done to ensure compatibility with puppet storeconfigs
|
|
def normalize_name
|
|
# Remove whitespace
|
|
self.name.gsub!(/\s/,'') if self.name
|
|
# no hostname was given or a domain was selected, since this is before validation we need to ignore
|
|
# it and let the validations to produce an error
|
|
return if name.empty?
|
|
if domain.nil? && name.match(/\./) && !changed_attributes['domain_id'].present?
|
|
# try to assign the domain automatically based on our existing domains from the host FQDN
|
|
self.domain = Domain.all.select{|d| name.match(/#{d.name}\Z/)}.first rescue nil
|
|
elsif persisted? && changed_attributes['domain_id'].present?
|
|
# if we've just updated the domain name, strip off the old one
|
|
old_domain = Domain.find(changed_attributes["domain_id"])
|
|
# Remove the old domain, until fqdn will be set as the full name
|
|
self.name.chomp!("." + old_domain.to_s)
|
|
end
|
|
# name should be fqdn
|
|
self.name = fqdn
|
|
# A managed host we should know the domain for; and the shortname shouldn't include a period
|
|
# This only applies for unattended=true, as otherwise the name field includes the domain
|
|
errors.add(:name, _("must not include periods")) if ( host && host.managed? && managed? && shortname.include?(".") && SETTINGS[:unattended] )
|
|
self.name = Net::Validations.normalize_hostname(name) if self.name.present?
|
|
end
|
|
end
|
|
end
|
|
|
|
require_dependency 'nic/managed'
|