]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
VMWare-NSXv: VMWare NSXv database models
authorKobi Samoray <ksamoray@vmware.com>
Thu, 25 Dec 2014 10:06:16 +0000 (12:06 +0200)
committerKobi Samoray <ksamoray@vmware.com>
Tue, 6 Jan 2015 12:13:43 +0000 (12:13 +0000)
For Kilo, the vendor-specific code should be moved to stackforge repo,
excluding the database models (https://review.openstack.org/#/c/134680/).
This patch adds the database model for VMWare NSXv plugin from
stackforge/vmware-nsx repo.

Partially-Implements: blueprint vmware-nsx-v

Change-Id: I17cbc1ba59131bd3bdefa232800842a9e739945f

neutron/db/migration/alembic_migrations/versions/4dbe243cd84d_nsxv.py [new file with mode: 0644]
neutron/db/migration/alembic_migrations/versions/HEAD
neutron/db/migration/models/head.py
neutron/plugins/vmware/common/nsxv_constants.py [new file with mode: 0644]
neutron/plugins/vmware/dbexts/nsxv_models.py [new file with mode: 0644]

diff --git a/neutron/db/migration/alembic_migrations/versions/4dbe243cd84d_nsxv.py b/neutron/db/migration/alembic_migrations/versions/4dbe243cd84d_nsxv.py
new file mode 100644 (file)
index 0000000..5867f6c
--- /dev/null
@@ -0,0 +1,166 @@
+# Copyright 2015 OpenStack Foundation
+#
+#    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.
+#
+
+"""nsxv
+
+Revision ID: 4dbe243cd84d
+Revises: 38495dc99731
+Create Date: 2015-01-05 23:22:04.501609
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '4dbe243cd84d'
+down_revision = '38495dc99731'
+from alembic import op
+import sqlalchemy as sa
+
+
+appliance_sizes_enum = sa.Enum('compact', 'large', 'xlarge', 'quadlarge',
+                               name='nsxv_router_bindings_appliance_size')
+edge_types_enum = sa.Enum('service', 'vdr',
+                          name='nsxv_router_bindings_edge_type')
+internal_network_purpose_enum = sa.Enum('inter_edge_net',
+                                        name='nsxv_internal_networks_purpose')
+internal_edge_purpose_enum = sa.Enum('inter_edge_net',
+                                     name='nsxv_internal_edges_purpose')
+tz_binding_type_enum = sa.Enum('flat', 'vlan', 'portgroup',
+                               name='nsxv_tz_network_bindings_binding_type')
+
+
+def upgrade():
+    op.create_table(
+        'nsxv_router_bindings',
+        sa.Column('status', sa.String(length=16), nullable=False),
+        sa.Column('status_description', sa.String(length=255), nullable=True),
+        sa.Column('router_id', sa.String(length=36), nullable=False),
+        sa.Column('edge_id', sa.String(length=36), nullable=True),
+        sa.Column('lswitch_id', sa.String(length=36), nullable=True),
+        sa.Column('appliance_size',
+                  appliance_sizes_enum,
+                  nullable=True),
+        sa.Column('edge_type', edge_types_enum, nullable=True),
+        sa.PrimaryKeyConstraint('router_id'))
+    op.create_table(
+        'nsxv_internal_networks',
+        sa.Column('network_purpose', internal_network_purpose_enum,
+                  nullable=False),
+        sa.Column('network_id', sa.String(length=36), nullable=False),
+        sa.ForeignKeyConstraint(['network_id'], ['networks.id'],
+                                ondelete='CASCADE'),
+        sa.PrimaryKeyConstraint('network_purpose'))
+    op.create_table(
+        'nsxv_internal_edges',
+        sa.Column('ext_ip_address', sa.String(length=64), nullable=False),
+        sa.Column('router_id', sa.String(length=36), nullable=False),
+        sa.Column('purpose', internal_edge_purpose_enum, nullable=True),
+        sa.PrimaryKeyConstraint('ext_ip_address'))
+    op.create_table(
+        'nsxv_firewall_rule_bindings',
+        sa.Column('rule_id', sa.String(length=36), nullable=False),
+        sa.Column('edge_id', sa.String(length=36), nullable=False),
+        sa.Column('rule_vse_id', sa.String(length=36), nullable=True),
+        sa.PrimaryKeyConstraint('rule_id', 'edge_id'))
+    op.create_table(
+        'nsxv_edge_dhcp_static_bindings',
+        sa.Column('edge_id', sa.String(length=36), nullable=False),
+        sa.Column('mac_address', sa.String(length=32), nullable=False),
+        sa.Column('binding_id', sa.String(length=36), nullable=False),
+        sa.PrimaryKeyConstraint('edge_id', 'mac_address'))
+    op.create_table(
+        'nsxv_edge_vnic_bindings',
+        sa.Column('edge_id', sa.String(length=36), nullable=False),
+        sa.Column('vnic_index', sa.Integer(), nullable=False),
+        sa.Column('tunnel_index', sa.Integer(), nullable=False),
+        sa.Column('network_id', sa.String(length=36), nullable=True),
+        sa.PrimaryKeyConstraint('edge_id', 'vnic_index', 'tunnel_index'))
+    op.create_table(
+        'nsxv_spoofguard_policy_network_mappings',
+        sa.Column('network_id', sa.String(length=36), nullable=False),
+        sa.Column('policy_id', sa.String(length=36), nullable=False),
+        sa.ForeignKeyConstraint(['network_id'], ['networks.id'],
+                                ondelete='CASCADE'),
+        sa.PrimaryKeyConstraint('network_id'))
+    op.create_table(
+        'nsxv_security_group_section_mappings',
+        sa.Column('neutron_id', sa.String(length=36), nullable=False),
+        sa.Column('ip_section_id', sa.String(length=100), nullable=True),
+        sa.ForeignKeyConstraint(['neutron_id'], ['securitygroups.id'],
+                                ondelete='CASCADE'),
+        sa.PrimaryKeyConstraint('neutron_id'))
+    op.create_table(
+        'nsxv_tz_network_bindings',
+        sa.Column('network_id', sa.String(length=36), nullable=False),
+        sa.Column('binding_type',
+                  tz_binding_type_enum,
+                  nullable=False),
+        sa.Column('phy_uuid', sa.String(length=36), nullable=True),
+        sa.Column('vlan_id', sa.Integer(), autoincrement=False, nullable=True),
+        sa.ForeignKeyConstraint(['network_id'], ['networks.id'],
+                                ondelete='CASCADE'),
+        sa.PrimaryKeyConstraint('network_id', 'binding_type', 'phy_uuid',
+                                'vlan_id'))
+    op.create_table(
+        'nsxv_port_vnic_mappings',
+        sa.Column('neutron_id', sa.String(length=36), nullable=False),
+        sa.Column('nsx_id', sa.String(length=42), nullable=False),
+        sa.ForeignKeyConstraint(['neutron_id'], ['ports.id'],
+                                ondelete='CASCADE'),
+        sa.PrimaryKeyConstraint('neutron_id', 'nsx_id'))
+    op.create_table(
+        'nsxv_port_index_mappings',
+        sa.Column('port_id', sa.String(length=36), nullable=False),
+        sa.Column('device_id', sa.String(length=255), nullable=False),
+        sa.Column('index', sa.Integer(), nullable=False),
+        sa.ForeignKeyConstraint(['port_id'], ['ports.id'], ondelete='CASCADE'),
+        sa.PrimaryKeyConstraint('port_id'),
+        sa.UniqueConstraint('device_id', 'index'))
+    op.create_table(
+        'nsxv_rule_mappings',
+        sa.Column('neutron_id', sa.String(length=36), nullable=False),
+        sa.Column('nsx_rule_id', sa.String(length=36), nullable=False),
+        sa.ForeignKeyConstraint(['neutron_id'], ['securitygrouprules.id'],
+                                ondelete='CASCADE'),
+        sa.PrimaryKeyConstraint('neutron_id', 'nsx_rule_id'))
+    op.create_table(
+        'nsxv_router_ext_attributes',
+        sa.Column('router_id', sa.String(length=36), nullable=False),
+        sa.Column('distributed', sa.Boolean(), nullable=False),
+        sa.Column('exclusive', sa.Boolean(), nullable=False),
+        sa.Column('service_router', sa.Boolean(), nullable=False),
+        sa.ForeignKeyConstraint(['router_id'], ['routers.id'],
+                                ondelete='CASCADE'),
+        sa.PrimaryKeyConstraint('router_id'))
+
+
+def downgrade():
+    op.drop_table('nsxv_router_ext_attributes')
+    op.drop_table('nsxv_rule_mappings')
+    op.drop_table('nsxv_port_index_mappings')
+    op.drop_table('nsxv_port_vnic_mappings')
+    op.drop_table('nsxv_tz_network_bindings')
+    op.drop_table('nsxv_section_mappings')
+    op.drop_table('nsxv_spoofguard_policy_network_mappings')
+    op.drop_table('nsxv_edge_vnic_bindings')
+    op.drop_table('nsxv_edge_dhcp_static_bindings')
+    op.drop_table('nsxv_firewall_rule_bindings')
+    op.drop_table('nsxv_internal_edges')
+    op.drop_table('nsxv_internal_networks')
+    op.drop_table('nsxv_router_bindings')
+    appliance_sizes_enum.drop(op.get_bind(), checkfirst=False)
+    edge_types_enum.drop(op.get_bind(), checkfirst=False)
+    internal_network_purpose_enum.drop(op.get_bind(), checkfirst=False)
+    internal_edge_purpose_enum.drop(op.get_bind(), checkfirst=False)
+    tz_binding_type_enum.drop(op.get_bind(), checkfirst=False)
\ No newline at end of file
index f7415c8a2d62a0a94437d9e9c0913e993fde2f8f..a3793d94d4104b01958a45c0d118601d43e131f6 100644 (file)
@@ -1 +1 @@
-38495dc99731
\ No newline at end of file
+4dbe243cd84d
index 43222e477d7db8e15823ae449eed4b1229bbe47c..7c46b8b5f9c7ddb6ac723b6807144a9be7b4c1c9 100644 (file)
@@ -71,6 +71,7 @@ from neutron.plugins.vmware.dbexts import lsn_db  # noqa
 from neutron.plugins.vmware.dbexts import maclearning  # noqa
 from neutron.plugins.vmware.dbexts import models as vmware_models  # noqa
 from neutron.plugins.vmware.dbexts import networkgw_db  # noqa
+from neutron.plugins.vmware.dbexts import nsxv_models  # noqa
 from neutron.plugins.vmware.dbexts import qos_db  # noqa
 from neutron.plugins.vmware.dbexts import vcns_models  # noqa
 
diff --git a/neutron/plugins/vmware/common/nsxv_constants.py b/neutron/plugins/vmware/common/nsxv_constants.py
new file mode 100644 (file)
index 0000000..3d1ae85
--- /dev/null
@@ -0,0 +1,28 @@
+# Copyright 2015 VMware, 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.
+
+# Edge size
+COMPACT = 'compact'
+LARGE = 'large'
+XLARGE = 'xlarge'
+QUADLARGE = 'quadlarge'
+
+
+# Edge type
+SERVICE_EDGE = 'service'
+VDR_EDGE = 'vdr'
+
+# Internal element purpose
+INTER_EDGE_PURPOSE = 'inter_edge_net'
diff --git a/neutron/plugins/vmware/dbexts/nsxv_models.py b/neutron/plugins/vmware/dbexts/nsxv_models.py
new file mode 100644 (file)
index 0000000..4e9cecd
--- /dev/null
@@ -0,0 +1,235 @@
+# Copyright 2015 VMware, 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 sqlalchemy as sa
+from sqlalchemy import orm
+
+from neutron.db import l3_db
+from neutron.db import model_base
+from neutron.db import models_v2
+from neutron.plugins.vmware.common import nsxv_constants
+
+
+class NsxvRouterBinding(model_base.BASEV2, models_v2.HasStatusDescription):
+    """Represents the mapping between neutron router and vShield Edge."""
+
+    __tablename__ = 'nsxv_router_bindings'
+
+    # no ForeignKey to routers.id because for now, a router can be removed
+    # from routers when delete_router is executed, but the binding is only
+    # removed after the Edge is deleted
+    router_id = sa.Column(sa.String(36),
+                          primary_key=True)
+    edge_id = sa.Column(sa.String(36),
+                        nullable=True)
+    lswitch_id = sa.Column(sa.String(36),
+                           nullable=True)
+    appliance_size = sa.Column(sa.Enum(
+        nsxv_constants.COMPACT,
+        nsxv_constants.LARGE,
+        nsxv_constants.XLARGE,
+        nsxv_constants.QUADLARGE,
+        name='nsxv_router_bindings_appliance_size'))
+    edge_type = sa.Column(sa.Enum(nsxv_constants.SERVICE_EDGE,
+                                  nsxv_constants.VDR_EDGE,
+                                  name='nsxv_router_bindings_edge_type'))
+
+
+class NsxvEdgeVnicBinding(model_base.BASEV2):
+    """Represents mapping between vShield Edge vnic and neutron netowrk."""
+
+    __tablename__ = 'nsxv_edge_vnic_bindings'
+
+    edge_id = sa.Column(sa.String(36),
+                        primary_key=True)
+    vnic_index = sa.Column(sa.Integer(),
+                           primary_key=True)
+    tunnel_index = sa.Column(sa.Integer(),
+                             primary_key=True)
+    network_id = sa.Column(sa.String(36), nullable=True)
+
+
+class NsxvEdgeDhcpStaticBinding(model_base.BASEV2):
+    """Represents mapping between mac addr and bindingId."""
+
+    __tablename__ = 'nsxv_edge_dhcp_static_bindings'
+
+    edge_id = sa.Column(sa.String(36), primary_key=True)
+    mac_address = sa.Column(sa.String(32), primary_key=True)
+    binding_id = sa.Column(sa.String(36), nullable=False)
+
+
+class NsxvInternalNetworks(model_base.BASEV2):
+    """Represents internal networks between NSXV plugin elements."""
+
+    __tablename__ = 'nsxv_internal_networks'
+
+    network_purpose = sa.Column(
+        sa.Enum(nsxv_constants.INTER_EDGE_PURPOSE,
+                name='nsxv_internal_networks_purpose'),
+        primary_key=True)
+    network_id = sa.Column(sa.String(36),
+                           sa.ForeignKey("networks.id", ondelete="CASCADE"),
+                           nullable=False)
+
+
+class NsxvInternalEdges(model_base.BASEV2):
+    """Represents internal Edge appliances for NSXV plugin operations."""
+
+    __tablename__ = 'nsxv_internal_edges'
+
+    ext_ip_address = sa.Column(sa.String(64), primary_key=True)
+    router_id = sa.Column(sa.String(36), nullable=False)
+    purpose = sa.Column(
+        sa.Enum(nsxv_constants.INTER_EDGE_PURPOSE,
+                name='nsxv_internal_edges_purpose'))
+
+
+class NsxvSecurityGroupSectionMapping(model_base.BASEV2):
+    """Backend mappings for Neutron Rule Sections.
+
+    This class maps a neutron security group identifier to the corresponding
+    NSX layer 3 section.
+    """
+
+    __tablename__ = 'nsxv_security_group_section_mappings'
+    neutron_id = sa.Column(sa.String(36),
+                           sa.ForeignKey('securitygroups.id',
+                                         ondelete="CASCADE"),
+                           primary_key=True)
+    ip_section_id = sa.Column(sa.String(100))
+
+
+class NsxvRuleMapping(model_base.BASEV2):
+    """Backend mappings for Neutron Rule Sections.
+
+    This class maps a neutron security group identifier to the corresponding
+    NSX layer 3 and layer 2 sections.
+    """
+
+    __tablename__ = 'nsxv_rule_mappings'
+
+    neutron_id = sa.Column(sa.String(36),
+                           sa.ForeignKey('securitygrouprules.id',
+                                         ondelete="CASCADE"),
+                           primary_key=True)
+    nsx_rule_id = sa.Column(sa.String(36), primary_key=True)
+
+
+class NsxvPortVnicMapping(model_base.BASEV2):
+    """Maps neutron port to NSXv VM Vnic Id."""
+
+    __tablename__ = 'nsxv_port_vnic_mappings'
+
+    neutron_id = sa.Column(sa.String(36),
+                           sa.ForeignKey('ports.id', ondelete="CASCADE"),
+                           primary_key=True)
+    nsx_id = sa.Column(sa.String(42), primary_key=True)
+
+
+class NsxvRouterExtAttributes(model_base.BASEV2):
+    """Router attributes managed by NSX plugin extensions."""
+
+    __tablename__ = 'nsxv_router_ext_attributes'
+
+    router_id = sa.Column(sa.String(36),
+                          sa.ForeignKey('routers.id', ondelete="CASCADE"),
+                          primary_key=True)
+    distributed = sa.Column(sa.Boolean, default=False, nullable=False)
+    exclusive = sa.Column(sa.Boolean, default=False, nullable=False)
+    service_router = sa.Column(sa.Boolean, default=False, nullable=False)
+    # Add a relationship to the Router model in order to instruct
+    # SQLAlchemy to eagerly load this association
+    router = orm.relationship(
+        l3_db.Router,
+        backref=orm.backref("nsx_attributes", lazy='joined',
+                            uselist=False, cascade='delete'))
+
+
+class NsxvTzNetworkBinding(model_base.BASEV2):
+    """Represents a binding of a virtual network with a transport zone.
+
+    This model class associates a Neutron network with a transport zone;
+    optionally a vlan ID might be used if the binding type is 'bridge'
+    """
+
+    __tablename__ = 'nsxv_tz_network_bindings'
+
+    network_id = sa.Column(sa.String(36),
+                           sa.ForeignKey('networks.id', ondelete="CASCADE"),
+                           primary_key=True)
+    binding_type = sa.Column(sa.Enum('flat', 'vlan', 'portgroup',
+                                     name='tz_network_bindings_binding_type'),
+                             nullable=False, primary_key=True)
+    phy_uuid = sa.Column(sa.String(36), primary_key=True, nullable=True)
+    vlan_id = sa.Column(sa.Integer, primary_key=True, nullable=True,
+                        autoincrement=False)
+
+    def __init__(self, network_id, binding_type, phy_uuid, vlan_id):
+        self.network_id = network_id
+        self.binding_type = binding_type
+        self.phy_uuid = phy_uuid
+        self.vlan_id = vlan_id
+
+    def __repr__(self):
+        return "<NsxvTzNetworkBinding(%s,%s,%s,%s)>" % (self.network_id,
+                                                        self.binding_type,
+                                                        self.phy_uuid,
+                                                        self.vlan_id)
+
+
+class NsxvPortIndexMapping(model_base.BASEV2):
+    """Associates attached Neutron ports with the instance VNic index."""
+
+    __tablename__ = 'nsxv_port_index_mappings'
+
+    port_id = sa.Column(sa.String(36),
+                        sa.ForeignKey('ports.id', ondelete="CASCADE"),
+                        primary_key=True)
+    device_id = sa.Column(sa.String(255), nullable=False)
+    index = sa.Column(sa.Integer, nullable=False)
+    __table_args__ = (sa.UniqueConstraint(device_id, index),)
+
+    # Add a relationship to the Port model in order to instruct SQLAlchemy to
+    # eagerly read port vnic-index
+    port = orm.relationship(
+        models_v2.Port,
+        backref=orm.backref("vnic_index", lazy='joined',
+                            uselist=False, cascade='delete'))
+
+
+class NsxvEdgeFirewallRuleBinding(model_base.BASEV2):
+    """Mapping between firewall rule and edge firewall rule_id."""
+
+    __tablename__ = 'nsxv_firewall_rule_bindings'
+
+    rule_id = sa.Column(sa.String(36),
+                        primary_key=True)
+    edge_id = sa.Column(sa.String(36), primary_key=True)
+    rule_vse_id = sa.Column(sa.String(36))
+
+
+class NsxvSpoofGuardPolicyNetworkMapping(model_base.BASEV2):
+    """Mapping between SpoofGuard and neutron networks"""
+
+    __tablename__ = 'nsxv_spoofguard_policy_network_mappings'
+
+    network_id = sa.Column(sa.String(36),
+                           sa.ForeignKey('networks.id', ondelete='CASCADE'),
+                           primary_key=True,
+                           nullable=False)
+    policy_id = sa.Column(sa.String(36), nullable=False)