173 lines
6.8 KiB
Python
173 lines
6.8 KiB
Python
# (c) Copyright 2015 Cisco Systems Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
#
|
|
|
|
"""Multiple local subnets
|
|
|
|
Revision ID: 2cb4ee992b41
|
|
Revises: 2c82e782d734
|
|
Create Date: 2015-09-09 20:32:54.254267
|
|
|
|
"""
|
|
|
|
from alembic import op
|
|
from oslo_utils import uuidutils
|
|
import sqlalchemy as sa
|
|
from sqlalchemy.sql import expression as sa_expr
|
|
|
|
from neutron.db import migration
|
|
|
|
from neutron_vpnaas.services.vpn.common import constants as v_constants
|
|
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision = '2cb4ee992b41'
|
|
down_revision = '2c82e782d734'
|
|
depends_on = ('28ee739a7e4b',)
|
|
|
|
# milestone identifier, used by neutron-db-manage
|
|
neutron_milestone = [migration.MITAKA]
|
|
|
|
|
|
vpnservices = sa.Table(
|
|
'vpnservices', sa.MetaData(),
|
|
sa.Column('id', sa.String(length=36), nullable=False),
|
|
sa.Column('tenant_id', sa.String(length=255), nullable=False),
|
|
sa.Column('name', sa.String(255)),
|
|
sa.Column('description', sa.String(255)),
|
|
sa.Column('status', sa.String(16), nullable=False),
|
|
sa.Column('admin_state_up', sa.Boolean(), nullable=False),
|
|
sa.Column('external_v4_ip', sa.String(16)),
|
|
sa.Column('external_v6_ip', sa.String(64)),
|
|
sa.Column('subnet_id', sa.String(36)),
|
|
sa.Column('router_id', sa.String(36), nullable=False))
|
|
|
|
ipsec_site_conns = sa.Table(
|
|
'ipsec_site_connections', sa.MetaData(),
|
|
sa.Column('id', sa.String(length=36), nullable=False),
|
|
sa.Column('tenant_id', sa.String(length=255), nullable=False),
|
|
sa.Column('name', sa.String(255)),
|
|
sa.Column('description', sa.String(255)),
|
|
sa.Column('peer_address', sa.String(255), nullable=False),
|
|
sa.Column('peer_id', sa.String(255), nullable=False),
|
|
sa.Column('route_mode', sa.String(8), nullable=False),
|
|
sa.Column('mtu', sa.Integer, nullable=False),
|
|
sa.Column('initiator', sa.Enum("bi-directional", "response-only",
|
|
name="vpn_initiators"), nullable=False),
|
|
sa.Column('auth_mode', sa.String(16), nullable=False),
|
|
sa.Column('psk', sa.String(255), nullable=False),
|
|
sa.Column('dpd_action', sa.Enum("hold", "clear", "restart", "disabled",
|
|
"restart-by-peer", name="vpn_dpd_actions"),
|
|
nullable=False),
|
|
sa.Column('dpd_interval', sa.Integer, nullable=False),
|
|
sa.Column('dpd_timeout', sa.Integer, nullable=False),
|
|
sa.Column('status', sa.String(16), nullable=False),
|
|
sa.Column('admin_state_up', sa.Boolean(), nullable=False),
|
|
sa.Column('vpnservice_id', sa.String(36), nullable=False),
|
|
sa.Column('ipsecpolicy_id', sa.String(36), nullable=False),
|
|
sa.Column('ikepolicy_id', sa.String(36), nullable=False),
|
|
sa.Column('local_ep_group_id', sa.String(36)),
|
|
sa.Column('peer_ep_group_id', sa.String(36)))
|
|
|
|
ipsecpeercidrs = sa.Table(
|
|
'ipsecpeercidrs', sa.MetaData(),
|
|
sa.Column('cidr', sa.String(32), nullable=False, primary_key=True),
|
|
sa.Column('ipsec_site_connection_id', sa.String(36), primary_key=True))
|
|
|
|
|
|
def _make_endpoint_groups(new_groups, new_endpoints):
|
|
"""Create endpoint groups and their corresponding endpoints."""
|
|
md = sa.MetaData()
|
|
engine = op.get_bind()
|
|
sa.Table('vpn_endpoint_groups', md, autoload_with=engine)
|
|
op.bulk_insert(md.tables['vpn_endpoint_groups'], new_groups)
|
|
sa.Table('vpn_endpoints', md, autoload_with=engine)
|
|
op.bulk_insert(md.tables['vpn_endpoints'], new_endpoints)
|
|
|
|
|
|
def _update_connections(connection_map):
|
|
"""Store the endpoint group IDs in the connections."""
|
|
for conn_id, mapping in connection_map.items():
|
|
stmt = ipsec_site_conns.update().where(
|
|
ipsec_site_conns.c.id == conn_id).values(
|
|
local_ep_group_id=mapping['local'],
|
|
peer_ep_group_id=mapping['peer'])
|
|
op.execute(stmt)
|
|
|
|
|
|
def upgrade():
|
|
new_groups = []
|
|
new_endpoints = []
|
|
service_map = {}
|
|
session = sa.orm.Session(bind=op.get_bind())
|
|
vpn_services = session.query(vpnservices).filter(
|
|
vpnservices.c.subnet_id is not None).all()
|
|
for vpn_service in vpn_services:
|
|
subnet_id = vpn_service.subnet_id
|
|
if subnet_id is None:
|
|
continue # Skip new service entries
|
|
# Define the subnet group
|
|
group_id = uuidutils.generate_uuid()
|
|
group = {'id': group_id,
|
|
'name': '',
|
|
'description': '',
|
|
'tenant_id': vpn_service.tenant_id,
|
|
'endpoint_type': v_constants.SUBNET_ENDPOINT}
|
|
new_groups.append(group)
|
|
# Define the (sole) endpoint
|
|
endpoint = {'endpoint_group_id': group_id,
|
|
'endpoint': subnet_id}
|
|
new_endpoints.append(endpoint)
|
|
# Save info to use for connections
|
|
service_map[vpn_service.id] = group_id
|
|
|
|
connection_map = {}
|
|
ipsec_conns = session.query(ipsec_site_conns).all()
|
|
for connection in ipsec_conns:
|
|
peer_cidrs = session.query(ipsecpeercidrs.c.cidr).filter(
|
|
ipsecpeercidrs.c.ipsec_site_connection_id == connection.id).all()
|
|
if not peer_cidrs:
|
|
continue # Skip new style connections
|
|
# Define the CIDR group
|
|
group_id = uuidutils.generate_uuid()
|
|
group = {'id': group_id,
|
|
'name': '',
|
|
'description': '',
|
|
'tenant_id': connection.tenant_id,
|
|
'endpoint_type': v_constants.CIDR_ENDPOINT}
|
|
new_groups.append(group)
|
|
# Define the endpoint(s)
|
|
for peer_cidr in peer_cidrs:
|
|
endpoint = {'endpoint_group_id': group_id,
|
|
'endpoint': peer_cidr[0]}
|
|
new_endpoints.append(endpoint)
|
|
# Save the endpoint group ID info for the connection
|
|
vpn_service = connection.vpnservice_id
|
|
connection_map[connection.id] = {'local': service_map[vpn_service],
|
|
'peer': group_id}
|
|
|
|
# Create all the defined endpoint groups and their endpoints
|
|
_make_endpoint_groups(new_groups, new_endpoints)
|
|
# Refer to new groups, in the IPSec connections
|
|
_update_connections(connection_map)
|
|
|
|
# Remove the peer_cidrs from IPSec connections
|
|
op.execute(sa_expr.table('ipsecpeercidrs').delete())
|
|
# Remove the subnets from VPN services
|
|
stmt = vpnservices.update().where(
|
|
vpnservices.c.subnet_id is not None).values(
|
|
subnet_id=None)
|
|
op.execute(stmt)
|
|
session.commit()
|