diff --git a/astara/api/config/router.py b/astara/api/config/router.py index dcc17245..ec12e325 100644 --- a/astara/api/config/router.py +++ b/astara/api/config/router.py @@ -74,7 +74,8 @@ def get_default_v4_gateway(client, router, networks): """Find the IPv4 default gateway for the router. """ LOG.debug('networks = %r', networks) - LOG.debug('external interface = %s', router.external_port.mac_address) + if router.external_port: + LOG.debug('external interface = %s', router.external_port.mac_address) # Now find the subnet that our external IP is on, and return its # gateway. @@ -122,11 +123,6 @@ def load_provider_rules(path): def generate_network_config(client, router, management_port, iface_map): retval = [ - common.network_config( - client, - router.external_port, - iface_map[router.external_port.network_id], - EXTERNAL_NET), common.network_config( client, management_port, @@ -135,6 +131,14 @@ def generate_network_config(client, router, management_port, iface_map): ) ] + if router.external_port: + retval.extend([ + common.network_config( + client, + router.external_port, + iface_map[router.external_port.network_id], + EXTERNAL_NET)]) + retval.extend( common.network_config( client, diff --git a/astara/api/neutron.py b/astara/api/neutron.py index fe6cd146..e1e12508 100644 --- a/astara/api/neutron.py +++ b/astara/api/neutron.py @@ -15,14 +15,12 @@ # under the License. -import collections import itertools import socket import time import uuid import netaddr -import six from neutronclient.v2_0 import client from neutronclient.common import exceptions as neutron_exc @@ -43,11 +41,8 @@ CONF = cfg.CONF neutron_opts = [ cfg.StrOpt('management_network_id'), - cfg.StrOpt('external_network_id'), cfg.StrOpt('management_subnet_id'), - cfg.StrOpt('external_subnet_id'), cfg.StrOpt('management_prefix', default='fdca:3ba5:a17a:acda::/64'), - cfg.StrOpt('external_prefix', default='172.16.77.0/24'), cfg.IntOpt('astara_mgt_service_port', default=5000), cfg.StrOpt('default_instance_flavor', default=1), cfg.StrOpt('interface_driver', @@ -206,10 +201,13 @@ class Router(object): @property def ports(self): - return itertools.chain( - [self.external_port], - self.internal_ports - ) + if self.external_port: + return itertools.chain( + [self.external_port], + self.internal_ports + ) + else: + return self.internal_ports class Network(DictModelBase): @@ -753,63 +751,6 @@ class Neutron(object): for port in port_data: self.api_client.delete_port(port['id']) - def create_router_external_port(self, router): - # FIXME: Need to make this smarter in case the switch is full. - network_args = {'network_id': self.conf.external_network_id} - update_args = { - 'name': router.name, - 'admin_state_up': router.admin_state_up, - 'external_gateway_info': network_args - } - - self.api_client.update_router( - router.id, - body=dict(router=update_args) - ) - new_port = self.get_router_external_port(router) - - # Make sure the port has enough IPs. - subnets = self.get_network_subnets(self.conf.external_network_id) - sn_by_id = { - sn.id: sn - for sn in subnets - } - sn_by_version = collections.defaultdict(list) - for sn in subnets: - sn_by_version[sn.ip_version].append(sn) - versions_needed = set(sn_by_version.keys()) - found = set(sn_by_id[fip.subnet_id].ip_version - for fip in new_port.fixed_ips) - if found != versions_needed: - missing_versions = list(sorted(versions_needed - found)) - raise MissingIPAllocation( - new_port.id, - [(mv, [sn.id for sn in sn_by_version[mv]]) - for mv in missing_versions] - ) - return new_port - - def get_router_external_port(self, router): - for i in six.moves.range(self.conf.max_retries): - LOG.debug( - 'Looking for router external port. Attempt %d of %d', - i, - cfg.CONF.max_retries, - ) - query_dict = { - 'device_owner': DEVICE_OWNER_ROUTER_GW, - 'device_id': router.id, - 'network_id': self.conf.external_network_id - } - ports = self.api_client.list_ports(**query_dict)['ports'] - - if len(ports): - port = Port.from_dict(ports[0]) - LOG.debug('Found router external port: %s', port.id) - return port - time.sleep(self.conf.retry_delay) - raise RouterGatewayMissing() - def _ensure_local_port(self, network_id, subnet_id, prefix, network_type): driver = importutils.import_object(self.conf.interface_driver, @@ -900,13 +841,6 @@ class Neutron(object): driver.init_l3(driver.get_device_name(port), [ip_cidr]) return ip_cidr - def ensure_local_external_port(self): - return self._ensure_local_port( - self.conf.external_network_id, - self.conf.external_subnet_id, - self.conf.external_prefix, - 'external') - def ensure_local_service_port(self): return self._ensure_local_port( self.conf.management_network_id, diff --git a/astara/drivers/router.py b/astara/drivers/router.py index f2c29fbf..c742b24a 100644 --- a/astara/drivers/router.py +++ b/astara/drivers/router.py @@ -164,21 +164,6 @@ class Router(BaseDriver): self.log.info(_('Config updated for %s after %s seconds'), self.name, round(delta, 2)) - def pre_plug(self, worker_context): - """pre-plug hook - Sets up the external port. - - :param worker_context: - :returs: None - """ - if self._router.external_port is None: - # FIXME: Need to do some work to pick the right external - # network for a tenant. - self.log.debug('Adding external port to router %s') - ext_port = worker_context.neutron.create_router_external_port( - self._router) - self._router.external_port = ext_port - def make_ports(self, worker_context): """make ports call back for the nova client. diff --git a/astara/main.py b/astara/main.py index ca7d1d4d..c6b1150c 100644 --- a/astara/main.py +++ b/astara/main.py @@ -46,7 +46,6 @@ MAIN_OPTS = [ cfg.StrOpt('host', default=socket.getfqdn(), help="The hostname Astara is running on"), - cfg.BoolOpt('plug_external_port', default=True), ] CONF.register_opts(MAIN_OPTS) @@ -122,10 +121,6 @@ def main(argv=sys.argv[1:]): # bring the mgt tap interface up mgt_ip_address = neutron.ensure_local_service_port().split('/')[0] - # bring the external port - if cfg.CONF.plug_external_port: - neutron.ensure_local_external_port() - # Set up the queue to move messages between the eventlet-based # listening process and the scheduler. notification_queue = multiprocessing.Queue() diff --git a/astara/test/unit/api/config/test_router_config.py b/astara/test/unit/api/config/test_router_config.py index 7d0d7d85..ecbebfff 100644 --- a/astara/test/unit/api/config/test_router_config.py +++ b/astara/test/unit/api/config/test_router_config.py @@ -147,15 +147,17 @@ class TestAstaraClient(unittest.TestCase): self.assertEqual(result, expected) expected_calls = [ - mock.call( - mock_client, fakes.fake_router.external_port, - 'ge1', 'external'), mock.call( mock_client, fakes.fake_router.management_port, 'ge0', 'management'), + mock.call( + mock_client, fakes.fake_router.external_port, + 'ge1', 'external'), mock.call( mock_client, fakes.fake_int_port, 'ge2', 'internal', mock.ANY)] + for c in expected_calls: + self.assertIn(c, mock_net_conf.call_args_list) mock_net_conf.assert_has_calls(expected_calls) def test_generate_floating_config(self): diff --git a/astara/test/unit/api/test_neutron_wrapper.py b/astara/test/unit/api/test_neutron_wrapper.py index d78fa745..0713e5d9 100644 --- a/astara/test/unit/api/test_neutron_wrapper.py +++ b/astara/test/unit/api/test_neutron_wrapper.py @@ -15,8 +15,6 @@ # under the License. -import copy - import mock import netaddr @@ -364,211 +362,9 @@ class TestNeutronWrapper(base.RugTestBase): self.assertFalse(neutron_wrapper.api_client.delete_port.called) -class TestExternalPort(base.RugTestBase): - - EXTERNAL_NET_ID = 'a0c63b93-2c42-4346-909e-39c690f53ba0' - EXTERNAL_PORT_ID = '089ae859-10ec-453c-b264-6c452fc355e5' - ROUTER = { - u'status': u'ACTIVE', - u'external_gateway_info': { - u'network_id': EXTERNAL_NET_ID, - u'enable_snat': True}, - u'name': u'ak-b81e555336da4bf48886e5b93ac6186d', - u'admin_state_up': True, - u'tenant_id': u'b81e555336da4bf48886e5b93ac6186d', - u'ports': [ - # This is the external port: - {u'status': u'ACTIVE', - u'binding:host_id': u'devstack-develop', - u'name': u'', - u'allowed_address_pairs': [], - u'admin_state_up': True, - u'network_id': EXTERNAL_NET_ID, - u'tenant_id': u'', - u'extra_dhcp_opts': [], - u'binding:vif_type': u'ovs', - u'device_owner': u'network:router_gateway', - u'binding:capabilities': {u'port_filter': True}, - u'mac_address': u'fa:16:3e:a1:a6:ac', - u'fixed_ips': [ - {u'subnet_id': u'ipv4snid', - u'ip_address': u'172.16.77.2'}, - {u'subnet_id': u'ipv6snid', - u'ip_address': u'fdee:9f85:83be::0'}], - u'id': EXTERNAL_PORT_ID, - u'security_groups': [], - u'device_id': u'7770b189-1223-4d85-9bf7-4d7bc2a28cd7'}, - # Some other nice ports you might like: - {u'status': u'ACTIVE', - u'binding:host_id': u'devstack-develop', - u'name': u'', - u'allowed_address_pairs': [], - u'admin_state_up': True, - u'network_id': u'adf190e0-b281-4453-bd87-4ae6fd96d5c1', - u'tenant_id': u'a09298ceed154d26b4ea96977e1c7f17', - u'extra_dhcp_opts': [], - u'binding:vif_type': u'ovs', - u'device_owner': u'network:router_management', - u'binding:capabilities': {u'port_filter': True}, - u'mac_address': u'fa:16:3e:e5:dd:55', - u'fixed_ips': [ - {u'subnet_id': u'ipv6snid2', - u'ip_address': u'fdca:3ba5:a17a:acda::0'}], - u'id': u'2f4e41b2-c923-48e5-ad19-59e4d02c26a4', - u'security_groups': [], - u'device_id': u'7770b189-1223-4d85-9bf7-4d7bc2a28cd7'}, - {u'status': u'ACTIVE', - u'binding:host_id': u'devstack-develop', - u'name': u'', - u'allowed_address_pairs': [], - u'admin_state_up': True, - u'network_id': u'0c04f39c-f739-44dd-9e65-dca6ae20e35c', - u'tenant_id': u'b81e555336da4bf48886e5b93ac6186d', - u'extra_dhcp_opts': [], - u'binding:vif_type': u'ovs', - u'device_owner': u'network:router_interface', - u'binding:capabilities': {u'port_filter': True}, - u'mac_address': u'fa:16:3e:e7:27:fc', - u'fixed_ips': [{u'subnet_id': u'ipv4snid2', - u'ip_address': u'192.168.0.1'}, - {u'subnet_id': u'ipv6snid3', - u'ip_address': u'fdd6:a1fa:cfa8:cd70::1'}], - u'id': u'b24139b8-a3d0-46cf-bc53-f4b70bb33596', - u'security_groups': [], - u'device_id': u'7770b189-1223-4d85-9bf7-4d7bc2a28cd7'}], - u'routes': [], - u'id': u'5366e8ca-b3e4-408a-91d4-e207af48c755', - } - - SUBNETS = [ - neutron.Subnet(u'ipv4snid', u'ipv4snid', None, None, 4, - '172.16.77.0/24', '172.16.77.1', False, - [], [], None), - neutron.Subnet(u'ipv6snid', u'ipv4snid', None, None, 6, - 'fdee:9f85:83be::/48', 'fdee:9f85:83be::1', - False, [], [], None), - ] - - def setUp(self): - super(TestExternalPort, self).setUp() - self.conf = mock.Mock() - self.conf.external_network_id = 'ext' - self.conf.max_retries = 3 - self.conf.retry_delay = 1 - self.conf.external_network_id = self.EXTERNAL_NET_ID - self.router = neutron.Router.from_dict(self.ROUTER) - - @mock.patch('astara.api.neutron.AstaraExtClientWrapper') - def test_create(self, client_wrapper): - mock_client = mock.Mock() - mock_client.show_router.return_value = {'router': self.ROUTER} - mock_client.list_ports.return_value = { - 'ports': [self.ROUTER['ports'][0]] - } - client_wrapper.return_value = mock_client - neutron_wrapper = neutron.Neutron(self.conf) - with mock.patch.object(neutron_wrapper, 'get_network_subnets') as gns: - gns.return_value = self.SUBNETS - port = neutron_wrapper.create_router_external_port(self.router) - self.assertEqual(port.id, self.EXTERNAL_PORT_ID) - - @mock.patch('astara.api.neutron.AstaraExtClientWrapper') - def test_create_missing_gateway_port(self, client_wrapper): - self.conf.retry_delay = 0 - mock_client = mock.Mock() - router = copy.deepcopy(self.ROUTER) - router['ports'] = [] - mock_client.show_router.return_value = {'router': router} - mock_client.list_ports.return_value = {'ports': []} - - client_wrapper.return_value = mock_client - neutron_wrapper = neutron.Neutron(self.conf) - with mock.patch.object(neutron_wrapper, 'get_network_subnets') as gns: - gns.return_value = self.SUBNETS - self.assertRaises( - neutron.RouterGatewayMissing, - neutron_wrapper.create_router_external_port, - self.router - ) - - @mock.patch('astara.api.neutron.AstaraExtClientWrapper') - def test_missing_v4(self, client_wrapper): - mock_client = mock.Mock() - - router = copy.deepcopy(self.ROUTER) - del router['ports'][0]['fixed_ips'][0] - - mock_client.list_ports.return_value = { - 'ports': [router['ports'][0]] - } - - mock_client.show_router.return_value = {'router': router} - client_wrapper.return_value = mock_client - neutron_wrapper = neutron.Neutron(self.conf) - with mock.patch.object(neutron_wrapper, 'get_network_subnets') as gns: - gns.return_value = self.SUBNETS - try: - neutron_wrapper.create_router_external_port(self.router) - except neutron.MissingIPAllocation as e: - self.assertEqual(4, e.missing[0][0]) - else: - self.fail('Should have seen MissingIPAllocation') - - @mock.patch('astara.api.neutron.AstaraExtClientWrapper') - def test_missing_v6(self, client_wrapper): - mock_client = mock.Mock() - - router = copy.deepcopy(self.ROUTER) - del router['ports'][0]['fixed_ips'][1] - - mock_client.list_ports.return_value = { - 'ports': [router['ports'][0]] - } - - mock_client.show_router.return_value = {'router': router} - client_wrapper.return_value = mock_client - neutron_wrapper = neutron.Neutron(self.conf) - with mock.patch.object(neutron_wrapper, 'get_network_subnets') as gns: - gns.return_value = self.SUBNETS - try: - neutron_wrapper.create_router_external_port(self.router) - except neutron.MissingIPAllocation as e: - self.assertEqual(6, e.missing[0][0]) - else: - self.fail('Should have seen MissingIPAllocation') - - @mock.patch('astara.api.neutron.AstaraExtClientWrapper') - def test_missing_both(self, client_wrapper): - mock_client = mock.Mock() - - router = copy.deepcopy(self.ROUTER) - router['ports'][0]['fixed_ips'] = [] - - mock_client.show_router.return_value = {'router': router} - mock_client.list_ports.return_value = { - 'ports': [router['ports'][0]] - } - - client_wrapper.return_value = mock_client - - neutron_wrapper = neutron.Neutron(self.conf) - with mock.patch.object(neutron_wrapper, 'get_network_subnets') as gns: - gns.return_value = self.SUBNETS - try: - neutron_wrapper.create_router_external_port(self.router) - except neutron.MissingIPAllocation as e: - self.assertEqual(4, e.missing[0][0]) - self.assertEqual(6, e.missing[1][0]) - else: - self.fail('Should have seen MissingIPAllocation') - - class TestLocalServicePorts(base.RugTestBase): def setUp(self): super(TestLocalServicePorts, self).setUp() - self.config(external_network_id='fake_extnet_network_id') - self.config(external_subnet_id='fake_extnet_subnet_id') - self.config(external_prefix='172.16.77.0/24') self.config(management_network_id='fake_mgtnet_network_id') self.config(management_subnet_id='fake_mgtnet_subnet_id') self.config(management_prefix='172.16.77.0/24') @@ -579,17 +375,6 @@ class TestLocalServicePorts(base.RugTestBase): init_l3=mock.Mock(), get_device_name=mock.Mock()) - def test_ensure_local_external_port(self): - with mock.patch.object(self.neutron_wrapper, - '_ensure_local_port') as ep: - self.neutron_wrapper.ensure_local_external_port() - ep.assert_called_with( - 'fake_extnet_network_id', - 'fake_extnet_subnet_id', - '172.16.77.0/24', - 'external', - ) - def test_ensure_local_service_port(self): with mock.patch.object(self.neutron_wrapper, '_ensure_local_port') as ep: diff --git a/astara/test/unit/drivers/test_router.py b/astara/test/unit/drivers/test_router.py index 07f7609f..99f6e980 100644 --- a/astara/test/unit/drivers/test_router.py +++ b/astara/test/unit/drivers/test_router.py @@ -117,25 +117,6 @@ class RouterDriverTest(base.RugTestBase): rtr.mgt_port, 'fake_config',) - def test_pre_plug_no_external_port(self): - rtr = self._init_driver() - fake_router_obj = fakes.fake_router() - fake_router_obj.external_port = None - rtr._router = fake_router_obj - self.ctx.neutron.create_router_external_port.return_value = 'fake_port' - rtr.pre_plug(self.ctx) - self.ctx.neutron.create_router_external_port.assert_called_with( - fake_router_obj, - ) - self.assertEqual(rtr._router.external_port, 'fake_port') - - def test_pre_plug_with_external_port(self): - rtr = self._init_driver() - fake_router_obj = fakes.fake_router() - fake_router_obj.external_port = 'fake_port' - rtr.pre_plug(self.ctx) - self.assertFalse(self.ctx.neutron.create_router_external_port.called) - @mock.patch('astara.drivers.router.Router._ensure_cache') def test_make_ports(self, mock_ensure_cache): rtr = self._init_driver() diff --git a/devstack/plugin.sh b/devstack/plugin.sh index 2d2d1d55..2700daa8 100644 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -88,6 +88,7 @@ function configure_astara_neutron() { # We need the RUG to be able to get neutron's events notification like port.create.start/end # or router.interface.start/end to make it able to boot astara routers iniset $NEUTRON_CONF DEFAULT notification_driver "neutron.openstack.common.notifier.rpc_notifier" + iniset $NEUTRON_CONF DEFAULT astara_auto_add_resources False } function configure_astara_horizon() { @@ -146,15 +147,6 @@ function create_astara_nova_flavor() { iniset $ASTARA_CONF router instance_flavor $ROUTER_INSTANCE_FLAVOR_ID } -function _remove_subnets() { - # Attempt to delete subnets associated with a network. - # We have to modify the output of net-show to allow it to be - # parsed properly as shell variables, and we run both commands in - # a subshell to avoid polluting the local namespace. - (eval $(neutron $auth_args net-show -f shell $1 | sed 's/:/_/g'); - neutron $auth_args subnet-delete $subnets || true) -} - function pre_start_astara() { # Create and init the database recreate_database astara @@ -166,33 +158,13 @@ function pre_start_astara() { # CLI. unset OS_TENANT_NAME OS_PROJECT_NAME - if ! neutron $auth_args net-show $PUBLIC_NETWORK_NAME; then - neutron $auth_args net-create $PUBLIC_NETWORK_NAME --router:external - fi - - # Remove the ipv6 subnet created automatically before adding our own. - # NOTE(adam_g): For some reason this fails the first time and needs to be repeated? - _remove_subnets $PUBLIC_NETWORK_NAME ; _remove_subnets $PUBLIC_NETWORK_NAME - - typeset public_subnet_id=$(neutron $auth_args subnet-create --ip-version 4 $PUBLIC_NETWORK_NAME 172.16.77.0/24 | grep ' id ' | awk '{ print $4 }') - iniset $ASTARA_CONF DEFAULT external_subnet_id $public_subnet_id - neutron $auth_args subnet-create --ip-version 6 $PUBLIC_NETWORK_NAME fdee:9f85:83be::/48 - # setup masq rule for public network - sudo iptables -t nat -A POSTROUTING -s 172.16.77.0/24 -o $PUBLIC_INTERFACE_DEFAULT -j MASQUERADE - - neutron $auth_args net-show $PUBLIC_NETWORK_NAME | grep ' id ' | awk '{ print $4 }' - - typeset public_network_id=$(neutron $auth_args net-show $PUBLIC_NETWORK_NAME | grep ' id ' | awk '{ print $4 }') - iniset $ASTARA_CONF DEFAULT external_network_id $public_network_id + #sudo iptables -t nat -A POSTROUTING -s 172.16.77.0/24 -o $PUBLIC_INTERFACE_DEFAULT -j MASQUERADE neutron $auth_args net-create mgt typeset mgt_network_id=$(neutron $auth_args net-show mgt | grep ' id ' | awk '{ print $4 }') iniset $ASTARA_CONF DEFAULT management_network_id $mgt_network_id - # Remove the ipv6 subnet created automatically before adding our own. - _remove_subnets mgt - local subnet_create_args="" if [[ "$ASTARA_MANAGEMENT_PREFIX" =~ ':' ]]; then subnet_create_args="--ip-version=6 --ipv6_address_mode=slaac --enable_dhcp" @@ -200,10 +172,6 @@ function pre_start_astara() { typeset mgt_subnet_id=$(neutron $auth_args subnet-create mgt $ASTARA_MANAGEMENT_PREFIX $subnet_create_args | grep ' id ' | awk '{ print $4 }') iniset $ASTARA_CONF DEFAULT management_subnet_id $mgt_subnet_id - # Remove the private network created by devstack - neutron $auth_args subnet-delete $PRIVATE_SUBNET_NAME - neutron $auth_args net-delete $PRIVATE_NETWORK_NAME - local astara_dev_image_src="" local lb_element="" @@ -251,15 +219,6 @@ function pre_start_astara() { fi create_astara_nova_flavor - - # Restart neutron so that `astara.floatingip_subnet` is properly set - if [[ "$USE_SCREEN" == "True" ]]; then - screen_stop_service q-svc - else - stop_process q-svc - fi - start_neutron_service_and_check - sleep 10 } function start_astara() { @@ -271,13 +230,8 @@ function start_astara() { } function post_start_astara() { - echo "Creating demo user network and subnet" - local auth_args="$(_auth_args demo $OS_PASSWORD demo)" - neutron $auth_args net-create thenet - neutron $auth_args subnet-create thenet $FIXED_RANGE - # Open all traffic on the private CIDR - set_demo_tenant_sec_group_private_traffic + set_demo_tenant_sec_group_private_traffic } function stop_astara() { @@ -293,8 +247,6 @@ function set_neutron_user_permission() { # public networks, we need to modify the policy and allow users with the service # to do that too. - echo "Updating Nova policy file" - local old_value='"network:attach_external_network": "rule:admin_api"' local new_value='"network:attach_external_network": "rule:admin_api or role:service"' sed -i "s/$old_value/$new_value/g" "$NOVA_CONF_DIR/policy.json" @@ -331,7 +283,6 @@ if is_service_enabled astara; then elif [[ "$1" == "stack" && "$2" == "install" ]]; then echo_summary "Installing Astara" - if is_service_enabled n-api; then set_neutron_user_permission fi diff --git a/devstack/settings b/devstack/settings index c433b5c5..33aba2a5 100644 --- a/devstack/settings +++ b/devstack/settings @@ -58,4 +58,6 @@ ASTARA_COORDINATION_URL=${ASTARA_COORDINATION_URL:-memcached://localhost:11211} if [[ "$ASTARA_ENABLED_DRIVERS" =~ "router" ]]; then ML2_L3_PLUGIN="astara_neutron.plugins.ml2_neutron_plugin.L3RouterPlugin" + Q_L3_ENABLED=True + Q_L3_ROUTER_PER_TENANT=True fi diff --git a/releasenotes/notes/devstack_default_external-d5b9e5e830d5a8df.yaml b/releasenotes/notes/devstack_default_external-d5b9e5e830d5a8df.yaml new file mode 100644 index 00000000..03c6e329 --- /dev/null +++ b/releasenotes/notes/devstack_default_external-d5b9e5e830d5a8df.yaml @@ -0,0 +1,17 @@ +--- +prelude: > + Astara has dropped a number of legacy convenience hooks available in + earlier releases. The hooks complicated automation and created + potential for mismatch of end state and the desired state. +fixes: + - Bug `1539345 `_ + auto added resources break interoperability +upgrade: + - Astara will no longer automatically add the external gateway to a router. + Previous usage was causing issues with automation tooling. + - Astara no longer requires the external network and subnet id to be known. + In production deployments this step was handled externally and the + internal hooks were often disabled. +critical: + - The devstack plugin no longer creates the external network as before and + instead follows the setup used for reference implementation. diff --git a/tools/run_functional.sh b/tools/run_functional.sh index 4b0de72d..2e74c3c0 100755 --- a/tools/run_functional.sh +++ b/tools/run_functional.sh @@ -26,6 +26,7 @@ os_tenant_name=$OS_TENANT_NAME service_tenant_name=$SERVICE_TENANT_NAME service_tenant_id=$SERVICE_TENANT_ID appliance_api_port=$APPLIANCE_API_PORT +astara_auto_add_resources=False # Defaults for the gate health_check_timeout=10