From 5aaa572a021f4bbf82a5450908e92cd60c26287e Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Fri, 14 Feb 2025 08:57:44 +0000 Subject: [PATCH] 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]https://github.com/openstack/neutron/blob/0008cf562e33c6c69d9a0abbc714c7839771a110/neutron/policy.py#L138-L143 Depends-On: https://review.opendev.org/c/openstack/neutron-tempest-plugin/+/941689 Related-Bug: #2098109 Change-Id: Id64ccbdc4750eaa5f64bbbf374e6d9db2388c4db --- neutron_lib/api/definitions/l3_ext_gw_mode.py | 38 ++++++++----------- neutron_lib/api/definitions/qos_gateway_ip.py | 27 +++++++------ ...r_gw_info_validation-210d27abd4c3fa71.yaml | 6 +++ 3 files changed, 38 insertions(+), 33 deletions(-) create mode 100644 releasenotes/notes/router_gw_info_validation-210d27abd4c3fa71.yaml diff --git a/neutron_lib/api/definitions/l3_ext_gw_mode.py b/neutron_lib/api/definitions/l3_ext_gw_mode.py index 7d3ca8fa6..7dbc11be1 100644 --- a/neutron_lib/api/definitions/l3_ext_gw_mode.py +++ b/neutron_lib/api/definitions/l3_ext_gw_mode.py @@ -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] diff --git a/neutron_lib/api/definitions/qos_gateway_ip.py b/neutron_lib/api/definitions/qos_gateway_ip.py index 8dfade819..70943ccc1 100644 --- a/neutron_lib/api/definitions/qos_gateway_ip.py +++ b/neutron_lib/api/definitions/qos_gateway_ip.py @@ -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] diff --git a/releasenotes/notes/router_gw_info_validation-210d27abd4c3fa71.yaml b/releasenotes/notes/router_gw_info_validation-210d27abd4c3fa71.yaml new file mode 100644 index 000000000..37904919b --- /dev/null +++ b/releasenotes/notes/router_gw_info_validation-210d27abd4c3fa71.yaml @@ -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.