Project

General

Profile

Download (2.71 KB) Statistics
| Branch: | Tag: | Revision:
06823dc7 Ohad Levy
require 'ipaddr'
96b38b3c Ohad Levy
class Subnet < ActiveRecord::Base
9fd7478e Paul Kelly
include Authorization
06823dc7 Ohad Levy
has_many :hosts
# sps = Service processors / ilom boards etc
has_many :sps, :class_name => "Host", :foreign_key => 'sp_subnet_id'
belongs_to :dhcp, :class_name => "SmartProxy"
belongs_to :tftp, :class_name => "SmartProxy"
96b38b3c Ohad Levy
belongs_to :domain
06823dc7 Ohad Levy
validates_presence_of :network, :mask, :domain_id, :name
validates_uniqueness_of :network
ec777026 Ohad Levy
validates_format_of :network, :with => Net::Validations::IP_REGEXP
validates_format_of :mask, :with => Net::Validations::IP_REGEXP
06823dc7 Ohad Levy
validates_uniqueness_of :name, :scope => :domain_id
default_scope :order => 'priority'
96b38b3c Ohad Levy
06823dc7 Ohad Levy
before_destroy Ensure_not_used_by.new(:hosts, :sps)
96b38b3c Ohad Levy
8104eced Ohad Levy
scoped_search :on => [:name, :network, :mask], :complete_value => true
scoped_search :in => :domain, :on => :name, :rename => :domain, :complete_value => true

06823dc7 Ohad Levy
# Subnets are displayed in the form of their network network/network mask
96b38b3c Ohad Levy
def to_label
06823dc7 Ohad Levy
"#{network}/#{cidr}"
96b38b3c Ohad Levy
end

06823dc7 Ohad Levy
# Subnets are sorted on their priority value
# [+other+] : Subnet object with which to compare ourself
# +returns+ : Subnet object with higher precedence
def <=> (other)
self.priority <=> other.priority
96b38b3c Ohad Levy
end
06823dc7 Ohad Levy
96b38b3c Ohad Levy
# Given an IP returns the subnet that contains that IP
# [+ip+] : "doted quad" string
06823dc7 Ohad Levy
# Returns : Subnet object or nil if not found
def self.subnet_for(ip)
Subnet.all.each {|s| return s if s.contains? IPAddr.new(ip)}
96b38b3c Ohad Levy
nil
end

06823dc7 Ohad Levy
# Indicates whether the IP is within this subnet
# [+ip+] String: Contains 4 dotted decimal values
# Returns Boolean: True if if ip is in this subnet
def contains? ip
IPAddr.new("#{network}/#{mask}", Socket::AF_INET).include? IPAddr.new(ip, Socket::AF_INET)
end

def cidr
IPAddr.new(mask).to_i.to_s(2).count("1")
end

b1116c90 Ohad Levy
def dhcp?
6285a614 Ohad Levy
!!(dhcp and dhcp.url and !dhcp.url.blank?)
b1116c90 Ohad Levy
end

6285a614 Ohad Levy
def dhcp_proxy attrs = {}
@dhcp_proxy ||= ProxyAPI::DHCP.new({:url => dhcp.url}.merge(attrs)) if dhcp?
end

def tftp?
!!(tftp and tftp.url and !tftp.url.blank?)
end

def tftp_proxy attrs = {}
@tftp_proxy ||= ProxyAPI::TFTP.new({:url => tftp.url}.merge(attrs)) if tftp?
06823dc7 Ohad Levy
end

def unused_ip
b1116c90 Ohad Levy
return unless dhcp?
dhcp_proxy.unused_ip(network)["ip"]
06823dc7 Ohad Levy
rescue => e
455f5d2b Paul Kelly
logger.warn "Failed to fetch a free IP from our proxy: #{e}"
06823dc7 Ohad Levy
nil
96b38b3c Ohad Levy
end
10139fde José Luis Escalante
4c091cd8 Ohad Levy
# imports subnets from a dhcp smart proxy
def self.import proxy
return unless proxy.features.include?(Feature.find_by_name("DHCP"))
ProxyAPI::DHCP.new(:url => proxy.url).subnets.map do |s|
# do not import existing networks.
attrs = { :network => s["network"], :mask => s["netmask"] }
next if first(:conditions => attrs)
new(attrs.update(:dhcp => proxy))
end.compact
end

06823dc7 Ohad Levy
end