Revision 4bae5ced
Added by Stephen Benjamin over 10 years ago
app/models/host/base.rb | ||
---|---|---|
has_many :fact_values, :dependent => :destroy, :foreign_key => :host_id
|
||
has_many :fact_names, :through => :fact_values
|
||
|
||
alias_attribute :hostname, :name
|
||
validates :name, :presence => true, :uniqueness => true
|
||
validate :is_name_downcased?
|
||
alias_attribute :hostname, :name
|
||
before_validation :normalize_name
|
||
validates :name, :presence => true,
|
||
:uniqueness => true,
|
||
:format => {:with => Net::Validations::HOST_REGEXP}
|
||
validates_inclusion_of :owner_type,
|
||
:in => OWNER_TYPES,
|
||
:allow_blank => true,
|
||
... | ... | |
end
|
||
end
|
||
|
||
def is_name_downcased?
|
||
return unless name.present?
|
||
errors.add(:name, _("must be lowercase")) unless name == name.downcase
|
||
end
|
||
|
||
def facts_hash
|
||
hash = {}
|
||
fact_values.includes(:fact_name).collect do |fact|
|
||
... | ... | |
comparison_object.id == id
|
||
end
|
||
|
||
def normalize_name
|
||
self.name = Net::Validations.normalize_hostname(name) if self.name.present?
|
||
end
|
||
end
|
||
end
|
app/models/host/managed.rb | ||
---|---|---|
private
|
||
|
||
def lookup_value_match
|
||
normalize_hostname
|
||
"fqdn=#{fqdn}"
|
||
end
|
||
|
||
... | ... | |
# 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)}.first rescue nil
|
||
else
|
||
# if our host is in short name, append the domain name
|
||
# if we've just updated the domain name, strip off the old one
|
||
if !new_record? and changed_attributes['domain_id'].present?
|
||
old_domain = Domain.find(changed_attributes["domain_id"])
|
||
self.name.gsub(old_domain.to_s,"")
|
||
self.name.chomp!("." + old_domain.to_s)
|
||
end
|
||
# if our host is in short name, append the domain name
|
||
self.name += ".#{domain}" unless name =~ /\./i
|
||
end
|
||
# A managed host we should know the domain for; and the shortname shouldn't include a period
|
||
errors.add(:name, _("must not include periods")) if managed? and shortname.include? "."
|
||
end
|
||
|
||
def assign_hostgroup_attributes attrs = []
|
app/models/nic/managed.rb | ||
---|---|---|
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.
|
||
validates :name, :uniqueness => {:scope => :domain_id}, :allow_nil => true, :allow_blank => true
|
||
before_validation :normalize_name
|
||
|
||
validates :name, :uniqueness => {:scope => :domain_id},
|
||
:allow_nil => true,
|
||
:allow_blank => true,
|
||
:format => {:with => Net::Validations::HOST_REGEXP}
|
||
|
||
belongs_to :subnet
|
||
belongs_to :domain
|
||
... | ... | |
:network => network
|
||
}
|
||
end
|
||
|
||
def normalize_name
|
||
self.name = Net::Validations.normalize_hostname(name) if self.name.present?
|
||
end
|
||
|
||
end
|
||
end
|
lib/net/validations.rb | ||
---|---|---|
module Net
|
||
module Validations
|
||
|
||
IP_REGEXP = /^(\d{1,3}\.){3}\d{1,3}$/
|
||
MAC_REGEXP = /^([a-f0-9]{1,2}:){5}[a-f0-9]{1,2}$/i
|
||
IP_REGEXP = /\A((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\z/
|
||
MAC_REGEXP = /\A([a-f0-9]{1,2}:){5}[a-f0-9]{1,2}\z/i
|
||
HOST_REGEXP = /\A(([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\z/
|
||
|
||
class Error < RuntimeError;
|
||
end
|
||
|
||
... | ... | |
mac
|
||
end
|
||
|
||
# validates the hostname
|
||
def validate_hostname hostname
|
||
raise Error, "Invalid hostname #{hostname}" unless (hostname =~ HOST_REGEXP)
|
||
hostname
|
||
end
|
||
|
||
def validate_network network
|
||
begin
|
||
validate_ip(network)
|
||
... | ... | |
m.split("-").map { |nibble| "%02x" % ("0x" + nibble) }.join(":")
|
||
end
|
||
end
|
||
|
||
def self.normalize_hostname hostname
|
||
hostname.downcase! if hostname.present?
|
||
hostname
|
||
end
|
||
end
|
||
end
|
test/fixtures/hosts.yml | ||
---|---|---|
|
||
owned_by_restricted:
|
||
type: Host::Managed
|
||
name: owned_by_restricted.mydomain.net
|
||
name: owned-by-restricted.mydomain.net
|
||
ip: "2.3.4.155"
|
||
mac: deadbeeffeed
|
||
environment: production
|
test/lib/net/validations_test.rb | ||
---|---|---|
end
|
||
end
|
||
|
||
test "hostname should be valid" do
|
||
assert_nothing_raised Net::Validations::Error do
|
||
validate_hostname "this.is.an.example.com"
|
||
end
|
||
assert_nothing_raised Net::Validations::Error do
|
||
validate_hostname "this-is.an.example.com"
|
||
end
|
||
assert_nothing_raised Net::Validations::Error do
|
||
validate_hostname "localhost"
|
||
end
|
||
end
|
||
|
||
test "hostname should not be valid" do
|
||
assert_raise Net::Validations::Error do
|
||
validate_hostname "-this.is.a.bad.example.com"
|
||
end
|
||
assert_raise Net::Validations::Error do
|
||
validate_hostname "this_is_a_bad.example.com"
|
||
end
|
||
end
|
||
|
||
describe "hostname normalization" do
|
||
let(:hostname) { "this.is.an.example.com" }
|
||
|
||
test "should normalize incorrect case" do
|
||
Net::Validations.normalize_hostname("ThIs.Is.An.eXaMPlE.CoM").must_equal(hostname)
|
||
end
|
||
end
|
||
|
||
describe "mac normalization" do
|
||
|
||
let(:mac) { "aa:bb:cc:dd:ee:ff" }
|
test/unit/host_test.rb | ||
---|---|---|
|
||
test "should not save without a hostname" do
|
||
host = Host.new
|
||
assert !host.save
|
||
host.valid?
|
||
assert_equal "can't be blank", host.errors[:name].first
|
||
end
|
||
|
||
test "should not save with invalid hostname" do
|
||
host = Host.new :name => "invalid_hostname"
|
||
host.valid?
|
||
assert_equal "is invalid", host.errors[:name].first
|
||
end
|
||
|
||
test "should not save hostname with periods in shortname" do
|
||
host = Host.new :name => "my.host", :domain => Domain.find_or_create_by_name("mydomain.net"), :managed => true
|
||
host.valid?
|
||
assert_equal "must not include periods", host.errors[:name].first
|
||
end
|
||
|
||
test "should make hostname lowercase" do
|
||
host = Host.new :name => "MYHOST", :domain => Domain.find_or_create_by_name("mydomain.net")
|
||
host.valid?
|
||
assert_equal "myhost.mydomain.net", host.name
|
||
end
|
||
|
||
test "should update name when domain is changed" do
|
||
host = hosts(:one)
|
||
host.domain_name = "yourdomain.net"
|
||
host.save!
|
||
assert_equal "my5name.yourdomain.net", host.name
|
||
end
|
||
|
||
test "should fix mac address hyphens" do
|
||
... | ... | |
end
|
||
|
||
test "should not add domain name to hostname if it already include it" do
|
||
host = Host.create :name => "myhost.COMPANY.COM", :mac => "aabbccddeeff", :ip => "123.1.2.3",
|
||
host = Host.create :name => "myhost.company.com", :mac => "aabbccddeeff", :ip => "123.1.2.3",
|
||
:domain => Domain.find_or_create_by_name("company.com")
|
||
assert_equal "myhost.COMPANY.COM", host.name
|
||
assert_equal "myhost.company.com", host.name
|
||
end
|
||
|
||
test "should add hostname if it contains domain name" do
|
||
... | ... | |
assert_equal 'sinn1636.lan.cert', Host.find_by_name('sinn1636.lan').certname
|
||
end
|
||
|
||
test "host is created when uploading facts if setting is true" do
|
||
assert_difference 'Host.count' do
|
||
Setting[:create_new_host_when_facts_are_uploaded] = true
|
||
raw = parse_json_fixture('/facts_with_certname.json')
|
||
Host.importHostAndFacts(raw['name'], raw['facts'], raw['certname'])
|
||
assert Host.find_by_name('sinn1636.lan')
|
||
Setting[:create_new_host_when_facts_are_uploaded] =
|
||
Setting.find_by_name("create_new_host_when_facts_are_uploaded").default
|
||
end
|
||
end
|
||
|
||
test "host is not created when uploading facts if setting is false" do
|
||
Setting[:create_new_host_when_facts_are_uploaded] = false
|
||
assert_equal false, Setting[:create_new_host_when_facts_are_uploaded]
|
||
... | ... | |
assert_nil host
|
||
end
|
||
|
||
test "host is created when receiving a report if setting is true" do
|
||
assert_difference 'Host.count' do
|
||
Setting[:create_new_host_when_report_is_uploaded] = true
|
||
Report.import parse_json_fixture("/../fixtures/report-no-logs.json")
|
||
assert Host.find_by_name('builder.fm.example.net')
|
||
Setting[:create_new_host_when_report_is_uploaded] =
|
||
Setting.find_by_name("create_new_host_when_facts_are_uploaded").default
|
||
end
|
||
end
|
||
|
||
test "host is not created when receiving a report if setting is false" do
|
||
Setting[:create_new_host_when_report_is_uploaded] = false
|
||
assert_equal false, Setting[:create_new_host_when_report_is_uploaded]
|
||
... | ... | |
assert_equal ["#{pc} does not belong to the #{h.environment} environment"], h.errors[:puppetclasses]
|
||
end
|
||
|
||
test "name should be lowercase" do
|
||
h = hosts(:redhat)
|
||
assert h.valid?
|
||
h.name.upcase!
|
||
assert !h.valid?
|
||
end
|
||
|
||
test "should allow to save root pw" do
|
||
h = hosts(:redhat)
|
||
pw = h.root_pass
|
test/unit/nic_test.rb | ||
---|---|---|
|
||
test "type casting should return the correct class" do
|
||
i = ''
|
||
i = Nic::Base.create! :ip => "127.2.3.8", :mac => "babbccddeeff", :host => hosts(:one), :name => hosts(:one).name + "!", :type => "Nic::Interface"
|
||
i = Nic::Base.create! :ip => "127.2.3.8", :mac => "babbccddeeff", :host => hosts(:one), :name => hosts(:one).name, :type => "Nic::Interface"
|
||
assert_equal "Nic::Interface", i.type
|
||
end
|
||
|
||
... | ... | |
assert i.errors.keys.include?(:mac)
|
||
end
|
||
|
||
test "should fail on invalid dns name" do
|
||
i = Nic::Managed.new :mac => "dabbccddeeff", :host => hosts(:one), :name => "invalid_dns_name"
|
||
assert !i.valid?
|
||
assert i.errors.keys.include?(:name)
|
||
end
|
||
|
||
test "should fix mac address" do
|
||
interface = Nic::Base.create! :mac => "cabbccddeeff", :host => hosts(:one)
|
||
assert_equal "ca:bb:cc:dd:ee:ff", interface.mac
|
||
... | ... | |
assert_equal subnet.network, interface.network
|
||
assert_equal subnet.vlanid, interface.vlanid
|
||
end
|
||
end
|
||
end
|
test/unit/subnet_test.rb | ||
---|---|---|
# missing dot
|
||
s.network = "100101.102.103."
|
||
refute s.valid?
|
||
# greater than 255
|
||
s.network = "300.300.300.0"
|
||
refute s.valid?
|
||
# missing number
|
||
s.network = "100.101.102"
|
||
refute s.valid?
|
Also available in: Unified diff
fixes #3697, #3701 - more comprehensive field validations