Revision a6f4f5f7
Added by Ohad Levy almost 13 years ago
- ID a6f4f5f7e750c345d4e6d83b65311fe74636d6a4
app/models/host.rb | ||
---|---|---|
has_many :host_parameters, :dependent => :destroy, :foreign_key => :reference_id
|
||
accepts_nested_attributes_for :host_parameters, :reject_if => lambda { |a| a[:value].blank? }, :allow_destroy => true
|
||
belongs_to :owner, :polymorphic => true
|
||
belongs_to :sp_subnet
|
||
|
||
include Hostext::Search
|
||
include HostCommon
|
app/models/orchestration.rb | ||
---|---|---|
def self.included(base)
|
||
base.send :include, InstanceMethods
|
||
base.class_eval do
|
||
attr_reader :queue, :old
|
||
attr_reader :queue, :old, :record_conflicts
|
||
# stores actions to be performed on our proxies based on priority
|
||
before_validation :set_queue
|
||
before_validation :setup_clone
|
||
... | ... | |
begin
|
||
task.status = execute({:action => task.action}) ? "completed" : "failed"
|
||
|
||
rescue Net::Conflict => e
|
||
task.status = "conflict"
|
||
@record_conflicts << e
|
||
failure e.message
|
||
rescue => e
|
||
task.status = "failed"
|
||
failed "failed #{e}"
|
||
failure "failed #{e}"
|
||
end
|
||
end
|
||
|
||
# if we have no failures - we are done
|
||
return true if q.failed.empty? and q.pending.empty? and errors.empty?
|
||
return true if q.failed.empty? and q.pending.empty? and q.conflict.empty? and errors.empty?
|
||
|
||
logger.debug "Rolling back due to a problem: #{q.failed}"
|
||
logger.debug "Rolling back due to a problem: #{q.failed + q.conflict}"
|
||
# handle errors
|
||
# we try to undo all completed operations and trigger a DB rollback
|
||
(q.completed + q.running).sort.reverse_each do |task|
|
||
... | ... | |
execute({:action => task.action, :rollback => true})
|
||
rescue => e
|
||
# if the operation failed, we can just report upon it
|
||
failed "Failed to perform rollback on #{task.name} - #{e}"
|
||
failure "Failed to perform rollback on #{task.name} - #{e}"
|
||
end
|
||
end
|
||
|
||
... | ... | |
if obj.respond_to?(met)
|
||
return obj.send(met)
|
||
else
|
||
failed "invalid method #{met}"
|
||
failure "invalid method #{met}"
|
||
raise "invalid method #{met}"
|
||
end
|
||
end
|
||
|
||
def set_queue
|
||
@queue = Orchestration::Queue.new
|
||
@record_conflicts = []
|
||
end
|
||
|
||
# we keep the before update host object in order to compare changes
|
app/models/orchestration/dhcp.rb | ||
---|---|---|
def self.included(base)
|
||
base.send :include, InstanceMethods
|
||
base.class_eval do
|
||
attr_reader :dhcp
|
||
after_validation :initialize_dhcp, :queue_dhcp
|
||
before_destroy :initialize_dhcp, :queue_dhcp_destroy
|
||
validate :ip_belongs_to_subnet?
|
||
after_validation :queue_dhcp
|
||
before_destroy :queue_dhcp_destroy
|
||
validate :ip_belongs_to_subnet?, :valid_jumpstart_model
|
||
end
|
||
end
|
||
|
||
... | ... | |
!subnet.nil? and !subnet.dhcp.nil? and !subnet.dhcp.url.empty?
|
||
end
|
||
|
||
protected
|
||
def sp_dhcp?
|
||
!sp_subnet.nil? and !sp_subnet.dhcp.nil? and !sp_subnet.dhcp.url.empty?
|
||
end
|
||
|
||
def initialize_dhcp sub = nil
|
||
def dhcp_record
|
||
return unless dhcp?
|
||
# there are usage cases where our object is saved across subnets
|
||
# i.e. management port is not on the same subnet
|
||
sub ||= subnet
|
||
@dhcp = ProxyAPI::DHCP.new(:url => sub.dhcp.url)
|
||
rescue => e
|
||
failure "Failed to initialize the DHCP proxy: #{e}"
|
||
end
|
||
|
||
# Retrieves the DHCP entry for this host via a lookup on the MAC
|
||
# Returns: Hash Example {
|
||
# "mac" :"22:33:44:55:66:11"
|
||
# "nextServer":"192.168.122.1"
|
||
# "title" :"some.host.name"
|
||
# "filename" :"pxelinux.0"
|
||
# "ip" :"192.168.122.4"}
|
||
def getDHCP
|
||
logger.info "Query a DHCP reservation for #{name}/#{ip}"
|
||
dhcp.record subnet.network, mac
|
||
rescue => e
|
||
failure "Failed to read the DHCP record: #{proxy_error e}"
|
||
@dhcp_record ||= Net::DhcpRecord.new dhcp_attrs
|
||
end
|
||
|
||
# Deletes the DHCP entry for this host
|
||
def delDHCP
|
||
logger.info "{#{User.current.login}}Delete the DHCP reservation for #{name}/#{ip}"
|
||
dhcp.delete subnet.network, mac
|
||
rescue => e
|
||
failure "Failed to delete the DHCP record: #{proxy_error e}"
|
||
def sp_dhcp_record
|
||
return unless sp_dhcp?
|
||
@sp_dhcp_record ||= Net::DhcpRecord.new sp_dhcp_attrs
|
||
end
|
||
|
||
def delSPDHCP
|
||
return true unless sp_valid?
|
||
initialize_dhcp(sp_subnet) unless subnet == sp_subnet
|
||
logger.info "{#{User.current.login}}Delete a DHCP reservation for #{sp_name}/#{sp_ip}"
|
||
dhcp.delete subnet.network, sp_mac
|
||
rescue => e
|
||
failure "Failed to delete the Service Processor DHCP record: #{proxy_error e}"
|
||
protected
|
||
|
||
def set_dhcp
|
||
dhcp_record.create
|
||
end
|
||
|
||
# Updates the DHCP scope to add a reservation for this host
|
||
# +returns+ : Boolean true on success
|
||
def setDHCP
|
||
logger.info "{#{User.current.login}}Add a DHCP reservation for #{name}/#{ip}"
|
||
dhcp_attr = {:name => name, :filename => operatingsystem.boot_filename(self),
|
||
:ip => ip, :mac => mac, :hostname => name}
|
||
def set_sp_dhcp
|
||
sp_dhcp_record.create
|
||
end
|
||
|
||
next_server = boot_server
|
||
dhcp_attr.merge!(:nextserver => next_server) if next_server
|
||
def del_dhcp
|
||
dhcp_record.destroy
|
||
end
|
||
|
||
if jumpstart?
|
||
raise "Host's operating system has an unknown vendor class" unless (vendor = model.vendor_class and !vendor.empty?)
|
||
def del_sp_dhcp
|
||
sp_dhcp_record.destroy
|
||
end
|
||
|
||
private
|
||
# returns a hash of dhcp record settings
|
||
def dhcp_attrs
|
||
return unless dhcp?
|
||
dhcp_attr = { :name => name, :filename => operatingsystem.boot_filename(self),
|
||
:ip => ip, :mac => mac, :hostname => name, :proxy => proxy_for_host,
|
||
:network => subnet.network, :nextServer => boot_server }
|
||
|
||
jumpstart_arguments = os.jumpstart_params self, vendor
|
||
if jumpstart?
|
||
jumpstart_arguments = os.jumpstart_params self, model.vendor_class
|
||
dhcp_attr.merge! jumpstart_arguments unless jumpstart_arguments.empty?
|
||
end
|
||
|
||
dhcp.set subnet.network, dhcp_attr
|
||
rescue => e
|
||
failure "Failed to set the DHCP record: #{proxy_error e}"
|
||
dhcp_attr
|
||
end
|
||
|
||
def setSPDHCP
|
||
return true unless sp_valid?
|
||
initialize_dhcp(sp_subnet) unless subnet == sp_subnet
|
||
logger.info "{#{User.current.login}}Add a DHCP reservation for #{sp_name}/#{sp_ip}"
|
||
dhcp.set sp_subnet.network, sp_mac, :name => sp_name, :ip => sp_ip
|
||
rescue => e
|
||
failure "Failed to set the Service Processor DHCP record: #{proxy_error e}"
|
||
# returns a hash of service processor / ilo dhcp record settings
|
||
def sp_dhcp_attrs
|
||
return unless sp_dhcp?
|
||
{ :name => sp_name, :ip => sp_ip, :mac => sp_mac, :proxy => proxy_for_sp, :network => sp_subnet.network }
|
||
end
|
||
|
||
private
|
||
|
||
# where are we booting from
|
||
def boot_server
|
||
|
||
# if we don't manage tftp at all, we dont create a next-server entry.
|
||
return nil if tftp.nil?
|
||
|
||
begin
|
||
bs = tftp.bootServer
|
||
rescue RestClient::ResourceNotFound
|
||
nil
|
||
end
|
||
bs = tftp.bootServer
|
||
if bs.blank?
|
||
# trying to guess out tftp next server based on the smart proxy hostname
|
||
bs = URI.parse(subnet.tftp.url).host if subnet and subnet.tftp and subnet.tftp.url
|
||
bs = URI.parse(subnet.tftp.url).host if respond_to?(:tftp?) and tftp?
|
||
end
|
||
return bs unless bs.blank?
|
||
failure "Unable to determine the host's boot server. The DHCP smart proxy failed to provide this information and this subnet is not provided with TFTP services."
|
||
... | ... | |
end
|
||
|
||
def queue_dhcp_create
|
||
queue.create(:name => "DHCP Settings for #{self}", :priority => 10,
|
||
:action => [self, :setDHCP])
|
||
queue.create(:name => "DHCP Settings for #{sp_name}", :priority => 15,
|
||
:action => [self, :setSPDHCP]) if sp_valid?
|
||
queue.create(:name => "DHCP Settings for #{self}", :priority => 10,
|
||
:action => [self, :set_dhcp])
|
||
queue.create(:name => "DHCP Settings for #{sp_name}", :priority => 15,
|
||
:action => [self, :set_sp_dhcp]) if sp_dhcp?
|
||
end
|
||
|
||
def queue_dhcp_update
|
||
update = false
|
||
# IP Address / name changed
|
||
if (old.ip != ip) or (old.name != name) or (old.mac != mac)
|
||
update = true
|
||
if old.dhcp?
|
||
old.initialize_dhcp
|
||
queue.create(:name => "DHCP Settings for #{old}", :priority => 5,
|
||
:action => [old, :delDHCP])
|
||
end
|
||
end
|
||
if old.sp_valid? and ((old.sp_name != sp_name) or (old.sp_mac != sp_mac) or (old.sp_ip != sp_ip))
|
||
update = true
|
||
if old.sp_subnet and old.sp_subnet.dhcp and old.sp_subnet.dhcp.url
|
||
queue.create(:name => "DHCP Settings for #{old.sp_name}", :priority => 5,
|
||
:action => [old, :delSPDHCP])
|
||
end
|
||
end
|
||
queue.create(:name => "DHCP Settings for #{old}", :priority => 5,
|
||
:action => [old, :del_dhcp]) if old.dhcp? and dhcp_update_required?
|
||
queue.create(:name => "DHCP Settings for #{old.sp_name}", :priority => 5,
|
||
:action => [old, :del_sp_dhcp]) if old.sp_dhcp? and sp_dhcp_update_required?
|
||
queue_dhcp_create if dhcp_update_required?
|
||
end
|
||
|
||
# do we need to update our dhcp reservations
|
||
def dhcp_update_required?
|
||
# IP Address / name changed
|
||
return true if (old.ip != ip) or (old.name != name) or (old.mac != mac)
|
||
# Handle jumpstart
|
||
if jumpstart?
|
||
if !old.build? or (old.medium != medium or old.arch != arch) or
|
||
(os and old.os and (old.os.name != os.name or old.os != os))
|
||
update = true
|
||
old.initialize_dhcp if old.dhcp.nil? and old.dhcp?
|
||
queue.create(:name => "DHCP Settings for #{old}", :priority => 5, :action => [old, :delDHCP])
|
||
(os and old.os and (old.os.name != os.name or old.os != os))
|
||
return true
|
||
end
|
||
end
|
||
queue_dhcp_create if update
|
||
false
|
||
end
|
||
|
||
def sp_dhcp_update_required?
|
||
return true if old.sp_valid? and ((old.sp_name != sp_name) or (old.sp_mac != sp_mac) or (old.sp_ip != sp_ip))
|
||
false
|
||
end
|
||
|
||
def queue_dhcp_destroy
|
||
return unless dhcp? and errors.empty?
|
||
queue.create(:name => "DHCP Settings for #{self}", :priority => 5,
|
||
:action => [self, :delDHCP])
|
||
queue.create(:name => "DHCP Settings for #{sp_name}", :priority => 5,
|
||
:action => [self, :delSPDHCP]) if sp_valid?
|
||
queue.create(:name => "DHCP Settings for #{self}", :priority => 5,
|
||
:action => [self, :del_dhcp])
|
||
queue.create(:name => "DHCP Settings for #{sp_name}", :priority => 5,
|
||
:action => [self, :del_sp_dhcp]) if sp_valid?
|
||
true
|
||
end
|
||
|
||
... | ... | |
errors.add :ip, "Does not match selected Subnet"
|
||
return false
|
||
end
|
||
rescue => e
|
||
rescue
|
||
# probably an invalid ip / subnet were entered
|
||
# we let other validations handle that
|
||
end
|
||
|
||
def valid_jumpstart_model
|
||
return unless jumpstart?
|
||
errors.add :model, "Has an unknown vendor class" if model.vendor_class.empty?
|
||
false
|
||
end
|
||
|
||
def proxy_for_host
|
||
ProxyAPI::DHCP.new(:url => subnet.dhcp.url) if dhcp?
|
||
end
|
||
|
||
def proxy_for_sp
|
||
ProxyAPI::DHCP.new(:url => sp_subnet.dhcp.url) if sp_dhcp?
|
||
end
|
||
end
|
||
end
|
lib/net.rb | ||
---|---|---|
module Net
|
||
autoload :DhcpRecord, "net/dhcp_record.rb"
|
||
|
||
class Record
|
||
include Net::Validations
|
||
attr_accessor :hostname, :proxy, :logger
|
||
|
||
def initialize opts = {}
|
||
# set all attributes
|
||
opts.each do |k,v|
|
||
eval("self.#{k}= v") if self.respond_to?("#{k}=")
|
||
end if opts
|
||
self.logger ||= Rails.logger
|
||
raise "Must define a hostname" if hostname.blank?
|
||
raise "Must define a proxy" if proxy.nil?
|
||
end
|
||
|
||
def inspect
|
||
to_s
|
||
end
|
||
|
||
# Do we have conflicting entries?
|
||
def conflicting?
|
||
!conflicts.empty?
|
||
end
|
||
|
||
# clears internal cache
|
||
def reload!
|
||
@conflicts = nil
|
||
end
|
||
|
||
# Compares two records by their attributes
|
||
def == other
|
||
return false unless other.respond_to? :attrs
|
||
self.attrs == other.attrs
|
||
end
|
||
|
||
end
|
||
|
||
class Error < RuntimeError; end
|
||
|
||
class Conflict < Exception
|
||
attr_accessor :type, :expected, :actual, :message
|
||
end
|
||
end
|
lib/net/dhcp_record.rb | ||
---|---|---|
module Net
|
||
class DhcpRecord < Record
|
||
attr_accessor :ip, :mac, :network, :nextServer, :filename
|
||
|
||
def initialize opts = { }
|
||
super(opts)
|
||
self.mac = validate_mac self.mac
|
||
self.network = validate_network self.network
|
||
self.ip = validate_ip self.ip
|
||
end
|
||
|
||
def to_s
|
||
"#{hostname}-#{mac}/#{ip}"
|
||
end
|
||
|
||
# Deletes the DHCP entry
|
||
def destroy
|
||
logger.debug "Delete DHCP reservation for #{to_s}"
|
||
# it is save to call destroy even if the entry does not exists, so we don't bother with validating anything here.
|
||
proxy.delete network, mac
|
||
end
|
||
|
||
# Create a DHCP entry
|
||
def create
|
||
logger.debug "Create DHCP reservation for #{to_s}"
|
||
begin
|
||
proxy.set network, attrs
|
||
rescue RestClient::Conflict
|
||
logger.warn "Conflicting DHCP reservation for #{to_s} detected"
|
||
e = Net::Conflict.new
|
||
e.type = "dhcp"
|
||
e.expected = to_s
|
||
e.actual = conflicts
|
||
e.message = "DHCP conflict detected - expected #{to_s}, found #{conflicts.map(&:to_s).join(', ')}"
|
||
raise e
|
||
end
|
||
end
|
||
|
||
# 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
|
||
end
|
||
|
||
# Verifies that are record already exists on the dhcp server
|
||
def valid?
|
||
logger.debug "Fetching DHCP reservation for #{to_s}"
|
||
self == proxy.record(network, mac)
|
||
end
|
||
|
||
def attrs
|
||
{ :hostname => hostname, :mac => mac, :ip => ip, :network => network,
|
||
:nextServer => nextServer, :filename => filename
|
||
}.delete_if { |k, v| v.nil? }
|
||
end
|
||
end
|
||
end
|
lib/net/validations.rb | ||
---|---|---|
module Net
|
||
module Validations
|
||
|
||
class Error < RuntimeError; end
|
||
|
||
# validates the ip address
|
||
def validate_ip ip
|
||
raise Error, "Invalid IP Address #{ip}" unless (ip =~ /(\d{1,3}\.){3}\d{1,3}/)
|
||
ip
|
||
end
|
||
|
||
# validates the mac
|
||
def validate_mac mac
|
||
raise Error, "Invalid MAC #{mac}" unless (mac =~ /([a-f0-9]{1,2}:){5}[a-f0-9]{1,2}/i)
|
||
mac
|
||
end
|
||
|
||
def validate_network network
|
||
begin
|
||
validate_ip(network)
|
||
rescue Error
|
||
raise Error, "Invalid Network #{network}"
|
||
end
|
||
network
|
||
end
|
||
|
||
end
|
||
end
|
lib/orchestration/queue.rb | ||
---|---|---|
class Queue
|
||
|
||
attr_reader :items
|
||
STATUS = %w[ pending running failed completed rollbacked ]
|
||
STATUS = %w[ pending running failed completed rollbacked conflict ]
|
||
|
||
def initialize
|
||
@items = []
|
lib/proxy_api.rb | ||
---|---|---|
require "rest_client"
|
||
require "json"
|
||
require "uri"
|
||
require 'net'
|
||
|
||
module ProxyAPI
|
||
|
||
... | ... | |
# [+mac+] : String in coloned sextuplet format
|
||
# Returns : Hash or false
|
||
def record subnet, mac
|
||
parse get("#{subnet}/#{mac}")
|
||
response = parse(get("#{subnet}/#{mac}"))
|
||
Net::DhcpRecord.new response.merge(:network => subnet, :proxy => self)
|
||
rescue RestClient::ResourceNotFound
|
||
false
|
||
end
|
||
... | ... | |
return response["serverName"]
|
||
end
|
||
false
|
||
rescue RestClient::ResourceNotFound
|
||
nil
|
||
end
|
||
|
||
# Create a default pxe menu
|
lib/tasks/test_lib_dir.rake | ||
---|---|---|
namespace :test do
|
||
|
||
desc "Test lib source"
|
||
Rake::TestTask.new(:lib) do |t|
|
||
t.libs << "test"
|
||
t.pattern = 'test/lib/**/*_test.rb'
|
||
t.verbose = true
|
||
end
|
||
|
||
end
|
test/functional/hosts_controller_test.rb | ||
---|---|---|
private
|
||
def initialize_host
|
||
User.current = users(:admin)
|
||
disable_orchestration
|
||
@host = Host.create :name => "myfullhost",
|
||
:mac => "aabbecddeeff",
|
||
:ip => "2.3.4.99",
|
test/lib/net/dhcp_test.rb | ||
---|---|---|
require 'test_helper'
|
||
require 'net'
|
||
|
||
class DhcpTest < ActiveSupport::TestCase
|
||
|
||
test "dhcp record should not be created without a mac" do
|
||
assert_raise Net::Validations::Error do
|
||
Net::DhcpRecord.new :name => "test", "proxy" => smart_proxies(:one)
|
||
end
|
||
end
|
||
|
||
test "dhcp record should not be created without a network" do
|
||
assert_raise Net::Validations::Error do
|
||
Net::DhcpRecord.new :name => "test", :mac => "aa:bb:cc:dd:ee:ff", "proxy" => smart_proxies(:one)
|
||
end
|
||
end
|
||
|
||
test "dhcp record should not be created without an ip" do
|
||
assert_raise Net::Validations::Error do
|
||
Net::DhcpRecord.new :name => "test", :mac => "aa:bb:cc:dd:ee:ff", :network => "127.0.0.0", "proxy" => smart_proxies(:one)
|
||
end
|
||
end
|
||
|
||
test "record should have dhcp attributes" do
|
||
record = Net::DhcpRecord.new(:name => "test", :mac => "aa:bb:cc:dd:ee:ff",
|
||
:network => "127.0.0.0", :ip => "127.0.0.1", "proxy" => smart_proxies(:one))
|
||
assert_equal({:name => "test", :mac => "aa:bb:cc:dd:ee:ff",:network => "127.0.0.0", :ip => "127.0.0.1"}, record.send(:attrs))
|
||
|
||
end
|
||
|
||
test "record should be equal if their attrs are the same" do
|
||
record1 = Net::DhcpRecord.new(:name => "test", :mac => "aa:bb:cc:dd:ee:ff",
|
||
:network => "127.0.0.0", :ip => "127.0.0.1", "proxy" => smart_proxies(:one))
|
||
record2 = Net::DhcpRecord.new(:name => "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
|
||
|
||
end
|
test/lib/net/net_test.rb | ||
---|---|---|
require 'test_helper'
|
||
require 'net'
|
||
|
||
class NetTest < ActiveSupport::TestCase
|
||
|
||
test "Net record should auto assign attributes" do
|
||
record = Net::Record.new :name => "test", "proxy" => smart_proxies(:one)
|
||
assert_equal "test", record.name
|
||
end
|
||
|
||
test "should have a logger" do
|
||
record = Net::Record.new :name => "test", "proxy" => smart_proxies(:one)
|
||
assert_not_nil record.logger
|
||
end
|
||
|
||
test "should default logger to rails logger" do
|
||
record = Net::Record.new :name => "test", "proxy" => smart_proxies(:one)
|
||
assert_equal logger, record.logger
|
||
end
|
||
end
|
||
|
test/lib/net/validations_test.rb | ||
---|---|---|
require 'test_helper'
|
||
require 'net'
|
||
|
||
class ValidationsTest < ActiveSupport::TestCase
|
||
include Net::Validations
|
||
|
||
test "mac address should be valid" do
|
||
assert_nothing_raised Net::Validations::Error do
|
||
validate_mac "aa:bb:cc:dd:ee:ff"
|
||
end
|
||
end
|
||
|
||
test "mac should be invalid" do
|
||
assert_raise Net::Validations::Error do
|
||
validate_mac "abc123asdas"
|
||
end
|
||
end
|
||
|
||
end
|
test/test_helper.rb | ||
---|---|---|
def unattended?
|
||
SETTINGS[:unattended].nil? or SETTINGS[:unattended]
|
||
end
|
||
|
||
def self.disable_orchestration
|
||
#This disables the DNS/DHCP orchestration
|
||
Host.any_instance.stubs(:boot_server).returns("boot_server")
|
||
end
|
||
|
||
def disable_orchestration
|
||
ActiveSupport::TestCase.disable_orchestration
|
||
end
|
||
end
|
test/unit/domain_test.rb | ||
---|---|---|
end
|
||
|
||
test "should not destroy if it contains hosts" do
|
||
disable_orchestration
|
||
host = create_a_host
|
||
host.valid?
|
||
puts host.errors.full_messages unless host.errors.empty?
|
||
assert host.save
|
||
|
||
domain = host.domain
|
test/unit/host_test.rb | ||
---|---|---|
|
||
class HostTest < ActiveSupport::TestCase
|
||
setup do
|
||
disable_orchestration
|
||
User.current = User.find_by_login "admin"
|
||
end
|
||
|
||
... | ... | |
:operatingsystem => operatingsystems(:redhat), :subnet => subnets(:one),
|
||
:architecture => architectures(:x86_64), :environment => environments(:production), :disk => "aaa"
|
||
assert host.save
|
||
|
||
assert_equal domain, host.domain
|
||
end
|
||
|
test/unit/orchestration/dhcp_test.rb | ||
---|---|---|
require 'test_helper'
|
||
|
||
class DhcpOrchestrationTest < ActiveSupport::TestCase
|
||
def setup
|
||
disable_orchestration
|
||
end
|
||
|
||
def test_host_should_have_dhcp
|
||
if unattended?
|
||
h = hosts(:one)
|
||
assert h.valid?
|
||
assert h.dhcp != nil
|
||
assert h.dhcp?
|
||
assert_instance_of Net::DhcpRecord, h.dhcp_record
|
||
end
|
||
end
|
||
|
||
... | ... | |
if unattended?
|
||
h = hosts(:minimal)
|
||
assert h.valid?
|
||
assert_equal h.dhcp, nil
|
||
assert_equal h.dhcp?, false
|
||
assert_equal false, h.dhcp?
|
||
end
|
||
end
|
||
|
Also available in: Unified diff
fixes #1120 - Replaced DHCP functionaitlity by the new net dhcp record classes