Merge "LLDP OVS enablement: puppet configuration"
This commit is contained in:
commit
38027c134f
|
@ -35,6 +35,7 @@ define platform::vswitch::ovs::device(
|
||||||
|
|
||||||
define platform::vswitch::ovs::bridge(
|
define platform::vswitch::ovs::bridge(
|
||||||
$datapath_type = 'netdev',
|
$datapath_type = 'netdev',
|
||||||
|
$attributes = [],
|
||||||
) {
|
) {
|
||||||
exec { "ovs-add-br: ${title}":
|
exec { "ovs-add-br: ${title}":
|
||||||
command => template("platform/ovs.add-bridge.erb")
|
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(
|
class platform::vswitch::ovs(
|
||||||
$devices = {},
|
$devices = {},
|
||||||
$bridges = {},
|
$bridges = {},
|
||||||
$ports = {},
|
$ports = {},
|
||||||
$addresses = {},
|
$addresses = {},
|
||||||
|
$flows = {},
|
||||||
) inherits ::platform::vswitch::params {
|
) inherits ::platform::vswitch::params {
|
||||||
|
|
||||||
if $::platform::params::vswitch_type == 'ovs' {
|
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::Port<||>
|
||||||
Platform::Vswitch::Ovs::Bridge<||> -> Platform::Vswitch::Ovs::Address<||>
|
Platform::Vswitch::Ovs::Bridge<||> -> Platform::Vswitch::Ovs::Address<||>
|
||||||
|
Platform::Vswitch::Ovs::Port<||> -> Platform::Vswitch::Ovs::Flow<||>
|
||||||
}
|
}
|
||||||
|
|
||||||
create_resources('platform::vswitch::ovs::bridge', $bridges, {
|
create_resources('platform::vswitch::ovs::bridge', $bridges, {
|
||||||
|
@ -129,4 +144,8 @@ class platform::vswitch::ovs(
|
||||||
create_resources('platform::vswitch::ovs::address', $addresses, {
|
create_resources('platform::vswitch::ovs::address', $addresses, {
|
||||||
require => Service['openvswitch']
|
require => Service['openvswitch']
|
||||||
})
|
})
|
||||||
|
|
||||||
|
create_resources('platform::vswitch::ovs::flow', $flows, {
|
||||||
|
require => Service['openvswitch']
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,3 +2,4 @@ configure system hostname '<%= @hostname %>:<%= @system %>'
|
||||||
configure system description 'Titanium Cloud version <%= @version %>'
|
configure system description 'Titanium Cloud version <%= @version %>'
|
||||||
configure lldp tx-interval <%= @tx_interval %>
|
configure lldp tx-interval <%= @tx_interval %>
|
||||||
configure lldp tx-hold <%= @tx_hold %>
|
configure lldp tx-hold <%= @tx_hold %>
|
||||||
|
configure system interface pattern *,!br*,!ovs*,!tap*
|
||||||
|
|
|
@ -1,2 +1,6 @@
|
||||||
ovs-vsctl --timeout 10 -- --may-exist add-br <%= @name -%>
|
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 -%>
|
||||||
|
|
|
@ -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 -%>
|
|
@ -13,4 +13,9 @@ ovs-vsctl --timeout 10 -- --may-exist add-<%= @type -%> <%= @bridge -%> <%= @nam
|
||||||
<%- interface['attributes'].each do |attribute| -%>
|
<%- interface['attributes'].each do |attribute| -%>
|
||||||
<%= attribute -%>
|
<%= attribute -%>
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
|
<%- end %>
|
||||||
|
<%- @interfaces.each do |interface| -%>
|
||||||
|
<%- if interface['type'] == 'internal' -%>
|
||||||
|
ip link set <%= interface['name'] -%> up
|
||||||
|
<%- end -%>
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
class sysinv::agent (
|
class sysinv::agent (
|
||||||
$agent_driver = false,
|
$agent_driver = false,
|
||||||
$package_ensure = 'latest',
|
$package_ensure = 'latest',
|
||||||
$enabled = true
|
$enabled = true,
|
||||||
|
$lldp_drivers = []
|
||||||
) {
|
) {
|
||||||
|
|
||||||
include sysinv::params
|
include sysinv::params
|
||||||
|
@ -32,6 +33,10 @@ class sysinv::agent (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sysinv_config {
|
||||||
|
'lldp/drivers': value => join($lldp_drivers,",");
|
||||||
|
}
|
||||||
|
|
||||||
if $::sysinv::params::agent_package {
|
if $::sysinv::params::agent_package {
|
||||||
Package['sysinv-agent'] -> Sysinv_config<||>
|
Package['sysinv-agent'] -> Sysinv_config<||>
|
||||||
Package['sysinv-agent'] -> Sysinv_api_paste_ini<||>
|
Package['sysinv-agent'] -> Sysinv_api_paste_ini<||>
|
||||||
|
|
|
@ -1041,6 +1041,10 @@ UPGRADE_ABORT_COMPLETING = 'abort-completing'
|
||||||
UPGRADE_ABORTING_ROLLBACK = 'aborting-reinstall'
|
UPGRADE_ABORTING_ROLLBACK = 'aborting-reinstall'
|
||||||
|
|
||||||
# LLDP
|
# 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_CHASSIS_ID = 'chassis_id'
|
||||||
LLDP_TLV_TYPE_PORT_ID = 'port_identifier'
|
LLDP_TLV_TYPE_PORT_ID = 'port_identifier'
|
||||||
LLDP_TLV_TYPE_TTL = 'ttl'
|
LLDP_TLV_TYPE_TTL = 'ttl'
|
||||||
|
|
|
@ -2039,6 +2039,15 @@ class ConductorManager(service.PeriodicService):
|
||||||
LOG.info("Updating port name: %s to %s" % (port_name, updated_name))
|
LOG.info("Updating port name: %s to %s" % (port_name, updated_name))
|
||||||
self.dbapi.ethernet_port_update(port['uuid'], {'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):
|
def lldp_tlv_dict(self, agent_neighbour_dict):
|
||||||
tlv_dict = {}
|
tlv_dict = {}
|
||||||
for k, v in agent_neighbour_dict.iteritems():
|
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)
|
"Error getting LLDP agents for host %s") % host_uuid)
|
||||||
|
|
||||||
for agent in agent_dict_array:
|
for agent in agent_dict_array:
|
||||||
port_found = None
|
db_port = self.lldp_id_to_port(agent['name_or_uuid'], db_ports)
|
||||||
for db_port in db_ports:
|
if not db_port:
|
||||||
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:
|
|
||||||
LOG.debug("Could not find port for agent %s",
|
LOG.debug("Could not find port for agent %s",
|
||||||
agent['name_or_uuid'])
|
agent['name_or_uuid'])
|
||||||
return
|
return
|
||||||
|
@ -2269,16 +2272,10 @@ class ConductorManager(service.PeriodicService):
|
||||||
neighbour['uuid'])
|
neighbour['uuid'])
|
||||||
|
|
||||||
for neighbour in neighbour_dict_array:
|
for neighbour in neighbour_dict_array:
|
||||||
port_found = None
|
db_port = self.lldp_id_to_port(neighbour['name_or_uuid'], db_ports)
|
||||||
for db_port in db_ports:
|
if not db_port:
|
||||||
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:
|
|
||||||
LOG.debug("Could not find port for neighbour %s",
|
LOG.debug("Could not find port for neighbour %s",
|
||||||
neighbour['name'])
|
neighbour['name_or_uuid'])
|
||||||
return
|
return
|
||||||
|
|
||||||
LOG.debug("Processing lldp neighbour %s" % neighbour)
|
LOG.debug("Processing lldp neighbour %s" % neighbour)
|
||||||
|
|
|
@ -26,6 +26,7 @@ class OVSPuppet(base.BasePuppet):
|
||||||
config.update(self._get_port_config(host))
|
config.update(self._get_port_config(host))
|
||||||
config.update(self._get_virtual_config(host))
|
config.update(self._get_virtual_config(host))
|
||||||
config.update(self._get_neutron_config(host))
|
config.update(self._get_neutron_config(host))
|
||||||
|
config.update(self._get_lldp_config(host))
|
||||||
return config
|
return config
|
||||||
|
|
||||||
def _get_port_config(self, host):
|
def _get_port_config(self, host):
|
||||||
|
@ -33,6 +34,7 @@ class OVSPuppet(base.BasePuppet):
|
||||||
ovs_bridges = {}
|
ovs_bridges = {}
|
||||||
ovs_ports = {}
|
ovs_ports = {}
|
||||||
ovs_addresses = {}
|
ovs_addresses = {}
|
||||||
|
ovs_flows = {}
|
||||||
|
|
||||||
index = 0
|
index = 0
|
||||||
for iface in sorted(self.context['interfaces'].values(),
|
for iface in sorted(self.context['interfaces'].values(),
|
||||||
|
@ -61,6 +63,31 @@ class OVSPuppet(base.BasePuppet):
|
||||||
ovs_ports.update({port['name']: port})
|
ovs_ports.update({port['name']: port})
|
||||||
ovs_devices.update({d['pci_addr']: d for d in devices})
|
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
|
index += 1
|
||||||
|
|
||||||
# currently only one provider network is supported per
|
# 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::bridges': ovs_bridges,
|
||||||
'platform::vswitch::ovs::ports': ovs_ports,
|
'platform::vswitch::ovs::ports': ovs_ports,
|
||||||
'platform::vswitch::ovs::addresses': ovs_addresses,
|
'platform::vswitch::ovs::addresses': ovs_addresses,
|
||||||
|
'platform::vswitch::ovs::flows': ovs_flows,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _get_ethernet_device(self, iface):
|
def _get_ethernet_device(self, iface):
|
||||||
|
@ -147,6 +175,74 @@ class OVSPuppet(base.BasePuppet):
|
||||||
|
|
||||||
return port, devices
|
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):
|
def _get_bond_port(self, host, iface, bridge, index):
|
||||||
devices = []
|
devices = []
|
||||||
interfaces = []
|
interfaces = []
|
||||||
|
@ -294,3 +390,11 @@ class OVSPuppet(base.BasePuppet):
|
||||||
def _is_vxlan_providernet(self, name):
|
def _is_vxlan_providernet(self, name):
|
||||||
providernet_type = self._get_providernet_type(name)
|
providernet_type = self._get_providernet_type(name)
|
||||||
return bool(providernet_type == constants.NEUTRON_PROVIDERNET_VXLAN)
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -70,6 +70,7 @@ class PlatformPuppet(base.BasePuppet):
|
||||||
config.update(self._get_host_tpm_config(host))
|
config.update(self._get_host_tpm_config(host))
|
||||||
config.update(self._get_host_cpu_config(host))
|
config.update(self._get_host_cpu_config(host))
|
||||||
config.update(self._get_host_memory_config(host))
|
config.update(self._get_host_memory_config(host))
|
||||||
|
config.update(self._get_host_lldp_config(host))
|
||||||
return config
|
return config
|
||||||
|
|
||||||
def _get_static_software_config(self):
|
def _get_static_software_config(self):
|
||||||
|
@ -818,3 +819,15 @@ class PlatformPuppet(base.BasePuppet):
|
||||||
def _get_platform_cpu_count(self, host):
|
def _get_platform_cpu_count(self, host):
|
||||||
cpus = self._get_host_cpu_list(host, constants.PLATFORM_FUNCTION, True)
|
cpus = self._get_host_cpu_list(host, constants.PLATFORM_FUNCTION, True)
|
||||||
return len(cpus)
|
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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue