NFP - DB Framework and DB Model Implementation
This patch adds the DB Model implementation for NFP Orchestrator
process. This DB layer framework is going to be consumed by NFP
Orchestrator process which will be introduced in a subsequent
patch.
Change-Id: Ib249dfc9c1e5c10736d87781fcfadc5a930e2cc8
Implements: blueprint gbp-network-services-framework
Co-Authored-By: Akash Deep <akash.deep@oneconvergence.com>
Co-Authored-By: ashutosh mishra <mca.ashu4@gmail.com>
(cherry picked from commit b0f4ecf9d6)
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
# 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_db
|
||||
Revision ID: 54ee8e8d205a
|
||||
Revises: 98862f2d814e
|
||||
"""
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '54ee8e8d205a'
|
||||
down_revision = '98862f2d814e'
|
||||
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
from gbpservice.nfp.common import constants as nfp_constants
|
||||
|
||||
|
||||
def upgrade():
|
||||
|
||||
op.create_table(
|
||||
'nfp_port_infos',
|
||||
sa.Column('tenant_id', sa.String(length=255), nullable=True),
|
||||
sa.Column('id', sa.String(length=36), nullable=False),
|
||||
sa.Column('port_model',
|
||||
sa.Enum(nfp_constants.NEUTRON_PORT,
|
||||
nfp_constants.GBP_PORT,
|
||||
name='port_model'),
|
||||
nullable=False),
|
||||
sa.Column('port_classification',
|
||||
sa.Enum(nfp_constants.PROVIDER,
|
||||
nfp_constants.CONSUMER,
|
||||
nfp_constants.MANAGEMENT,
|
||||
nfp_constants.MONITOR,
|
||||
name='port_classification'),
|
||||
nullable=False),
|
||||
sa.Column('port_role',
|
||||
sa.Enum(nfp_constants.ACTIVE_PORT,
|
||||
nfp_constants.STANDBY_PORT,
|
||||
nfp_constants.MASTER_PORT,
|
||||
name='port_role'),
|
||||
nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'nfp_network_infos',
|
||||
sa.Column('tenant_id', sa.String(length=255), nullable=True),
|
||||
sa.Column('id', sa.String(length=36), nullable=False),
|
||||
sa.Column('network_model',
|
||||
sa.Enum(nfp_constants.NEUTRON_NETWORK,
|
||||
nfp_constants.GBP_NETWORK,
|
||||
name='network_model'),
|
||||
nullable=False),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'nfp_network_functions',
|
||||
sa.Column('tenant_id', sa.String(length=255), nullable=True),
|
||||
sa.Column('id', sa.String(length=36), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=True),
|
||||
sa.Column('description', sa.String(length=1024), nullable=True),
|
||||
sa.Column('status', sa.String(length=50), nullable=True),
|
||||
sa.Column('status_description', sa.String(length=4096), nullable=True),
|
||||
sa.Column('service_id', sa.String(length=36), nullable=False),
|
||||
sa.Column('service_chain_id', sa.String(length=36), nullable=False),
|
||||
sa.Column('service_profile_id', sa.String(length=36), nullable=True),
|
||||
sa.Column('service_config', sa.TEXT(), nullable=True),
|
||||
sa.Column('heat_stack_id', sa.String(length=36), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'nfp_network_function_devices',
|
||||
sa.Column('tenant_id', sa.String(length=255), nullable=True),
|
||||
sa.Column('id', sa.String(length=36), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=True),
|
||||
sa.Column('description', sa.String(length=255), nullable=True),
|
||||
sa.Column('status', sa.String(length=50), nullable=True),
|
||||
sa.Column('status_description', sa.String(length=4096), nullable=True),
|
||||
sa.Column('mgmt_ip_address', sa.String(length=36), nullable=True),
|
||||
sa.Column('mgmt_port_id',
|
||||
sa.String(length=36),
|
||||
nullable=True),
|
||||
sa.Column('monitoring_port_id',
|
||||
sa.String(length=36),
|
||||
nullable=True),
|
||||
sa.Column('monitoring_port_network',
|
||||
sa.String(length=36),
|
||||
nullable=True),
|
||||
sa.Column('service_vendor', sa.String(length=36), nullable=True),
|
||||
sa.Column('max_interfaces', sa.Integer(), nullable=True),
|
||||
sa.Column('reference_count', sa.Integer(), nullable=True),
|
||||
sa.Column('interfaces_in_use', sa.Integer(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['mgmt_port_id'],
|
||||
['nfp_port_infos.id'],
|
||||
ondelete='SET NULL',
|
||||
name='nfp_nfd_mgmt_fk_port_info'),
|
||||
sa.ForeignKeyConstraint(['monitoring_port_network'],
|
||||
['nfp_network_infos.id'],
|
||||
ondelete='SET NULL',
|
||||
name='nfp_nfd_fk_net_info'),
|
||||
sa.ForeignKeyConstraint(['monitoring_port_id'],
|
||||
['nfp_port_infos.id'],
|
||||
ondelete='SET NULL',
|
||||
name='nfp_nfd_mon_fk_port_info'),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'nfp_network_function_instances',
|
||||
sa.Column('tenant_id', sa.String(length=255), nullable=True),
|
||||
sa.Column('id', sa.String(length=36), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=True),
|
||||
sa.Column('description', sa.String(length=255), nullable=True),
|
||||
sa.Column('status', sa.String(length=50), nullable=True),
|
||||
sa.Column('status_description', sa.String(length=4096), nullable=True),
|
||||
sa.Column('ha_state', sa.String(length=50), nullable=True),
|
||||
sa.Column('network_function_id', sa.String(length=36), nullable=True),
|
||||
sa.Column('network_function_device_id',
|
||||
sa.String(length=36),
|
||||
nullable=True),
|
||||
sa.ForeignKeyConstraint(['network_function_device_id'],
|
||||
['nfp_network_function_devices.id'],
|
||||
ondelete='SET NULL',
|
||||
name='nfp_nfi_fk_nfd'),
|
||||
sa.ForeignKeyConstraint(['network_function_id'],
|
||||
['nfp_network_functions.id'],
|
||||
ondelete='SET NULL',
|
||||
name='nfp_nfi_fk_nf'),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'nfp_nfi_dataport_associations',
|
||||
sa.Column('network_function_instance_id',
|
||||
sa.String(length=36),
|
||||
nullable=True),
|
||||
sa.Column('data_port_id', sa.String(length=36), nullable=False),
|
||||
sa.ForeignKeyConstraint(['network_function_instance_id'],
|
||||
['nfp_network_function_instances.id'],
|
||||
name='nfp_nfi_dp_assoc_fk_nfi'),
|
||||
sa.ForeignKeyConstraint(['data_port_id'], ['nfp_port_infos.id'],
|
||||
ondelete='CASCADE',
|
||||
name='nfp_nfi_dp_assoc_fk_port_info'),
|
||||
sa.PrimaryKeyConstraint('network_function_instance_id', 'data_port_id')
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
pass
|
||||
@@ -1 +1 @@
|
||||
98862f2d814e
|
||||
54ee8e8d205a
|
||||
|
||||
563
gbpservice/neutron/tests/unit/nfp/orchestrator/db/test_nfp_db.py
Normal file
563
gbpservice/neutron/tests/unit/nfp/orchestrator/db/test_nfp_db.py
Normal file
@@ -0,0 +1,563 @@
|
||||
# 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
|
||||
import fixtures
|
||||
|
||||
from neutron import context
|
||||
from neutron.db import api as db_api
|
||||
from neutron.tests import base
|
||||
|
||||
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
|
||||
|
||||
|
||||
class SqlFixture(fixtures.Fixture):
|
||||
|
||||
# flag to indicate that the models have been loaded
|
||||
_TABLES_ESTABLISHED = False
|
||||
|
||||
def _setUp(self):
|
||||
# Register all data models
|
||||
engine = db_api.get_engine()
|
||||
if not SqlFixture._TABLES_ESTABLISHED:
|
||||
nfp_db_model.BASE.metadata.create_all(engine)
|
||||
SqlFixture._TABLES_ESTABLISHED = True
|
||||
|
||||
def clear_tables():
|
||||
with engine.begin() as conn:
|
||||
for table in reversed(
|
||||
nfp_db_model.BASE.metadata.sorted_tables):
|
||||
conn.execute(table.delete())
|
||||
|
||||
self.addCleanup(clear_tables)
|
||||
|
||||
|
||||
class SqlTestCaseLight(base.DietTestCase):
|
||||
"""All SQL taste, zero plugin/rpc sugar"""
|
||||
|
||||
def setUp(self):
|
||||
super(SqlTestCaseLight, self).setUp()
|
||||
self.useFixture(SqlFixture())
|
||||
|
||||
|
||||
class SqlTestCase(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(SqlTestCase, self).setUp()
|
||||
self.useFixture(SqlFixture())
|
||||
|
||||
|
||||
class NFPDB(nfp_db.NFPDbBase):
|
||||
pass
|
||||
|
||||
|
||||
class NFPDBTestCase(SqlTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(NFPDBTestCase, self).setUp()
|
||||
self.ctx = context.get_admin_context()
|
||||
self.nfp_db = NFPDB()
|
||||
self.session = db_api.get_session()
|
||||
|
||||
def create_network_function(self, attributes=None):
|
||||
if attributes is None:
|
||||
attributes = {
|
||||
'name': 'name',
|
||||
'description': 'description',
|
||||
'tenant_id': 'tenant_id',
|
||||
'service_id': 'service_id',
|
||||
'service_chain_id': 'service_chain_id',
|
||||
'service_profile_id': 'service_profile_id',
|
||||
'service_config': 'service_config',
|
||||
'heat_stack_id': 'heat_stack_id',
|
||||
'status': 'status'
|
||||
}
|
||||
return self.nfp_db.create_network_function(self.session, attributes)
|
||||
|
||||
def test_create_network_function(self):
|
||||
attrs = {
|
||||
'name': 'name',
|
||||
'description': 'description',
|
||||
'tenant_id': 'tenant_id',
|
||||
'service_id': 'service_id',
|
||||
'service_chain_id': 'service_chain_id',
|
||||
'service_profile_id': 'service_profile_id',
|
||||
'service_config': 'service_config',
|
||||
'heat_stack_id': 'heat_stack_id',
|
||||
'status': 'status'
|
||||
}
|
||||
|
||||
network_function = self.create_network_function(attrs)
|
||||
for key in attrs:
|
||||
self.assertEqual(attrs[key], network_function[key])
|
||||
self.assertIsNotNone(network_function['id'])
|
||||
|
||||
def test_create_network_function_with_mandatory_values(self):
|
||||
attrs_mandatory = {
|
||||
'name': 'name',
|
||||
'tenant_id': 'tenant_id',
|
||||
'service_id': 'service_id',
|
||||
'service_profile_id': 'service_profile_id',
|
||||
'status': 'status'
|
||||
}
|
||||
network_function = self.create_network_function(attrs_mandatory)
|
||||
for key in attrs_mandatory:
|
||||
self.assertEqual(attrs_mandatory[key], network_function[key])
|
||||
self.assertIsNotNone(network_function['id'])
|
||||
non_mandatory_args = ['service_chain_id', 'service_config',
|
||||
'heat_stack_id']
|
||||
for arg in non_mandatory_args:
|
||||
self.assertIsNone(network_function[arg])
|
||||
|
||||
def test_get_network_function(self):
|
||||
attrs_all = {
|
||||
'name': 'name',
|
||||
'description': 'description',
|
||||
'tenant_id': 'tenant_id',
|
||||
'service_id': 'service_id',
|
||||
'service_chain_id': 'service_chain_id',
|
||||
'service_profile_id': 'service_profile_id',
|
||||
'service_config': 'service_config',
|
||||
'heat_stack_id': 'heat_stack_id',
|
||||
'status': 'status'
|
||||
}
|
||||
network_function = self.create_network_function(attrs_all)
|
||||
db_network_function = self.nfp_db.get_network_function(
|
||||
self.session, network_function['id'])
|
||||
for key in attrs_all:
|
||||
self.assertEqual(attrs_all[key], db_network_function[key])
|
||||
|
||||
def test_list_network_function(self):
|
||||
network_function = self.create_network_function()
|
||||
network_functions = self.nfp_db.get_network_functions(self.session)
|
||||
self.assertEqual(1, len(network_functions))
|
||||
self.assertEqual(network_function['id'], network_functions[0]['id'])
|
||||
|
||||
def test_list_network_function_with_filters(self):
|
||||
attrs = {
|
||||
'name': 'name',
|
||||
'tenant_id': 'tenant_id',
|
||||
'service_id': 'service_id',
|
||||
'service_profile_id': 'service_profile_id',
|
||||
'status': 'status'
|
||||
}
|
||||
network_function = self.create_network_function(attrs)
|
||||
filters = {'service_id': ['service_id']}
|
||||
network_functions = self.nfp_db.get_network_functions(
|
||||
self.session, filters=filters)
|
||||
self.assertEqual(1, len(network_functions))
|
||||
self.assertEqual(network_function['id'], network_functions[0]['id'])
|
||||
filters = {'service_id': ['nonexisting']}
|
||||
network_functions = self.nfp_db.get_network_functions(
|
||||
self.session, filters=filters)
|
||||
self.assertEqual([], network_functions)
|
||||
|
||||
def test_update_network_function(self):
|
||||
network_function = self.create_network_function()
|
||||
self.assertIsNotNone(network_function['id'])
|
||||
updated_network_function = {'status': 'ERROR'}
|
||||
network_function = self.nfp_db.update_network_function(
|
||||
self.session, network_function['id'], updated_network_function)
|
||||
self.assertEqual('ERROR', network_function['status'])
|
||||
|
||||
def test_delete_network_function(self):
|
||||
network_function = self.create_network_function()
|
||||
self.assertIsNotNone(network_function['id'])
|
||||
self.nfp_db.delete_network_function(
|
||||
self.session, network_function['id'])
|
||||
self.assertRaises(nfp_exc.NetworkFunctionNotFound,
|
||||
self.nfp_db.get_network_function,
|
||||
self.session, network_function['id'])
|
||||
|
||||
def create_network_function_instance(self, attributes=None,
|
||||
create_nfd=True):
|
||||
if attributes is None:
|
||||
nfd = (self.create_network_function_device()['id']
|
||||
if create_nfd else None)
|
||||
attributes = {
|
||||
'name': 'name',
|
||||
'description': 'description',
|
||||
'tenant_id': 'tenant_id',
|
||||
'network_function_id': self.create_network_function()['id'],
|
||||
'network_function_device_id': nfd,
|
||||
'ha_state': "Active",
|
||||
'port_info': [
|
||||
{'id': 'myportid1',
|
||||
'port_model': nfp_constants.NEUTRON_PORT,
|
||||
'port_classification': nfp_constants.PROVIDER,
|
||||
'port_role': nfp_constants.ACTIVE_PORT},
|
||||
{'id': 'myportid2',
|
||||
'port_model': nfp_constants.GBP_PORT,
|
||||
'port_classification': nfp_constants.CONSUMER,
|
||||
'port_role': nfp_constants.MASTER_PORT}
|
||||
],
|
||||
'status': 'status'
|
||||
}
|
||||
return self.nfp_db.create_network_function_instance(
|
||||
self.session, attributes)
|
||||
|
||||
def test_create_network_function_instance(self):
|
||||
network_function = self.create_network_function()
|
||||
attrs = {
|
||||
'name': 'name',
|
||||
'description': 'description',
|
||||
'tenant_id': 'tenant_id',
|
||||
'network_function_id': network_function['id'],
|
||||
'network_function_device_id': (
|
||||
self.create_network_function_device()['id']),
|
||||
'ha_state': 'Active',
|
||||
'port_info': [
|
||||
{'id': 'my_nfi_port_id1',
|
||||
'port_model': nfp_constants.NEUTRON_PORT,
|
||||
'port_classification': nfp_constants.PROVIDER,
|
||||
'port_role': nfp_constants.ACTIVE_PORT},
|
||||
{'id': 'my_nfi_port_id2',
|
||||
'port_model': nfp_constants.GBP_PORT,
|
||||
'port_classification': nfp_constants.CONSUMER,
|
||||
'port_role': nfp_constants.MASTER_PORT}
|
||||
],
|
||||
'status': 'status'
|
||||
}
|
||||
network_function_instance = (
|
||||
self.nfp_db.create_network_function_instance(self.session, attrs))
|
||||
for key in attrs:
|
||||
self.assertEqual(attrs[key], network_function_instance[key])
|
||||
self.assertIsNotNone(network_function_instance['id'])
|
||||
|
||||
def test_create_network_function_instance_mandatory_values(self):
|
||||
network_function = self.create_network_function()
|
||||
attrs_mandatory = {
|
||||
'name': 'name',
|
||||
'tenant_id': 'tenant_id',
|
||||
'network_function_id': network_function['id'],
|
||||
'status': 'status'
|
||||
}
|
||||
network_function_instance = (
|
||||
self.nfp_db.create_network_function_instance(
|
||||
self.session, attrs_mandatory))
|
||||
for key in attrs_mandatory:
|
||||
self.assertEqual(attrs_mandatory[key],
|
||||
network_function_instance[key])
|
||||
self.assertIsNotNone(network_function_instance['id'])
|
||||
non_mandatory_args = ['network_function_device_id', 'ha_state']
|
||||
for arg in non_mandatory_args:
|
||||
self.assertIsNone(network_function_instance[arg])
|
||||
self.assertEqual([], network_function_instance['port_info'])
|
||||
|
||||
def test_get_network_function_instance(self):
|
||||
network_function = self.create_network_function()
|
||||
attrs_all = {
|
||||
'name': 'name',
|
||||
'description': 'description',
|
||||
'tenant_id': 'tenant_id',
|
||||
'network_function_id': network_function['id'],
|
||||
'network_function_device_id': (
|
||||
self.create_network_function_device()['id']),
|
||||
'ha_state': 'Active',
|
||||
'port_info': [
|
||||
{'id': 'my_nfi_port_id1',
|
||||
'port_model': nfp_constants.NEUTRON_PORT,
|
||||
'port_classification': nfp_constants.PROVIDER,
|
||||
'port_role': nfp_constants.ACTIVE_PORT},
|
||||
{'id': 'my_nfi_port_id2',
|
||||
'port_model': nfp_constants.GBP_PORT,
|
||||
'port_classification': nfp_constants.CONSUMER,
|
||||
'port_role': nfp_constants.MASTER_PORT}
|
||||
],
|
||||
'status': 'status'
|
||||
}
|
||||
network_function_instance = (
|
||||
self.nfp_db.create_network_function_instance(
|
||||
self.session, attrs_all))
|
||||
db_network_function_instance = (
|
||||
self.nfp_db.get_network_function_instance(
|
||||
self.session, network_function_instance['id']))
|
||||
for key in attrs_all:
|
||||
self.assertEqual(attrs_all[key], db_network_function_instance[key])
|
||||
|
||||
def test_list_network_function_instance(self):
|
||||
self.test_create_network_function_instance()
|
||||
nf_instances = self.nfp_db.get_network_function_instances(
|
||||
self.session)
|
||||
self.assertEqual(1, len(nf_instances))
|
||||
|
||||
def test_list_network_function_instances_with_filters(self):
|
||||
self.test_create_network_function_instance()
|
||||
filters = {'ha_state': ['Active']}
|
||||
nf_instances = self.nfp_db.get_network_function_instances(
|
||||
self.session, filters=filters)
|
||||
self.assertEqual(1, len(nf_instances))
|
||||
filters = {'ha_state': ['nonexisting']}
|
||||
nf_instances = self.nfp_db.get_network_function_instances(
|
||||
self.session, filters=filters)
|
||||
self.assertEqual([], nf_instances)
|
||||
|
||||
def test_update_network_function_instance(self):
|
||||
network_function_instance = self.create_network_function_instance()
|
||||
self.assertIsNotNone(network_function_instance['id'])
|
||||
updated_nfi = {'status': 'ERROR'}
|
||||
nf_instance = self.nfp_db.update_network_function_instance(
|
||||
self.session, network_function_instance['id'], updated_nfi)
|
||||
self.assertEqual('ERROR', nf_instance['status'])
|
||||
|
||||
def test_delete_network_function_instance(self):
|
||||
network_function_instance = self.create_network_function_instance()
|
||||
port_info = network_function_instance['port_info']
|
||||
self.assertIsNotNone(network_function_instance['id'])
|
||||
self.nfp_db.delete_network_function_instance(
|
||||
self.session, network_function_instance['id'])
|
||||
self.assertRaises(nfp_exc.NetworkFunctionInstanceNotFound,
|
||||
self.nfp_db.get_network_function_instance,
|
||||
self.session, network_function_instance['id'])
|
||||
for port_id in port_info:
|
||||
self.assertRaises(nfp_exc.NFPPortNotFound,
|
||||
self.nfp_db.get_port_info,
|
||||
self.session,
|
||||
port_id)
|
||||
|
||||
def create_network_function_device(self, attributes=None):
|
||||
if attributes is None:
|
||||
attributes = {
|
||||
'name': 'name',
|
||||
'description': 'description',
|
||||
'tenant_id': 'tenant_id',
|
||||
'mgmt_ip_address': 'mgmt_ip_address',
|
||||
'monitoring_port_id': {
|
||||
'id': 'myid1_ha_port',
|
||||
'port_model': nfp_constants.NEUTRON_PORT,
|
||||
'port_classification': nfp_constants.MONITOR,
|
||||
'port_role': nfp_constants.ACTIVE_PORT
|
||||
},
|
||||
'monitoring_port_network': {
|
||||
'id': 'mynetwork_id',
|
||||
'network_model': nfp_constants.NEUTRON_NETWORK
|
||||
},
|
||||
'service_vendor': 'service_vendor',
|
||||
'max_interfaces': 3,
|
||||
'reference_count': 2,
|
||||
'interfaces_in_use': 1,
|
||||
'mgmt_port_id': {
|
||||
'id': 'myid1',
|
||||
'port_model': nfp_constants.NEUTRON_PORT,
|
||||
'port_classification': nfp_constants.MANAGEMENT,
|
||||
'port_role': nfp_constants.ACTIVE_PORT},
|
||||
'status': 'status'
|
||||
}
|
||||
return self.nfp_db.create_network_function_device(
|
||||
self.session, attributes)
|
||||
|
||||
def test_create_network_function_device(self):
|
||||
attrs = {
|
||||
'name': 'name',
|
||||
'description': 'description',
|
||||
'tenant_id': 'tenant_id',
|
||||
'mgmt_ip_address': 'mgmt_ip_address',
|
||||
'monitoring_port_id': {
|
||||
'id': 'myid1_ha_port',
|
||||
'port_model': nfp_constants.NEUTRON_PORT,
|
||||
'port_classification': nfp_constants.MONITOR,
|
||||
'port_role': nfp_constants.ACTIVE_PORT
|
||||
},
|
||||
'monitoring_port_network': {
|
||||
'id': 'mynetwork_id',
|
||||
'network_model': nfp_constants.NEUTRON_NETWORK
|
||||
},
|
||||
'service_vendor': 'service_vendor',
|
||||
'max_interfaces': 3,
|
||||
'reference_count': 2,
|
||||
'interfaces_in_use': 1,
|
||||
'mgmt_port_id': {
|
||||
'id': 'myid1',
|
||||
'port_model': nfp_constants.NEUTRON_PORT,
|
||||
'port_classification': nfp_constants.MANAGEMENT,
|
||||
'port_role': nfp_constants.ACTIVE_PORT},
|
||||
'status': 'status'
|
||||
}
|
||||
network_function_device = self.nfp_db.create_network_function_device(
|
||||
self.session, attrs)
|
||||
for key in attrs:
|
||||
if key == 'mgmt_port_id':
|
||||
self.assertEqual(attrs[key]['id'],
|
||||
network_function_device[key])
|
||||
continue
|
||||
self.assertEqual(attrs[key], network_function_device[key])
|
||||
self.assertIsNotNone(network_function_device['id'])
|
||||
|
||||
def test_create_network_function_device_mandatory_values(self):
|
||||
attrs_mandatory = {
|
||||
'name': 'name',
|
||||
'tenant_id': 'tenant_id',
|
||||
'mgmt_ip_address': 'mgmt_ip_address',
|
||||
'service_vendor': 'service_vendor',
|
||||
'max_interfaces': 3,
|
||||
'reference_count': 2,
|
||||
'interfaces_in_use': 1,
|
||||
'status': 'status'
|
||||
}
|
||||
nf_device = self.nfp_db.create_network_function_device(
|
||||
self.session, attrs_mandatory)
|
||||
for key in attrs_mandatory:
|
||||
self.assertEqual(attrs_mandatory[key], nf_device[key])
|
||||
self.assertIsNotNone(nf_device['id'])
|
||||
non_mandatory_args = ['monitoring_port_id',
|
||||
'monitoring_port_network']
|
||||
for arg in non_mandatory_args:
|
||||
self.assertIsNone(nf_device[arg])
|
||||
self.assertEqual(None, nf_device['mgmt_port_id'])
|
||||
|
||||
def test_get_network_function_device(self):
|
||||
attrs = {
|
||||
'name': 'name',
|
||||
'description': 'description',
|
||||
'tenant_id': 'tenant_id',
|
||||
'mgmt_ip_address': 'mgmt_ip_address',
|
||||
'monitoring_port_id': {
|
||||
'id': 'myid1_ha_port',
|
||||
'port_model': nfp_constants.NEUTRON_PORT,
|
||||
'port_classification': nfp_constants.MONITOR,
|
||||
'port_role': nfp_constants.ACTIVE_PORT
|
||||
},
|
||||
'monitoring_port_network': {
|
||||
'id': 'mynetwork_id',
|
||||
'network_model': nfp_constants.NEUTRON_NETWORK
|
||||
},
|
||||
'service_vendor': 'service_vendor',
|
||||
'max_interfaces': 3,
|
||||
'reference_count': 2,
|
||||
'interfaces_in_use': 1,
|
||||
'mgmt_port_id': {
|
||||
'id': 'myid1',
|
||||
'port_model': nfp_constants.NEUTRON_PORT,
|
||||
'port_classification': nfp_constants.MANAGEMENT,
|
||||
'port_role': nfp_constants.ACTIVE_PORT},
|
||||
'status': 'status'
|
||||
}
|
||||
network_function_device = self.nfp_db.create_network_function_device(
|
||||
self.session, attrs)
|
||||
db_network_function_device = self.nfp_db.get_network_function_device(
|
||||
self.session, network_function_device['id'])
|
||||
for key in attrs:
|
||||
if key == 'mgmt_port_id':
|
||||
self.assertEqual(attrs[key]['id'],
|
||||
network_function_device[key])
|
||||
continue
|
||||
self.assertEqual(attrs[key], db_network_function_device[key])
|
||||
|
||||
def test_list_network_function_device(self):
|
||||
self.test_create_network_function_device()
|
||||
network_function_devices = self.nfp_db.get_network_function_devices(
|
||||
self.session)
|
||||
self.assertEqual(1, len(network_function_devices))
|
||||
|
||||
def test_list_network_function_devices_with_filters(self):
|
||||
self.test_create_network_function_device()
|
||||
filters = {'service_vendor': ['service_vendor']}
|
||||
network_function_devices = self.nfp_db.get_network_function_devices(
|
||||
self.session, filters=filters)
|
||||
self.assertEqual(1, len(network_function_devices))
|
||||
filters = {'service_vendor': ['nonexisting']}
|
||||
network_function_devices = self.nfp_db.get_network_function_devices(
|
||||
self.session, filters=filters)
|
||||
self.assertEqual([], network_function_devices)
|
||||
|
||||
def test_update_network_function_device(self):
|
||||
attrs = {
|
||||
'name': 'name',
|
||||
'description': 'description',
|
||||
'tenant_id': 'tenant_id',
|
||||
'mgmt_ip_address': 'mgmt_ip_address',
|
||||
'monitoring_port_id': {
|
||||
'id': 'myid1_ha_port',
|
||||
'port_model': nfp_constants.NEUTRON_PORT,
|
||||
'port_classification': nfp_constants.MONITOR,
|
||||
'port_role': nfp_constants.ACTIVE_PORT
|
||||
},
|
||||
'monitoring_port_network': {
|
||||
'id': 'mynetwork_id',
|
||||
'network_model': nfp_constants.NEUTRON_NETWORK
|
||||
},
|
||||
'service_vendor': 'service_vendor',
|
||||
'max_interfaces': 3,
|
||||
'reference_count': 2,
|
||||
'interfaces_in_use': 1,
|
||||
'mgmt_port_id': {
|
||||
'id': 'myid1',
|
||||
'port_model': nfp_constants.NEUTRON_PORT,
|
||||
'port_classification': nfp_constants.MANAGEMENT,
|
||||
'port_role': nfp_constants.ACTIVE_PORT},
|
||||
'status': 'status'
|
||||
}
|
||||
network_function_device = self.nfp_db.create_network_function_device(
|
||||
self.session, attrs)
|
||||
for key in attrs:
|
||||
if key == 'mgmt_port_id':
|
||||
self.assertEqual(attrs[key]['id'],
|
||||
network_function_device[key])
|
||||
continue
|
||||
|
||||
self.assertEqual(attrs[key], network_function_device[key])
|
||||
self.assertIsNotNone(network_function_device['id'])
|
||||
|
||||
# update name
|
||||
updated_network_function_device = {
|
||||
'name': 'new_name'
|
||||
}
|
||||
updated_nfd = self.nfp_db.update_network_function_device(
|
||||
self.session,
|
||||
network_function_device['id'],
|
||||
updated_network_function_device)
|
||||
self.assertEqual('new_name', updated_nfd['name'])
|
||||
del updated_nfd['name']
|
||||
for key in attrs:
|
||||
if key == 'mgmt_port_id':
|
||||
self.assertEqual(attrs[key]['id'],
|
||||
network_function_device[key])
|
||||
continue
|
||||
if key != 'name':
|
||||
self.assertEqual(attrs[key], updated_nfd[key])
|
||||
|
||||
# Update mgmt port
|
||||
updated_network_function_device = {
|
||||
'mgmt_port_id': {
|
||||
'id': 'myid3',
|
||||
'port_model': nfp_constants.NEUTRON_PORT,
|
||||
'port_classification': nfp_constants.MANAGEMENT,
|
||||
'port_role': nfp_constants.ACTIVE_PORT},
|
||||
'name': 'name'
|
||||
}
|
||||
updated_nfd = self.nfp_db.update_network_function_device(
|
||||
self.session,
|
||||
network_function_device['id'],
|
||||
copy.deepcopy(updated_network_function_device))
|
||||
self.assertEqual(updated_nfd['mgmt_port_id'], 'myid3')
|
||||
del updated_nfd['mgmt_port_id']
|
||||
for key in attrs:
|
||||
if key != 'mgmt_port_id':
|
||||
self.assertEqual(attrs[key], updated_nfd[key])
|
||||
|
||||
def test_delete_network_function_device(self):
|
||||
network_function_device = self.create_network_function_device()
|
||||
mgmt_port_id = network_function_device['mgmt_port_id']
|
||||
self.assertIsNotNone(network_function_device['id'])
|
||||
self.nfp_db.delete_network_function_device(
|
||||
self.session, network_function_device['id'])
|
||||
self.assertRaises(nfp_exc.NetworkFunctionDeviceNotFound,
|
||||
self.nfp_db.get_network_function_device,
|
||||
self.session, network_function_device['id'])
|
||||
self.assertRaises(nfp_exc.NFPPortNotFound,
|
||||
self.nfp_db.get_port_info,
|
||||
self.session,
|
||||
mgmt_port_id)
|
||||
0
gbpservice/nfp/common/__init__.py
Normal file
0
gbpservice/nfp/common/__init__.py
Normal file
37
gbpservice/nfp/common/constants.py
Normal file
37
gbpservice/nfp/common/constants.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# 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.
|
||||
|
||||
GBP_MODE = "gbp"
|
||||
NEUTRON_MODE = "neutron"
|
||||
|
||||
NEUTRON_PORT = "neutron_port"
|
||||
GBP_PORT = "gbp_policy_target"
|
||||
|
||||
NEUTRON_NETWORK = "neutron_network"
|
||||
GBP_NETWORK = "gbp_group"
|
||||
|
||||
PROVIDER = "provider"
|
||||
CONSUMER = "consumer"
|
||||
MANAGEMENT = "management"
|
||||
MONITOR = "monitoring"
|
||||
|
||||
ACTIVE_PORT = "ACTIVE"
|
||||
STANDBY_PORT = "STANDBY"
|
||||
MASTER_PORT = "MASTER"
|
||||
STANDALONE_PORT = "STANDALONE"
|
||||
|
||||
ACTIVE = "ACTIVE"
|
||||
# REVISIT(ashu) - Merge to have single BUILD state
|
||||
PENDING_CREATE = "PENDING_CREATE"
|
||||
PENDING_UPDATE = "PENDING_UPDATE"
|
||||
PENDING_DELETE = "PENDING_DELETE"
|
||||
ERROR = "ERROR"
|
||||
111
gbpservice/nfp/common/exceptions.py
Normal file
111
gbpservice/nfp/common/exceptions.py
Normal file
@@ -0,0 +1,111 @@
|
||||
# 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 sys
|
||||
|
||||
from neutron._i18n import _
|
||||
from neutron._i18n import _LE
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
import six
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
exc_log_opts = [
|
||||
cfg.BoolOpt('fatal_exception_format_errors',
|
||||
default=False,
|
||||
help='Make exception message format errors fatal.'),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(exc_log_opts)
|
||||
|
||||
|
||||
class NFPException(Exception):
|
||||
"""Base NFP Exception
|
||||
|
||||
To correctly use this class, inherit from it and define
|
||||
a 'message' property. That message will get printf'd
|
||||
with the keyword arguments provided to the constructor.
|
||||
|
||||
"""
|
||||
message = _("An unknown exception occurred.")
|
||||
code = 500
|
||||
headers = {}
|
||||
safe = False
|
||||
|
||||
def __init__(self, message=None, **kwargs):
|
||||
self.kwargs = kwargs
|
||||
self.kwargs['message'] = message
|
||||
|
||||
if 'code' not in self.kwargs:
|
||||
try:
|
||||
self.kwargs['code'] = self.code
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
for k, v in self.kwargs.items():
|
||||
if isinstance(v, Exception):
|
||||
self.kwargs[k] = six.text_type(v)
|
||||
|
||||
if self._should_format():
|
||||
try:
|
||||
message = self.message % kwargs
|
||||
|
||||
except Exception:
|
||||
exc_info = sys.exc_info()
|
||||
# kwargs doesn't match a variable in the message
|
||||
# log the issue and the kwargs
|
||||
LOG.exception(_LE('Exception in string format operation'))
|
||||
for name, value in kwargs.items():
|
||||
LOG.error(_LE("%(name)s: %(value)s"),
|
||||
{'name': name, 'value': value})
|
||||
if CONF.fatal_exception_format_errors:
|
||||
six.reraise(*exc_info)
|
||||
# at least get the core message out if something happened
|
||||
message = self.message
|
||||
elif isinstance(message, Exception):
|
||||
message = six.text_type(message)
|
||||
|
||||
self.msg = message
|
||||
super(NFPException, self).__init__(message)
|
||||
|
||||
def _should_format(self):
|
||||
return self.kwargs['message'] is None or '%(message)' in self.message
|
||||
|
||||
def __unicode__(self):
|
||||
return six.text_type(self.msg)
|
||||
|
||||
|
||||
class NotFound(NFPException):
|
||||
message = _("Resource could not be found.")
|
||||
code = 404
|
||||
safe = True
|
||||
|
||||
|
||||
class NetworkFunctionNotFound(NotFound):
|
||||
message = _("NetworkFunction %(network_function_id)s could not be found")
|
||||
|
||||
|
||||
class NetworkFunctionInstanceNotFound(NotFound):
|
||||
message = _("NetworkFunctionInstance %(network_function_instance_id)s "
|
||||
"could not be found")
|
||||
|
||||
|
||||
class NetworkFunctionDeviceNotFound(NotFound):
|
||||
message = _("NetworkFunctionDevice %(network_function_device_id)s could "
|
||||
"not be found")
|
||||
|
||||
|
||||
class NFPPortNotFound(NotFound):
|
||||
message = _("NFP Port %(port_id)s could not be found")
|
||||
0
gbpservice/nfp/orchestrator/__init__.py
Normal file
0
gbpservice/nfp/orchestrator/__init__.py
Normal file
0
gbpservice/nfp/orchestrator/db/__init__.py
Normal file
0
gbpservice/nfp/orchestrator/db/__init__.py
Normal file
174
gbpservice/nfp/orchestrator/db/common_db_mixin.py
Normal file
174
gbpservice/nfp/orchestrator/db/common_db_mixin.py
Normal file
@@ -0,0 +1,174 @@
|
||||
# Copyright (c) 2014 OpenStack Foundation.
|
||||
# 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.
|
||||
|
||||
from neutron.db import sqlalchemyutils
|
||||
import weakref
|
||||
|
||||
|
||||
# TODO(ashu): Below class need to extend neutron's CommonDbMixin.
|
||||
class CommonDbMixin(object):
|
||||
"""Common methods used in core and service plugins."""
|
||||
# Plugins, mixin classes implementing extension will register
|
||||
# hooks into the dict below for "augmenting" the "core way" of
|
||||
# building a query for retrieving objects from a model class.
|
||||
# To this aim, the register_model_query_hook and unregister_query_hook
|
||||
# from this class should be invoked
|
||||
_model_query_hooks = {}
|
||||
|
||||
# This dictionary will store methods for extending attributes of
|
||||
# api resources. Mixins can use this dict for adding their own methods
|
||||
_dict_extend_functions = {}
|
||||
|
||||
@classmethod
|
||||
def register_model_query_hook(cls, model, name, query_hook, filter_hook,
|
||||
result_filters=None):
|
||||
"""Register a hook to be invoked when a query is executed.
|
||||
|
||||
Add the hooks to the _model_query_hooks dict. Models are the keys
|
||||
of this dict, whereas the value is another dict mapping hook names to
|
||||
callables performing the hook.
|
||||
Each hook has a "query" component, used to build the query expression
|
||||
and a "filter" component, which is used to build the filter expression.
|
||||
|
||||
Query hooks take as input the query being built and return a
|
||||
transformed query expression.
|
||||
|
||||
Filter hooks take as input the filter expression being built and return
|
||||
a transformed filter expression
|
||||
"""
|
||||
model_hooks = cls._model_query_hooks.get(model)
|
||||
if not model_hooks:
|
||||
# add key to dict
|
||||
model_hooks = {}
|
||||
cls._model_query_hooks[model] = model_hooks
|
||||
model_hooks[name] = {'query': query_hook, 'filter': filter_hook,
|
||||
'result_filters': result_filters}
|
||||
|
||||
@property
|
||||
def safe_reference(self):
|
||||
"""Return a weakref to the instance.
|
||||
|
||||
Minimize the potential for the instance persisting
|
||||
unnecessarily in memory by returning a weakref proxy that
|
||||
won't prevent deallocation.
|
||||
"""
|
||||
return weakref.proxy(self)
|
||||
|
||||
def _model_query(self, session, model, is_admin=False):
|
||||
query = session.query(model)
|
||||
# define basic filter condition for model query
|
||||
query_filter = None
|
||||
# Execute query hooks registered from mixins and plugins
|
||||
for _name, hooks in self._model_query_hooks.get(model,
|
||||
{}).iteritems():
|
||||
query_hook = hooks.get('query')
|
||||
if isinstance(query_hook, basestring):
|
||||
query_hook = getattr(self, query_hook, None)
|
||||
if query_hook:
|
||||
query = query_hook(model, query)
|
||||
|
||||
filter_hook = hooks.get('filter')
|
||||
if isinstance(filter_hook, basestring):
|
||||
filter_hook = getattr(self, filter_hook, None)
|
||||
if filter_hook:
|
||||
query_filter = filter_hook(model, query_filter)
|
||||
|
||||
if query_filter is not None:
|
||||
query = query.filter(query_filter)
|
||||
return query
|
||||
|
||||
def _fields(self, resource, fields):
|
||||
if fields:
|
||||
return dict(((key, item) for key, item in resource.items()
|
||||
if key in fields))
|
||||
return resource
|
||||
|
||||
def _get_tenant_id_for_create(self, resource):
|
||||
return resource['tenant_id']
|
||||
|
||||
def _get_by_id(self, session, model, id):
|
||||
query = self._model_query(session, model)
|
||||
return query.filter(model.id == id).one()
|
||||
|
||||
def _apply_filters_to_query(self, query, model, filters):
|
||||
if filters:
|
||||
for key, value in filters.iteritems():
|
||||
column = getattr(model, key, None)
|
||||
if column:
|
||||
query = query.filter(column.in_(value))
|
||||
for _name, hooks in self._model_query_hooks.get(model,
|
||||
{}).iteritems():
|
||||
result_filter = hooks.get('result_filters', None)
|
||||
if isinstance(result_filter, basestring):
|
||||
result_filter = getattr(self, result_filter, None)
|
||||
|
||||
if result_filter:
|
||||
query = result_filter(query, filters)
|
||||
return query
|
||||
|
||||
def _apply_dict_extend_functions(self, resource_type,
|
||||
response, db_object):
|
||||
for func in self._dict_extend_functions.get(
|
||||
resource_type, []):
|
||||
args = (response, db_object)
|
||||
if isinstance(func, basestring):
|
||||
func = getattr(self, func, None)
|
||||
else:
|
||||
# must call unbound method - use self as 1st argument
|
||||
args = (self,) + args
|
||||
if func:
|
||||
func(*args)
|
||||
|
||||
def _get_collection_query(self, session, model, filters=None,
|
||||
sorts=None, limit=None, marker_obj=None,
|
||||
page_reverse=False):
|
||||
collection = self._model_query(session, model)
|
||||
collection = self._apply_filters_to_query(collection, model, filters)
|
||||
if limit and page_reverse and sorts:
|
||||
sorts = [(s[0], not s[1]) for s in sorts]
|
||||
collection = sqlalchemyutils.paginate_query(collection, model, limit,
|
||||
sorts, marker_obj=marker_obj)
|
||||
return collection
|
||||
|
||||
def _get_collection(self, session, model, dict_func, filters=None,
|
||||
fields=None, sorts=None, limit=None, marker_obj=None,
|
||||
page_reverse=False):
|
||||
query = self._get_collection_query(session, model, filters=filters,
|
||||
sorts=sorts,
|
||||
limit=limit,
|
||||
marker_obj=marker_obj,
|
||||
page_reverse=page_reverse)
|
||||
items = [dict_func(c, fields) for c in query]
|
||||
if limit and page_reverse:
|
||||
items.reverse()
|
||||
return items
|
||||
|
||||
def _get_collection_count(self, model, filters=None):
|
||||
return self._get_collection_query(model, filters).count()
|
||||
|
||||
def _get_marker_obj(self, resource, limit, marker):
|
||||
if limit and marker:
|
||||
return getattr(self, '_get_%s' % resource)(marker)
|
||||
return None
|
||||
|
||||
def _filter_non_model_columns(self, data, model):
|
||||
"""Filter non model columns
|
||||
|
||||
Remove all the attributes from data which are not columns of
|
||||
the model passed as second parameter.
|
||||
"""
|
||||
columns = [c.name for c in model.__table__.columns]
|
||||
return dict((k, v) for (k, v) in
|
||||
data.iteritems() if k in columns)
|
||||
446
gbpservice/nfp/orchestrator/db/nfp_db.py
Normal file
446
gbpservice/nfp/orchestrator/db/nfp_db.py
Normal file
@@ -0,0 +1,446 @@
|
||||
# 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 oslo_utils import uuidutils
|
||||
from sqlalchemy.orm import exc
|
||||
|
||||
from gbpservice.nfp.common import exceptions as nfp_exc
|
||||
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
|
||||
LOG = nfp_logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NFPDbBase(common_db_mixin.CommonDbMixin):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(NFPDbBase, self).__init__(*args, **kwargs)
|
||||
|
||||
def create_network_function(self, session, network_function):
|
||||
with session.begin(subtransactions=True):
|
||||
network_function_db = nfp_db_model.NetworkFunction(
|
||||
id=uuidutils.generate_uuid(),
|
||||
name=network_function['name'],
|
||||
description=network_function.get('description'),
|
||||
tenant_id=network_function['tenant_id'],
|
||||
service_id=network_function['service_id'],
|
||||
service_chain_id=network_function.get('service_chain_id'),
|
||||
service_profile_id=network_function['service_profile_id'],
|
||||
service_config=network_function.get('service_config'),
|
||||
heat_stack_id=network_function.get('heat_stack_id'),
|
||||
status=network_function['status'])
|
||||
session.add(network_function_db)
|
||||
return self._make_network_function_dict(network_function_db)
|
||||
|
||||
def _get_network_function(self, session, network_function_id):
|
||||
try:
|
||||
return self._get_by_id(
|
||||
session, nfp_db_model.NetworkFunction, network_function_id)
|
||||
except exc.NoResultFound:
|
||||
raise nfp_exc.NetworkFunctionNotFound(
|
||||
network_function_id=network_function_id)
|
||||
|
||||
def update_network_function(self, session, network_function_id,
|
||||
updated_network_function):
|
||||
with session.begin(subtransactions=True):
|
||||
network_function_db = self._get_network_function(
|
||||
session, network_function_id)
|
||||
network_function_db.update(updated_network_function)
|
||||
return self._make_network_function_dict(network_function_db)
|
||||
|
||||
def delete_network_function(self, session, network_function_id):
|
||||
with session.begin(subtransactions=True):
|
||||
network_function_db = self._get_network_function(
|
||||
session, network_function_id)
|
||||
session.delete(network_function_db)
|
||||
|
||||
def get_network_function(self, session, network_function_id, fields=None):
|
||||
service = self._get_network_function(session, network_function_id)
|
||||
return self._make_network_function_dict(service, fields)
|
||||
|
||||
def get_network_functions(self, session, filters=None, fields=None,
|
||||
sorts=None, limit=None, marker=None,
|
||||
page_reverse=False):
|
||||
marker_obj = self._get_marker_obj(
|
||||
'network_functions', limit, marker)
|
||||
return self._get_collection(session, nfp_db_model.NetworkFunction,
|
||||
self._make_network_function_dict,
|
||||
filters=filters, fields=fields,
|
||||
sorts=sorts, limit=limit,
|
||||
marker_obj=marker_obj,
|
||||
page_reverse=page_reverse)
|
||||
|
||||
def _set_port_info_for_nfi(self, session, network_function_instance_db,
|
||||
network_function_instance, is_update=False):
|
||||
nfi_db = network_function_instance_db
|
||||
port_info = network_function_instance.get('port_info')
|
||||
if not port_info:
|
||||
nfi_db.port_info = []
|
||||
return
|
||||
with session.begin(subtransactions=True):
|
||||
nfi_db.port_info = []
|
||||
for port in port_info:
|
||||
port_info_db = nfp_db_model.PortInfo(
|
||||
id=port['id'],
|
||||
port_model=port['port_model'],
|
||||
port_classification=port.get('port_classification'),
|
||||
port_role=port.get('port_role'))
|
||||
if is_update:
|
||||
session.merge(port_info_db)
|
||||
else:
|
||||
session.add(port_info_db)
|
||||
session.flush() # Any alternatives for flush ??
|
||||
assoc = nfp_db_model.NSIPortAssociation(
|
||||
network_function_instance_id=(
|
||||
network_function_instance_db['id']),
|
||||
data_port_id=port['id'])
|
||||
nfi_db.port_info.append(assoc)
|
||||
del network_function_instance['port_info']
|
||||
|
||||
def create_network_function_instance(self, session,
|
||||
network_function_instance):
|
||||
with session.begin(subtransactions=True):
|
||||
network_function_instance_db = (
|
||||
nfp_db_model.NetworkFunctionInstance(
|
||||
id=uuidutils.generate_uuid(),
|
||||
name=network_function_instance['name'],
|
||||
tenant_id=network_function_instance['tenant_id'],
|
||||
description=network_function_instance.get('description'),
|
||||
network_function_id=network_function_instance[
|
||||
'network_function_id'],
|
||||
network_function_device_id=network_function_instance.get(
|
||||
'network_function_device_id'),
|
||||
ha_state=network_function_instance.get('ha_state'),
|
||||
status=network_function_instance['status']))
|
||||
session.add(network_function_instance_db)
|
||||
self._set_port_info_for_nfi(session, network_function_instance_db,
|
||||
network_function_instance)
|
||||
return self._make_network_function_instance_dict(
|
||||
network_function_instance_db)
|
||||
|
||||
def _get_network_function_instance(self, session,
|
||||
network_function_instance_id):
|
||||
try:
|
||||
return self._get_by_id(
|
||||
session,
|
||||
nfp_db_model.NetworkFunctionInstance,
|
||||
network_function_instance_id)
|
||||
except exc.NoResultFound:
|
||||
raise nfp_exc.NetworkFunctionInstanceNotFound(
|
||||
network_function_instance_id=network_function_instance_id)
|
||||
|
||||
def update_network_function_instance(self, session,
|
||||
network_function_instance_id,
|
||||
updated_network_function_instance):
|
||||
with session.begin(subtransactions=True):
|
||||
network_function_instance_db = self._get_network_function_instance(
|
||||
session, network_function_instance_id)
|
||||
if 'port_info' in updated_network_function_instance:
|
||||
self._set_port_info_for_nfi(
|
||||
session,
|
||||
network_function_instance_db,
|
||||
updated_network_function_instance, is_update=True)
|
||||
network_function_instance_db.update(
|
||||
updated_network_function_instance)
|
||||
return self._make_network_function_instance_dict(
|
||||
network_function_instance_db)
|
||||
|
||||
def delete_network_function_instance(self, session,
|
||||
network_function_instance_id):
|
||||
with session.begin(subtransactions=True):
|
||||
network_function_instance_db = self._get_network_function_instance(
|
||||
session, network_function_instance_id)
|
||||
for port in network_function_instance_db.port_info:
|
||||
self.delete_port_info(session, port['data_port_id'])
|
||||
session.delete(network_function_instance_db)
|
||||
|
||||
def get_network_function_instance(self, session,
|
||||
network_function_instance_id,
|
||||
fields=None):
|
||||
network_function_instance = self._get_network_function_instance(
|
||||
session, network_function_instance_id)
|
||||
return self._make_network_function_instance_dict(
|
||||
network_function_instance, fields)
|
||||
|
||||
def get_network_function_instances(self, session, filters=None,
|
||||
fields=None, sorts=None, limit=None,
|
||||
marker=None, page_reverse=False):
|
||||
marker_obj = self._get_marker_obj(
|
||||
'network_function_instances', limit, marker)
|
||||
return self._get_collection(
|
||||
session, nfp_db_model.NetworkFunctionInstance,
|
||||
self._make_network_function_instance_dict,
|
||||
filters=filters, fields=fields, sorts=sorts, limit=limit,
|
||||
marker_obj=marker_obj, page_reverse=page_reverse)
|
||||
|
||||
def _set_mgmt_port_for_nfd(self, session, network_function_device_db,
|
||||
network_function_device, is_update=False):
|
||||
nfd_db = network_function_device_db
|
||||
mgmt_port_id = network_function_device.get('mgmt_port_id')
|
||||
if not mgmt_port_id:
|
||||
nfd_db.mgmt_port_id = None
|
||||
return
|
||||
with session.begin(subtransactions=True):
|
||||
port_info_db = nfp_db_model.PortInfo(
|
||||
id=mgmt_port_id['id'],
|
||||
port_model=mgmt_port_id['port_model'],
|
||||
port_classification=mgmt_port_id['port_classification'],
|
||||
port_role=mgmt_port_id['port_role'])
|
||||
if is_update:
|
||||
session.merge(port_info_db)
|
||||
else:
|
||||
session.add(port_info_db)
|
||||
session.flush()
|
||||
nfd_db.mgmt_port_id = port_info_db['id']
|
||||
# del network_function_device['mgmt_port_id']
|
||||
|
||||
def _set_monitoring_port_id_for_nfd(self, session,
|
||||
network_function_device_db,
|
||||
network_function_device):
|
||||
nfd_db = network_function_device_db
|
||||
monitoring_port_id = network_function_device.get(
|
||||
'monitoring_port_id')
|
||||
if not monitoring_port_id:
|
||||
nfd_db.monitoring_port_id = None
|
||||
return
|
||||
with session.begin(subtransactions=True):
|
||||
port_info_db = nfp_db_model.PortInfo(
|
||||
id=monitoring_port_id['id'],
|
||||
port_model=monitoring_port_id['port_model'],
|
||||
port_classification=monitoring_port_id[
|
||||
'port_classification'],
|
||||
port_role=monitoring_port_id['port_role'])
|
||||
session.add(port_info_db)
|
||||
session.flush()
|
||||
nfd_db.monitoring_port_id = monitoring_port_id['id']
|
||||
del network_function_device['monitoring_port_id']
|
||||
|
||||
def _set_monitoring_port_network_for_nfd(self, session,
|
||||
network_function_device_db,
|
||||
network_function_device):
|
||||
nfd_db = network_function_device_db
|
||||
monitoring_port_network = network_function_device.get(
|
||||
'monitoring_port_network')
|
||||
if not monitoring_port_network:
|
||||
nfd_db.monitoring_port_network = None
|
||||
return
|
||||
with session.begin(subtransactions=True):
|
||||
network_info_db = nfp_db_model.NetworkInfo(
|
||||
id=monitoring_port_network['id'],
|
||||
network_model=monitoring_port_network['network_model'])
|
||||
session.add(network_info_db)
|
||||
session.flush()
|
||||
nfd_db.monitoring_port_network = (
|
||||
monitoring_port_network['id'])
|
||||
del network_function_device['monitoring_port_network']
|
||||
|
||||
def create_network_function_device(self, session, network_function_device):
|
||||
with session.begin(subtransactions=True):
|
||||
network_function_device_db = nfp_db_model.NetworkFunctionDevice(
|
||||
id=(network_function_device.get('id') or
|
||||
uuidutils.generate_uuid()),
|
||||
name=network_function_device['name'],
|
||||
description=network_function_device.get('description'),
|
||||
tenant_id=network_function_device['tenant_id'],
|
||||
mgmt_ip_address=network_function_device[
|
||||
'mgmt_ip_address'],
|
||||
service_vendor=network_function_device.get('service_vendor'),
|
||||
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'])
|
||||
session.add(network_function_device_db)
|
||||
self._set_mgmt_port_for_nfd(
|
||||
session, network_function_device_db, network_function_device)
|
||||
self._set_monitoring_port_id_for_nfd(
|
||||
session, network_function_device_db, network_function_device)
|
||||
self._set_monitoring_port_network_for_nfd(
|
||||
session, network_function_device_db, network_function_device)
|
||||
return self._make_network_function_device_dict(
|
||||
network_function_device_db)
|
||||
|
||||
def _get_network_function_device(self, session,
|
||||
network_function_device_id):
|
||||
try:
|
||||
return self._get_by_id(
|
||||
session,
|
||||
nfp_db_model.NetworkFunctionDevice,
|
||||
network_function_device_id)
|
||||
except exc.NoResultFound:
|
||||
raise nfp_exc.NetworkFunctionDeviceNotFound(
|
||||
network_function_device_id=network_function_device_id)
|
||||
|
||||
def update_network_function_device(self, session,
|
||||
network_function_device_id,
|
||||
updated_network_function_device):
|
||||
with session.begin(subtransactions=True):
|
||||
network_function_device_db = self._get_network_function_device(
|
||||
session, network_function_device_id)
|
||||
if updated_network_function_device.get('mgmt_port_id'):
|
||||
self._set_mgmt_port_for_nfd(
|
||||
session,
|
||||
network_function_device_db,
|
||||
updated_network_function_device,
|
||||
is_update=True)
|
||||
|
||||
if 'monitoring_port_id' in updated_network_function_device:
|
||||
self._set_monitoring_port_id_for_nfd(
|
||||
session,
|
||||
network_function_device_db,
|
||||
updated_network_function_device)
|
||||
if 'monitoring_port_network' in updated_network_function_device:
|
||||
self._set_monitoring_port_network_for_nfd(
|
||||
session,
|
||||
network_function_device_db,
|
||||
updated_network_function_device)
|
||||
mgmt_port_id = (
|
||||
updated_network_function_device.pop('mgmt_port_id', None))
|
||||
if mgmt_port_id:
|
||||
updated_network_function_device[
|
||||
'mgmt_port_id'] = mgmt_port_id['id']
|
||||
network_function_device_db.update(updated_network_function_device)
|
||||
updated_network_function_device['mgmt_port_id'] = mgmt_port_id
|
||||
return self._make_network_function_device_dict(
|
||||
network_function_device_db)
|
||||
|
||||
def delete_network_function_device(self, session,
|
||||
network_function_device_id):
|
||||
with session.begin(subtransactions=True):
|
||||
network_function_device_db = self._get_network_function_device(
|
||||
session, network_function_device_id)
|
||||
if network_function_device_db.mgmt_port_id:
|
||||
self.delete_port_info(session,
|
||||
network_function_device_db.mgmt_port_id)
|
||||
if network_function_device_db.monitoring_port_id:
|
||||
self.delete_port_info(
|
||||
session,
|
||||
network_function_device_db.monitoring_port_id)
|
||||
if network_function_device_db.monitoring_port_network:
|
||||
self.delete_network_info(
|
||||
session,
|
||||
network_function_device_db.monitoring_port_network)
|
||||
session.delete(network_function_device_db)
|
||||
|
||||
def get_network_function_device(self, session, network_function_device_id,
|
||||
fields=None):
|
||||
network_function_device = self._get_network_function_device(
|
||||
session, network_function_device_id)
|
||||
return self._make_network_function_device_dict(
|
||||
network_function_device, fields)
|
||||
|
||||
def get_network_function_devices(self, session, filters=None, fields=None,
|
||||
sorts=None, limit=None, marker=None,
|
||||
page_reverse=False):
|
||||
marker_obj = self._get_marker_obj(
|
||||
'network_function_devices', limit, marker)
|
||||
return self._get_collection(session,
|
||||
nfp_db_model.NetworkFunctionDevice,
|
||||
self._make_network_function_device_dict,
|
||||
filters=filters, fields=fields,
|
||||
sorts=sorts, limit=limit,
|
||||
marker_obj=marker_obj,
|
||||
page_reverse=page_reverse)
|
||||
|
||||
def get_port_info(self, session, port_id, fields=None):
|
||||
port_info = self._get_port_info(session, port_id)
|
||||
return self._make_port_info_dict(port_info, fields)
|
||||
|
||||
def _get_port_info(self, session, port_id):
|
||||
try:
|
||||
return self._get_by_id(
|
||||
session, nfp_db_model.PortInfo, port_id)
|
||||
except exc.NoResultFound:
|
||||
raise nfp_exc.NFPPortNotFound(port_id=port_id)
|
||||
|
||||
def delete_port_info(self, session, port_id):
|
||||
with session.begin(subtransactions=True):
|
||||
port_info_db = self._get_port_info(session, port_id)
|
||||
session.delete(port_info_db)
|
||||
|
||||
def delete_network_info(self, session, network_id):
|
||||
with session.begin(subtransactions=True):
|
||||
network_info_db = self._get_network_info(session, network_id)
|
||||
session.delete(network_info_db)
|
||||
|
||||
def get_network_info(self, session, network_id, fields=None):
|
||||
network_info = self._get_network_info(session, network_id)
|
||||
return self._make_network_info_dict(network_info, fields)
|
||||
|
||||
def _get_network_info(self, session, network_id):
|
||||
return self._get_by_id(
|
||||
session, nfp_db_model.NetworkInfo, network_id)
|
||||
|
||||
def _make_port_info_dict(self, port_info, fields):
|
||||
res = {
|
||||
'id': port_info['id'],
|
||||
'port_classification': port_info['port_classification'],
|
||||
'port_model': port_info['port_model'],
|
||||
'port_role': port_info['port_role']
|
||||
}
|
||||
return res
|
||||
|
||||
def _make_network_info_dict(self, network_info, fields):
|
||||
res = {
|
||||
'id': network_info['id'],
|
||||
'network_model': network_info['network_model'],
|
||||
}
|
||||
return res
|
||||
|
||||
def _make_network_function_dict(self, network_function, fields=None):
|
||||
res = {'id': network_function['id'],
|
||||
'tenant_id': network_function['tenant_id'],
|
||||
'name': network_function['name'],
|
||||
'description': network_function['description'],
|
||||
'service_id': network_function['service_id'],
|
||||
'service_chain_id': network_function['service_chain_id'],
|
||||
'service_profile_id': network_function['service_profile_id'],
|
||||
'service_config': network_function['service_config'],
|
||||
'heat_stack_id': network_function['heat_stack_id'],
|
||||
'status': network_function['status']
|
||||
}
|
||||
res['network_function_instances'] = [
|
||||
nfi['id'] for nfi in network_function[
|
||||
'network_function_instances']]
|
||||
return res
|
||||
|
||||
def _make_network_function_instance_dict(self, nfi, fields=None):
|
||||
res = {'id': nfi['id'],
|
||||
'tenant_id': nfi['tenant_id'],
|
||||
'name': nfi['name'],
|
||||
'description': nfi['description'],
|
||||
'ha_state': nfi['ha_state'],
|
||||
'network_function_id': nfi['network_function_id'],
|
||||
'network_function_device_id': nfi['network_function_device_id'],
|
||||
'status': nfi['status']
|
||||
}
|
||||
res['port_info'] = [
|
||||
port['data_port_id'] for port in nfi['port_info']]
|
||||
return res
|
||||
|
||||
def _make_network_function_device_dict(self, nfd, fields=None):
|
||||
res = {'id': nfd['id'],
|
||||
'tenant_id': nfd['tenant_id'],
|
||||
'name': nfd['name'],
|
||||
'description': nfd['description'],
|
||||
'mgmt_ip_address': nfd['mgmt_ip_address'],
|
||||
'mgmt_port_id': nfd['mgmt_port_id'],
|
||||
'monitoring_port_id': nfd['monitoring_port_id'],
|
||||
'monitoring_port_network': nfd['monitoring_port_network'],
|
||||
'service_vendor': nfd['service_vendor'],
|
||||
'max_interfaces': nfd['max_interfaces'],
|
||||
'reference_count': nfd['reference_count'],
|
||||
'interfaces_in_use': nfd['interfaces_in_use'],
|
||||
'status': nfd['status']
|
||||
}
|
||||
return res
|
||||
143
gbpservice/nfp/orchestrator/db/nfp_db_model.py
Normal file
143
gbpservice/nfp/orchestrator/db/nfp_db_model.py
Normal file
@@ -0,0 +1,143 @@
|
||||
# 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.db import model_base
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy import orm
|
||||
|
||||
from gbpservice.nfp.common import constants as nfp_constants
|
||||
|
||||
TENANT_ID_MAX_LEN = 255
|
||||
DESCRIPTION_MAX_LEN = 4096
|
||||
|
||||
|
||||
class HasStatus(object):
|
||||
"""status mixin, add to subclasses that have a status."""
|
||||
|
||||
status = sa.Column(sa.String(16), nullable=False, index=True)
|
||||
|
||||
|
||||
class HasStatusDescription(HasStatus):
|
||||
"""Status with description mixin."""
|
||||
|
||||
status_description = sa.Column(sa.String(DESCRIPTION_MAX_LEN))
|
||||
|
||||
|
||||
BASE = declarative_base(cls=model_base.NeutronBaseV2)
|
||||
|
||||
|
||||
class PortInfo(BASE, model_base.HasId, model_base.HasTenant):
|
||||
"""Represents the Port Information"""
|
||||
__tablename__ = 'nfp_port_infos'
|
||||
|
||||
port_model = sa.Column(sa.Enum(nfp_constants.NEUTRON_PORT,
|
||||
nfp_constants.GBP_PORT,
|
||||
name='port_model'))
|
||||
port_classification = sa.Column(sa.Enum(nfp_constants.PROVIDER,
|
||||
nfp_constants.CONSUMER,
|
||||
nfp_constants.MANAGEMENT,
|
||||
nfp_constants.MONITOR,
|
||||
name='port_classification'))
|
||||
port_role = sa.Column(sa.Enum(nfp_constants.ACTIVE_PORT,
|
||||
nfp_constants.STANDBY_PORT,
|
||||
nfp_constants.MASTER_PORT,
|
||||
name='port_role'),
|
||||
nullable=True)
|
||||
|
||||
|
||||
class NetworkInfo(BASE, model_base.HasId, model_base.HasTenant):
|
||||
"""Represents the Network Service Instance"""
|
||||
__tablename__ = 'nfp_network_infos'
|
||||
|
||||
network_model = sa.Column(sa.Enum(nfp_constants.NEUTRON_NETWORK,
|
||||
nfp_constants.GBP_NETWORK,
|
||||
name='network_model'),
|
||||
nullable=False)
|
||||
|
||||
|
||||
class NSIPortAssociation(BASE):
|
||||
"""One to many relation between NSIs and DataPorts."""
|
||||
__tablename__ = 'nfp_nfi_dataport_associations'
|
||||
|
||||
network_function_instance_id = sa.Column(
|
||||
sa.String(36),
|
||||
sa.ForeignKey('nfp_network_function_instances.id'), primary_key=True)
|
||||
data_port_id = sa.Column(sa.String(36),
|
||||
sa.ForeignKey('nfp_port_infos.id',
|
||||
ondelete='CASCADE'),
|
||||
primary_key=True)
|
||||
|
||||
|
||||
class NetworkFunctionInstance(BASE, model_base.HasId, model_base.HasTenant,
|
||||
HasStatusDescription):
|
||||
"""Represents the Network Function Instance"""
|
||||
__tablename__ = 'nfp_network_function_instances'
|
||||
|
||||
name = sa.Column(sa.String(255))
|
||||
description = sa.Column(sa.String(255))
|
||||
ha_state = sa.Column(sa.String(255))
|
||||
network_function_id = sa.Column(
|
||||
sa.String(36),
|
||||
sa.ForeignKey('nfp_network_functions.id', ondelete="SET NULL"),
|
||||
nullable=True)
|
||||
network_function_device_id = sa.Column(
|
||||
sa.String(36),
|
||||
sa.ForeignKey('nfp_network_function_devices.id', ondelete="SET NULL"),
|
||||
nullable=True)
|
||||
port_info = orm.relationship(
|
||||
NSIPortAssociation,
|
||||
cascade='all, delete-orphan')
|
||||
|
||||
|
||||
class NetworkFunction(BASE, model_base.HasId, model_base.HasTenant,
|
||||
HasStatusDescription):
|
||||
"""Represents the Network Function object"""
|
||||
__tablename__ = 'nfp_network_functions'
|
||||
|
||||
name = sa.Column(sa.String(255))
|
||||
description = sa.Column(sa.String(1024))
|
||||
service_id = sa.Column(sa.String(36), nullable=False)
|
||||
service_chain_id = sa.Column(sa.String(36), nullable=True)
|
||||
service_profile_id = sa.Column(sa.String(36), nullable=False)
|
||||
service_config = sa.Column(sa.TEXT)
|
||||
heat_stack_id = sa.Column(sa.String(36), nullable=True)
|
||||
network_function_instances = orm.relationship(
|
||||
NetworkFunctionInstance,
|
||||
backref='network_function')
|
||||
|
||||
|
||||
class NetworkFunctionDevice(BASE, model_base.HasId, model_base.HasTenant,
|
||||
HasStatusDescription):
|
||||
"""Represents the Network Function Device"""
|
||||
__tablename__ = 'nfp_network_function_devices'
|
||||
|
||||
name = sa.Column(sa.String(255))
|
||||
description = sa.Column(sa.String(255))
|
||||
mgmt_ip_address = sa.Column(sa.String(36), nullable=True)
|
||||
mgmt_port_id = sa.Column(sa.String(36),
|
||||
sa.ForeignKey('nfp_port_infos.id',
|
||||
ondelete= 'SET NULL'),
|
||||
nullable=True)
|
||||
monitoring_port_id = sa.Column(sa.String(36),
|
||||
sa.ForeignKey('nfp_port_infos.id',
|
||||
ondelete= 'SET NULL'),
|
||||
nullable=True)
|
||||
monitoring_port_network = sa.Column(sa.String(36),
|
||||
sa.ForeignKey('nfp_network_infos.id',
|
||||
ondelete= 'SET NULL'),
|
||||
nullable=True)
|
||||
service_vendor = sa.Column(sa.String(36), nullable=False, index=True)
|
||||
max_interfaces = sa.Column(sa.Integer(), nullable=False)
|
||||
reference_count = sa.Column(sa.Integer(), nullable=False)
|
||||
interfaces_in_use = sa.Column(sa.Integer(), nullable=False)
|
||||
Reference in New Issue
Block a user