if setting interface_type equal 'internal' requires a different ovs-vsctl call to create the port. Closes-Bug: #1771134 Change-Id: Ib56b424b85a1be5ab34fc1e3255c017081509f0d
165 lines
4.5 KiB
Ruby
165 lines
4.5 KiB
Ruby
require File.join(File.dirname(__FILE__), '..','..','..', 'puppet/provider/ovs')
|
|
|
|
Puppet::Type.type(:vs_port).provide(
|
|
:ovs,
|
|
:parent => Puppet::Provider::Ovs
|
|
) do
|
|
|
|
UUID_RE ||= /[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}/
|
|
|
|
commands :vsctl => 'ovs-vsctl'
|
|
|
|
has_feature :bonding
|
|
has_feature :vlan
|
|
has_feature :interface_type
|
|
|
|
def exists?
|
|
vsctl('list-ports', @resource[:bridge]).split("\n").include? @resource[:port]
|
|
rescue Puppet::ExecutionFailure => e
|
|
return false
|
|
end
|
|
|
|
def create
|
|
if ! bridge.exists?
|
|
raise Puppet::Error, "Bridge #{@resource[:bridge]} does not exist"
|
|
end
|
|
|
|
# create with first interface, other interfaces will be added later when synchronizing properties
|
|
if @resource[:interface_type] == :internal
|
|
vsctl('add-port', @resource[:bridge], @resource[:port], '--', 'set', 'Interface', @resource[:port], 'type=internal')
|
|
else
|
|
vsctl('--', '--id=@iface0', 'create', 'Interface', "name=#{@resource[:interface][0]}", '--', 'add-port', @resource[:bridge], @resource[:port], 'interfaces=@iface0')
|
|
end
|
|
|
|
# synchronize properties
|
|
# Only sync those properties actually supported by the provider. This
|
|
# allows this provider to be used as a base class for providers not
|
|
# supporting all properties.
|
|
sync_properties = []
|
|
if @resource.provider.class.feature?(:bonding)
|
|
sync_properties += [:interface,
|
|
:bond_mode,
|
|
:lacp,
|
|
:lacp_time,
|
|
]
|
|
end
|
|
if @resource.provider.class.feature?(:vlan)
|
|
sync_properties += [:vlan_mode,
|
|
:vlan_tag,
|
|
:vlan_trunks,
|
|
]
|
|
end
|
|
if @resource.provider.class.feature?(:interface_type)
|
|
sync_properties += [:interface_type,
|
|
]
|
|
end
|
|
for prop_name in sync_properties
|
|
property = @resource.property(prop_name)
|
|
property.sync unless property.safe_insync?(property.retrieve)
|
|
end
|
|
end
|
|
|
|
def destroy
|
|
vsctl('del-port', @resource[:bridge], @resource[:port])
|
|
end
|
|
|
|
def interface
|
|
get_port_interface_property('name')
|
|
end
|
|
|
|
def interface=(value)
|
|
# find interfaces we want to keep on the port
|
|
keep = @resource.property(:interface).retrieve() & value
|
|
keep_uids = keep.map { |iface| vsctl('get', 'Interface', iface, '_uuid').strip }
|
|
new = value - keep
|
|
args = ['--'] + new.each_with_index.map { |iface, i| ["--id=@#{i+1}", 'create', 'Interface', "name=#{iface}", '--'] }
|
|
ifaces = (1..new.length).map { |i| "@#{i}" } + keep_uids
|
|
args += ['set', 'Port', @resource[:port], "interfaces=#{ifaces.join(',')}"]
|
|
vsctl(*args)
|
|
end
|
|
|
|
def interface_type
|
|
types = get_port_interface_property('type').uniq
|
|
types != nil ? types.join(' ') : :system
|
|
end
|
|
|
|
def interface_type=(value)
|
|
@resource.property(:interface).retrieve.each do |iface|
|
|
vsctl('set', 'Interface', iface, "type=#{value}")
|
|
end
|
|
end
|
|
|
|
def bond_mode
|
|
get_port_property('bond_mode')
|
|
end
|
|
|
|
def bond_mode=(value)
|
|
set_port_property('bond_mode', value)
|
|
end
|
|
|
|
def lacp
|
|
get_port_property('lacp')
|
|
end
|
|
|
|
def lacp=(value)
|
|
set_port_property('lacp', value)
|
|
end
|
|
|
|
def lacp_time
|
|
val = self.class.get_other_config('Port', @resource[:port], 'lacp-time')
|
|
if val.nil? then '' else val.gsub(/^"|"$/, '') end
|
|
end
|
|
|
|
def lacp_time=(value)
|
|
self.class.set_other_config('Port', @resource[:port], 'lacp-time', value)
|
|
end
|
|
|
|
def vlan_mode
|
|
get_port_property('vlan_mode')
|
|
end
|
|
|
|
def vlan_mode=(value)
|
|
set_port_property('vlan_mode', value)
|
|
end
|
|
|
|
def vlan_tag
|
|
get_port_property('tag')
|
|
end
|
|
|
|
def vlan_tag=(value)
|
|
set_port_property('tag', value)
|
|
end
|
|
|
|
def vlan_trunks
|
|
get_port_property('trunks').scan(/\d+/)
|
|
end
|
|
|
|
def vlan_trunks=(value)
|
|
set_port_property('trunks', value.join(' '))
|
|
end
|
|
|
|
protected
|
|
|
|
def bridge
|
|
@bridge ||= Puppet::Type.type(:vs_bridge).provider(:ovs).new(
|
|
Puppet::Type::Vs_bridge.new(:title => @resource[:bridge])
|
|
)
|
|
end
|
|
|
|
private
|
|
|
|
def get_port_property(key)
|
|
value = self.class.get_property('Port', @resource[:port], key)
|
|
if value == '[]' then '' else value end
|
|
end
|
|
|
|
def set_port_property(key, value)
|
|
self.class.set_property('Port', @resource[:port], key, value)
|
|
end
|
|
|
|
def get_port_interface_property(key)
|
|
uuids = get_port_property('interfaces').scan(UUID_RE)
|
|
uuids.map!{|id| self.class.get_property('Interface', id, key).gsub(/^"|"$/, '')}
|
|
end
|
|
end
|