Skip to content

Commit d541ee9

Browse files
committed
Make DB migration creating indexes in RBACs conditional
This patch makes conditional the existing DB migration that adds the new indexes "target_tenant" and "action" in the "*rbacs" tables. The rationale of this patch is to be able to manually improve older systems by just manually creating the indexes in the database. Once these indexes are added, those operations including RBACs checks (all these called from non-admin user to RBAC administrated resourced) will be improved. This patch is avoiding the migration issue a system could find if these indexes have been manually added and then the system is upgraded. The new check added will first retrieve the table indexes; if the index is already present, the index addition is skipped. Closes-Bug: #2020802 Change-Id: I1962fbc844bb67180e9071bcee01f8e95853bdda (cherry picked from commit e8cd39b)
1 parent b6145ee commit d541ee9

File tree

3 files changed

+114
-1
lines changed

3 files changed

+114
-1
lines changed

doc/source/admin/config-rbac.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,3 +804,37 @@ IDs.
804804
If an operator wants to prevent normal users from doing this, the
805805
``"create_rbac_policy":`` entry in ``policy.yaml`` can be adjusted
806806
from ``""`` to ``"rule:admin_only"``.
807+
808+
809+
Improve database RBAC query operations
810+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
811+
812+
Since [1]_, present in Yoga version, Neutron has indexes for
813+
"target_tenant" (now "target_project") and "action" columns in all
814+
RBAC related tables. That improves the SQL queries involving the
815+
RBAC tables [2]_. Any system before Yoga won't have these indexes
816+
but the system administrator can manually add them to the Neutron
817+
database following the next steps:
818+
819+
* Find the RBAC tables:
820+
821+
.. code-block:: console
822+
823+
$ tables=`mysql -e "use ovs_neutron; show tables;" | grep rbac`
824+
825+
826+
* Insert the indexes for the "target_tenant" and "action" columns:
827+
828+
$ for table in $tables do; mysql -e \
829+
"alter table $table add key (action); alter table $table add key (target_tenant);"; done
830+
831+
832+
In order to prevent errors during a system upgrade, [3]_ was
833+
implemented and backported up to Yoga. This patch checks if any index
834+
is already present in the Neutron tables and avoids executing the
835+
index creation command again.
836+
837+
838+
.. [1] https://review.opendev.org/c/openstack/neutron/+/810072
839+
.. [2] https://github.com/openstack/neutron-lib/blob/890d62a3df3f35bb18bf1a11e79a9e97e7dd2d2c/neutron_lib/db/model_query.py#L123-L131
840+
.. [3] https://review.opendev.org/c/openstack/neutron/+/884617

neutron/db/migration/alembic_migrations/versions/yoga/expand/ba859d649675_add_indexes_to_rbacs.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#
1515

1616
from alembic import op
17+
import sqlalchemy as sa
1718

1819

1920
"""Add indexes to RBACs
@@ -31,11 +32,34 @@
3132
OBJECTS = ('network', 'qospolicy', 'securitygroup', 'addressscope',
3233
'subnetpool', 'addressgroup')
3334
COLUMNS = ('target_tenant', 'action')
35+
_INSPECTOR = None
36+
37+
38+
def get_inspector():
39+
global _INSPECTOR
40+
if _INSPECTOR:
41+
return _INSPECTOR
42+
else:
43+
_INSPECTOR = sa.inspect(op.get_bind())
44+
45+
return _INSPECTOR
46+
47+
48+
def has_index(table, column):
49+
"""Check if the table has an index *using only* the column name provided"""
50+
inspector = get_inspector()
51+
table_indexes = inspector.get_indexes(table)
52+
for index in table_indexes:
53+
if [column] == index['column_names']:
54+
return True
55+
return False
3456

3557

3658
def upgrade():
3759
for object in OBJECTS:
3860
table = object + 'rbacs'
3961
ix = 'ix_' + table + '_'
4062
for column in COLUMNS:
41-
op.create_index(op.f(ix + column), table, [column], unique=False)
63+
if not has_index(table, column):
64+
op.create_index(op.f(ix + column), table, [column],
65+
unique=False)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Copyright 2017 OpenStack Foundation
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
#
15+
16+
from oslo_db.sqlalchemy import utils as db_utils
17+
18+
from neutron.db.migration.alembic_migrations.versions.yoga.expand import \
19+
ba859d649675_add_indexes_to_rbacs as _migration
20+
from neutron.tests.functional.db import test_migrations
21+
22+
23+
class TestAddIndexesToRbacsMixin(object):
24+
"""Validates binding_index for NetworkDhcpAgentBinding migration."""
25+
26+
@staticmethod
27+
def get_index(table_indexes, column):
28+
for index in table_indexes:
29+
if [column] == index['column_names']:
30+
return True
31+
return False
32+
33+
def _pre_upgrade_ba859d649675(self, engine):
34+
for table in _migration.OBJECTS:
35+
table_indexes = db_utils.get_indexes(engine, table + 'rbacs')
36+
for column in _migration.COLUMNS:
37+
self.assertFalse(self.get_index(table_indexes, column))
38+
39+
def _check_ba859d649675(self, engine, data):
40+
for table in _migration.OBJECTS:
41+
table_indexes = db_utils.get_indexes(engine, table + 'rbacs')
42+
for column in _migration.COLUMNS:
43+
self.assertTrue(self.get_index(table_indexes, column))
44+
45+
46+
class TestAddIndexesToRbacsMySQL(
47+
TestAddIndexesToRbacsMixin,
48+
test_migrations.TestWalkMigrationsMySQL):
49+
pass
50+
51+
52+
class TestAddIndexesToRbacsPostgreSQL(
53+
TestAddIndexesToRbacsMixin,
54+
test_migrations.TestWalkMigrationsPostgreSQL):
55+
pass

0 commit comments

Comments
 (0)