Make "project_id" in "L3HARouterNetwork" unique constraint
There could be just only one HA network per project. This database enforcement guarantees this limitation. Partial-Bug: #2016198 Change-Id: Ieb8aac6244d384b0af522f9ba145e9367de2c8ef
This commit is contained in:
parent
98ac1fa31a
commit
6a2ccfac32
@ -33,6 +33,7 @@ from neutron.db.extra_dhcp_opt import models as extra_dhcp_opt_models
|
||||
from neutron.db.models import agent as agent_model
|
||||
from neutron.db.models import external_net
|
||||
from neutron.db.models import l3 as l3_models
|
||||
from neutron.db.models import l3ha as l3ha_models
|
||||
from neutron.db.models.plugins.ml2 import vlanallocation
|
||||
from neutron.db.models import segment
|
||||
from neutron.db import models_v2
|
||||
@ -164,6 +165,16 @@ def get_fip_per_network_without_qos_policies(network_id):
|
||||
return query.count()
|
||||
|
||||
|
||||
def get_duplicated_ha_networks_per_project():
|
||||
"""Return those HA network reg. that have more than 1 entry per project"""
|
||||
ctx = context.get_admin_context()
|
||||
with db_api.CONTEXT_READER.using(ctx):
|
||||
query = ctx.session.query(l3ha_models.L3HARouterNetwork)
|
||||
query = query.group_by(l3ha_models.L3HARouterNetwork.project_id)
|
||||
query = query.having(func.count() > 1)
|
||||
return query.all()
|
||||
|
||||
|
||||
class CoreChecks(base.BaseChecks):
|
||||
|
||||
def get_checks(self):
|
||||
@ -192,6 +203,8 @@ class CoreChecks(base.BaseChecks):
|
||||
self.floatingip_inherit_qos_from_network),
|
||||
(_('Port extra DHCP options check'),
|
||||
self.extra_dhcp_options_check),
|
||||
(_('Duplicated HA network per project check'),
|
||||
self.extra_dhcp_options_check),
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
@ -528,3 +541,32 @@ class CoreChecks(base.BaseChecks):
|
||||
upgradecheck.Code.SUCCESS,
|
||||
_('There are no extra_dhcp_opts with the newline character '
|
||||
'in the option name or option value.'))
|
||||
|
||||
@staticmethod
|
||||
def duplicated_ha_network_per_project_check(checker):
|
||||
"""Check if there are duplicated HA networks per project
|
||||
|
||||
By definition there could be zero or one HA network per project. In
|
||||
case of having more than one register associated to any existing
|
||||
project (that should never happen), this check will fail.
|
||||
"""
|
||||
if not cfg.CONF.database.connection:
|
||||
return upgradecheck.Result(
|
||||
upgradecheck.Code.WARNING,
|
||||
_("Database connection string is not set. Check for "
|
||||
"extra_dhcp_opts can't be done."))
|
||||
|
||||
ha_networks = get_duplicated_ha_networks_per_project()
|
||||
project_ids = {ha_network['project_id'] for ha_network in ha_networks}
|
||||
network_ids = {ha_network['network_id'] for ha_network in ha_networks}
|
||||
if project_ids:
|
||||
return upgradecheck.Result(
|
||||
upgradecheck.Code.WARNING,
|
||||
_('The following projects have duplicated HA networks: '
|
||||
'%(project_ids)s. This is the list of duplicated HA '
|
||||
'networks: %(network_ids)s' %
|
||||
{'project_ids': project_ids, 'network_ids': network_ids}))
|
||||
|
||||
return upgradecheck.Result(
|
||||
upgradecheck.Code.SUCCESS,
|
||||
_('There are no duplicated HA networks in the system.'))
|
||||
|
@ -0,0 +1,40 @@
|
||||
# Copyright 2023 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.
|
||||
#
|
||||
|
||||
from alembic import op
|
||||
|
||||
|
||||
"""Create L3HARouterNetwork.project_id unique constraint
|
||||
|
||||
Revision ID: 682c319773d7
|
||||
Revises: 6f1145bff34c
|
||||
Create Date: 2023-04-27 13:45:05.103963
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '682c319773d7'
|
||||
down_revision = '6f1145bff34c'
|
||||
|
||||
|
||||
TABLE = 'ha_router_networks'
|
||||
COLUMN = 'project_id'
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.create_unique_constraint(
|
||||
constraint_name='uniq_%s0%s' % (TABLE, COLUMN),
|
||||
table_name=TABLE,
|
||||
columns=[COLUMN])
|
@ -1 +1 @@
|
||||
6f1145bff34c
|
||||
682c319773d7
|
||||
|
@ -67,6 +67,11 @@ class L3HARouterNetwork(model_base.BASEV2, model_base.HasProjectPrimaryKey):
|
||||
"""
|
||||
|
||||
__tablename__ = 'ha_router_networks'
|
||||
__table_args__ = (
|
||||
sa.UniqueConstraint('project_id',
|
||||
name='uniq_ha_router_networks0project_id'),
|
||||
model_base.BASEV2.__table_args__
|
||||
)
|
||||
|
||||
network_id = sa.Column(sa.String(36),
|
||||
sa.ForeignKey('networks.id', ondelete="CASCADE"),
|
||||
|
@ -278,3 +278,22 @@ class TestChecks(base.BaseTestCase):
|
||||
opt_value='bar\nbar')]
|
||||
result = checks.CoreChecks.extra_dhcp_options_check(mock.ANY)
|
||||
self.assertEqual(Code.WARNING, result.code)
|
||||
|
||||
@mock.patch.object(checks, 'get_duplicated_ha_networks_per_project')
|
||||
def test_duplicated_ha_network_per_project_check_success(self,
|
||||
mock_ha_nets):
|
||||
mock_ha_nets.return_value = []
|
||||
result = checks.CoreChecks.duplicated_ha_network_per_project_check(
|
||||
mock.ANY)
|
||||
self.assertEqual(Code.SUCCESS, result.code)
|
||||
|
||||
@mock.patch.object(checks, 'get_duplicated_ha_networks_per_project')
|
||||
def test_duplicated_ha_network_per_project_check_warning(self,
|
||||
mock_ha_nets):
|
||||
mock_ha_nets.return_value = [
|
||||
{'project_id': 'project1', 'network_id': 'net1'},
|
||||
{'project_id': 'project1', 'network_id': 'net2'},
|
||||
]
|
||||
result = checks.CoreChecks.duplicated_ha_network_per_project_check(
|
||||
mock.ANY)
|
||||
self.assertEqual(Code.WARNING, result.code)
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
other:
|
||||
- |
|
||||
Introduced a database constraint to limit the number of
|
||||
``ha_router_networks`` registers per project to one only. This register is
|
||||
used to bind projects and networks, defining the corresponding network
|
||||
as high availability (HA) network. By definition, only one HA network per
|
||||
project can exist.
|
Loading…
Reference in New Issue
Block a user