diff --git a/doc/source/admin/flavors.rst b/doc/source/admin/flavors.rst index 9d7a541a94..f007e7a276 100644 --- a/doc/source/admin/flavors.rst +++ b/doc/source/admin/flavors.rst @@ -22,14 +22,14 @@ balancing capabilities to their users. An Octavia flavor is a predefined set of provider configuration options that are created by the operator. When an user requests a load balancer they can request the load balancer be built with one of the defined flavors. Flavors are defined per provider -driver and expose the unique capabilites of each provider. +driver and expose the unique capabilities of each provider. This document is intended to explain the flavors capability for operators that wish to create flavors for their users. There are three steps to creating a new Octavia flavor: -#. Decide on the provider flavor capabilites that will be configured in the +#. Decide on the provider flavor capabilities that will be configured in the flavor. #. Create the flavor profile with the flavor capabilities. #. Create the user facing flavor. @@ -132,8 +132,8 @@ The output of the command above is:: | name | standalone-lb | | flavor_profile_id | 72b53ac2-b191-48eb-8f73-ed012caca23a | | enabled | True | - | description | A non-high availability load b | - | | alancer for testing. | + | description | A non-high availability load | + | | balancer for testing. | +-------------------+--------------------------------------+ At this point, the flavor is available for use by users creating new load diff --git a/doc/source/contributor/guides/providers.rst b/doc/source/contributor/guides/providers.rst index e621d75624..b45fe326fa 100644 --- a/doc/source/contributor/guides/providers.rst +++ b/doc/source/contributor/guides/providers.rst @@ -1770,7 +1770,8 @@ description. For example: .. code-block:: python {"compute_zone": "The compute availability zone to use for this loadbalancer.", - "management_network": "The management network ID for the loadbalancer."} + "management_network": "The management network ID for the loadbalancer.", + "valid_vip_networks": "List of network IDs that are allowed for VIP use. This overrides/replaces the list of allowed networks configured in `octavia.conf`."} validate_availability_zone ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/octavia/api/drivers/amphora_driver/availability_zone_schema.py b/octavia/api/drivers/amphora_driver/availability_zone_schema.py index 7a019e2480..34bc8fabe5 100644 --- a/octavia/api/drivers/amphora_driver/availability_zone_schema.py +++ b/octavia/api/drivers/amphora_driver/availability_zone_schema.py @@ -42,6 +42,12 @@ SUPPORTED_AVAILABILITY_ZONE_SCHEMA = { consts.MANAGEMENT_NETWORK: { "type": "string", "description": "The management network ID for the amphora." + }, + consts.VALID_VIP_NETWORKS: { + "type": "array", + "description": "List of network IDs that are allowed for VIP use. " + "This overrides/replaces the list of allowed " + "networks configured in `octavia.conf`." } } } diff --git a/octavia/api/drivers/amphora_driver/v2/driver.py b/octavia/api/drivers/amphora_driver/v2/driver.py index dc0f8dda94..83d7b7e037 100644 --- a/octavia/api/drivers/amphora_driver/v2/driver.py +++ b/octavia/api/drivers/amphora_driver/v2/driver.py @@ -464,3 +464,16 @@ class AmphoraProviderDriver(driver_base.ProviderDriver): # TODO(johnsom) Fix this to raise a NotFound error # when the octavia-lib supports it. compute_driver.validate_availability_zone(compute_zone) + + check_nets = availability_zone_dict.get( + consts.VALID_VIP_NETWORKS, []) + management_net = availability_zone_dict.get( + consts.MANAGEMENT_NETWORK, None) + if management_net: + check_nets.append(management_net) + for check_net in check_nets: + network_driver = utils.get_network_driver() + + # TODO(johnsom) Fix this to raise a NotFound error + # when the octavia-lib supports it. + network_driver.get_network(check_net) diff --git a/octavia/api/v2/controllers/load_balancer.py b/octavia/api/v2/controllers/load_balancer.py index 046760cb63..0173e3407d 100644 --- a/octavia/api/v2/controllers/load_balancer.py +++ b/octavia/api/v2/controllers/load_balancer.py @@ -247,7 +247,6 @@ class LoadBalancersController(base.BaseController): if load_balancer.vip_qos_policy_id: validate.qos_policy_exists( qos_policy_id=load_balancer.vip_qos_policy_id) - validate.network_allowed_by_config(load_balancer.vip_network_id) def _create_vip_port_if_not_exist(self, load_balancer_db): """Create vip port.""" @@ -428,6 +427,10 @@ class LoadBalancersController(base.BaseController): az_dict = self._validate_and_return_az_dict(lock_session, driver, lb_dict) + # Validate the network as soon as we have the AZ data + validate.network_allowed_by_config( + load_balancer.vip_network_id, + valid_networks=az_dict.get(constants.VALID_VIP_NETWORKS)) db_lb = self.repositories.create_load_balancer_and_vip( lock_session, lb_dict, vip_dict) diff --git a/octavia/common/constants.py b/octavia/common/constants.py index 8cdfb343de..32eee8665a 100644 --- a/octavia/common/constants.py +++ b/octavia/common/constants.py @@ -404,6 +404,7 @@ TOPOLOGY = 'topology' TOTAL_CONNECTIONS = 'total_connections' UPDATED_AT = 'updated_at' UPDATE_DICT = 'update_dict' +VALID_VIP_NETWORKS = 'valid_vip_networks' VIP = 'vip' VIP_ADDRESS = 'vip_address' VIP_NETWORK = 'vip_network' diff --git a/octavia/common/validate.py b/octavia/common/validate.py index 3dde6ada7f..17410af293 100644 --- a/octavia/common/validate.py +++ b/octavia/common/validate.py @@ -375,10 +375,12 @@ def network_exists_optionally_contains_subnet(network_id, subnet_id=None): return network -def network_allowed_by_config(network_id): - if CONF.networking.valid_vip_networks: - valid_networks = map(str.lower, CONF.networking.valid_vip_networks) - if network_id not in valid_networks: +def network_allowed_by_config(network_id, valid_networks=None): + if CONF.networking.valid_vip_networks and not valid_networks: + valid_networks = CONF.networking.valid_vip_networks + if valid_networks: + valid_networks = map(str.lower, valid_networks) + if network_id.lower() not in valid_networks: raise exceptions.ValidationException(detail=_( 'Supplied VIP network_id is not allowed by the configuration ' 'of this deployment.')) diff --git a/octavia/tests/unit/api/drivers/amphora_driver/v2/test_amphora_driver.py b/octavia/tests/unit/api/drivers/amphora_driver/v2/test_amphora_driver.py index 6d473e476b..a22df08e66 100644 --- a/octavia/tests/unit/api/drivers/amphora_driver/v2/test_amphora_driver.py +++ b/octavia/tests/unit/api/drivers/amphora_driver/v2/test_amphora_driver.py @@ -685,9 +685,18 @@ class TestAmphoraDriver(base.TestRpc): self.amp_driver.get_supported_availability_zone_metadata) def test_validate_availability_zone(self): + # Test compute zone ref_dict = {consts.COMPUTE_ZONE: 'my_compute_zone'} self.amp_driver.validate_availability_zone(ref_dict) + # Test vip networks + ref_dict = {consts.VALID_VIP_NETWORKS: ['my_vip_net']} + self.amp_driver.validate_availability_zone(ref_dict) + + # Test management network + ref_dict = {consts.MANAGEMENT_NETWORK: 'my_management_net'} + self.amp_driver.validate_availability_zone(ref_dict) + # Test bad availability zone metadata key ref_dict = {'bogus': 'bogus'} self.assertRaises(exceptions.UnsupportedOptionError, diff --git a/releasenotes/notes/availability-zones-can-override-valid-vip-networks-5566aa4769c158dc.yaml b/releasenotes/notes/availability-zones-can-override-valid-vip-networks-5566aa4769c158dc.yaml new file mode 100644 index 0000000000..fd3dc73462 --- /dev/null +++ b/releasenotes/notes/availability-zones-can-override-valid-vip-networks-5566aa4769c158dc.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Availability zone profiles can now override the ``valid_vip_networks`` + configuration option.