Skip to content
Merged
2 changes: 2 additions & 0 deletions doc/source/ovn/dhcp_opts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ classless-static-route classless_static_route
default-ttl default_ttl
dns-server dns_server
domain-name domain_name
domain-search domain_search_list
ethernet-encap ethernet_encap
ip-forward-enable ip_forward_enable
lease-time lease_time
Expand Down Expand Up @@ -67,6 +68,7 @@ wpad wpad
59 T2
66 tftp_server
67 bootfile_name
119 domain_search_list
121 classless_static_route
150 tftp_server_address
210 path_prefix
Expand Down
6 changes: 1 addition & 5 deletions neutron/agent/ovn/metadata/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
from oslo_utils import netutils
from ovsdbapp.backend.ovs_idl import event as row_event
from ovsdbapp.backend.ovs_idl import vlog
import tenacity

from neutron.agent.linux import external_process
from neutron.agent.linux import ip_lib
Expand Down Expand Up @@ -280,10 +279,7 @@ def start(self):

self._proxy.wait()

@tenacity.retry(
wait=tenacity.wait_exponential(
max=config.get_ovn_ovsdb_retry_max_interval()),
reraise=True)
@ovn_utils.retry()
def register_metadata_agent(self):
# NOTE(lucasagomes): db_add() will not overwrite the UUID if
# it's already set.
Expand Down
11 changes: 3 additions & 8 deletions neutron/agent/ovn/metadata/ovsdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
from ovsdbapp.backend.ovs_idl import connection
from ovsdbapp.backend.ovs_idl import idlutils
from ovsdbapp.schema.open_vswitch import impl_idl as idl_ovs
import tenacity

from neutron.common.ovn import utils as ovn_utils
from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf as config
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import impl_idl_ovn
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovsdb_monitor
Expand Down Expand Up @@ -54,16 +54,11 @@ def __init__(self, chassis=None, events=None, tables=None):
if events:
self.notify_handler.watch_events(events)

@tenacity.retry(
wait=tenacity.wait_exponential(max=180),
reraise=True)
@ovn_utils.retry(max_=180)
def _get_ovsdb_helper(self, connection_string):
return idlutils.get_schema_helper(connection_string, self.SCHEMA)

@tenacity.retry(
wait=tenacity.wait_exponential(
max=config.get_ovn_ovsdb_retry_max_interval()),
reraise=True)
@ovn_utils.retry()
def start(self):
LOG.info('Getting OvsdbSbOvnIdl for MetadataAgent with retry')
conn = connection.Connection(
Expand Down
2 changes: 2 additions & 0 deletions neutron/agent/ovn/metadata_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@
from neutron.agent.ovn.metadata import agent
from neutron.conf.agent.metadata import config as meta
from neutron.conf.agent.ovn.metadata import config as ovn_meta
from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf

LOG = logging.getLogger(__name__)


def main():
ovn_conf.register_opts()
ovn_meta.register_meta_conf_opts(meta.SHARED_OPTS)
ovn_meta.register_meta_conf_opts(meta.UNIX_DOMAIN_METADATA_PROXY_OPTS)
ovn_meta.register_meta_conf_opts(meta.METADATA_PROXY_HANDLER_OPTS)
Expand Down
1 change: 1 addition & 0 deletions neutron/cmd/ovn/neutron_ovn_db_sync_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ def security_groups_provider_updated(self, context,

def setup_conf():
conf = cfg.CONF
ovn_conf.register_opts()
ml2_group, ml2_opts = neutron_options.list_ml2_conf_opts()[0]
cfg.CONF.register_cli_opts(ml2_opts, ml2_group)
cfg.CONF.register_cli_opts(securitygroups_rpc.security_group_opts,
Expand Down
3 changes: 3 additions & 0 deletions neutron/common/ovn/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
'log-server': 'log_server',
'lpr-server': 'lpr_server',
'domain-name': 'domain_name',
'domain-search': 'domain_search_list',
'swap-server': 'swap_server',
'policy-filter': 'policy_filter',
'router-solicitation': 'router_solicitation',
Expand Down Expand Up @@ -162,6 +163,7 @@
'58': 'T1',
'59': 'T2',
'67': 'bootfile_name',
'119': 'domain_search_list',
'252': 'wpad',
'210': 'path_prefix',
'150': 'tftp_server_address'},
Expand All @@ -187,6 +189,7 @@
# OVN string type DHCP options
OVN_STR_TYPE_DHCP_OPTS = [
'domain_name',
'domain_search_list',
'bootfile_name',
'bootfile_name_alt',
'path_prefix',
Expand Down
130 changes: 130 additions & 0 deletions neutron/common/ovn/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@
from neutron_lib import exceptions as n_exc
from neutron_lib.plugins import directory
from neutron_lib.utils import net as n_utils
from oslo_concurrency import processutils
from oslo_config import cfg
from oslo_log import log
from oslo_serialization import jsonutils
from oslo_utils import netutils
from oslo_utils import strutils
from ovsdbapp import constants as ovsdbapp_const
import tenacity

from neutron._i18n import _
from neutron.common.ovn import constants
Expand All @@ -55,6 +57,70 @@
'PortExtraDHCPValidation', ['failed', 'invalid_ipv4', 'invalid_ipv6'])


class OvsdbClientCommand(object):
_CONNECTION = 0
_PRIVATE_KEY = 1
_CERTIFICATE = 2
_CA_AUTHORITY = 3

OVN_Northbound = "OVN_Northbound"
OVN_Southbound = "OVN_Southbound"

_db_settings = {
OVN_Northbound: {
_CONNECTION: ovn_conf.get_ovn_nb_connection,
_PRIVATE_KEY: ovn_conf.get_ovn_nb_private_key,
_CERTIFICATE: ovn_conf.get_ovn_nb_certificate,
_CA_AUTHORITY: ovn_conf.get_ovn_nb_ca_cert,
},
OVN_Southbound: {
_CONNECTION: ovn_conf.get_ovn_sb_connection,
_PRIVATE_KEY: ovn_conf.get_ovn_sb_private_key,
_CERTIFICATE: ovn_conf.get_ovn_sb_certificate,
_CA_AUTHORITY: ovn_conf.get_ovn_sb_ca_cert,
},
}

@classmethod
def run(cls, command):
"""Run custom ovsdb protocol command.

:param command: JSON object of ovsdb protocol command
"""
try:
db = command[0]
except IndexError:
raise KeyError(
_("%s or %s schema must be specified in the command %s" % (
cls.OVN_Northbound, cls.OVN_Southbound, command)))

if db not in (cls.OVN_Northbound, cls.OVN_Southbound):
raise KeyError(
_("%s or %s schema must be specified in the command %s" % (
cls.OVN_Northbound, cls.OVN_Southbound, command)))

cmd = ['ovsdb-client',
cls.COMMAND,
cls._db_settings[db][cls._CONNECTION](),
'--timeout',
str(ovn_conf.get_ovn_ovsdb_timeout())]

if cls._db_settings[db][cls._PRIVATE_KEY]():
cmd += ['-p', cls._db_settings[db][cls._PRIVATE_KEY](),
'-c', cls._db_settings[db][cls._CERTIFICATE](),
'-C', cls._db_settings[db][cls._CA_AUTHORITY]()]

cmd.append(jsonutils.dumps(command))

return processutils.execute(
*cmd,
log_errors=processutils.LOG_FINAL_ERROR)


class OvsdbClientTransactCommand(OvsdbClientCommand):
COMMAND = 'transact'


def ovn_name(id):
# The name of the OVN entry will be neutron-<UUID>
# This is due to the fact that the OVN application checks if the name
Expand Down Expand Up @@ -693,3 +759,67 @@ def is_port_external(port):

return (vnic_type in constants.EXTERNAL_PORT_TYPES and
constants.PORT_CAP_SWITCHDEV not in capabilities)


def retry(max_=None):
def inner(func):
def wrapper(*args, **kwargs):
local_max = max_ or ovn_conf.get_ovn_ovsdb_retry_max_interval()
return tenacity.retry(
wait=tenacity.wait_exponential(max=local_max),
reraise=True)(func)(*args, **kwargs)
return wrapper
return inner


def create_neutron_pg_drop():
"""Create neutron_pg_drop Port Group.

It uses ovsdb-client to send to server transact command using ovsdb
protocol that checks if the neutron_pg_drop row exists. If it exists
it times out immediatelly. If it doesn't exist then it creates the
Port_Group and default ACLs to drop all ingress and egress traffic.
"""
command = [
"OVN_Northbound", {
"op": "wait",
"timeout": 0,
"table": "Port_Group",
"where": [
["name", "==", constants.OVN_DROP_PORT_GROUP_NAME]
],
"until": "==",
"rows": []
}, {
"op": "insert",
"table": "ACL",
"row": {
"action": "drop",
"direction": "to-lport",
"match": "outport == @neutron_pg_drop && ip",
"priority": 1001
},
"uuid-name": "droptoport"
}, {
"op": "insert",
"table": "ACL",
"row": {
"action": "drop",
"direction": "from-lport",
"match": "inport == @neutron_pg_drop && ip",
"priority": 1001
},
"uuid-name": "dropfromport"
}, {
"op": "insert",
"table": "Port_Group",
"row": {
"name": constants.OVN_DROP_PORT_GROUP_NAME,
"acls": ["set", [
["named-uuid", "droptoport"],
["named-uuid", "dropfromport"]
]]
}
}]

OvsdbClientTransactCommand.run(command)
6 changes: 4 additions & 2 deletions neutron/conf/plugins/ml2/drivers/ovn/ovn_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,10 @@
'baremetal nodes. Defaults to False.')),
]

cfg.CONF.register_opts(ovn_opts, group='ovn')
ovs_conf.register_ovs_agent_opts()

def register_opts():
cfg.CONF.register_opts(ovn_opts, group='ovn')
ovs_conf.register_ovs_agent_opts()


def list_opts():
Expand Down
Loading