NFP DB changes to support gateway sharing

Added migration script and db utility method.
Added a column in 'gateway_port' in network_function_device table.

Change-Id: Ieb3325445e41a9620d4b918d7151c4bc6cb4a0d9
Closes-Bug: 1651303
This commit is contained in:
Vikash082 2016-12-12 10:41:49 +05:30 committed by Yogesh Rajmane
parent 749696f5f0
commit 88ae34dc73
5 changed files with 216 additions and 4 deletions

View File

@ -0,0 +1,56 @@
# 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.
#
"""nfp gateway db
Revision ID: 3e1f67cf951b
Revises: ce662ded3ba5
Create Date: 2016-11-28 04:07:43.928878
"""
# revision identifiers, used by Alembic.
revision = '3e1f67cf951b'
down_revision = 'ce662ded3ba5'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table('nfp_service_gateway_info',
sa.Column('id', sa.String(length=36), nullable=False),
sa.Column('network_function_id', sa.String(length=36),
nullable=False),
sa.Column('gateway_ptg', sa.String(length=36),
nullable=False),
sa.Column('primary_instance_gw_pt', sa.String(length=36),
nullable=False),
sa.Column('secondary_instance_gw_pt', sa.String(length=36),
nullable=True),
sa.Column('primary_gw_vip_pt', sa.String(length=36),
nullable=True),
sa.Column('secondary_gw_vip_pt', sa.String(length=36),
nullable=True),
sa.ForeignKeyConstraint(['network_function_id'],
['nfp_network_functions.id'],
ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id', 'network_function_id')
)
op.add_column('nfp_network_function_devices', sa.Column('gateway_port',
sa.String(length=36), nullable=True))
def downgrade():
pass

View File

@ -1 +1 @@
ce662ded3ba5
3e1f67cf951b

View File

@ -13,7 +13,6 @@
import copy
import fixtures
from neutron import context
from neutron.db import api as db_api
from neutron.tests import base
@ -22,6 +21,8 @@ from gbpservice.nfp.common import constants as nfp_constants
from gbpservice.nfp.common import exceptions as nfp_exc
from gbpservice.nfp.orchestrator.db import nfp_db
from gbpservice.nfp.orchestrator.db import nfp_db_model
from sqlalchemy.orm import exc
import uuid
class SqlFixture(fixtures.Fixture):
@ -389,6 +390,7 @@ class NFPDBTestCase(SqlTestCase):
}
network_function_device = self.nfp_db.create_network_function_device(
self.session, attrs)
self.assertIn('gateway_port', network_function_device)
for key in attrs:
if (key == 'mgmt_port_id') or (key == 'monitoring_port_id'):
self.assertEqual(attrs[key]['id'],
@ -693,3 +695,58 @@ class NFPDBTestCase(SqlTestCase):
self.nfp_db.get_network_function_device_interface,
self.session,
network_function_device_interface['id'])
def _get_gateway_details(self):
return dict(
id=str(uuid.uuid4()),
network_function_id=self.create_network_function()['id'],
gw_ptg=str(uuid.uuid4()),
primary_instance_gw_pt=str(uuid.uuid4()),
secondary_instance_gw_pt=str(uuid.uuid4()),
gateway_vips=[dict(id=str(uuid.uuid4()))]
)
def test_add_service_gateway_details(self):
gateway_details = self._get_gateway_details()
gateway = self.nfp_db.add_service_gateway_details(
self.session, gateway_details)
self.assertIsNotNone(gateway['id'])
self.nfp_db.delete_network_function(
self.session, gateway_details['network_function_id'])
gateway_details.update(
network_function_id=self.create_network_function()['id'],
gateway_vips=dict(primary_gw_vip_pt=str(uuid.uuid4()),
secondary_gw_vip_pt=str(uuid.uuid4())))
gateway = self.nfp_db.add_service_gateway_details(
self.session, gateway_details)
self.assertIsNotNone(gateway['id'])
def test_get_gateway_detail(self):
gateway_details = self._get_gateway_details()
gateway = self.nfp_db.add_service_gateway_details(
self.session, gateway_details)
self.assertIsNotNone(gateway['id'])
_gateway = self.nfp_db.get_gateway_detail(
self.session, gateway_details['network_function_id'])
self.assertEqual((gateway['id'], gateway['network_function_id']),
(_gateway['id'], _gateway['network_function_id']))
def test_get_providers_for_gateway(self):
gateway_details = self._get_gateway_details()
gateway = self.nfp_db.add_service_gateway_details(
self.session, gateway_details)
self.assertIsNotNone(gateway['id'])
_gateway = self.nfp_db.get_providers_for_gateway(
self.session, gateway_details['gw_ptg'])[0]
self.assertEqual((gateway['id'], gateway['network_function_id']),
(_gateway['id'], _gateway['network_function_id']))
def test_delete_gateway(self):
gateway_details = self._get_gateway_details()
gateway = self.nfp_db.add_service_gateway_details(
self.session, gateway_details)
self.assertIsNotNone(gateway['id'])
self.nfp_db.delete_network_function(self.session, gateway_details[
'network_function_id'])
self.assertRaises(exc.NoResultFound, self.nfp_db.get_gateway_detail,
self.session, gateway_details['network_function_id'])

View File

@ -20,6 +20,8 @@ from gbpservice.nfp.orchestrator.db import common_db_mixin
from gbpservice.nfp.orchestrator.db import nfp_db_model
from gbpservice.nfp.core import log as nfp_logging
from neutron._i18n import _LW
LOG = nfp_logging.getLogger(__name__)
@ -288,7 +290,8 @@ class NFPDbBase(common_db_mixin.CommonDbMixin):
max_interfaces=network_function_device['max_interfaces'],
reference_count=network_function_device['reference_count'],
interfaces_in_use=network_function_device['interfaces_in_use'],
status=network_function_device['status'])
status=network_function_device['status'],
gateway_port=network_function_device.get('gateway_port'))
session.add(network_function_device_db)
self._set_mgmt_port_for_nfd(
session, network_function_device_db, network_function_device)
@ -635,7 +638,8 @@ class NFPDbBase(common_db_mixin.CommonDbMixin):
'max_interfaces': nfd['max_interfaces'],
'reference_count': nfd['reference_count'],
'interfaces_in_use': nfd['interfaces_in_use'],
'status': nfd['status']
'status': nfd['status'],
'gateway_port': nfd.get('gateway_port')
}
if nfd.get('provider_metadata'):
res.update({'provider_metadata': nfd['provider_metadata']})
@ -710,3 +714,85 @@ class NFPDbBase(common_db_mixin.CommonDbMixin):
'multicast_ip': cluster_info['multicast_ip'],
'cluster_name': cluster_info['cluster_name']
}
def add_service_gateway_details(self, session, service_gw_details):
primary_gw_vip_pt, secondary_gw_vip_pt = self._get_vip_pt_ids(
service_gw_details.get('gateway_vips'))
if isinstance(service_gw_details['primary_instance_gw_pt'], dict):
primary_instance_gw_pt = service_gw_details[
'primary_instance_gw_pt']['id']
secondary_instance_gw_pt = service_gw_details.get(
'secondary_instance_gw_pt', {}).get('id')
else:
primary_instance_gw_pt = service_gw_details[
'primary_instance_gw_pt']
secondary_instance_gw_pt = service_gw_details.get(
'secondary_instance_gw_pt')
with session.begin(subtransactions=True):
gw_detail = nfp_db_model.ServiceGatewayDetails(
id=service_gw_details['id'],
network_function_id=service_gw_details[
'network_function_id'],
gateway_ptg=service_gw_details['gw_ptg'],
primary_instance_gw_pt=primary_instance_gw_pt,
secondary_instance_gw_pt=secondary_instance_gw_pt,
primary_gw_vip_pt=primary_gw_vip_pt,
secondary_gw_vip_pt=secondary_gw_vip_pt
)
session.add(gw_detail)
return gw_detail
def _get_vip_pt_ids(self, vips):
if not vips:
return None, None
else:
if isinstance(vips, list):
primary_gw_vip_pt = vips[0]['id']
secondary_gw_vip_pt = vips[1]['id'] if len(vips) == 2 else None
return primary_gw_vip_pt, secondary_gw_vip_pt
elif isinstance(vips, dict):
return vips['primary_gw_vip_pt'], vips['secondary_gw_vip_pt']
else:
return None, None
def get_providers_for_gateway(self, session, _id):
svc_gw = nfp_db_model.ServiceGatewayDetails
try:
with session.begin(subtransactions=True):
return self._get_gw_info_dict(session.query(svc_gw).filter(
svc_gw.gateway_ptg == _id).all())
except exc.NoResultFound:
raise
def get_gateway_detail(self, session, nf_id):
svc_gw = nfp_db_model.ServiceGatewayDetails
try:
with session.begin(subtransactions=True):
return self._get_gw_info_dict(session.query(svc_gw).filter(
svc_gw.network_function_id == nf_id).one())
except exc.NoResultFound:
LOG.warning(_LW("Gateway detail doesn't exist for Network Function"
" %s ") % nf_id)
raise
def _get_gw_info_dict(self, gw):
if not gw:
return
if isinstance(gw, list):
return [dict(id=info['id'],
network_function_id=info['network_function_id'],
gateway_ptg=info['gateway_ptg'],
primary_instance_gw_pt=info['primary_instance_gw_pt'],
secondary_instance_gw_pt=info[
'secondary_instance_gw_pt'],
primary_gw_vip_pt=info['primary_gw_vip_pt'],
secondary_gw_vip_pt=info['secondary_gw_vip_pt']
) for info in gw]
return {'id': gw['id'],
'network_function_id': gw['network_function_id'],
'gateway_ptg': gw['gateway_ptg'],
'primary_instance_gw_pt': gw['primary_instance_gw_pt'],
'secondary_instance_gw_pt': gw['secondary_instance_gw_pt'],
'primary_gw_vip_pt': gw['primary_gw_vip_pt'],
'secondary_gw_vip_pt': gw['secondary_gw_vip_pt']}

View File

@ -142,6 +142,7 @@ class NetworkFunctionDevice(BASE, model_base.HasId, model_base.HasTenant,
reference_count = sa.Column(sa.Integer(), nullable=False)
interfaces_in_use = sa.Column(sa.Integer(), nullable=False)
provider_metadata = sa.Column(sa.String(1024), nullable=True)
gateway_port = sa.Column(sa.String(36), nullable=True)
class NetworkFunctionDeviceInterface(BASE, model_base.HasId,
@ -173,3 +174,15 @@ class ClusterInfo(BASE, model_base.HasId, model_base.HasTenant):
virtual_ip = sa.Column(sa.String(36), nullable=True)
multicast_ip = sa.Column(sa.String(36), nullable=True)
cluster_name = sa.Column(sa.String(36), nullable=True)
class ServiceGatewayDetails(BASE, model_base.HasId):
__tablename__ = 'nfp_service_gateway_info'
network_function_id = sa.Column(sa.String(36), sa.ForeignKey(
'nfp_network_functions.id', ondelete='CASCADE'), nullable=False,
primary_key=True)
gateway_ptg = sa.Column(sa.String(36), nullable=False)
primary_instance_gw_pt = sa.Column(sa.String(36), nullable=True)
secondary_instance_gw_pt = sa.Column(sa.String(36), nullable=True)
primary_gw_vip_pt = sa.Column(sa.String(36), nullable=True)
secondary_gw_vip_pt = sa.Column(sa.String(36), nullable=True)