Browse Source

Don't assign VIPs for GET requests

Since VIPs make no sense before a cluster is deployed
there's no need to assign them when network configuration
is generated for GET requests.

Co-authored by: Maciej Kwiek <mkwiek@mirantis.com>
Co-authored by: Roman Prykhodchenko<me@romcheg.me>

Change-Id: I382066cc62a9d98f728f5cd5edf771a5a980922f
Closes-bug: #1504572
Closes-bug: #1499291
Partial-bug: #1524320
tags/9.0
Roman Prykhodchenko 3 years ago
parent
commit
77f5eaf896

+ 4
- 5
nailgun/nailgun/api/v1/handlers/network_configuration.py View File

@@ -99,10 +99,6 @@ class ProviderHandler(BaseHandler):
99 99
             # some corner cases, and it should be fixed. in order
100 100
             # to simplify troubleshootng, let's print traceback to log.
101 101
             return self.serializer.serialize_for_cluster(cluster)
102
-        except errors.OutOfIPs as exc:
103
-            raise self.http(400, six.text_type(exc))
104
-        except errors.DuplicatedVIPNames as exc:
105
-            raise self.http(400, six.text_type(exc))
106 102
         except Exception:
107 103
             logger.exception('Serialization failed')
108 104
             raise
@@ -136,7 +132,10 @@ class ProviderHandler(BaseHandler):
136 132
         nm.update(cluster, data)
137 133
 
138 134
         try:
139
-            network_config = self.serializer.serialize_for_cluster(cluster)
135
+            network_config = self.serializer.serialize_for_cluster(cluster,
136
+                                                                   True)
137
+        except errors.DuplicatedVIPNames as exc:
138
+            raise self.http(400, six.text_type(exc))
140 139
         except errors.OutOfIPs as exc:
141 140
             network_id = getattr(exc, 'network_id', None)
142 141
             raise self.http(

+ 97
- 72
nailgun/nailgun/network/manager.py View File

@@ -300,6 +300,30 @@ class NetworkManager(object):
300 300
                 db().add(ip_db)
301 301
             db().flush()
302 302
 
303
+    @classmethod
304
+    def get_assigned_vip(cls, nodegroup, network_name, vip_type):
305
+        """Get VIP address, if it was assigned already
306
+
307
+        :param nodegroup: Name of the node group.
308
+        :param nerwork_name: Name of a network the VIP is allocated in.
309
+        :param vip_type: Type of a required VIP.
310
+        :returns: IP address of a VIP that matches specified criterias.
311
+                  None, if no VIP matches specificied criterias.
312
+
313
+        """
314
+        network = cls.get_network_by_name_and_nodegroup(network_name,
315
+                                                        nodegroup)
316
+
317
+        cluster_vip_q = db().query(IPAddr).filter_by(vip_type=vip_type)
318
+
319
+        if network is not None:
320
+            cluster_vip_q = cluster_vip_q.filter_by(network=network.id)
321
+
322
+        cluster_vip = cluster_vip_q.first()
323
+
324
+        if cluster_vip:
325
+            return cluster_vip.ip_addr
326
+
303 327
     @classmethod
304 328
     def assign_vip(cls, nodegroup, network_name,
305 329
                    vip_type=consts.NETWORK_VIP_TYPES.haproxy):
@@ -322,20 +346,18 @@ class NetworkManager(object):
322 346
         :type  vip_type: str
323 347
         :returns: assigned VIP (string)
324 348
         :raises: Exception
349
+
325 350
         """
326
-        network = db().query(NetworkGroup).\
327
-            filter_by(name=network_name, group_id=nodegroup.id).first()
328
-        ips_in_use = None
351
+        already_assigned = cls.get_assigned_vip(nodegroup,
352
+                                                network_name, vip_type)
353
+        network = cls.get_network_by_name_and_nodegroup(network_name,
354
+                                                        nodegroup)
329 355
 
330
-        # FIXME:
331
-        #   Built-in fuelweb_admin network doesn't belong to any node
332
-        #   group, since it's shared between all clusters. So we need
333
-        #   to handle this very special case if we want to be able
334
-        #   to allocate VIP in default admin network.
335
-        if not network and network_name == consts.NETWORKS.fuelweb_admin:
336
-            network = cls.get_admin_network_group()
356
+        if already_assigned is not None and \
357
+                cls.check_ip_belongs_to_net(already_assigned, network):
358
+            return already_assigned
337 359
 
338
-        if not network:
360
+        if network is None:
339 361
             raise errors.CanNotFindNetworkForNodeGroup(
340 362
                 u"Network '{0}' for nodegroup='{1}' not found.".format(
341 363
                     network_name, nodegroup.name))
@@ -345,10 +367,8 @@ class NetworkManager(object):
345 367
             node=None,
346 368
             vip_type=vip_type
347 369
         ).first()
348
-        # check if cluster_vip is in required cidr: network.cidr
349
-        if cluster_vip and cls.check_ip_belongs_to_net(cluster_vip.ip_addr,
350
-                                                       network):
351
-            return cluster_vip.ip_addr
370
+
371
+        ips_in_use = None
352 372
 
353 373
         if network_name == consts.NETWORKS.fuelweb_admin:
354 374
             # Nodes not currently assigned to a cluster will still
@@ -463,7 +483,7 @@ class NetworkManager(object):
463 483
         db().flush()
464 484
 
465 485
     @classmethod
466
-    def assign_vips_for_net_groups_for_api(cls, cluster):
486
+    def assign_vips_for_net_groups_for_api(cls, cluster, allocate=True):
467 487
         return cls.assign_vips_for_net_groups(cluster)
468 488
 
469 489
     @classmethod
@@ -1721,6 +1741,31 @@ class NetworkManager(object):
1721 1741
             result.append(net_info)
1722 1742
         return result
1723 1743
 
1744
+    @classmethod
1745
+    def get_network_by_name_and_nodegroup(cls, name, nodegroup):
1746
+        """Find a network that matches a specified name and a nodegroup.
1747
+
1748
+        :param name: Name of a network
1749
+        :param nodegroup: The nodegroup object
1750
+        :return: Network object that matches a specified name and a nodegroup.
1751
+                 Admin network, if nothing found.
1752
+
1753
+        """
1754
+        network = db().query(NetworkGroup).\
1755
+            filter_by(name=name, group_id=nodegroup.id).first()
1756
+        network = next((net for net in nodegroup.networks if net.name == name),
1757
+                       None)
1758
+
1759
+        # FIXME:
1760
+        #   Built-in fuelweb_admin network doesn't belong to any node
1761
+        #   group, since it's shared between all clusters. So we need
1762
+        #   to handle this very special case if we want to be able
1763
+        #   to allocate VIP in default admin network.
1764
+        if not network and name == consts.NETWORKS.fuelweb_admin:
1765
+            network = cls.get_admin_network_group()
1766
+
1767
+        return network
1768
+
1724 1769
 
1725 1770
 class AllocateVIPs70Mixin(object):
1726 1771
 
@@ -1765,51 +1810,17 @@ class AllocateVIPs70Mixin(object):
1765 1810
 
1766 1811
     @classmethod
1767 1812
     def _assign_vips_for_net_groups(cls, cluster):
1768
-        # noderole -> nodegroup mapping
1769
-        #   is used for determine nodegroup where VIP should be allocated
1770
-        noderole_nodegroup = {}
1771
-        # nodegroup -> role-to-network mapping
1772
-        #   is used for determine role-to-network mapping that is needed
1773
-        #   for choosing proper network for VIP allocation
1774
-        nodegroup_networks = {}
1775
-
1776
-        # iterate over all network roles, assign vip and yield information
1777
-        # about assignment
1778
-        for role in objects.Cluster.get_network_roles(cluster):
1779
-            properties = role.get('properties', {})
1780
-            for vip_info in properties.get('vip', ()):
1781
-                noderoles = tuple(vip_info.get('node_roles', ['controller']))
1813
+        for nodegroup, net_group, vip_name, role, vip_info\
1814
+                in cls.get_node_groups_info(cluster):
1815
+            vip_addr = cls.assign_vip(nodegroup, net_group, vip_name)
1782 1816
 
1783
-                # Since we're iterating over all VIP requests, we most
1784
-                # likely meet the same noderoles again and again. Let's
1785
-                # calculate node group just once, cache and use cached
1786
-                # value in order to reduce number of SQL queries.
1787
-                if noderoles not in noderole_nodegroup:
1788
-                    noderole_nodegroup[noderoles] = \
1789
-                        objects.Cluster.get_common_node_group(cluster,
1790
-                                                              noderoles)
1791
-                nodegroup = noderole_nodegroup[noderoles]
1792
-
1793
-                # Since different node roles may have the same node group,
1794
-                # it'd be ridiculous to build "role-to-network-group" mapping
1795
-                # each time we retrieve the group. So let's save mapping
1796
-                # in cache and retrieve it if necessary.
1797
-                if nodegroup.name not in nodegroup_networks:
1798
-                    nodegroup_networks[nodegroup.name] = \
1799
-                        cls.build_role_to_network_group_mapping(
1800
-                            cluster, nodegroup.name)
1801
-
1802
-                net_group = cls.get_network_group_for_role(
1803
-                    role,
1804
-                    nodegroup_networks[nodegroup.name])
1805
-                vip_name = vip_info['name']
1817
+            if vip_addr is None:
1818
+                continue
1806 1819
 
1807
-                # do allocation
1808
-                vip_addr = cls.assign_vip(nodegroup, net_group, vip_name)
1809
-                yield role, vip_info, vip_addr
1820
+            yield role, vip_info, vip_addr
1810 1821
 
1811 1822
     @classmethod
1812
-    def assign_vips_for_net_groups_for_api(cls, cluster):
1823
+    def assign_vips_for_net_groups_for_api(cls, cluster, allocate=True):
1813 1824
         """Calls cls.assign_vip for all vips in network roles.
1814 1825
 
1815 1826
         Returns dict with vip definitions in API compatible format::
@@ -1822,13 +1833,17 @@ class AllocateVIPs70Mixin(object):
1822 1833
         :type  cluster: Cluster model
1823 1834
         :return: dict with vip definitions
1824 1835
         """
1825
-        # check VIPs names overlapping before assigning them
1826
-        cls.check_unique_vip_names_for_cluster(cluster)
1827 1836
 
1828 1837
         vips = {}
1829 1838
         vips['vips'] = {}
1830
-        for role, vip_info, vip_addr in cls._assign_vips_for_net_groups(
1831
-                cluster):
1839
+        if allocate:
1840
+            # check VIPs names overlapping before assigning them
1841
+            cls.check_unique_vip_names_for_cluster(cluster)
1842
+            allocated_vips_data = cls._assign_vips_for_net_groups(cluster)
1843
+        else:
1844
+            allocated_vips_data = cls._get_vips_for_net_groups(cluster)
1845
+
1846
+        for role, vip_info, vip_addr in allocated_vips_data:
1832 1847
 
1833 1848
             vip_name = vip_info['name']
1834 1849
 
@@ -1911,18 +1926,21 @@ class AllocateVIPs70Mixin(object):
1911 1926
                 .format(cluster.id, ', '.join(duplicate_vip_names))
1912 1927
             )
1913 1928
 
1929
+    @classmethod
1930
+    def _get_vips_for_net_groups(cls, cluster):
1931
+        for nodegroup, net_group, vip_name, role, vip_info \
1932
+                in cls.get_node_groups_info(cluster):
1914 1933
 
1915
-class AllocateVIPs80Mixin(object):
1934
+            net_mgr = objects.Cluster.get_network_manager(cluster)
1935
+            vip_addr = net_mgr.get_assigned_vip(nodegroup, net_group, vip_name)
1916 1936
 
1917
-    @classmethod
1918
-    def _build_advanced_vip_info(cls, vip_info, role, address):
1919
-        info = AllocateVIPs70Mixin._build_advanced_vip_info(
1920
-            vip_info, role, address)
1921
-        info['vendor_specific'] = vip_info.get('vendor_specific')
1922
-        return info
1937
+            if vip_addr is None:
1938
+                continue
1939
+
1940
+            yield role, vip_info, vip_addr
1923 1941
 
1924 1942
     @classmethod
1925
-    def _assign_vips_for_net_groups(cls, cluster):
1943
+    def get_node_groups_info(cls, cluster):
1926 1944
         # noderole -> nodegroup mapping
1927 1945
         #   is used for determine nodegroup where VIP should be allocated
1928 1946
         noderole_nodegroup = {}
@@ -1972,10 +1990,17 @@ class AllocateVIPs80Mixin(object):
1972 1990
                         "Skip VIP '{0}' which is mapped to non-existing"
1973 1991
                         " network '{1}'".format(vip_name, net_group))
1974 1992
                     continue
1993
+                yield nodegroup, net_group, vip_name, role, vip_info
1994
+
1995
+
1996
+class AllocateVIPs80Mixin(object):
1975 1997
 
1976
-                # do allocation
1977
-                vip_addr = cls.assign_vip(nodegroup, net_group, vip_name)
1978
-                yield role, vip_info, vip_addr
1998
+    @classmethod
1999
+    def _build_advanced_vip_info(cls, vip_info, role, address):
2000
+        info = AllocateVIPs70Mixin._build_advanced_vip_info(
2001
+            vip_info, role, address)
2002
+        info['vendor_specific'] = vip_info.get('vendor_specific')
2003
+        return info
1979 2004
 
1980 2005
 
1981 2006
 class AssignIPsLegacyMixin(object):

+ 11
- 0
nailgun/nailgun/objects/cluster.py View File

@@ -1175,6 +1175,17 @@ class Cluster(NailgunObject):
1175 1175
         return [x[0] for x in db().query(models.Node.id).filter(
1176 1176
             models.Node.cluster_id == instance.id).all()]
1177 1177
 
1178
+    @classmethod
1179
+    def get_vips(cls, instance):
1180
+
1181
+        net_roles = cls.get_network_roles(instance)
1182
+
1183
+        cluster_vips = []
1184
+        for nr in net_roles:
1185
+            cluster_vips.extend(nr['properties']['vip'])
1186
+
1187
+        return cluster_vips
1188
+
1178 1189
     @classmethod
1179 1190
     def get_assigned_roles(cls, instance):
1180 1191
         """Get list of all roles currently assigned to nodes in cluster

+ 9
- 6
nailgun/nailgun/objects/serializers/network_configuration.py View File

@@ -36,7 +36,7 @@ class NetworkConfigurationSerializer(BasicSerializer):
36 36
         return data_dict
37 37
 
38 38
     @classmethod
39
-    def serialize_net_groups_and_vips(cls, cluster):
39
+    def serialize_net_groups_and_vips(cls, cluster, allocate=False):
40 40
         result = {}
41 41
         net_manager = objects.Cluster.get_network_manager(cluster)
42 42
         nets = cluster.network_groups + [net_manager.get_admin_network_group()]
@@ -45,9 +45,11 @@ class NetworkConfigurationSerializer(BasicSerializer):
45 45
             cls.serialize_network_group,
46 46
             nets
47 47
         )
48
+
48 49
         if cluster.is_ha_mode:
49 50
             result.update(
50
-                net_manager.assign_vips_for_net_groups_for_api(cluster))
51
+                net_manager.assign_vips_for_net_groups_for_api(cluster,
52
+                                                               allocate))
51 53
 
52 54
         return result
53 55
 
@@ -71,8 +73,9 @@ class NovaNetworkConfigurationSerializer(NetworkConfigurationSerializer):
71 73
     )
72 74
 
73 75
     @classmethod
74
-    def serialize_for_cluster(cls, cluster):
75
-        result = cls.serialize_net_groups_and_vips(cluster)
76
+    def serialize_for_cluster(cls, cluster, allocate_vips=False):
77
+        result = cls.serialize_net_groups_and_vips(cluster,
78
+                                                   allocate=allocate_vips)
76 79
         result['networking_parameters'] = cls.serialize_network_params(
77 80
             cluster)
78 81
         return result
@@ -104,7 +107,7 @@ class NeutronNetworkConfigurationSerializer(NetworkConfigurationSerializer):
104 107
         return BasicSerializer.serialize(cluster.network_config, fields)
105 108
 
106 109
     @classmethod
107
-    def serialize_for_cluster(cls, cluster):
108
-        result = cls.serialize_net_groups_and_vips(cluster)
110
+    def serialize_for_cluster(cls, cluster, allocate_vips=False):
111
+        result = cls.serialize_net_groups_and_vips(cluster, allocate_vips)
109 112
         result['networking_parameters'] = cls.serialize_network_params(cluster)
110 113
         return result

+ 4
- 1
nailgun/nailgun/task/manager.py View File

@@ -99,7 +99,10 @@ class TaskManager(object):
99 99
     def serialize_network_cfg(self, cluster):
100 100
         serializer = {'nova_network': NovaNetworkConfigurationSerializer,
101 101
                       'neutron': NeutronNetworkConfigurationSerializer}
102
-        return serializer[cluster.net_provider].serialize_for_cluster(cluster)
102
+        return serializer[cluster.net_provider].serialize_for_cluster(
103
+            cluster,
104
+            allocate_vips=True
105
+        )
103 106
 
104 107
 
105 108
 class DeploymentCheckMixin(object):

+ 58
- 25
nailgun/nailgun/test/integration/test_network_configuration.py View File

@@ -14,10 +14,10 @@
14 14
 #    License for the specific language governing permissions and limitations
15 15
 #    under the License.
16 16
 
17
-import netaddr
17
+import copy
18 18
 
19 19
 from mock import patch
20
-
20
+import netaddr
21 21
 from oslo_serialization import jsonutils
22 22
 from sqlalchemy.sql import not_
23 23
 
@@ -286,13 +286,21 @@ class TestNeutronNetworkConfigurationHandler(BaseIntegrationTest):
286 286
             for key in keys:
287 287
                 self.assertEqual(network[key], getattr(network_group, key))
288 288
 
289
-    def test_get_request_should_return_vips(self):
289
+    def test_get_request_should_return_vips_after_put(self):
290
+        self.env.neutron_networks_put(self.cluster.id, {})
290 291
         resp = self.env.neutron_networks_get(self.cluster.id)
291 292
         data = resp.json_body
292 293
 
293 294
         self.assertIn('public_vip', data)
294 295
         self.assertIn('management_vip', data)
295 296
 
297
+    def test_get_request_should_not_return_vips_before_assignment(self):
298
+        resp = self.env.neutron_networks_get(self.cluster.id)
299
+        data = resp.json_body
300
+
301
+        self.assertNotIn('public_vip', data)
302
+        self.assertNotIn('management_vip', data)
303
+
296 304
     def test_not_found_cluster(self):
297 305
         resp = self.env.neutron_networks_get(self.cluster.id + 999,
298 306
                                              expect_errors=True)
@@ -523,7 +531,9 @@ class TestNeutronNetworkConfigurationHandler(BaseIntegrationTest):
523 531
         self.assertIsNone(strg['gateway'])
524 532
 
525 533
     def test_admin_vip_reservation(self):
526
-        self.cluster.release.network_roles_metadata.append({
534
+        nrm_copy = copy.deepcopy(
535
+            self.cluster.release.network_roles_metadata)
536
+        nrm_copy.append({
527 537
             'id': 'admin/vip',
528 538
             'default_mapping': consts.NETWORKS.fuelweb_admin,
529 539
             'properties': {
@@ -534,10 +544,11 @@ class TestNeutronNetworkConfigurationHandler(BaseIntegrationTest):
534 544
                 }]
535 545
             }
536 546
         })
547
+        self.cluster.release.network_roles_metadata = nrm_copy
537 548
         self.cluster.release.version = '2015.1-8.0'
538 549
         self.db.flush()
539 550
 
540
-        resp = self.env.neutron_networks_get(self.cluster.id)
551
+        resp = self.env.neutron_networks_put(self.cluster.id, {})
541 552
         self.assertEqual(200, resp.status_code)
542 553
 
543 554
         nm = objects.Cluster.get_network_manager(self.cluster)
@@ -546,7 +557,7 @@ class TestNeutronNetworkConfigurationHandler(BaseIntegrationTest):
546 557
             nm.assign_vip(nodegroup, consts.NETWORKS.fuelweb_admin, 'my-vip'),
547 558
             resp.json_body['vips']['my-vip']['ipaddr'])
548 559
 
549
-    def test_not_enough_ip_addresses_return_400_on_get(self):
560
+    def test_not_enough_ip_addresses_return_200_on_get(self):
550 561
         # restrict public network to have only 2 ip addresses
551 562
         netconfig = self.env.neutron_networks_get(self.cluster.id).json_body
552 563
         public = next((
@@ -572,15 +583,10 @@ class TestNeutronNetworkConfigurationHandler(BaseIntegrationTest):
572 583
         })
573 584
         self.db.flush()
574 585
 
575
-        # check that we return 400 Bad Request
576 586
         resp = self.env.neutron_networks_get(
577 587
             self.cluster.id,
578 588
             expect_errors=True)
579
-        self.assertEqual(400, resp.status_code)
580
-        self.assertEqual(
581
-            "Not enough free IP addresses in ranges [172.16.0.2-172.16.0.4] "
582
-            "of 'public' network",
583
-            resp.json_body['message'])
589
+        self.assertEqual(200, resp.status_code)
584 590
 
585 591
     def test_not_enough_ip_addresses_return_400_on_put(self):
586 592
         netconfig = self.env.neutron_networks_get(self.cluster.id).json_body
@@ -618,7 +624,9 @@ class TestNeutronNetworkConfigurationHandler(BaseIntegrationTest):
618 624
 
619 625
         # populate release with a network role that requests a VIP
620 626
         # for compute nodes
621
-        self.env.clusters[0].release.network_roles_metadata.append({
627
+        nrm_copy = copy.deepcopy(
628
+            self.env.clusters[0].release.network_roles_metadata)
629
+        nrm_copy.append({
622 630
             'id': 'mymgmt/vip',
623 631
             'default_mapping': consts.NETWORKS.management,
624 632
             'properties': {
@@ -629,24 +637,19 @@ class TestNeutronNetworkConfigurationHandler(BaseIntegrationTest):
629 637
                     'node_roles': ['compute'],
630 638
                 }]
631 639
             }})
640
+        self.env.clusters[0].release.network_roles_metadata = nrm_copy
632 641
         self.db.flush()
633 642
 
643
+        self.env.neutron_networks_put(self.cluster.id, {})
644
+
634 645
         resp = self.env.neutron_networks_get(self.cluster.id)
635 646
         self.assertEqual(200, resp.status_code)
636 647
         ipaddr = resp.json_body['vips']['my-vip']['ipaddr']
637 648
         self.assertEqual('10.42.0.2', ipaddr)
638 649
 
639
-    def test_get_returns_error_if_vip_names_are_intersected(self):
640
-        cluster = self.env.create(
641
-            release_kwargs={'version': '2015.1.0-7.0'},
642
-            cluster_kwargs={
643
-                'net_provider': consts.CLUSTER_NET_PROVIDERS.neutron,
644
-                'net_segment_type': consts.NEUTRON_SEGMENT_TYPES.gre,
645
-                'api': False,
646
-            },
647
-            nodes_kwargs=[{'roles': ['controller']}]
648
-        )
649
-        cluster.release.network_roles_metadata.append({
650
+    def test_put_returns_error_if_vip_names_are_intersected(self):
651
+        nrm_copy = copy.deepcopy(self.cluster.release.network_roles_metadata)
652
+        nrm_copy.append({
650 653
             'id': 'mymgmt/vip',
651 654
             'default_mapping': consts.NETWORKS.management,
652 655
             'properties': {
@@ -657,14 +660,44 @@ class TestNeutronNetworkConfigurationHandler(BaseIntegrationTest):
657 660
                     'node_roles': ['compute'],
658 661
                 }]
659 662
             }})
663
+        self.cluster.release.network_roles_metadata = nrm_copy
660 664
         self.db.flush()
661
-        resp = self.env.neutron_networks_get(cluster.id, expect_errors=True)
665
+        resp = self.env.neutron_networks_put(self.cluster.id, {},
666
+                                             expect_errors=True)
662 667
         self.assertEqual(400, resp.status_code)
663 668
         self.assertIn(
664 669
             'Duplicate VIP names found in network configuration',
665 670
             resp.json_body['message']
666 671
         )
667 672
 
673
+    @patch('nailgun.network.manager.AllocateVIPs70Mixin.'
674
+           '_assign_vips_for_net_groups')
675
+    def test_network_conf_not_applied_on_vip_allocation_error(self, m_assign):
676
+        m_assign.side_effect = Exception
677
+
678
+        resp = self.env.neutron_networks_get(self.cluster.id)
679
+        net_conf = resp.json_body
680
+
681
+        old_cidr = ''
682
+
683
+        for net in net_conf['networks']:
684
+            if net['name'] == 'management':
685
+                old_cidr = net['cidr']
686
+                net['cidr'] = net['cidr'].partition('/')[0] + '/25'
687
+
688
+        resp = self.env.neutron_networks_put(self.cluster.id,
689
+                                             net_conf,
690
+                                             expect_errors=True)
691
+
692
+        self.assertEqual(resp.status_code, 500)
693
+
694
+        self.db.refresh(self.cluster)
695
+        net = [ng for ng in self.cluster.network_groups
696
+               if ng.name == 'management'].pop()
697
+
698
+        self.assertEqual(net.cidr, old_cidr)
699
+        self.assertTrue(m_assign.called)  # Verifies no other error occured
700
+
668 701
 
669 702
 class TestNovaNetworkConfigurationHandlerHA(BaseIntegrationTest):
670 703
 

+ 2
- 5
nailgun/nailgun/test/integration/test_network_manager.py View File

@@ -206,11 +206,8 @@ class TestNetworkManager(BaseNetworkManagerTest):
206 206
         nodegroup = objects.Cluster.get_controllers_node_group(
207 207
             self.env.clusters[0])
208 208
 
209
-        self.assertNotRaises(
210
-            Exception,  # make sure there's no exceptions at all
211
-            self.env.network_manager.assign_vip,
212
-            nodegroup,
213
-            consts.NETWORKS.fuelweb_admin)
209
+        self.env.network_manager.assign_vip(nodegroup,
210
+                                            consts.NETWORKS.fuelweb_admin)
214 211
 
215 212
     def test_assign_vip_throws_not_found_exception(self):
216 213
         self.env.create_cluster(api=True)

+ 3
- 0
nailgun/nailgun/test/unit/test_node_groups.py View File

@@ -538,6 +538,8 @@ class TestNodeGroups(BaseIntegrationTest):
538 538
         self.env.clusters[0].release.network_roles_metadata = net_roles
539 539
         self.db.flush()
540 540
         # VIPs are allocated on this call
541
+        self.env.neutron_networks_put(self.cluster.id, {})
542
+
541 543
         config = self.env.neutron_networks_get(self.cluster.id).json_body
542 544
         # Storage network has no GW by default
543 545
         vip_config = config['vips']['my-vip']['ipaddr']
@@ -548,6 +550,7 @@ class TestNodeGroups(BaseIntegrationTest):
548 550
 
549 551
         resp = self.env.create_node_group()
550 552
         self.assertEquals(resp.status_code, 201)
553
+        self.env.neutron_networks_put(self.cluster.id, {})
551 554
 
552 555
         # VIP address was deleted
553 556
         self.assertEqual(

Loading…
Cancel
Save