# Copyright (c) 2015 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from neutron_lib.plugins.ml2 import ovs_constants from oslo_config import cfg from ovsdbapp.backend.ovs_idl import command from ovsdbapp.backend.ovs_idl import connection from ovsdbapp.backend.ovs_idl import idlutils from ovsdbapp.backend.ovs_idl import vlog from ovsdbapp.schema.open_vswitch import impl_idl from neutron.agent.ovsdb.native import connection as n_connection from neutron.common import utils from neutron.conf.agent import ovs_conf ovs_conf.register_ovs_agent_opts() _connection = None _idl_monitor = None def api_factory(): global _connection global _idl_monitor if _connection is None: _idl_monitor = n_connection.OvsIdlMonitor() _connection = connection.Connection( idl=_idl_monitor, timeout=cfg.CONF.OVS.ovsdb_timeout) return NeutronOvsdbIdl(_connection, _idl_monitor) class OvsCleanup(command.BaseCommand): def __init__(self, api, bridge, all_ports=False): super().__init__(api) self.bridge = bridge self.all_ports = all_ports def run_idl(self, txn): br = idlutils.row_by_value(self.api.idl, 'Bridge', 'name', self.bridge) for port in br.ports: if not any(self.is_deletable_port(iface) for iface in port.interfaces): continue br.delvalue('ports', port) for iface in port.interfaces: iface.delete() port.delete() def is_deletable_port(self, port): # Deletable defined as "looks like vif port and not set to skip delete" if self.all_ports: return True if ovs_constants.SKIP_CLEANUP in port.external_ids: return False if not all(field in port.external_ids for field in ('iface-id', 'attached-mac')): return False return True @utils.SingletonDecorator class NeutronOvsdbIdl(impl_idl.OvsdbIdl): def __init__(self, connection, idl_monitor): max_level = None if cfg.CONF.OVS.ovsdb_debug else vlog.INFO vlog.use_python_logger(max_level=max_level) self.idl_monitor = idl_monitor super().__init__(connection) def ovs_cleanup(self, bridges, all_ports=False): return OvsCleanup(self, bridges, all_ports)