--- a/components/openstack/neutron/files/evs/migrate/evs-neutron-migration.py Wed Sep 07 14:48:41 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,432 +0,0 @@
-#!/usr/bin/python2.7
-#
-# Copyright (c) 2015, Oracle and/or its affiliates. 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.
-
-#
-# This script migrates the network, subnet and port information from EVS DB to
-# neutron-server DB. It also re-creates routers and floatingips tables with
-# Neutron's l3 schema. This script needs to be run for the proper upgrade of
-# Neutron from Havana to Juno release.
-#
-
-import ConfigParser
-import time
-
-from oslo.config import cfg
-from oslo.db import exception as excp
-from oslo.db import options as db_options
-import rad.bindings.com.oracle.solaris.rad.evscntl as evsc
-import rad.connect as radcon
-import sqlalchemy as sa
-from sqlalchemy import MetaData, sql
-from sqlalchemy.orm import sessionmaker
-from sqlalchemy.schema import DropConstraint
-
-from neutron import context as ctx
-from neutron.db import common_db_mixin, model_base
-from neutron.plugins.evs.migrate import havana_api
-
-
-def create_db_network(nw, engine, ext_ro):
- ''' Method for creating networks table in the neutron-server DB
- Input params:
- @nw - Dictionary with values from EVS DB
- @engine - SQL engine
- @ext_ro - External router
- '''
- # Importing locally because these modules end up importing neutron.wsgi
- # which causes RAD to hang
- from neutron.db import db_base_plugin_v2
- from neutron.db import external_net_db as ext_net
- model_base.BASEV2.metadata.bind = engine
- for _none in range(60):
- try:
- model_base.BASEV2.metadata.create_all(engine)
- break
- except sa.exc.OperationalError as err:
- # mysql is not ready. sleep for 2 more seconds
- time.sleep(2)
- else:
- print "Unable to connect to MySQL: %s" % err
- print ("Please verify MySQL is properly configured and online "
- "before using svcadm(1M) to clear this service.")
- raise RuntimeError
- ctxt = ctx.get_admin_context()
- inst = db_base_plugin_v2.NeutronDbPluginV2()
- dup = False
- try:
- db_base_plugin_v2.NeutronDbPluginV2.create_network(inst, ctxt, nw)
- print "\nnetwork=%s added" % nw['network']['name']
- if ext_ro:
- ext_nw = ext_net.ExternalNetwork(network_id=nw['network']['id'])
- session = sessionmaker()
- session.configure(bind=engine)
- s = session()
- s.add(ext_nw)
- s.commit()
- except excp.DBDuplicateEntry:
- print "\nnetwork '%s' already exists" % nw['network']['name']
- dup = True
- return dup
-
-
-def create_db_subnet(sub):
- ''' Method for creating subnets table in the neutron-server DB
- Input params:
- @sub - Dictionary with values from EVS DB
- '''
- # Importing locally because this module ends up importing neutron.wsgi
- # which causes RAD to hang
- from neutron.db import db_base_plugin_v2
- ctxt = ctx.get_admin_context()
- inst = db_base_plugin_v2.NeutronDbPluginV2()
- try:
- db_base_plugin_v2.NeutronDbPluginV2.create_subnet(inst, ctxt, sub)
- print "\nsubnet=%s added" % sub['subnet']['id']
- except excp.DBDuplicateEntry:
- print "\nsubnet '%s' already exists" % sub['subnet']['id']
-
-
-def create_db_port(port):
- ''' Method for creating ports table in the neutron-server DB
- Input params:
- @port - Dictionary with values from EVS DB
- '''
- # Importing locally because this module ends up importing neutron.wsgi
- # which causes RAD to hang
- from neutron.db import db_base_plugin_v2
- ctxt = ctx.get_admin_context()
- inst = db_base_plugin_v2.NeutronDbPluginV2()
- try:
- db_base_plugin_v2.NeutronDbPluginV2.create_port(inst, ctxt, port)
- print "\nport=%s added" % port['port']['id']
- except excp.DBDuplicateEntry:
- print "\nport '%s' already exists" % port['port']['id']
-
-
-def main():
- print "Start Migration."
-
- # Connect to EVS controller
- config = ConfigParser.RawConfigParser()
- config.readfp(open("/etc/neutron/plugins/evs/evs_plugin.ini"))
- if config.has_option("EVS", 'evs_controller'):
- config_suh = config.get("EVS", 'evs_controller')
- else:
- config_suh = 'ssh://evsuser@localhost'
- suh = config_suh.split('://')
- if len(suh) != 2 or suh[0] != 'ssh' or not suh[1].strip():
- raise SystemExit(_("Specified evs_controller is invalid"))
- uh = suh[1].split('@')
- if len(uh) != 2 or not uh[0].strip() or not uh[1].strip():
- raise SystemExit(_("'user' and 'hostname' need to be specified "
- "for evs_controller"))
- try:
- rc = radcon.connect_ssh(uh[1], user=uh[0])
- except:
- raise SystemExit(_("Cannot connect to EVS Controller"))
- try:
- evs_contr = rc.get_object(evsc.EVSController())
- except:
- raise SystemExit(_("Could not retrieve EVS info from EVS Controller"))
-
- config.readfp(open("/etc/neutron/neutron.conf"))
- if config.has_option("database", 'connection'):
- SQL_CONNECTION = config.get("database", 'connection')
- else:
- SQL_CONNECTION = 'sqlite:////var/lib/neutron/neutron.sqlite'
-
- conf = cfg.CONF
- db_options.set_defaults(cfg.CONF,
- connection=SQL_CONNECTION,
- sqlite_db='', max_pool_size=10,
- max_overflow=20, pool_timeout=10)
-
- neutron_engine = sa.create_engine(SQL_CONNECTION)
- router_port_ids = {}
-
- evsinfo = evs_contr.getEVSInfo()
- for e in evsinfo:
- ext_ro = False
- for p in e.props:
- if p.name == 'OpenStack:router:external' and p.value == 'True':
- ext_ro = True
- # Populate networks table
- n = {
- 'tenant_id': e.tenantname,
- 'id': e.uuid,
- 'name': e.name,
- 'status': 'ACTIVE',
- 'admin_state_up': True,
- 'shared': False
- }
- nw = {'network': n}
- dup = create_db_network(nw, neutron_engine, ext_ro)
- if dup:
- continue # No need to iterate over subnets and ports
-
- # Populate subnets table
- if not e.ipnets:
- continue
- for i in e.ipnets:
- cidr = None
- gateway_ip = None
- enable_dhcp = None
- dns = []
- host = []
- start = []
- for p in i.props:
- if p.name == 'subnet':
- cidr = p.value
- elif p.name == 'defrouter':
- gateway_ip = p.value
- elif p.name == 'OpenStack:enable_dhcp':
- enable_dhcp = p.value == 'True'
- elif p.name == 'OpenStack:dns_nameservers':
- dns = p.value.split(',')
- elif p.name == 'OpenStack:host_routes':
- hh = p.value.split(',')
- for h in range(0, len(hh), 2):
- d = {hh[h]: hh[h+1]}
- host.append(d)
- elif p.name == 'pool':
- ss = p.value.split(',')
- for s in ss:
- if '-' in s:
- d = {'start': s.split('-')[0],
- 'end': s.split('-')[1]}
- start.append(d)
- else:
- d = {'start': s, 'end': s}
- start.append(d)
- ip_version = 4 if i.ipvers == evsc.IPVersion.IPV4 else 6
-
- if i.name.startswith(i.uuid[:8]):
- # Skip autogenerated names
- name = None
- else:
- name = i.name
- s = {
- 'tenant_id': i.tenantname,
- 'id': i.uuid,
- 'name': name,
- 'network_id': e.uuid,
- 'ip_version': ip_version,
- 'cidr': cidr,
- 'gateway_ip': gateway_ip,
- 'enable_dhcp': enable_dhcp,
- 'shared': False,
- 'allocation_pools': start,
- 'dns_nameservers': dns,
- 'host_routes': host
- }
-
- sub = {'subnet': s}
- create_db_subnet(sub)
-
- # Populate ports table
- if not e.vports:
- continue
- for j in e.vports:
- device_owner = ''
- device_id = ''
- mac_address = None
- ipaddr = None
- for v in j.props:
- if v.name == 'OpenStack:device_owner':
- device_owner = v.value
- if v.value in ('network:router_interface',
- 'network:router_gateway'):
- router_port_ids[j.uuid] = v.value
- elif v.name == 'OpenStack:device_id':
- device_id = v.value
- elif v.name == 'macaddr':
- mac_address = v.value
- elif v.name == 'ipaddr':
- ipaddr = v.value.split('/')[0]
- if j.name.startswith(j.uuid[:8]):
- # Skip autogenerated names
- name = None
- else:
- name = j.name
-
- p = {
- 'tenant_id': j.tenantname,
- 'id': j.uuid,
- 'name': name,
- 'network_id': e.uuid,
- 'mac_address': mac_address,
- 'admin_state_up': True,
- 'status': 'ACTIVE',
- 'device_id': device_id,
- 'device_owner': device_owner,
- 'fixed_ips': [{'subnet_id': e.ipnets[0].uuid,
- 'ip_address': ipaddr}]
- }
- port = {'port': p}
- create_db_port(port)
-
- # Change the schema of the floatingips and routers tables by doing
- # the following:
- # Fetch the floatingip, router entry using EVS API,
- # Temporarily store the information,
- # Delete floatingip, router entry,
- # Remove floatingip, router as a constraint from existing tables,
- # Drop the routers, floatingips table,
- # Add router, floatingip entry using Neutron API
-
- # Importing locally because this module ends up importing neutron.wsgi
- # which causes RAD to hang
- from neutron.db import l3_db
- havana_api.configure_db()
- session = havana_api.get_session()
-
- # Fetch the floatingip entry using EVS API
- query = session.query(havana_api.FloatingIP)
- floatingips = query.all()
- fl = []
- if floatingips:
- for f in floatingips:
- fi = {
- 'id': f['id'],
- 'floating_ip_address': f['floating_ip_address'],
- 'floating_network_id': f['floating_network_id'],
- 'floating_port_id': f['floating_port_id'],
- 'fixed_port_id': f['fixed_port_id'],
- 'fixed_ip_address': f['fixed_ip_address'],
- 'tenant_id': f['tenant_id'],
- 'router_id': f['router_id'],
- }
- fl.append(fi)
-
- # Delete floatingip entry
- ctxt = ctx.get_admin_context()
- ctxt = havana_api.get_evs_context(ctxt)
- with ctxt.session.begin(subtransactions=True):
- cm_db_inst = common_db_mixin.CommonDbMixin()
- query = common_db_mixin.CommonDbMixin._model_query(cm_db_inst,
- ctxt,
- havana_api.
- FloatingIP)
- for fip in query:
- ctxt.session.delete(fip)
-
- # Fetch the router entry using EVS API
- query = session.query(havana_api.Router)
- routers = []
- try:
- routers = query.all()
- except sa.exc.OperationalError:
- pass
- if routers:
- for r in routers:
- router_id = r['id']
- rt = {
- 'tenant_id': r['tenant_id'],
- 'id': r['id'],
- 'name': r['name'],
- 'admin_state_up': r['admin_state_up'],
- 'gw_port_id': r['gw_port_id'],
- 'status': 'ACTIVE'
- }
-
- # Delete router entry
- ctxt = ctx.get_admin_context()
- ctxt = havana_api.get_evs_context(ctxt)
- with ctxt.session.begin(subtransactions=True):
- cm_db_inst = common_db_mixin.CommonDbMixin()
- query = common_db_mixin.CommonDbMixin._model_query(cm_db_inst,
- ctxt,
- havana_api.
- Router)
- router = query.filter(havana_api.Router.id == router_id).one()
- ctxt.session.delete(router)
-
- engine = sa.create_engine(SQL_CONNECTION)
- meta = MetaData()
- conn = engine.connect()
- trans = conn.begin()
- meta.reflect(engine)
-
- # Remove router as a constraint from existing tables,
- # Drop the routers table to remove old schema
- for t in meta.tables.values():
- for fk in t.foreign_keys:
- if fk.column.table.name == "routers":
- if fk.constraint.name:
- engine.execute(DropConstraint(fk.constraint))
- for t in meta.tables.values():
- if t.name == "routers":
- t.drop(bind=conn)
-
- # Remove floatingip as a constraint from existing tables,
- # Drop the floatingip table to remove old schema
- for t in meta.tables.values():
- for fk in t.foreign_keys:
- if fk.column.table.name == "floatingips":
- if fk.constraint.name:
- engine.execute(DropConstraint(fk.constraint))
- for t in meta.tables.values():
- if t.name == "floatingips":
- t.drop(bind=conn)
- conn.close()
-
- # Add the routers and floatingips using the schema in l3_db.py
-
- setattr(l3_db.Router, 'enable_snat', sa.Column(sa.Boolean,
- default=True, server_default=sql.true(), nullable=False))
- neutron_engine = sa.create_engine(SQL_CONNECTION)
- model_base.BASEV2.metadata.bind = neutron_engine
- model_base.BASEV2.metadata.create_all(neutron_engine)
- if routers:
- ctxt = ctx.get_admin_context()
- with ctxt.session.begin(subtransactions=True):
- router_db = l3_db.Router(id=router_id,
- tenant_id=r['tenant_id'],
- name=rt['name'],
- admin_state_up=rt['admin_state_up'],
- gw_port_id=rt['gw_port_id'],
- status="ACTIVE")
- ctxt.session.add(router_db)
- print "\nrouter=%s updated" % rt['name']
- with ctxt.session.begin(subtransactions=True):
- for i, j in router_port_ids.iteritems():
- router_port = l3_db.RouterPort(
- port_id=i,
- router_id=router_id,
- port_type=j)
- ctxt.session.add(router_port)
-
- if floatingips:
- ctxt = ctx.get_admin_context()
- with ctxt.session.begin(subtransactions=True):
- for i in fl:
- fl_db = l3_db.FloatingIP(
- id=i['id'],
- floating_ip_address=i['floating_ip_address'],
- floating_network_id=i['floating_network_id'],
- floating_port_id=i['floating_port_id'],
- fixed_port_id=i['fixed_port_id'],
- fixed_ip_address=i['fixed_ip_address'],
- router_id=i['router_id'],
- tenant_id=i['tenant_id'])
- ctxt.session.add(fl_db)
- print "\nfloatingip=%s updated" % i['floating_ip_address']
-
- print "\nEnd Migration."
-
-
-if __name__ == '__main__':
- main()