Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions lib/charms/ovn_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import charmhelpers.contrib.network.ovs as ch_ovs
import charmhelpers.contrib.network.ovs.ovsdb as ch_ovsdb
import charmhelpers.contrib.openstack.deferred_events as deferred_events
import charmhelpers.core.host as ch_host
import charmhelpers.fetch as ch_fetch

import charms_openstack.adapters
Expand Down Expand Up @@ -1297,6 +1298,12 @@ def configure_bridges(self):
'other-config': {'disable-in-band': 'true'},
},
})

# We need to build a mac mapping to enable distributed ports on tenant
# VLAN networks.
# see: https://www.ovn.org/support/dist-docs/ovn-architecture.7.html
ovn_chassis_mac_mapping = ''

for br in bim:
if br not in ovnbridges:
continue
Expand Down Expand Up @@ -1328,13 +1335,37 @@ def configure_bridges(self):
portdata={
'external-ids': {
'charm-ovn-chassis': br}})
# We can use the MAC of the bridge as the unique chassis MAC. If
# a physical port has been added to the bridge, the MAC will most
# likely be inherited. If not, a unique mac will be generated
# anyway.
hw_addr = None
try:
hw_addr = ch_host.get_nic_hwaddr(br)
except Exception as err:
ch_core.hookenv.log('failed to get MAC for bridge "{}": {}'
.format(br, err),
level=ch_core.hookenv.ERROR)
if hw_addr:
networks = ovnbridges.get(br, [])
for net in networks:
if ovn_chassis_mac_mapping:
ovn_chassis_mac_mapping += ','
ovn_chassis_mac_mapping += '{}:{}'.format(
net, hw_addr)

opvs = ch_ovsdb.SimpleOVSDB('ovs-vsctl').open_vswitch
if ovn_br_map_str:
opvs.set('.', 'external_ids:ovn-bridge-mappings', ovn_br_map_str)
else:
opvs.remove('.', 'external_ids', 'ovn-bridge-mappings')

if ovn_chassis_mac_mapping:
opvs.set('.', 'external_ids:ovn-chassis-mac-mappings',
ovn_chassis_mac_mapping)
else:
opvs.remove('.', 'external_ids', 'ovn-chassis-mac-mappings')

cms_opts = self._get_ovn_cms_options()
if cms_opts:
opvs.set('.', 'external_ids:ovn-cms-options', ','.join(cms_opts))
Expand Down
27 changes: 23 additions & 4 deletions unit_tests/test_lib_charms_ovn_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,18 @@ def test__init__(self):
})

def test_configure_bridges(self):
def mock_get_nic_hwaddr_fn(iface):
mac_mapping = {
"br-ex": "a0:36:9f:dd:37:dd",
"br-data": "a0:36:9f:dd:37:db",
}
return mac_mapping.get(iface, "")
mock_get_nic_hwaddr = mock.MagicMock()
mock_get_nic_hwaddr.side_effect = mock_get_nic_hwaddr_fn

self.patch_object(ovn_charm.ch_host, "get_nic_hwaddr")
self.get_nic_hwaddr.side_effect = mock_get_nic_hwaddr

self.patch_object(ovn_charm.os_context, 'BridgePortInterfaceMap')
dict_bpi = {
'br-ex': { # bridge
Expand Down Expand Up @@ -891,10 +903,17 @@ def test_configure_bridges(self):
'data': 'fake',
'external-ids': {'charm-ovn-chassis': 'br-ex'}},
linkup=False, promisc=None, portdata={
'external-ids': {'charm-ovn-chassis': 'br-ex'}}),
ovsdb.open_vswitch.set.assert_called_once_with(
'.', 'external_ids:ovn-bridge-mappings',
'other:br-data,provider:br-ex')
'external-ids': {'charm-ovn-chassis': 'br-ex'}})
ovsdb.open_vswitch.set.assert_has_calls([
mock.call(
'.', 'external_ids:ovn-bridge-mappings',
'other:br-data,provider:br-ex'
),
mock.call(
'.', 'external_ids:ovn-chassis-mac-mappings',
'provider:a0:36:9f:dd:37:dd,other:a0:36:9f:dd:37:db'
),
], any_order=False)
ovsdb.open_vswitch.remove.assert_called_once_with(
'.', 'external_ids', 'ovn-cms-options')

Expand Down