Merge "LLDP OVS enablement: puppet configuration"

This commit is contained in:
Zuul 2018-09-27 00:56:51 +00:00 committed by Gerrit Code Review
commit 38027c134f
10 changed files with 180 additions and 19 deletions

View File

@ -35,6 +35,7 @@ define platform::vswitch::ovs::device(
define platform::vswitch::ovs::bridge(
$datapath_type = 'netdev',
$attributes = [],
) {
exec { "ovs-add-br: ${title}":
command => template("platform/ovs.add-bridge.erb")
@ -69,11 +70,24 @@ define platform::vswitch::ovs::address(
}
define platform::vswitch::ovs::flow(
$bridge,
$attributes = [],
$actions,
) {
exec { "ovs-add-flow: ${title}":
command => template("platform/ovs.add-flow.erb"),
logoutput => true
}
}
class platform::vswitch::ovs(
$devices = {},
$bridges = {},
$ports = {},
$addresses = {},
$flows = {},
) inherits ::platform::vswitch::params {
if $::platform::params::vswitch_type == 'ovs' {
@ -116,6 +130,7 @@ class platform::vswitch::ovs(
Platform::Vswitch::Ovs::Bridge<||> -> Platform::Vswitch::Ovs::Port<||>
Platform::Vswitch::Ovs::Bridge<||> -> Platform::Vswitch::Ovs::Address<||>
Platform::Vswitch::Ovs::Port<||> -> Platform::Vswitch::Ovs::Flow<||>
}
create_resources('platform::vswitch::ovs::bridge', $bridges, {
@ -129,4 +144,8 @@ class platform::vswitch::ovs(
create_resources('platform::vswitch::ovs::address', $addresses, {
require => Service['openvswitch']
})
create_resources('platform::vswitch::ovs::flow', $flows, {
require => Service['openvswitch']
})
}

View File

@ -2,3 +2,4 @@ configure system hostname '<%= @hostname %>:<%= @system %>'
configure system description 'Titanium Cloud version <%= @version %>'
configure lldp tx-interval <%= @tx_interval %>
configure lldp tx-hold <%= @tx_hold %>
configure system interface pattern *,!br*,!ovs*,!tap*

View File

@ -1,2 +1,6 @@
ovs-vsctl --timeout 10 -- --may-exist add-br <%= @name -%>
-- set bridge <%= @name -%> datapath_type=<%= @datapath_type -%>
-- set bridge <%= @name -%>
<%- @attributes.each do |attribute| -%>
<%= attribute -%>
<%- end -%>
datapath_type=<%= @datapath_type -%>

View File

@ -0,0 +1,9 @@
ovs-ofctl add-flow <%= @bridge -%>
<%- @attributes.each_with_index do |attrib, idx| -%>
<% if idx == 0 %> <% else -%>,<% end -%>
<%= attrib[0] -%>=<%= attrib[1] -%>
<%- end -%>
,actions=<%- @actions.each_with_index do |action, idx| -%>
<%- if idx > 0 -%>,<%- end -%>
<%= action['type'] -%>:<%= action['value'] -%>
<%- end -%>

View File

@ -13,4 +13,9 @@ ovs-vsctl --timeout 10 -- --may-exist add-<%= @type -%> <%= @bridge -%> <%= @nam
<%- interface['attributes'].each do |attribute| -%>
<%= attribute -%>
<%- end -%>
<%- end %>
<%- @interfaces.each do |interface| -%>
<%- if interface['type'] == 'internal' -%>
ip link set <%= interface['name'] -%> up
<%- end -%>
<%- end -%>

View File

@ -17,7 +17,8 @@
class sysinv::agent (
$agent_driver = false,
$package_ensure = 'latest',
$enabled = true
$enabled = true,
$lldp_drivers = []
) {
include sysinv::params
@ -32,6 +33,10 @@ class sysinv::agent (
}
}
sysinv_config {
'lldp/drivers': value => join($lldp_drivers,",");
}
if $::sysinv::params::agent_package {
Package['sysinv-agent'] -> Sysinv_config<||>
Package['sysinv-agent'] -> Sysinv_api_paste_ini<||>

View File

@ -1041,6 +1041,10 @@ UPGRADE_ABORT_COMPLETING = 'abort-completing'
UPGRADE_ABORTING_ROLLBACK = 'aborting-reinstall'
# LLDP
LLDP_OVS_PORT_PREFIX = 'lldp'
LLDP_OVS_PORT_NAME_LEN = 15
LLDP_MULTICAST_ADDRESS = '01:80:c2:00:00:0e'
LLDP_ETHER_TYPE = '0x88cc'
LLDP_TLV_TYPE_CHASSIS_ID = 'chassis_id'
LLDP_TLV_TYPE_PORT_ID = 'port_identifier'
LLDP_TLV_TYPE_TTL = 'ttl'

View File

@ -2039,6 +2039,15 @@ class ConductorManager(service.PeriodicService):
LOG.info("Updating port name: %s to %s" % (port_name, updated_name))
self.dbapi.ethernet_port_update(port['uuid'], {'name': updated_name})
def lldp_id_to_port(self, id, ports):
ovs_id = re.sub(r'^{}'.format(constants.LLDP_OVS_PORT_PREFIX), '', id)
for port in ports:
if (port['name'] == id or
port['uuid'] == id or
port['uuid'].find(ovs_id) == 0):
return port
return None
def lldp_tlv_dict(self, agent_neighbour_dict):
tlv_dict = {}
for k, v in agent_neighbour_dict.iteritems():
@ -2156,14 +2165,8 @@ class ConductorManager(service.PeriodicService):
"Error getting LLDP agents for host %s") % host_uuid)
for agent in agent_dict_array:
port_found = None
for db_port in db_ports:
if (db_port['name'] == agent['name_or_uuid'] or
db_port['uuid'] == agent['name_or_uuid']):
port_found = db_port
break
if not port_found:
db_port = self.lldp_id_to_port(agent['name_or_uuid'], db_ports)
if not db_port:
LOG.debug("Could not find port for agent %s",
agent['name_or_uuid'])
return
@ -2269,16 +2272,10 @@ class ConductorManager(service.PeriodicService):
neighbour['uuid'])
for neighbour in neighbour_dict_array:
port_found = None
for db_port in db_ports:
if (db_port['name'] == neighbour['name_or_uuid'] or
db_port['uuid'] == neighbour['name_or_uuid']):
port_found = db_port
break
if not port_found:
db_port = self.lldp_id_to_port(neighbour['name_or_uuid'], db_ports)
if not db_port:
LOG.debug("Could not find port for neighbour %s",
neighbour['name'])
neighbour['name_or_uuid'])
return
LOG.debug("Processing lldp neighbour %s" % neighbour)

View File

@ -26,6 +26,7 @@ class OVSPuppet(base.BasePuppet):
config.update(self._get_port_config(host))
config.update(self._get_virtual_config(host))
config.update(self._get_neutron_config(host))
config.update(self._get_lldp_config(host))
return config
def _get_port_config(self, host):
@ -33,6 +34,7 @@ class OVSPuppet(base.BasePuppet):
ovs_bridges = {}
ovs_ports = {}
ovs_addresses = {}
ovs_flows = {}
index = 0
for iface in sorted(self.context['interfaces'].values(),
@ -61,6 +63,31 @@ class OVSPuppet(base.BasePuppet):
ovs_ports.update({port['name']: port})
ovs_devices.update({d['pci_addr']: d for d in devices})
if iface['iftype'] == constants.INTERFACE_TYPE_ETHERNET:
ovs_ifname = port['interfaces'][0]['name']
lldp_port = self._get_lldp_port(
iface, brname, ovs_ifname=ovs_ifname)
ovs_ports.update({lldp_port['name']: lldp_port})
flow = self._get_lldp_flow(
brname, ovs_ifname, lldp_port['name'])
ovs_flows.update({port['name']: flow})
if iface['iftype'] == constants.INTERFACE_TYPE_AE:
slaves = interface.get_bond_interface_slaves(
self.context, iface)
for member, slave in enumerate(slaves):
ovs_ifname = port['interfaces'][member]['name']
lldp_port = self._get_lldp_port(
slave, brname, ovs_ifname=ovs_ifname)
ovs_ports.update({lldp_port['name']: lldp_port})
flow = self._get_lldp_flow(
brname, ovs_ifname, lldp_port['name'])
ovs_flows.update({flow['name']: flow})
flow = self._get_lldp_flow(
brname, lldp_port['name'], ovs_ifname)
ovs_flows.update({flow['name']: flow})
index += 1
# currently only one provider network is supported per
@ -83,6 +110,7 @@ class OVSPuppet(base.BasePuppet):
'platform::vswitch::ovs::bridges': ovs_bridges,
'platform::vswitch::ovs::ports': ovs_ports,
'platform::vswitch::ovs::addresses': ovs_addresses,
'platform::vswitch::ovs::flows': ovs_flows,
}
def _get_ethernet_device(self, iface):
@ -147,6 +175,74 @@ class OVSPuppet(base.BasePuppet):
return port, devices
def _get_lldp_interface(self, ifname, peer_ifname):
attributes = []
iftype = 'internal'
attributes.append("other_config:lldp_phy_peer=%s" % peer_ifname)
return {
'name': ifname,
'type': iftype,
'attributes': attributes,
}
def _get_lldp_port(self, iface, lldp_brname, ovs_ifname=None):
interfaces = []
port = interface.get_interface_port(self.context, iface)
# Limit port name length to the maximum supported by ovs-ofctl to
# reference a port with a name rather than ofport number
# when creating flows.
port_name_len = constants.LLDP_OVS_PORT_NAME_LEN
uuid_len = port_name_len - len(constants.LLDP_OVS_PORT_PREFIX)
port_name = '{}{}'.format(constants.LLDP_OVS_PORT_PREFIX,
port.uuid[:uuid_len])
if ovs_ifname:
interfaces.append(self._get_lldp_interface(port_name, ovs_ifname))
else:
interfaces.append(self._get_lldp_interface(port_name, iface['name']))
port = {
'name': port_name,
'bridge': lldp_brname,
'interfaces': interfaces,
}
return port
def _get_lldp_flow(self, bridge, in_port, out_port):
actions = []
attributes = {
'idle_timeout': 0,
'hard_timeout': 0,
'in_port': in_port,
'dl_dst': constants.LLDP_MULTICAST_ADDRESS,
'dl_type': constants.LLDP_ETHER_TYPE
}
action = {
'type': 'output',
'value': out_port
}
actions.append(action)
flow = {
'name': '{}-{}-{}'.format(bridge, in_port, out_port),
'bridge': bridge,
'attributes': attributes,
'actions': actions
}
return flow
def _get_bond_port(self, host, iface, bridge, index):
devices = []
interfaces = []
@ -294,3 +390,11 @@ class OVSPuppet(base.BasePuppet):
def _is_vxlan_providernet(self, name):
providernet_type = self._get_providernet_type(name)
return bool(providernet_type == constants.NEUTRON_PROVIDERNET_VXLAN)
def _get_lldp_config(self, host):
driver_list = self.context['_lldp_drivers']
driver_list.append('ovs')
return {
'sysinv::agent::lldp_drivers': driver_list
}

View File

@ -70,6 +70,7 @@ class PlatformPuppet(base.BasePuppet):
config.update(self._get_host_tpm_config(host))
config.update(self._get_host_cpu_config(host))
config.update(self._get_host_memory_config(host))
config.update(self._get_host_lldp_config(host))
return config
def _get_static_software_config(self):
@ -818,3 +819,15 @@ class PlatformPuppet(base.BasePuppet):
def _get_platform_cpu_count(self, host):
cpus = self._get_host_cpu_list(host, constants.PLATFORM_FUNCTION, True)
return len(cpus)
def _get_host_lldp_config(self, host):
driver_list = []
# Default is lldpd
driver_list.append('lldpd')
self.context['_lldp_drivers'] = driver_list
return {
'sysinv::agent::lldp_drivers': driver_list
}