Fix the router "external_gateway_info" validation

In [1], a change that removed the validation fields for router
"external_gateway_info" was introduced. In order to be able to use
the subattributes in the policy engine, it is needed to define then
using a "type:dict*" validator and set them as "key_specs". This
validation is done in [2].

This patch is restoring the validation of the router
"external_gateway_info" field by just amending what is new in each
extension modifying the field. This change makes any extension
compatible when loaded at the same time, regardless of the loading
priority (usually loaded in alphabetical order).

NOTE: this fix should be backported up to 2023.2, where [1] is included.

[1]https://review.opendev.org/c/openstack/neutron-lib/+/870887/20/neutron_lib/api/definitions/qos_gateway_ip.py
[2]0008cf562e/neutron/policy.py (L138-L143)

Depends-On: https://review.opendev.org/c/openstack/neutron-tempest-plugin/+/941689

Related-Bug: #2098109
Change-Id: Id64ccbdc4750eaa5f64bbbf374e6d9db2388c4db
This commit is contained in:
Rodolfo Alonso Hernandez 2025-02-14 08:57:44 +00:00
parent e2d68e39f5
commit 5aaa572a02
3 changed files with 38 additions and 33 deletions

View File

@ -13,6 +13,9 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
import typing
from neutron_lib.api import converters
from neutron_lib.api.definitions import l3
@ -27,29 +30,20 @@ DESCRIPTION = ('Extension of the router abstraction for specifying whether '
UPDATED_TIMESTAMP = '2013-03-28T10:00:00-00:00'
RESOURCE_NAME = l3.ROUTER
COLLECTION_NAME = l3.ROUTERS
RESOURCE_ATTRIBUTE_MAP = {
COLLECTION_NAME: {
l3.EXTERNAL_GW_INFO: {
'allow_post': True,
'allow_put': True,
'is_visible': True,
'default': None,
'enforce_policy': True,
'validate': {
'type:dict_or_nodata': {
'network_id': {'type:uuid': None, 'required': True},
'enable_snat': {'type:boolean': None, 'required': False,
'convert_to':
converters.convert_to_boolean},
'external_fixed_ips': {
'type:fixed_ips': None,
'required': False
}
}
}
}
}
routers: typing.Dict[str, typing.Any] = copy.deepcopy(
l3.RESOURCE_ATTRIBUTE_MAP[COLLECTION_NAME]
)
routers[l3.EXTERNAL_GW_INFO]['validate']['type:dict_or_nodata'][
'enable_snat'] = {
'type:boolean': None,
'required': False,
'convert_to': converters.convert_to_boolean
}
RESOURCE_ATTRIBUTE_MAP = {
COLLECTION_NAME: routers
}
SUB_RESOURCE_ATTRIBUTE_MAP = {}
ACTION_MAP = {}
REQUIRED_EXTENSIONS = [l3.ALIAS]

View File

@ -11,9 +11,13 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
import typing
from neutron_lib.api.definitions import l3
from neutron_lib.api.definitions import l3_ext_gw_mode
from neutron_lib.api.definitions import qos
from neutron_lib.services.qos import constants as qos_consts
ALIAS = 'qos-gateway-ip'
@ -25,18 +29,19 @@ DESCRIPTION = 'The Router gateway IP Quality of Service extension'
UPDATED_TIMESTAMP = '2018-02-24T00:00:00-00:00'
RESOURCE_NAME = l3.ROUTER
COLLECTION_NAME = l3.ROUTERS
RESOURCE_ATTRIBUTE_MAP = {
COLLECTION_NAME: {
l3.EXTERNAL_GW_INFO: {
'allow_post': True,
'allow_put': True,
'is_visible': True,
'default': None,
'enforce_policy': True,
'validate': {'type:external_gw_info': None},
}
}
routers: typing.Dict[str, typing.Any] = copy.deepcopy(
l3_ext_gw_mode.RESOURCE_ATTRIBUTE_MAP[COLLECTION_NAME]
)
routers[l3.EXTERNAL_GW_INFO]['validate']['type:dict_or_nodata'][
qos_consts.QOS_POLICY_ID] = {
'type:uuid_or_none': None,
'required': False
}
RESOURCE_ATTRIBUTE_MAP = {
COLLECTION_NAME: routers
}
SUB_RESOURCE_ATTRIBUTE_MAP = {}
ACTION_MAP = {}
REQUIRED_EXTENSIONS = [l3.ALIAS, qos.ALIAS, l3_ext_gw_mode.ALIAS]

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Fixed the validation of router ``external_gateway_info`` field. Each
extension adding a new validator amends the previous definition, but
doesn't overwrite it.