Merge "[OVN] Migrate the OVN tools"
This commit is contained in:
commit
f73f39f2cf
0
neutron/cmd/ovn/__init__.py
Normal file
0
neutron/cmd/ovn/__init__.py
Normal file
119
neutron/cmd/ovn/migration_mtu.py
Normal file
119
neutron/cmd/ovn/migration_mtu.py
Normal file
@ -0,0 +1,119 @@
|
||||
# Copyright 2018 Red Hat, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from openstack import connection
|
||||
|
||||
# TODO(dalvarez): support also GRE
|
||||
GENEVE_TO_VXLAN_OVERHEAD = 8
|
||||
|
||||
|
||||
def get_connection():
|
||||
user_domain_id = os.environ.get('OS_USER_DOMAIN_ID', 'default')
|
||||
project_domain_id = os.environ.get('OS_PROJECT_DOMAIN_ID', 'default')
|
||||
conn = connection.Connection(auth_url=os.environ['OS_AUTH_URL'],
|
||||
project_name=os.environ['OS_PROJECT_NAME'],
|
||||
username=os.environ['OS_USERNAME'],
|
||||
password=os.environ['OS_PASSWORD'],
|
||||
user_domain_id=user_domain_id,
|
||||
project_domain_id=project_domain_id)
|
||||
return conn
|
||||
|
||||
|
||||
def verify_network_mtu():
|
||||
print("Verifying the tenant network mtu's")
|
||||
conn = get_connection()
|
||||
success = True
|
||||
for network in conn.network.networks():
|
||||
if network.provider_physical_network is None and (
|
||||
network.provider_network_type == 'vxlan') and (
|
||||
'adapted_mtu' not in network.tags):
|
||||
print("adapted_mtu tag is not set for the Network "
|
||||
"[" + str(network.name) + "]")
|
||||
success = False
|
||||
|
||||
if success:
|
||||
print("All the networks are set to expected mtu value")
|
||||
else:
|
||||
print("Some tenant networks need to have their MTU updated to a "
|
||||
"lower value.")
|
||||
return success
|
||||
|
||||
|
||||
def update_network_mtu():
|
||||
print("Updating the tenant network mtu")
|
||||
conn = get_connection()
|
||||
for network in conn.network.networks():
|
||||
try:
|
||||
if network.provider_physical_network is None and (
|
||||
network.provider_network_type == 'vxlan') and (
|
||||
'adapted_mtu' not in network.tags):
|
||||
print("Updating the mtu and the tag 'adapted_mtu"
|
||||
" of the network - " + str(network.name))
|
||||
new_tags = list(network.tags)
|
||||
new_tags.append('adapted_mtu')
|
||||
conn.network.update_network(
|
||||
network,
|
||||
mtu=int(network.mtu) - GENEVE_TO_VXLAN_OVERHEAD)
|
||||
conn.network.set_tags(network, new_tags)
|
||||
except Exception as e:
|
||||
print("Exception occured while updating the MTU:" + str(e))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def print_usage():
|
||||
print('Invalid options:')
|
||||
print('Usage: %s <update|verify> mtu' % sys.argv[0])
|
||||
|
||||
|
||||
def main():
|
||||
"""Tool for updating the networks MTU's pre migration.
|
||||
|
||||
This lowers the MTU of the pre migration VXLAN and GRE networks. The
|
||||
tool will ignore non-VXLAN/GRE networks, so if you use VLAN for tenant
|
||||
networks it will be fine if you find this step not doing anything.
|
||||
|
||||
This step will go network by network reducing the MTU, and tagging
|
||||
with adapted_mtu the networks which have been already handled.
|
||||
|
||||
Every time a network is updated all the existing L3/DHCP agents
|
||||
connected to such network will update their internal leg MTU,
|
||||
instances will start fetching the new MTU as the DHCP T1 timer
|
||||
expires. As explained before, instances not obeying the DHCP T1
|
||||
parameter will need to be restarted, and instances with static IP
|
||||
assignment will need to be manually updated.
|
||||
"""
|
||||
if len(sys.argv) < 3:
|
||||
print_usage()
|
||||
sys.exit(1)
|
||||
|
||||
retval = 1
|
||||
if sys.argv[1] == "update" and sys.argv[2] == "mtu":
|
||||
if update_network_mtu():
|
||||
retval = 0
|
||||
elif sys.argv[1] == "verify" and sys.argv[2] == "mtu":
|
||||
if verify_network_mtu():
|
||||
retval = 0
|
||||
else:
|
||||
print_usage()
|
||||
|
||||
sys.exit(retval)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
222
neutron/cmd/ovn/neutron_ovn_db_sync_util.py
Normal file
222
neutron/cmd/ovn/neutron_ovn_db_sync_util.py
Normal file
@ -0,0 +1,222 @@
|
||||
# Copyright 2016 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.
|
||||
|
||||
import copy
|
||||
|
||||
from neutron_lib.agent import topics
|
||||
from neutron_lib.plugins import directory
|
||||
from oslo_config import cfg
|
||||
from oslo_db import options as db_options
|
||||
from oslo_log import log as logging
|
||||
|
||||
from neutron.conf.agent import securitygroups_rpc
|
||||
from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf
|
||||
from neutron import manager
|
||||
from neutron import opts as neutron_options
|
||||
from neutron.plugins.ml2.drivers.ovn.mech_driver import mech_driver
|
||||
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import impl_idl_ovn
|
||||
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovn_client
|
||||
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovn_db_sync
|
||||
from neutron.plugins.ml2 import plugin as ml2_plugin
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Ml2Plugin(ml2_plugin.Ml2Plugin):
|
||||
|
||||
def _setup_dhcp(self):
|
||||
pass
|
||||
|
||||
def _start_rpc_notifiers(self):
|
||||
# Override the notifier so that when calling the ML2 plugin to create
|
||||
# resources, it doesn't crash trying to notify subscribers.
|
||||
self.notifier = AgentNotifierApi(topics.AGENT)
|
||||
|
||||
|
||||
class OVNMechanismDriver(mech_driver.OVNMechanismDriver):
|
||||
|
||||
def subscribe(self):
|
||||
pass
|
||||
|
||||
def post_fork_initialize(self, resource, event, trigger, **kwargs):
|
||||
pass
|
||||
|
||||
@property
|
||||
def ovn_client(self):
|
||||
if not self._ovn_client:
|
||||
self._ovn_client = ovn_client.OVNClient(self._nb_ovn, self._sb_ovn)
|
||||
return self._ovn_client
|
||||
|
||||
# Since we are not using the ovn mechanism driver while syncing,
|
||||
# we override the post and pre commit methods so that original ones are
|
||||
# not called.
|
||||
def create_port_precommit(self, context):
|
||||
pass
|
||||
|
||||
def create_port_postcommit(self, context):
|
||||
port = context.current
|
||||
self.ovn_client.create_port(port)
|
||||
|
||||
def update_port_precommit(self, context):
|
||||
pass
|
||||
|
||||
def update_port_postcommit(self, context):
|
||||
port = context.current
|
||||
original_port = context.original
|
||||
self.ovn_client.update_port(port, original_port)
|
||||
|
||||
def delete_port_precommit(self, context):
|
||||
pass
|
||||
|
||||
def delete_port_postcommit(self, context):
|
||||
port = copy.deepcopy(context.current)
|
||||
port['network'] = context.network.current
|
||||
# FIXME(lucasagomes): PortContext does not have a session, therefore
|
||||
# we need to use the _plugin_context attribute.
|
||||
self.ovn_client.delete_port(context._plugin_context, port['id'],
|
||||
port_object=port)
|
||||
|
||||
|
||||
class AgentNotifierApi(object):
|
||||
"""Default Agent Notifier class for ovn-db-sync-util.
|
||||
|
||||
This class implements empty methods so that when creating resources in
|
||||
the core plugin, the original ones don't get called and don't interfere
|
||||
with the syncing process.
|
||||
"""
|
||||
def __init__(self, topic):
|
||||
self.topic = topic
|
||||
self.topic_network_delete = topics.get_topic_name(topic,
|
||||
topics.NETWORK,
|
||||
topics.DELETE)
|
||||
self.topic_port_update = topics.get_topic_name(topic,
|
||||
topics.PORT,
|
||||
topics.UPDATE)
|
||||
self.topic_port_delete = topics.get_topic_name(topic,
|
||||
topics.PORT,
|
||||
topics.DELETE)
|
||||
self.topic_network_update = topics.get_topic_name(topic,
|
||||
topics.NETWORK,
|
||||
topics.UPDATE)
|
||||
|
||||
def network_delete(self, context, network_id):
|
||||
pass
|
||||
|
||||
def port_update(self, context, port, network_type, segmentation_id,
|
||||
physical_network):
|
||||
pass
|
||||
|
||||
def port_delete(self, context, port_id):
|
||||
pass
|
||||
|
||||
def network_update(self, context, network):
|
||||
pass
|
||||
|
||||
def security_groups_provider_updated(self, context,
|
||||
devices_to_udpate=None):
|
||||
pass
|
||||
|
||||
|
||||
def setup_conf():
|
||||
conf = cfg.CONF
|
||||
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,
|
||||
'SECURITYGROUP')
|
||||
ovn_group, ovn_opts = ovn_conf.list_opts()[0]
|
||||
cfg.CONF.register_cli_opts(ovn_opts, group=ovn_group)
|
||||
db_group, neutron_db_opts = db_options.list_opts()[0]
|
||||
cfg.CONF.register_cli_opts(neutron_db_opts, db_group)
|
||||
return conf
|
||||
|
||||
|
||||
def main():
|
||||
"""Main method for syncing neutron networks and ports with ovn nb db.
|
||||
|
||||
This script provides a utility for syncing the OVN Northbound Database
|
||||
with the Neutron database.
|
||||
|
||||
This script is used for the migration from ML2/OVS to ML2/OVN.
|
||||
"""
|
||||
conf = setup_conf()
|
||||
|
||||
# if no config file is passed or no configuration options are passed
|
||||
# then load configuration from /etc/neutron/neutron.conf
|
||||
try:
|
||||
conf(project='neutron')
|
||||
except TypeError:
|
||||
LOG.error('Error parsing the configuration values. Please verify.')
|
||||
return
|
||||
|
||||
logging.setup(conf, 'neutron_ovn_db_sync_util')
|
||||
LOG.info('Started Neutron OVN db sync')
|
||||
mode = ovn_conf.get_ovn_neutron_sync_mode()
|
||||
if mode not in [ovn_db_sync.SYNC_MODE_LOG, ovn_db_sync.SYNC_MODE_REPAIR]:
|
||||
LOG.error(
|
||||
'Invalid sync mode : ["%s"]. Should be "log" or "repair"', mode)
|
||||
return
|
||||
|
||||
# Validate and modify core plugin and ML2 mechanism drivers for syncing.
|
||||
if (cfg.CONF.core_plugin.endswith('.Ml2Plugin') or
|
||||
cfg.CONF.core_plugin == 'ml2'):
|
||||
cfg.CONF.core_plugin = (
|
||||
'neutron.cmd.ovn.neutron_ovn_db_sync_util.Ml2Plugin')
|
||||
if not cfg.CONF.ml2.mechanism_drivers:
|
||||
LOG.error('please use --config-file to specify '
|
||||
'neutron and ml2 configuration file.')
|
||||
return
|
||||
if 'ovn' not in cfg.CONF.ml2.mechanism_drivers:
|
||||
LOG.error('No "ovn" mechanism driver found : "%s".',
|
||||
cfg.CONF.ml2.mechanism_drivers)
|
||||
return
|
||||
cfg.CONF.set_override('mechanism_drivers', ['ovn-sync'], 'ml2')
|
||||
conf.service_plugins = [
|
||||
'neutron.services.ovn_l3.plugin.OVNL3RouterPlugin']
|
||||
else:
|
||||
LOG.error('Invalid core plugin : ["%s"].', cfg.CONF.core_plugin)
|
||||
return
|
||||
|
||||
try:
|
||||
conn = impl_idl_ovn.get_connection(impl_idl_ovn.OvsdbNbOvnIdl)
|
||||
ovn_api = impl_idl_ovn.OvsdbNbOvnIdl(conn)
|
||||
except RuntimeError:
|
||||
LOG.error('Invalid --ovn-ovn_nb_connection parameter provided.')
|
||||
return
|
||||
|
||||
try:
|
||||
sb_conn = impl_idl_ovn.get_connection(impl_idl_ovn.OvsdbSbOvnIdl)
|
||||
ovn_sb_api = impl_idl_ovn.OvsdbSbOvnIdl(sb_conn)
|
||||
except RuntimeError:
|
||||
LOG.error('Invalid --ovn-ovn_sb_connection parameter provided.')
|
||||
return
|
||||
|
||||
manager.init()
|
||||
core_plugin = directory.get_plugin()
|
||||
ovn_driver = core_plugin.mechanism_manager.mech_drivers['ovn-sync'].obj
|
||||
ovn_driver._nb_ovn = ovn_api
|
||||
ovn_driver._sb_ovn = ovn_sb_api
|
||||
|
||||
synchronizer = ovn_db_sync.OvnNbSynchronizer(
|
||||
core_plugin, ovn_api, ovn_sb_api, mode, ovn_driver)
|
||||
|
||||
LOG.info('Sync for Northbound db started with mode : %s', mode)
|
||||
synchronizer.do_sync()
|
||||
LOG.info('Sync completed for Northbound db')
|
||||
|
||||
sb_synchronizer = ovn_db_sync.OvnSbSynchronizer(
|
||||
core_plugin, ovn_sb_api, ovn_driver)
|
||||
|
||||
LOG.info('Sync for Southbound db started with mode : %s', mode)
|
||||
sb_synchronizer.do_sync()
|
||||
LOG.info('Sync completed for Southbound db')
|
@ -55,6 +55,8 @@ console_scripts =
|
||||
neutron-sanity-check = neutron.cmd.sanity_check:main
|
||||
neutron-status = neutron.cmd.status:main
|
||||
neutron-ovn-metadata-agent = neutron.cmd.eventlet.agents.ovn_metadata:main
|
||||
neutron-ovn-migration-mtu = neutron.cmd.ovn.migration_mtu:main
|
||||
neutron-ovn-db-sync-util = neutron.cmd.ovn.neutron_ovn_db_sync_util:main
|
||||
neutron.core_plugins =
|
||||
ml2 = neutron.plugins.ml2.plugin:Ml2Plugin
|
||||
neutron.service_plugins =
|
||||
@ -94,6 +96,7 @@ neutron.ml2.mechanism_drivers =
|
||||
l2population = neutron.plugins.ml2.drivers.l2pop.mech_driver:L2populationMechanismDriver
|
||||
sriovnicswitch = neutron.plugins.ml2.drivers.mech_sriov.mech_driver.mech_driver:SriovNicSwitchMechanismDriver
|
||||
ovn = neutron.plugins.ml2.drivers.ovn.mech_driver.mech_driver:OVNMechanismDriver
|
||||
ovn-sync = neutron.cmd.ovn.neutron_ovn_db_sync_util:OVNMechanismDriver
|
||||
fake_agent = neutron.tests.unit.plugins.ml2.drivers.mech_fake_agent:FakeAgentMechanismDriver
|
||||
fake_agent_l3 = neutron.tests.unit.plugins.ml2.drivers.mech_fake_agent:FakeAgentMechanismDriverL3
|
||||
another_fake_agent = neutron.tests.unit.plugins.ml2.drivers.mech_fake_agent:AnotherFakeAgentMechanismDriver
|
||||
|
Loading…
Reference in New Issue
Block a user