99 lines
3.8 KiB
Python
99 lines
3.8 KiB
Python
# Copyright 2015 Cisco Systems 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.
|
|
|
|
from neutron_lib.db import model_base
|
|
from neutron_lib.exceptions import firewall_v1 as fwrtrins
|
|
from oslo_log import helpers as log_helpers
|
|
from oslo_log import log as logging
|
|
import sqlalchemy as sa
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class FirewallRouterAssociation(model_base.BASEV2):
|
|
|
|
"""Tracks FW Router Association"""
|
|
|
|
__tablename__ = 'firewall_router_associations'
|
|
|
|
fw_id = sa.Column(sa.String(36),
|
|
sa.ForeignKey('firewalls.id', ondelete="CASCADE"),
|
|
primary_key=True)
|
|
router_id = sa.Column(sa.String(36),
|
|
sa.ForeignKey('routers.id', ondelete="CASCADE"),
|
|
primary_key=True)
|
|
|
|
|
|
class FirewallRouterInsertionDbMixin(object):
|
|
|
|
"""Access methods for the firewall_router_associations table."""
|
|
|
|
@log_helpers.log_method_call
|
|
def set_routers_for_firewall(self, context, fw):
|
|
"""Sets the routers associated with the fw."""
|
|
with context.session.begin(subtransactions=True):
|
|
for r_id in fw['router_ids']:
|
|
fw_rtr_db = FirewallRouterAssociation(fw_id=fw['fw_id'],
|
|
router_id=r_id)
|
|
context.session.add(fw_rtr_db)
|
|
|
|
@log_helpers.log_method_call
|
|
def get_firewall_routers(self, context, fwid):
|
|
"""Gets all routers associated with a firewall."""
|
|
with context.session.begin(subtransactions=True):
|
|
fw_rtr_qry = context.session.query(
|
|
FirewallRouterAssociation.router_id)
|
|
fw_rtr_rows = fw_rtr_qry.filter_by(fw_id=fwid)
|
|
fw_rtrs = [entry.router_id for entry in fw_rtr_rows]
|
|
LOG.debug("get_firewall_routers(): fw_rtrs: %s", fw_rtrs)
|
|
return fw_rtrs
|
|
|
|
@log_helpers.log_method_call
|
|
def validate_firewall_routers_not_in_use(
|
|
self, context, router_ids, fwid=None):
|
|
"""Validate if router-ids not associated with any firewall.
|
|
|
|
If any of the router-ids in the list is already associated with
|
|
a firewall, raise an exception else just return.
|
|
"""
|
|
fw_rtr_qry = context.session.query(FirewallRouterAssociation.router_id)
|
|
fw_rtrs = fw_rtr_qry.filter(
|
|
FirewallRouterAssociation.router_id.in_(router_ids),
|
|
FirewallRouterAssociation.fw_id != fwid).all()
|
|
if fw_rtrs:
|
|
router_ids = [entry.router_id for entry in fw_rtrs]
|
|
raise fwrtrins.FirewallRouterInUse(router_ids=router_ids)
|
|
|
|
@log_helpers.log_method_call
|
|
def update_firewall_routers(self, context, fw):
|
|
"""Update the firewall with new routers.
|
|
|
|
This involves removing existing router associations and replacing
|
|
it with the new router associations provided in the update method.
|
|
"""
|
|
with context.session.begin(subtransactions=True):
|
|
fw_rtr_qry = context.session.query(FirewallRouterAssociation)
|
|
fw_rtr_qry.filter_by(fw_id=fw['fw_id']).delete()
|
|
if fw['router_ids']:
|
|
self.set_routers_for_firewall(context, fw)
|
|
|
|
# TODO(sridar): Investigate potential corner case if rpc failure
|
|
# happens on PENDING_UPDATE and agent did not restart. Evaluate
|
|
# complexity vs benefit of holding on to old entries until ack
|
|
# from agent.
|
|
|
|
return fw
|