fuel-library/deployment/puppet/l23network/lib/puppet/provider/l3_ifconfig/lnx.rb

232 lines
6.7 KiB
Ruby

Puppet::Type.type(:l3_ifconfig).provide(:lnx) do
defaultfor :osfamily => :linux
commands :iproute => 'ip'
def self.prefetch(resources)
interfaces = instances
resources.keys.each do |name|
if provider = interfaces.find{ |ii| ii.name == name }
resources[name].provider = provider
end
end
end
def self.instances
insts = []
rou_list = self.get_if_defroutes_mappings()
# parse all system interfaces
self.get_if_addr_mappings().each_pair do |if_name, pro|
props = {
:ensure => :present,
:name => if_name,
:ipaddr => pro[:ipaddr],
}
if !rou_list[if_name].nil?
props.merge! rou_list[if_name]
else
props.merge!({
:gateway => :absent,
:gateway_metric => :absent
})
end
debug("PREFETCHED properties for '#{if_name}': #{props}")
insts << new(props)
end
return insts
end
def exists?
@property_hash[:ensure] == :present
end
def create
debug("CREATE resource: #{@resource}") # with hash: '#{m}'")
@old_property_hash = {}
@property_flush = {}.merge! @resource
#p @property_flush
#p @property_hash
#p @resource.inspect
end
def destroy
debug("DESTROY resource: #{@resource}")
# todo: Destroing of L3 resource -- is a removing any IP addresses.
# DO NOT!!! put intedafce to Down state.
iproute('--force', 'addr', 'flush', 'dev', @resource[:interface])
@property_hash.clear
end
def initialize(value={})
super(value)
@property_flush = {}
@old_property_hash = {}
@old_property_hash.merge! @property_hash
end
def flush
if @property_flush
debug("FLUSH properties: #{@property_flush}")
#
# FLUSH changed properties
if ! @property_flush[:ipaddr].nil?
if @property_flush[:ipaddr].include?(:absent)
# flush all ip addresses from interface
iproute('--force', 'addr', 'flush', 'dev', @resource[:interface])
elsif @property_flush[:ipaddr].include?(:dhcp)
# start dhclient on interface
iproute('--force', 'addr', 'flush', 'dev', @resource[:interface])
#todo: start dhclient
else
# add-remove static IP addresses
if !@old_property_hash.nil? and !@old_property_hash[:ipaddr].nil?
(@old_property_hash[:ipaddr] - @property_flush[:ipaddr]).each do |ipaddr|
iproute('--force', 'addr', 'del', ipaddr, 'dev', @resource[:interface])
end
adding_addresses = @property_flush[:ipaddr] - @old_property_hash[:ipaddr]
else
adding_addresses = @property_flush[:ipaddr]
end
if adding_addresses.include? :none
iproute('--force', 'link', 'set', 'dev', @resource[:interface], 'up')
elsif adding_addresses.include? :dhcp
debug("!!! DHCP runtime configuration not implemented now !!!")
else
# add IP addresses
adding_addresses.each do |ipaddr|
iproute('addr', 'add', ipaddr, 'dev', @resource[:interface])
end
end
end
end
if !@property_flush[:gateway].nil? or !@property_flush[:gateway_metric].nil?
# clean all default gateways for this interface with any metrics
cmdline = ['route', 'del', 'default', 'dev', @resource[:interface]]
rc = 0
while rc == 0
# we should remove route repeatedly for prevent situation
# when has multiple default routes through the same router,
# but with different metrics
begin
iproute(cmdline)
rescue
rc = 1
end
end
# add new route
if @resource[:gateway] != :absent
cmdline = ['route', 'add', 'default', 'via', @resource[:gateway], 'dev', @resource[:interface]]
if ![nil, :absent].include?(@property_flush[:gateway_metric]) and @property_flush[:gateway_metric].to_i > 0
cmdline << ['metric', @property_flush[:gateway_metric]]
end
begin
rv = iproute(cmdline)
rescue
warn("!!! Iproute can't setup new gateway.\n!!! May be you already have default gateway with same metric:")
rv = iproute('-f', 'inet', 'route', 'show')
warn("#{rv}\n\n")
end
end
end
# if ! @property_flush[:onboot].nil?
# iproute('link', 'set', 'dev', @resource[:interface], 'up')
# end
@property_hash = resource.to_hash
end
end
#-----------------------------------------------------------------
# def bridge
# @property_hash[:bridge] || :absent
# end
# def bridge=(val)
# @property_flush[:bridge] = val
# end
# def name
# @property_hash[:name]
# end
def port_type
@property_hash[:port_type] || :absent
end
def port_type=(val)
@property_flush[:port_type] = val
end
def onboot
@property_hash[:onboot] || :absent
end
def onboot=(val)
@property_flush[:onboot] = val
end
def ipaddr
@property_hash[:ipaddr] || :absent
end
def ipaddr=(val)
if (@old_property_hash[:ipaddr] - val) != (val - @old_property_hash[:ipaddr])
@property_flush[:ipaddr] = val
end
end
def gateway
@property_hash[:gateway] || :absent
end
def gateway=(val)
@property_flush[:gateway] = val
end
def gateway_metric
@property_hash[:gateway_metric] || :absent
end
def gateway_metric=(val)
@property_flush[:gateway_metric] = val
end
def dhcp_hostname
@property_hash[:dhcp_hostname] || :absent
end
def dhcp_hostname=(val)
@property_flush[:dhcp_hostname] = val
end
#-----------------------------------------------------------------
def self.get_if_addr_mappings
if_list = {}
ip_a = iproute('-f', 'inet', 'addr', 'show').split(/\n+/)
if_name = nil
ip_a.each do |line|
line.rstrip!
case line
when /^\s*\d+\:\s+([\w\-\.]+)[\:\@]/i
if_name = $1
if_list[if_name] = { :ipaddr => [] }
when /^\s+inet\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2})/
next if if_name.nil?
if_list[if_name][:ipaddr] << $1
else
next
end
end
return if_list
end
def self.get_if_defroutes_mappings
rou_list = {}
ip_a = iproute('-f', 'inet', 'route', 'show').split(/\n+/)
ip_a.each do |line|
line.rstrip!
next if !line.match(/^\s*default\s+via\s+([\d\.]+)\s+dev\s+([\w\-\.]+)(\s+metric\s+(\d+))?/)
metric = $4.nil? ? :absent : $4.to_i
rou_list[$2] = { :gateway => $1, :gateway_metric => metric } if rou_list[$2].nil? # do not replace to gateway with highest metric
end
return rou_list
end
end
# vim: set ts=2 sw=2 et :