Support standard_attrs for fwaas resources
Now, this patch will support standard_attrs for firewall_group/firewall_rule/firewall_policy. Closes-Bug: #1986906 Change-Id: Ib7b06d604a0950a104215bcf4386e14b77d20d12
This commit is contained in:
parent
e479c1a1d6
commit
3b4e1bdda1
|
@ -22,6 +22,8 @@ from neutron_lib.db import api as db_api
|
|||
from neutron_lib.db import constants as db_constants
|
||||
from neutron_lib.db import model_base
|
||||
from neutron_lib.db import model_query
|
||||
from neutron_lib.db import resource_extend
|
||||
from neutron_lib.db import standard_attr
|
||||
from neutron_lib.db import utils as db_utils
|
||||
from neutron_lib import exceptions
|
||||
from neutron_lib.exceptions import firewall_v2 as f_exc
|
||||
|
@ -65,8 +67,8 @@ class HasDescription(object):
|
|||
sa.String(db_constants.LONG_DESCRIPTION_FIELD_SIZE))
|
||||
|
||||
|
||||
class FirewallRuleV2(model_base.BASEV2, model_base.HasId, HasName,
|
||||
HasDescription, model_base.HasProject):
|
||||
class FirewallRuleV2(standard_attr.HasStandardAttributes, model_base.BASEV2,
|
||||
model_base.HasId, HasName, model_base.HasProject):
|
||||
__tablename__ = "firewall_rules_v2"
|
||||
shared = sa.Column(sa.Boolean)
|
||||
protocol = sa.Column(sa.String(40))
|
||||
|
@ -80,18 +82,19 @@ class FirewallRuleV2(model_base.BASEV2, model_base.HasId, HasName,
|
|||
action = sa.Column(sa.Enum('allow', 'deny', 'reject',
|
||||
name='firewallrules_action'))
|
||||
enabled = sa.Column(sa.Boolean)
|
||||
api_collections = ['firewall_rules']
|
||||
collection_resource_map = {"firewall_rules": "firewall_rule"}
|
||||
tag_support = True
|
||||
|
||||
|
||||
class FirewallGroup(model_base.BASEV2, model_base.HasId, HasName,
|
||||
HasDescription, model_base.HasProject):
|
||||
class FirewallGroup(standard_attr.HasStandardAttributes, model_base.BASEV2,
|
||||
model_base.HasId, HasName, model_base.HasProject):
|
||||
__tablename__ = 'firewall_groups_v2'
|
||||
port_associations = orm.relationship(
|
||||
'FirewallGroupPortAssociation',
|
||||
backref=orm.backref('firewall_group_port_associations_v2',
|
||||
cascade='all, delete'))
|
||||
name = sa.Column(sa.String(db_constants.NAME_FIELD_SIZE))
|
||||
description = sa.Column(
|
||||
sa.String(db_constants.LONG_DESCRIPTION_FIELD_SIZE))
|
||||
ingress_firewall_policy_id = sa.Column(
|
||||
sa.String(db_constants.UUID_FIELD_SIZE),
|
||||
sa.ForeignKey('firewall_policies_v2.id'))
|
||||
|
@ -101,6 +104,9 @@ class FirewallGroup(model_base.BASEV2, model_base.HasId, HasName,
|
|||
admin_state_up = sa.Column(sa.Boolean)
|
||||
status = sa.Column(sa.String(db_constants.STATUS_FIELD_SIZE))
|
||||
shared = sa.Column(sa.Boolean)
|
||||
api_collections = ['firewall_groups']
|
||||
collection_resource_map = {"firewall_groups": "firewall_group"}
|
||||
tag_support = True
|
||||
|
||||
|
||||
class DefaultFirewallGroup(model_base.BASEV2, model_base.HasProjectPrimaryKey):
|
||||
|
@ -145,12 +151,10 @@ class FirewallPolicyRuleAssociation(model_base.BASEV2):
|
|||
position = sa.Column(sa.Integer)
|
||||
|
||||
|
||||
class FirewallPolicy(model_base.BASEV2, model_base.HasId, HasName,
|
||||
HasDescription, model_base.HasProject):
|
||||
class FirewallPolicy(standard_attr.HasStandardAttributes, model_base.BASEV2,
|
||||
model_base.HasId, HasName, model_base.HasProject):
|
||||
__tablename__ = 'firewall_policies_v2'
|
||||
name = sa.Column(sa.String(db_constants.NAME_FIELD_SIZE))
|
||||
description = sa.Column(
|
||||
sa.String(db_constants.LONG_DESCRIPTION_FIELD_SIZE))
|
||||
rule_count = sa.Column(sa.Integer)
|
||||
audited = sa.Column(sa.Boolean)
|
||||
rule_associations = orm.relationship(
|
||||
|
@ -159,6 +163,9 @@ class FirewallPolicy(model_base.BASEV2, model_base.HasId, HasName,
|
|||
order_by='FirewallPolicyRuleAssociation.position',
|
||||
collection_class=ordering_list('position', count_from=1))
|
||||
shared = sa.Column(sa.Boolean)
|
||||
api_collections = ['firewall_policies']
|
||||
collection_resource_map = {"firewall_policies": "firewall_policy"}
|
||||
tag_support = True
|
||||
|
||||
|
||||
def _list_firewall_groups_result_filter_hook(query, filters):
|
||||
|
@ -289,6 +296,10 @@ class FirewallPluginDb(object):
|
|||
'action': firewall_rule['action'],
|
||||
'enabled': firewall_rule['enabled'],
|
||||
'shared': firewall_rule['shared']}
|
||||
if hasattr(firewall_rule.standard_attr, 'id'):
|
||||
res['standard_attr_id'] = firewall_rule.standard_attr.id
|
||||
resource_extend.apply_funcs('firewall_rules', res,
|
||||
firewall_rule)
|
||||
return db_utils.resource_fields(res, fields)
|
||||
|
||||
def _make_firewall_policy_dict(self, firewall_policy, fields=None):
|
||||
|
@ -302,6 +313,10 @@ class FirewallPluginDb(object):
|
|||
'audited': firewall_policy['audited'],
|
||||
'firewall_rules': fw_rules,
|
||||
'shared': firewall_policy['shared']}
|
||||
if hasattr(firewall_policy.standard_attr, 'id'):
|
||||
res['standard_attr_id'] = firewall_policy.standard_attr.id
|
||||
resource_extend.apply_funcs('firewall_policies', res,
|
||||
firewall_policy)
|
||||
return db_utils.resource_fields(res, fields)
|
||||
|
||||
def _make_firewall_group_dict(self, firewall_group_db, fields=None):
|
||||
|
@ -319,6 +334,10 @@ class FirewallPluginDb(object):
|
|||
'ports': fwg_ports,
|
||||
'status': firewall_group_db['status'],
|
||||
'shared': firewall_group_db['shared']}
|
||||
if hasattr(firewall_group_db.standard_attr, 'id'):
|
||||
res['standard_attr_id'] = firewall_group_db.standard_attr.id
|
||||
resource_extend.apply_funcs('firewall_groups', res,
|
||||
firewall_group_db)
|
||||
return db_utils.resource_fields(res, fields)
|
||||
|
||||
def _get_policy_ordered_rules(self, context, policy_id):
|
||||
|
@ -988,7 +1007,7 @@ class FirewallPluginDb(object):
|
|||
# make sure that no group can be updated to have name=default
|
||||
self._ensure_not_default_resource(fwg, 'firewall_group')
|
||||
with db_api.CONTEXT_WRITER.using(context):
|
||||
fwg_db = self.get_firewall_group(context, id)
|
||||
fwg_db = self._get_firewall_group(context, id)
|
||||
if _is_default(fwg_db):
|
||||
attrs = [
|
||||
'name', 'description', 'admin_state_up',
|
||||
|
@ -1008,10 +1027,8 @@ class FirewallPluginDb(object):
|
|||
del fwg['ports']
|
||||
# If fwg is empty, skip updating
|
||||
if fwg:
|
||||
count = context.session.query(
|
||||
FirewallGroup).filter_by(id=id).update(fwg)
|
||||
if not count:
|
||||
raise f_exc.FirewallGroupNotFound(firewall_id=id)
|
||||
fwg_db.update(
|
||||
db_utils.filter_non_model_columns(fwg, FirewallGroup))
|
||||
return self.get_firewall_group(context, id)
|
||||
|
||||
def update_firewall_group_status(self, context, id, status, not_in=None):
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
# Copyright 2023 EasyStack Limited
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
"""add standard attributes
|
||||
|
||||
Revision ID: 6941ce70131e
|
||||
Revises: f24e0d5e5bff
|
||||
Create Date: 2022-12-01 04:19:57.324584
|
||||
|
||||
"""
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '6941ce70131e'
|
||||
down_revision = 'f24e0d5e5bff'
|
||||
tables = ['firewall_groups_v2', 'firewall_rules_v2', 'firewall_policies_v2']
|
||||
|
||||
|
||||
standardattrs = sa.Table(
|
||||
'standardattributes', sa.MetaData(),
|
||||
sa.Column('id', sa.BigInteger(), primary_key=True, autoincrement=True),
|
||||
sa.Column('resource_type', sa.String(length=255), nullable=False),
|
||||
sa.Column('description', sa.String(length=255), nullable=True))
|
||||
|
||||
|
||||
def generate_records_for_existing(table):
|
||||
model = sa.Table(table, sa.MetaData(),
|
||||
sa.Column('id', sa.String(length=36), nullable=False),
|
||||
sa.Column('description', sa.String(length=255),
|
||||
nullable=True),
|
||||
sa.Column('standard_attr_id', sa.BigInteger(),
|
||||
nullable=True))
|
||||
session = sa.orm.Session(bind=op.get_bind())
|
||||
with session.begin(subtransactions=True):
|
||||
for row in session.query(model):
|
||||
res = session.execute(
|
||||
standardattrs.insert().values(resource_type=table,
|
||||
description=row[1])
|
||||
)
|
||||
session.execute(
|
||||
model.update().values(
|
||||
standard_attr_id=res.inserted_primary_key[0]).where(
|
||||
model.c.id == row[0])
|
||||
)
|
||||
session.commit()
|
||||
|
||||
|
||||
def upgrade():
|
||||
for table in tables:
|
||||
op.add_column(table, sa.Column('standard_attr_id', sa.BigInteger(),
|
||||
nullable=True))
|
||||
op.create_foreign_key(
|
||||
constraint_name=None, source_table=table,
|
||||
referent_table='standardattributes',
|
||||
local_cols=['standard_attr_id'], remote_cols=['id'],
|
||||
ondelete='CASCADE')
|
||||
generate_records_for_existing(table)
|
||||
op.alter_column(table, 'standard_attr_id', nullable=False,
|
||||
existing_type=sa.BigInteger(), existing_nullable=True,
|
||||
existing_server_default=False)
|
||||
op.create_unique_constraint(
|
||||
constraint_name='uniq_%s0standard_attr_id' % table,
|
||||
table_name=table, columns=['standard_attr_id'])
|
||||
op.drop_column(table, 'description')
|
|
@ -1 +1 @@
|
|||
f24e0d5e5bff
|
||||
6941ce70131e
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# Copyright 2023 EasyStack Limited
|
||||
#
|
||||
# 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.api.definitions import firewall_v2_stdattrs as apidef
|
||||
from neutron_lib.api import extensions
|
||||
|
||||
|
||||
class Standard_attr_fwaas(extensions.APIExtensionDescriptor):
|
||||
api_definition = apidef
|
|
@ -1 +1,2 @@
|
|||
NETWORK_API_EXTENSIONS+=,fwaas_v2
|
||||
NETWORK_API_EXTENSIONS+=,standard-attr-fwaas-v2
|
||||
|
|
|
@ -405,6 +405,8 @@ class FirewallPluginV2TestCase(test_db_plugin.NeutronDbPluginV2TestCase):
|
|||
res = req.get_response(self.ext_api)
|
||||
self.assertEqual(expected_code, res.status_int)
|
||||
response = self.deserialize(self.fmt, res)
|
||||
if 'standard_attr_id' in response:
|
||||
del response['standard_attr_id']
|
||||
if expected_body:
|
||||
self.assertEqual(expected_body, response)
|
||||
return response
|
||||
|
|
|
@ -11,7 +11,7 @@ eventlet!=0.18.3,!=0.20.1,>=0.18.2 # MIT
|
|||
netaddr>=0.7.18 # BSD
|
||||
SQLAlchemy>=1.4.23 # MIT
|
||||
alembic>=1.6.5 # MIT
|
||||
neutron-lib>=2.19.0 # Apache-2.0
|
||||
neutron-lib>=3.6.1 # Apache-2.0
|
||||
os-ken >= 0.3.0 # Apache-2.0
|
||||
oslo.config>=5.2.0 # Apache-2.0
|
||||
oslo.db>=4.37.0 # Apache-2.0
|
||||
|
|
Loading…
Reference in New Issue