multi-ext-gw: api-def and api-ref
New router attribute: external_gateways New router actions: PUT add_external_gateways PUT update_external_gateways PUT remove_external_gateways Change-Id: I46381b70f770ccd32943644341388b09f7e14556 Partial-Bug: #1905295 Related-Change (spec): https://review.opendev.org/c/openstack/neutron-specs/+/779511
This commit is contained in:
parent
60046e4f2c
commit
75057767eb
@ -5399,6 +5399,12 @@ router-external_gateway_ports:
|
||||
in: body
|
||||
required: true
|
||||
type: string
|
||||
router-external_gateways:
|
||||
description: |
|
||||
The list of external gateways of the router.
|
||||
in: body
|
||||
required: true
|
||||
type: array
|
||||
router-flavor_id:
|
||||
description: |
|
||||
The ID of the flavor associated with the router.
|
||||
|
@ -68,6 +68,21 @@ modes, adds the ``external_gateway_info`` attribute to ``routers``
|
||||
and allows definitions for ``network_id``, ``enable_snat`` and
|
||||
``external_fixed_ips``.
|
||||
|
||||
L3 multiple external gateways extension (``multiple-external-gateways``)
|
||||
========================================================================
|
||||
|
||||
The ``multiple-external-gateways`` extension allows a router to have
|
||||
multiple external gateways, that is multiple legs towards the outside
|
||||
world.
|
||||
|
||||
.. warning::
|
||||
|
||||
This API extension was merged as experimental to enable parallel
|
||||
development of multiple backends. At the moment this API does not have
|
||||
a reference implementation and should not be considered final. The
|
||||
removal of this warning will mark when the reference implementation
|
||||
gets merged and the feauture is ready to be consumed.
|
||||
|
||||
L3 flavors extension (``l3-flavors``)
|
||||
=====================================
|
||||
|
||||
@ -178,6 +193,7 @@ Response Parameters
|
||||
- admin_state_up: admin_state_up
|
||||
- status: router-status
|
||||
- external_gateway_info: router-external_gateway_info
|
||||
- external_gateways: router-external_gateways
|
||||
- revision_number: revision_number
|
||||
- routes: router-routes
|
||||
- destination: router-destination
|
||||
@ -258,6 +274,7 @@ Response Parameters
|
||||
- admin_state_up: admin_state_up
|
||||
- status: router-status
|
||||
- external_gateway_info: router-external_gateway_info
|
||||
- external_gateways: router-external_gateways
|
||||
- revision_number: revision_number
|
||||
- routes: router-routes
|
||||
- destination: router-destination
|
||||
@ -318,6 +335,7 @@ Response Parameters
|
||||
- admin_state_up: admin_state_up
|
||||
- status: router-status
|
||||
- external_gateway_info: router-external_gateway_info
|
||||
- external_gateways: router-external_gateways
|
||||
- revision_number: revision_number
|
||||
- routes: router-routes
|
||||
- destination: router-destination
|
||||
@ -389,6 +407,7 @@ Response Parameters
|
||||
- admin_state_up: admin_state_up
|
||||
- status: router-status
|
||||
- external_gateway_info: router-external_gateway_info
|
||||
- external_gateways: router-external_gateways
|
||||
- revision_number: revision_number
|
||||
- routes: router-routes
|
||||
- destination: router-destination
|
||||
@ -748,3 +767,220 @@ Response Example
|
||||
|
||||
.. literalinclude:: samples/routers/router-remove-extraroutes-response.json
|
||||
:language: javascript
|
||||
|
||||
Add external gateways to router
|
||||
===============================
|
||||
|
||||
.. rest_method:: PUT /v2.0/routers/{router_id}/add_external_gateways
|
||||
|
||||
Add external gateways to router, beyond the external gateways the router
|
||||
already has.
|
||||
|
||||
Adding an external gateway to a network that already has
|
||||
one raises an error.
|
||||
|
||||
The add/update/remove external gateways operations extend the use of
|
||||
``router.external_gateway_info`` to manage multiple external gateways.
|
||||
The full set of external gateways is exposed in the read-only
|
||||
``router.external_gateways`` parameter. ``router.external_gateways``
|
||||
contains a list of ``external_gateway_info`` structures like:
|
||||
|
||||
::
|
||||
|
||||
[
|
||||
{"network_id": ...,
|
||||
"external_fixed_ips": [{"ip_address": ..., "subnet_id": ...}, ...],
|
||||
"enable_snat": ...},
|
||||
...
|
||||
]
|
||||
|
||||
The first item (index 0) of the ``external_gateways`` list is special:
|
||||
|
||||
* It is always a duplicate of ``router.external_gateway_info``.
|
||||
|
||||
* This first item sets a router's default route. The other items have
|
||||
no effect on it.
|
||||
|
||||
The order of the the rest of the list (indexes 1, 2, ...) is irrelevant
|
||||
and ignored.
|
||||
|
||||
The first external gateway can be managed in two
|
||||
ways: via ``router.external_gateway_info`` or via
|
||||
``add/update/remove_external_gateways``. The other external gateways
|
||||
can only be managed via ``add/update/remove_external_gateways``.
|
||||
|
||||
The format of the request body is the same as the format of the read-only
|
||||
``router.external_gateways`` parameter, but wrapped as follows:
|
||||
|
||||
::
|
||||
|
||||
{"router": {"external_gateways": EXTERNAL-GATEWAY-LIST}}
|
||||
|
||||
The response codes and response body are the same as to the update of
|
||||
the router. That is the whole router object is returned including the
|
||||
``external_gateway_info`` and ``external_gateways`` parameters which
|
||||
represents the result of the operation.
|
||||
|
||||
Changes in ``router.external_gateway_info`` are reflected
|
||||
in ``router.external_gateways`` and vice versa. Updating
|
||||
``external_gateway_info`` also updates the first element of
|
||||
``external_gateways`` and it leaves the rest of ``external_gateways``
|
||||
unchanged. Setting ``external_gateway_info`` to an empty value also
|
||||
resets ``external_gateways`` to the empty list.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 400, 401, 404, 412
|
||||
|
||||
Request Parameters
|
||||
------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- router_id: router_id
|
||||
- external_gateways: router-external_gateways
|
||||
|
||||
Request Example
|
||||
---------------
|
||||
|
||||
.. literalinclude:: samples/routers/router-add-external-gateways-request.json
|
||||
:language: javascript
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- id: router-id-body
|
||||
- name: router_name
|
||||
- external_gateways: router-external_gateways
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/routers/router-add-external-gateways-response.json
|
||||
:language: javascript
|
||||
|
||||
Update external gateways of router
|
||||
==================================
|
||||
|
||||
.. rest_method:: PUT /v2.0/routers/{router_id}/update_external_gateways
|
||||
|
||||
Update some external gateways of router.
|
||||
|
||||
For general information on the add/update/remove external gateways
|
||||
operations see ``add_external_gateways`` above.
|
||||
|
||||
The external gateways to be updated are identified by the ``network_ids``
|
||||
found in the PUT request. The ``external_fixed_ips`` and ``enable_snat``
|
||||
fields can be updated. The ``network_id`` field cannot be updated.
|
||||
|
||||
The format of the request body is the same as the format of the read-only
|
||||
``router.external_gateways`` parameter, but wrapped as follows:
|
||||
|
||||
::
|
||||
|
||||
{"router": {"external_gateways": EXTERNAL-GATEWAY-LIST}}
|
||||
|
||||
If the whole ``external_fixed_ips`` or ``enable_snat`` fields are meant
|
||||
to be left unchanged they can be omitted from the request.
|
||||
|
||||
The response codes and response body are the same as to the update of
|
||||
the router. That is the whole router object is returned including the
|
||||
``external_gateway_info`` and ``external_gateways`` parameters which
|
||||
represents the result of the operation.
|
||||
|
||||
Please note that updating ``external_gateway_info`` also updates
|
||||
the first element of ``external_gateways`` and it leaves the rest of
|
||||
``external_gateways`` unchanged.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 400, 401, 404, 412
|
||||
|
||||
Request Parameters
|
||||
------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- router_id: router_id
|
||||
- external_gateways: router-external_gateways
|
||||
|
||||
Request Example
|
||||
---------------
|
||||
|
||||
.. literalinclude:: samples/routers/router-update-external-gateways-request.json
|
||||
:language: javascript
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- id: router-id-body
|
||||
- name: router_name
|
||||
- external_gateways: router-external_gateways
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/routers/router-update-external-gateways-response.json
|
||||
:language: javascript
|
||||
|
||||
Remove external gateways from router
|
||||
====================================
|
||||
|
||||
.. rest_method:: PUT /v2.0/routers/{router_id}/remove_external_gateways
|
||||
|
||||
Remove some external gateways from router.
|
||||
|
||||
For general information on the add/update/remove external gateways
|
||||
operations see ``add_external_gateways`` above.
|
||||
|
||||
The format of the request body is the same as the format of the read-only
|
||||
``router.external_gateways`` parameter, but wrapped as follows:
|
||||
|
||||
::
|
||||
|
||||
{"router": {"external_gateways": EXTERNAL-GATEWAY-LIST}}
|
||||
|
||||
However the request body can be partial. Only the ``network_id``
|
||||
field from ``external_gateway_info`` structure is used. The
|
||||
``external_fixed_ips`` and ``enable_snat`` keys can be present but their
|
||||
values are ignored.
|
||||
|
||||
Please note that setting ``external_gateway_info`` to an empty value
|
||||
also resets ``external_gateways`` to the empty list.
|
||||
|
||||
Normal response codes: 200
|
||||
|
||||
Error response codes: 400, 401, 404, 412
|
||||
|
||||
Request Parameters
|
||||
------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- router_id: router_id
|
||||
- external_gateways: router-external_gateways
|
||||
|
||||
Request Example
|
||||
---------------
|
||||
|
||||
.. literalinclude:: samples/routers/router-remove-external-gateways-request.json
|
||||
:language: javascript
|
||||
|
||||
Response Parameters
|
||||
-------------------
|
||||
|
||||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- id: router-id-body
|
||||
- name: router_name
|
||||
- external_gateways: router-external_gateways
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
||||
.. literalinclude:: samples/routers/router-remove-external-gateways-response.json
|
||||
:language: javascript
|
||||
|
@ -0,0 +1,16 @@
|
||||
{
|
||||
"router" : {
|
||||
"external_gateways" : [
|
||||
{
|
||||
"enable_snat" : false,
|
||||
"external_fixed_ips" : [
|
||||
{
|
||||
"ip_address" : "10.0.0.2",
|
||||
"subnet_id" : "b189c314-ebb9-11eb-939c-9bde3f3867cb"
|
||||
}
|
||||
],
|
||||
"network_id" : "8edec774-ebb9-11eb-9b09-371108ef5905"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
{
|
||||
"router" : {
|
||||
"admin_state_up" : true,
|
||||
"availability_zone_hints" : [],
|
||||
"availability_zones" : [
|
||||
"nova"
|
||||
],
|
||||
"created_at" : "2021-06-29T13:33:40Z",
|
||||
"description" : "",
|
||||
"distributed" : false,
|
||||
"external_gateway_info" : {
|
||||
"enable_snat" : false,
|
||||
"external_fixed_ips" : [
|
||||
{
|
||||
"ip_address" : "172.24.4.144",
|
||||
"subnet_id" : "1ed1c499-a45d-48d0-a567-e83a2364a40e"
|
||||
}
|
||||
],
|
||||
"network_id" : "52700ca1-1647-46ad-8f86-b9e64eaed820"
|
||||
},
|
||||
"external_gateways" : [
|
||||
{
|
||||
"enable_snat" : false,
|
||||
"external_fixed_ips" : [
|
||||
{
|
||||
"ip_address" : "172.24.4.144",
|
||||
"subnet_id" : "1ed1c499-a45d-48d0-a567-e83a2364a40e"
|
||||
}
|
||||
],
|
||||
"network_id" : "52700ca1-1647-46ad-8f86-b9e64eaed820"
|
||||
},
|
||||
{
|
||||
"enable_snat" : false,
|
||||
"external_fixed_ips" : [
|
||||
{
|
||||
"ip_address" : "10.0.0.2",
|
||||
"subnet_id" : "b189c314-ebb9-11eb-939c-9bde3f3867cb"
|
||||
}
|
||||
],
|
||||
"network_id" : "8edec774-ebb9-11eb-9b09-371108ef5905"
|
||||
}
|
||||
],
|
||||
"flavor_id" : null,
|
||||
"ha" : false,
|
||||
"id" : "47c32c39-1c09-47de-8d50-ec57a96db5e7",
|
||||
"interfaces_info" : [
|
||||
{
|
||||
"ip_address" : "fd26:d08e:af31::1",
|
||||
"port_id" : "20683e3d-b041-4977-9686-b97db622c76a",
|
||||
"subnet_id" : "2921b809-b60a-4799-ac99-59dacbeb7c3a"
|
||||
},
|
||||
{
|
||||
"ip_address" : "10.0.0.1",
|
||||
"port_id" : "89ab7084-7883-48e6-8281-d498a0cf4c92",
|
||||
"subnet_id" : "3a5bec20-2df1-4d11-b0d5-5481969b91ac"
|
||||
},
|
||||
{
|
||||
"ip_address" : "10.0.5.1",
|
||||
"port_id" : "b04c6f4e-5bc7-43a2-85e9-c28452368532",
|
||||
"subnet_id" : "f96970c4-026a-46f3-9852-f512a56688fe"
|
||||
}
|
||||
],
|
||||
"name" : "router1",
|
||||
"project_id" : "b66a1cea961f49738fff1210733ec440",
|
||||
"revision_number" : 7,
|
||||
"routes" : [],
|
||||
"status" : "ACTIVE",
|
||||
"tags" : [],
|
||||
"updated_at" : "2021-06-29T13:37:07Z"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"router" : {
|
||||
"external_gateways" : [
|
||||
{
|
||||
"network_id" : "8edec774-ebb9-11eb-9b09-371108ef5905"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
{
|
||||
"router" : {
|
||||
"admin_state_up" : true,
|
||||
"availability_zone_hints" : [],
|
||||
"availability_zones" : [
|
||||
"nova"
|
||||
],
|
||||
"created_at" : "2021-06-29T13:33:40Z",
|
||||
"description" : "",
|
||||
"distributed" : false,
|
||||
"external_gateway_info" : {
|
||||
"enable_snat" : false,
|
||||
"external_fixed_ips" : [
|
||||
{
|
||||
"ip_address" : "172.24.4.144",
|
||||
"subnet_id" : "1ed1c499-a45d-48d0-a567-e83a2364a40e"
|
||||
}
|
||||
],
|
||||
"network_id" : "52700ca1-1647-46ad-8f86-b9e64eaed820"
|
||||
},
|
||||
"external_gateways" : [
|
||||
{
|
||||
"enable_snat" : false,
|
||||
"external_fixed_ips" : [
|
||||
{
|
||||
"ip_address" : "172.24.4.144",
|
||||
"subnet_id" : "1ed1c499-a45d-48d0-a567-e83a2364a40e"
|
||||
}
|
||||
],
|
||||
"network_id" : "52700ca1-1647-46ad-8f86-b9e64eaed820"
|
||||
}
|
||||
],
|
||||
"flavor_id" : null,
|
||||
"ha" : false,
|
||||
"id" : "47c32c39-1c09-47de-8d50-ec57a96db5e7",
|
||||
"interfaces_info" : [
|
||||
{
|
||||
"ip_address" : "fd26:d08e:af31::1",
|
||||
"port_id" : "20683e3d-b041-4977-9686-b97db622c76a",
|
||||
"subnet_id" : "2921b809-b60a-4799-ac99-59dacbeb7c3a"
|
||||
},
|
||||
{
|
||||
"ip_address" : "10.0.0.1",
|
||||
"port_id" : "89ab7084-7883-48e6-8281-d498a0cf4c92",
|
||||
"subnet_id" : "3a5bec20-2df1-4d11-b0d5-5481969b91ac"
|
||||
},
|
||||
{
|
||||
"ip_address" : "10.0.5.1",
|
||||
"port_id" : "b04c6f4e-5bc7-43a2-85e9-c28452368532",
|
||||
"subnet_id" : "f96970c4-026a-46f3-9852-f512a56688fe"
|
||||
}
|
||||
],
|
||||
"name" : "router1",
|
||||
"project_id" : "b66a1cea961f49738fff1210733ec440",
|
||||
"revision_number" : 7,
|
||||
"routes" : [],
|
||||
"status" : "ACTIVE",
|
||||
"tags" : [],
|
||||
"updated_at" : "2021-06-29T13:37:07Z"
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"router" : {
|
||||
"external_gateways" : [
|
||||
{
|
||||
"enable_snat" : true,
|
||||
"network_id" : "8edec774-ebb9-11eb-9b09-371108ef5905"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
{
|
||||
"router" : {
|
||||
"admin_state_up" : true,
|
||||
"availability_zone_hints" : [],
|
||||
"availability_zones" : [
|
||||
"nova"
|
||||
],
|
||||
"created_at" : "2021-06-29T13:33:40Z",
|
||||
"description" : "",
|
||||
"distributed" : false,
|
||||
"external_gateway_info" : {
|
||||
"enable_snat" : false,
|
||||
"external_fixed_ips" : [
|
||||
{
|
||||
"ip_address" : "172.24.4.144",
|
||||
"subnet_id" : "1ed1c499-a45d-48d0-a567-e83a2364a40e"
|
||||
}
|
||||
],
|
||||
"network_id" : "52700ca1-1647-46ad-8f86-b9e64eaed820"
|
||||
},
|
||||
"external_gateways" : [
|
||||
{
|
||||
"enable_snat" : false,
|
||||
"external_fixed_ips" : [
|
||||
{
|
||||
"ip_address" : "172.24.4.144",
|
||||
"subnet_id" : "1ed1c499-a45d-48d0-a567-e83a2364a40e"
|
||||
}
|
||||
],
|
||||
"network_id" : "52700ca1-1647-46ad-8f86-b9e64eaed820"
|
||||
},
|
||||
{
|
||||
"enable_snat" : true,
|
||||
"external_fixed_ips" : [
|
||||
{
|
||||
"ip_address" : "10.0.0.2",
|
||||
"subnet_id" : "b189c314-ebb9-11eb-939c-9bde3f3867cb"
|
||||
}
|
||||
],
|
||||
"network_id" : "8edec774-ebb9-11eb-9b09-371108ef5905"
|
||||
}
|
||||
],
|
||||
"flavor_id" : null,
|
||||
"ha" : false,
|
||||
"id" : "47c32c39-1c09-47de-8d50-ec57a96db5e7",
|
||||
"interfaces_info" : [
|
||||
{
|
||||
"ip_address" : "fd26:d08e:af31::1",
|
||||
"port_id" : "20683e3d-b041-4977-9686-b97db622c76a",
|
||||
"subnet_id" : "2921b809-b60a-4799-ac99-59dacbeb7c3a"
|
||||
},
|
||||
{
|
||||
"ip_address" : "10.0.0.1",
|
||||
"port_id" : "89ab7084-7883-48e6-8281-d498a0cf4c92",
|
||||
"subnet_id" : "3a5bec20-2df1-4d11-b0d5-5481969b91ac"
|
||||
},
|
||||
{
|
||||
"ip_address" : "10.0.5.1",
|
||||
"port_id" : "b04c6f4e-5bc7-43a2-85e9-c28452368532",
|
||||
"subnet_id" : "f96970c4-026a-46f3-9852-f512a56688fe"
|
||||
}
|
||||
],
|
||||
"name" : "router1",
|
||||
"project_id" : "b66a1cea961f49738fff1210733ec440",
|
||||
"revision_number" : 7,
|
||||
"routes" : [],
|
||||
"status" : "ACTIVE",
|
||||
"tags" : [],
|
||||
"updated_at" : "2021-06-29T13:37:07Z"
|
||||
}
|
||||
}
|
@ -15,7 +15,6 @@ from oslo_config import cfg
|
||||
from oslo_utils import strutils
|
||||
|
||||
from neutron_lib._i18n import _
|
||||
from neutron_lib.api import validators
|
||||
from neutron_lib import constants
|
||||
from neutron_lib import exceptions as n_exc
|
||||
from neutron_lib.utils import net as net_utils
|
||||
@ -256,7 +255,7 @@ def convert_to_protocol(data):
|
||||
"names and their integer representation (0 to "
|
||||
"255) are supported") % data
|
||||
try:
|
||||
if validators.validate_range(convert_to_int(data), [0, 255]) is None:
|
||||
if 0 <= convert_to_int(data) <= 255:
|
||||
return data
|
||||
else:
|
||||
raise n_exc.InvalidInput(error_message=error_message)
|
||||
|
@ -64,6 +64,7 @@ from neutron_lib.api.definitions import l3_ext_gw_mode
|
||||
from neutron_lib.api.definitions import l3_ext_ha_mode
|
||||
from neutron_lib.api.definitions import l3_ext_ndp_proxy
|
||||
from neutron_lib.api.definitions import l3_flavors
|
||||
from neutron_lib.api.definitions import l3_multi_ext_gw
|
||||
from neutron_lib.api.definitions import l3_ndp_proxy
|
||||
from neutron_lib.api.definitions import l3_port_ip_change_not_allowed
|
||||
from neutron_lib.api.definitions import logging
|
||||
@ -192,6 +193,7 @@ _ALL_API_DEFINITIONS = {
|
||||
l3_ext_ha_mode,
|
||||
l3_ext_ndp_proxy,
|
||||
l3_flavors,
|
||||
l3_multi_ext_gw,
|
||||
l3_ndp_proxy,
|
||||
l3_port_ip_change_not_allowed,
|
||||
logging,
|
||||
|
@ -25,6 +25,7 @@ KNOWN_ATTRIBUTES = (
|
||||
'dns_nameservers',
|
||||
'enable_dhcp',
|
||||
'enable_ndp_proxy',
|
||||
'external_gateways',
|
||||
'fixed_ips',
|
||||
'gateway_ip',
|
||||
'host_routes',
|
||||
@ -118,6 +119,7 @@ KNOWN_EXTENSIONS = (
|
||||
'metering',
|
||||
'metering_source_and_destination_filters',
|
||||
'multi-provider',
|
||||
'multiple-external-gateways',
|
||||
'net-mtu',
|
||||
'network-ip-availability',
|
||||
'network-segment-range',
|
||||
|
@ -13,7 +13,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib.api import converters
|
||||
from neutron_lib.api.definitions import l3
|
||||
|
||||
|
||||
@ -35,18 +34,7 @@ RESOURCE_ATTRIBUTE_MAP = {
|
||||
'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
|
||||
}
|
||||
}
|
||||
}
|
||||
'validate': {'type:external_gw_info': None},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
48
neutron_lib/api/definitions/l3_multi_ext_gw.py
Normal file
48
neutron_lib/api/definitions/l3_multi_ext_gw.py
Normal file
@ -0,0 +1,48 @@
|
||||
# Copyright 2021 Ericsson Software Technology
|
||||
#
|
||||
# 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 l3
|
||||
from neutron_lib.api.definitions import l3_ext_gw_mode
|
||||
|
||||
|
||||
ALIAS = 'multiple-external-gateways'
|
||||
IS_SHIM_EXTENSION = False
|
||||
IS_STANDARD_ATTR_EXTENSION = False
|
||||
NAME = 'Neutron L3 Multiple External Gateways'
|
||||
API_PREFIX = ''
|
||||
DESCRIPTION = 'Allow more than one External Gateways'
|
||||
UPDATED_TIMESTAMP = '2021-04-01T00:00:00-00:00'
|
||||
RESOURCE_NAME = l3.ROUTER
|
||||
COLLECTION_NAME = l3.ROUTERS
|
||||
RESOURCE_ATTRIBUTE_MAP = {
|
||||
COLLECTION_NAME: {
|
||||
'external_gateways': {
|
||||
'allow_post': False,
|
||||
'allow_put': False,
|
||||
'is_visible': True,
|
||||
'default': None,
|
||||
'validate': {'type:external_gw_info_list': None},
|
||||
},
|
||||
},
|
||||
}
|
||||
SUB_RESOURCE_ATTRIBUTE_MAP = {}
|
||||
ACTION_MAP = l3.ACTION_MAP
|
||||
ACTION_MAP[l3.ROUTER].update({
|
||||
'add_external_gateways': 'PUT',
|
||||
'update_external_gateways': 'PUT',
|
||||
'remove_external_gateways': 'PUT',
|
||||
})
|
||||
REQUIRED_EXTENSIONS = [l3.ALIAS, l3_ext_gw_mode.ALIAS]
|
||||
OPTIONAL_EXTENSIONS = []
|
||||
ACTION_STATUS = {}
|
@ -25,6 +25,7 @@ from oslo_utils import uuidutils
|
||||
from webob import exc
|
||||
|
||||
from neutron_lib._i18n import _
|
||||
from neutron_lib.api import converters
|
||||
from neutron_lib import constants
|
||||
from neutron_lib import exceptions as n_exc
|
||||
from neutron_lib.plugins import directory
|
||||
@ -1169,6 +1170,35 @@ def validate_ethertype(ethertype, valid_values=None):
|
||||
return msg
|
||||
|
||||
|
||||
def validate_external_gw_info(data, valid_values=None):
|
||||
"""Validate data is an external_gateway_info.
|
||||
|
||||
:param data: The data to validate.
|
||||
:param valid_values: Not used!
|
||||
:returns: None if valid, error string otherwise.
|
||||
"""
|
||||
return validate_dict_or_nodata(
|
||||
data,
|
||||
key_specs={
|
||||
'network_id': {'type:uuid': None, 'required': True},
|
||||
'external_fixed_ips': {'type:fixed_ips': None, 'required': False},
|
||||
'enable_snat': {'type:boolean': None, 'required': False,
|
||||
'convert_to': converters.convert_to_boolean},
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def validate_external_gw_info_list(data, valid_values=None):
|
||||
"""Validate data is a list of external_gateway_info.
|
||||
|
||||
:param data: The data to validate.
|
||||
:param valid_values: Not used!
|
||||
:returns: None if valid, error string otherwise.
|
||||
"""
|
||||
if data is not None:
|
||||
return _validate_list_of_items(validate_external_gw_info, data)
|
||||
|
||||
|
||||
# Dictionary that maintains a list of validation functions
|
||||
validators = {'type:dict': validate_dict,
|
||||
'type:dict_or_none': validate_dict_or_none,
|
||||
@ -1215,7 +1245,9 @@ validators = {'type:dict': validate_dict,
|
||||
'type:service_plugin_type': validate_service_plugin_type,
|
||||
'type:list_of_subnets_or_none': validate_subnet_list_or_none,
|
||||
'type:list_of_subnet_service_types':
|
||||
validate_subnet_service_types
|
||||
validate_subnet_service_types,
|
||||
'type:external_gw_info': validate_external_gw_info,
|
||||
'type:external_gw_info_list': validate_external_gw_info_list,
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
# Copyright 2021 Ericsson Software Technology
|
||||
#
|
||||
# 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 l3_multi_ext_gw
|
||||
from neutron_lib.tests.unit.api.definitions import base
|
||||
|
||||
|
||||
class L3MultipleExternalGatewaysDefinitionTestCase(
|
||||
base.DefinitionBaseTestCase):
|
||||
extension_module = l3_multi_ext_gw
|
9
releasenotes/notes/l3-multi-ext-gw-5a55c7afb7114db7.yaml
Normal file
9
releasenotes/notes/l3-multi-ext-gw-5a55c7afb7114db7.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Definition for API extension: ``multiple-external-gateways``. This API
|
||||
definition was merged as experimental to enable parallel development
|
||||
of multiple backends. At the moment this API does not have a reference
|
||||
implementation and should not be considered final. A later release
|
||||
note will mark when the reference implementation gets merged and
|
||||
the feauture is ready to be consumed.
|
Loading…
Reference in New Issue
Block a user