Browse Source

Add fullstack test for release overlap address

Related-Bug: #1782947
Change-Id: I25164449d053d5a4287aa0cf3fccb33b8c6f367d
Hongbin Lu 9 months ago
parent
commit
669352706a

+ 2
- 24
kuryr_libnetwork/controllers.py View File

@@ -18,7 +18,6 @@ from itertools import groupby
18 18
 import jsonschema
19 19
 from operator import itemgetter
20 20
 import six
21
-import time
22 21
 
23 22
 from neutronclient.common import exceptions as n_exceptions
24 23
 from oslo_concurrency import processutils
@@ -405,27 +404,6 @@ def _get_networks_by_identifier(identifier):
405 404
     return _get_networks_by_attrs(name=identifier)
406 405
 
407 406
 
408
-def _port_active(neutron_port_id, vif_plug_timeout):
409
-    port_active = False
410
-    tries = 0
411
-    while True:
412
-        try:
413
-            port = app.neutron.show_port(neutron_port_id)
414
-        except n_exceptions.NeutronClientException as ex:
415
-            LOG.error('Could not get the port %s to check '
416
-                      'its status', ex)
417
-        else:
418
-            if port['port']['status'] == lib_const.PORT_STATUS_ACTIVE:
419
-                port_active = True
420
-        if port_active or (vif_plug_timeout > 0 and tries >= vif_plug_timeout):
421
-            break
422
-        LOG.debug('Waiting for port %s to become ACTIVE', neutron_port_id)
423
-        tries += 1
424
-        time.sleep(1)
425
-
426
-    return port_active
427
-
428
-
429 407
 def _program_expose_ports(options, port_id):
430 408
     exposed_ports = options.get(const.DOCKER_EXPOSED_PORTS_OPTION)
431 409
     if not exposed_ports:
@@ -1175,8 +1153,8 @@ def network_driver_create_endpoint():
1175 1153
                 LOG.error('Failed to set up the interface: %s', ex)
1176 1154
 
1177 1155
         if app.vif_plug_is_fatal:
1178
-            port_active = _port_active(neutron_port['id'],
1179
-                                       app.vif_plug_timeout)
1156
+            port_active = utils.wait_for_port_active(
1157
+                app.neutron, neutron_port['id'], app.vif_plug_timeout)
1180 1158
             if not port_active:
1181 1159
                 neutron_port_name = neutron_port['name']
1182 1160
                 raise exceptions.InactiveResourceException(

+ 153
- 0
kuryr_libnetwork/tests/fullstack/test_ipam.py View File

@@ -482,3 +482,156 @@ class IpamTest(kuryr_base.KuryrBaseTest):
482 482
         self.neutron_client.delete_subnet(
483 483
             neutron_v6_subnet['subnets'][0]['id'])
484 484
         self.neutron_client.delete_network(neutron_network['network']['id'])
485
+
486
+    def test_container_ipam_release_address_with_existing_port_same_ip(self):
487
+        ipv4_address = "10.15.0.10"
488
+
489
+        # pre-created the first Neutron network and subnet and port
490
+        neutron_net_name = lib_utils.get_random_string(8)
491
+        neutron_network = self.neutron_client.create_network(
492
+            {'network': {'name': neutron_net_name,
493
+                         "admin_state_up": True}})
494
+        neutron_subnet_name = lib_utils.get_random_string(8)
495
+        subnet_param = [{
496
+            'name': neutron_subnet_name,
497
+            'network_id': neutron_network['network']['id'],
498
+            'ip_version': 4,
499
+            'cidr': "10.15.0.0/24",
500
+        }]
501
+        neutron_subnet = self.neutron_client.create_subnet(
502
+            {'subnets': subnet_param})
503
+        existing_neutron_port = self.neutron_client.create_port(
504
+            {'port': {'network_id': neutron_network['network']['id'],
505
+                      'fixed_ips': [{'ip_address': ipv4_address}]}})
506
+        fake_ipam = {
507
+            "Driver": "kuryr",
508
+            "Options": {
509
+                'neutron.subnet.name': neutron_subnet_name
510
+            },
511
+            "Config": [
512
+                {
513
+                    "Subnet": "10.15.0.0/24",
514
+                    "Gateway": "10.15.0.1"
515
+                }
516
+            ]
517
+        }
518
+        # Create docker network using existing Neutron network
519
+        options = {'neutron.net.name': neutron_net_name,
520
+                   'neutron.subnet.name': neutron_subnet_name}
521
+        container_net_name = lib_utils.get_random_string(8)
522
+        container_net = self.docker_client.create_network(
523
+            name=container_net_name,
524
+            driver='kuryr',
525
+            options=options,
526
+            ipam=fake_ipam)
527
+        container_net_id = container_net.get('Id')
528
+
529
+        # pre-created the second Neutron network and subnet and port
530
+        neutron_net_name2 = lib_utils.get_random_string(8)
531
+        neutron_network2 = self.neutron_client.create_network(
532
+            {'network': {'name': neutron_net_name2,
533
+                         "admin_state_up": True}})
534
+        neutron_subnet_name2 = lib_utils.get_random_string(8)
535
+        subnet_param2 = [{
536
+            'name': neutron_subnet_name2,
537
+            'network_id': neutron_network2['network']['id'],
538
+            'ip_version': 4,
539
+            'cidr': "10.15.0.0/24",
540
+        }]
541
+        neutron_subnet2 = self.neutron_client.create_subnet(
542
+            {'subnets': subnet_param2})
543
+        existing_neutron_port2 = self.neutron_client.create_port(
544
+            {'port': {'network_id': neutron_network2['network']['id'],
545
+                      'fixed_ips': [{'ip_address': ipv4_address}]}})
546
+        fake_ipam2 = {
547
+            "Driver": "kuryr",
548
+            "Options": {
549
+                'neutron.subnet.name': neutron_subnet_name2
550
+            },
551
+            "Config": [
552
+                {
553
+                    "Subnet": "10.15.0.0/24",
554
+                    "Gateway": "10.15.0.1"
555
+                }
556
+            ]
557
+        }
558
+        # Create docker network using existing Neutron network
559
+        options = {'neutron.net.name': neutron_net_name2,
560
+                   'neutron.subnet.name': neutron_subnet_name2}
561
+        container_net_name2 = lib_utils.get_random_string(8)
562
+        container_net2 = self.docker_client.create_network(
563
+            name=container_net_name2,
564
+            driver='kuryr',
565
+            options=options,
566
+            ipam=fake_ipam2)
567
+        container_net_id2 = container_net2.get('Id')
568
+
569
+        # Boot the first container, and connect to the first docker network.
570
+        endpoint_config = self.docker_client.create_endpoint_config(
571
+            ipv4_address=ipv4_address)
572
+        network_config = self.docker_client.create_networking_config({
573
+            container_net_id: endpoint_config})
574
+        container_name = lib_utils.get_random_string(8)
575
+        container = self.docker_client.create_container(
576
+            image='kuryr/busybox',
577
+            command='/bin/sleep 600',
578
+            hostname='kuryr_test_container',
579
+            name=container_name,
580
+            networking_config=network_config)
581
+        container_id = container.get('Id')
582
+        self.docker_client.start(container=container_id)
583
+
584
+        # Boot the second container, and connect to the second docker network.
585
+        endpoint_config = self.docker_client.create_endpoint_config(
586
+            ipv4_address=ipv4_address)
587
+        network_config = self.docker_client.create_networking_config({
588
+            container_net_id2: endpoint_config})
589
+        container_name2 = lib_utils.get_random_string(8)
590
+        container2 = self.docker_client.create_container(
591
+            image='kuryr/busybox',
592
+            command='/bin/sleep 600',
593
+            hostname='kuryr_test_container2',
594
+            name=container_name2,
595
+            networking_config=network_config)
596
+        container_id2 = container2.get('Id')
597
+        self.docker_client.start(container=container_id2)
598
+
599
+        # Assert both existing neutron ports active
600
+        for port_id in (existing_neutron_port['port']['id'],
601
+                        existing_neutron_port2['port']['id']):
602
+            utils.wait_for_port_active(
603
+                self.neutron_client, port_id, 60)
604
+            neutron_port = self.neutron_client.show_port(port_id)
605
+            self.assertEqual('ACTIVE', neutron_port['port']['status'])
606
+
607
+        # Disconnect the first container from network and
608
+        # assert the first neutron port is down and the second is still active
609
+        self.docker_client.disconnect_container_from_network(container_id,
610
+                                                             container_net_id)
611
+        existing_neutron_port = self.neutron_client.show_port(
612
+            existing_neutron_port['port']['id'])
613
+        self.assertEqual('DOWN', existing_neutron_port['port']['status'])
614
+        existing_neutron_port2 = self.neutron_client.show_port(
615
+            existing_neutron_port2['port']['id'])
616
+        self.assertEqual('ACTIVE', existing_neutron_port2['port']['status'])
617
+
618
+        # Disconnect the second container from network and
619
+        # assert both neutron ports are down.
620
+        self.docker_client.disconnect_container_from_network(container_id2,
621
+                                                             container_net_id2)
622
+        for port_id in (existing_neutron_port['port']['id'],
623
+                        existing_neutron_port2['port']['id']):
624
+            neutron_port = self.neutron_client.show_port(port_id)
625
+            self.assertEqual('DOWN', neutron_port['port']['status'])
626
+
627
+        # Cleanup resources
628
+        self.docker_client.stop(container=container_id)
629
+        self.docker_client.stop(container=container_id2)
630
+        self.docker_client.remove_network(container_net_id)
631
+        self.docker_client.remove_network(container_net_id2)
632
+        self.neutron_client.delete_port(existing_neutron_port['port']['id'])
633
+        self.neutron_client.delete_port(existing_neutron_port2['port']['id'])
634
+        self.neutron_client.delete_subnet(neutron_subnet['subnets'][0]['id'])
635
+        self.neutron_client.delete_subnet(neutron_subnet2['subnets'][0]['id'])
636
+        self.neutron_client.delete_network(neutron_network['network']['id'])
637
+        self.neutron_client.delete_network(neutron_network2['network']['id'])

+ 24
- 0
kuryr_libnetwork/utils.py View File

@@ -12,6 +12,7 @@
12 12
 
13 13
 import os
14 14
 import sys
15
+import time
15 16
 import traceback
16 17
 
17 18
 import flask
@@ -22,6 +23,7 @@ from oslo_concurrency import processutils
22 23
 from oslo_log import log
23 24
 from werkzeug import exceptions as w_exceptions
24 25
 
26
+from kuryr.lib import constants as lib_const
25 27
 from kuryr.lib import exceptions
26 28
 from kuryr.lib import utils as lib_utils
27 29
 from kuryr_libnetwork import constants as const
@@ -126,3 +128,25 @@ def make_net_name(netid, tags=True):
126 128
 
127 129
 def make_subnet_name(pool_cidr):
128 130
     return const.SUBNET_NAME_PREFIX + pool_cidr
131
+
132
+
133
+def wait_for_port_active(neutron_client, neutron_port_id, vif_plug_timeout):
134
+    port_active = False
135
+    tries = 0
136
+    while True:
137
+        try:
138
+            port = neutron_client.show_port(neutron_port_id)
139
+        except n_exceptions.NeutronClientException as ex:
140
+            LOG.error('Could not get the port %s to check '
141
+                      'its status', ex)
142
+        else:
143
+            if port['port']['status'] == lib_const.PORT_STATUS_ACTIVE:
144
+                port_active = True
145
+        if port_active or (vif_plug_timeout > 0 and
146
+                           tries >= vif_plug_timeout):
147
+            break
148
+        LOG.debug('Waiting for port %s to become ACTIVE', neutron_port_id)
149
+        tries += 1
150
+        time.sleep(1)
151
+
152
+    return port_active

Loading…
Cancel
Save