Merge "Fix checking of public IPs count"

This commit is contained in:
Jenkins 2014-11-12 12:37:26 +00:00 committed by Gerrit Code Review
commit f63dcb4f0e
6 changed files with 129 additions and 28 deletions

View File

@ -515,6 +515,23 @@ class Cluster(NailgunObject):
def get_creds(cls, instance):
return instance.attributes.editable['access']
@classmethod
def should_assign_public_to_all_nodes(cls, instance):
"""Determine whether Public network is to be assigned to all nodes in
this cluster.
:param instance: cluster instance
:returns: True when Public network is to be assigned to all nodes
"""
if instance.net_provider == \
consts.CLUSTER_NET_PROVIDERS.nova_network:
return True
assignment = instance.attributes.editable.get(
'public_network_assignment')
if not assignment or assignment['assign_to_all_nodes']['value']:
return True
return False
class ClusterCollection(NailgunCollection):
"""Cluster collection

View File

@ -152,12 +152,7 @@ class Node(NailgunObject):
:param instance: Node DB instance
:returns: True when node has Public network
"""
if instance.cluster.net_provider == \
consts.CLUSTER_NET_PROVIDERS.nova_network:
return True
assignment = instance.cluster.attributes.editable.get(
'public_network_assignment')
if not assignment or assignment['assign_to_all_nodes']['value']:
if Cluster.should_assign_public_to_all_nodes(instance.cluster):
return True
ctrl = set(['primary-controller', 'controller', 'zabbix-server'])
if ctrl & (set(instance.roles) or set(instance.pending_roles)):
@ -799,3 +794,7 @@ class NodeCollection(NailgunCollection):
instances_ids = [instance.id for instance in instances]
q = cls.filter_by_list(None, 'id', instances_ids, order_by='id')
return cls.lock_for_update(q).all()
@classmethod
def get_by_group_id(cls, group_id):
return cls.filter_by(None, group_id=group_id)

View File

@ -575,7 +575,7 @@ class CheckBeforeDeploymentTask(object):
cls._check_disks(task)
cls._check_ceph(task)
cls._check_volumes(task)
cls._check_network(task)
cls._check_public_network(task)
@classmethod
def _check_nodes_are_online(cls, task):
@ -687,17 +687,26 @@ class CheckBeforeDeploymentTask(object):
(osd_count, osd_pool_size))
@classmethod
def _check_network(cls, task):
nodes_count = len(task.cluster.nodes)
def _check_public_network(cls, task):
all_public = \
objects.Cluster.should_assign_public_to_all_nodes(task.cluster)
public_network = filter(
public_networks = filter(
lambda ng: ng.name == 'public',
task.cluster.network_groups)[0]
public_network_size = cls.__network_size(public_network)
task.cluster.network_groups)
if public_network_size < nodes_count:
error_message = cls.__format_network_error(nodes_count)
raise errors.NetworkCheckError(error_message)
for public in public_networks:
nodes = objects.NodeCollection.get_by_group_id(public.group_id)
if all_public:
nodes_count = nodes.count()
else:
nodes_count = sum(int(objects.Node.should_have_public(node))
for node in nodes)
vip_count = 0 if not task.cluster.is_ha_mode else \
int(any('controller' in node.all_roles for node in nodes))
if cls.__network_size(public) < nodes_count + vip_count:
error_message = cls.__format_network_error(public, nodes_count)
raise errors.NetworkCheckError(error_message)
@classmethod
def __network_size(cls, network):
@ -705,9 +714,9 @@ class CheckBeforeDeploymentTask(object):
for ip_range in network.ip_ranges)
@classmethod
def __format_network_error(cls, nodes_count):
return 'Not enough IP addresses. Public network must have at least '\
'{nodes_count} IP addresses '.format(nodes_count=nodes_count) + \
def __format_network_error(cls, public, nodes_count):
return 'Not enough IP addresses. Public network {0} must have ' \
'at least {1} IP addresses '.format(public.cidr, nodes_count) + \
'for the current environment.'

View File

@ -1044,8 +1044,8 @@ class TestHandlers(BaseIntegrationTest):
self.assertEqual(task.status, 'error')
self.assertEqual(
task.message,
'Not enough IP addresses. Public network must have at least '
'3 IP addresses for the current environment.')
'Not enough IP addresses. Public network 172.16.0.0/24 must have '
'at least 3 IP addresses for the current environment.')
def test_occurs_error_not_enough_ip_addresses(self):
self.env.create(
@ -1082,8 +1082,8 @@ class TestHandlers(BaseIntegrationTest):
self.assertEqual(task.status, 'error')
self.assertEqual(
task.message,
'Not enough IP addresses. Public network must have at least '
'3 IP addresses for the current environment.')
'Not enough IP addresses. Public network 220.0.1.0/24 must have '
'at least 3 IP addresses for the current environment.')
def test_occurs_error_not_enough_free_space(self):
meta = self.env.default_metadata()

View File

@ -234,10 +234,11 @@ class TestNodeObject(BaseIntegrationTest):
attrs['public_network_assignment']['assign_to_all_nodes']['value'],
False
)
self.assertFalse(
objects.Cluster.should_assign_public_to_all_nodes(cluster))
nodes_w_public_count = 0
for node in self.env.nodes:
nodes_w_public_count += int(objects.Node.should_have_public(node))
nodes_w_public_count = sum(int(objects.Node.should_have_public(node))
for node in self.env.nodes)
self.assertEqual(nodes_w_public_count, 2)
attrs['public_network_assignment']['assign_to_all_nodes']['value'] = \
@ -250,10 +251,11 @@ class TestNodeObject(BaseIntegrationTest):
headers=self.default_headers
)
self.assertEqual(200, resp.status_code)
self.assertTrue(
objects.Cluster.should_assign_public_to_all_nodes(cluster))
nodes_w_public_count = 0
for node in self.env.nodes:
nodes_w_public_count += int(objects.Node.should_have_public(node))
nodes_w_public_count = sum(int(objects.Node.should_have_public(node))
for node in self.env.nodes)
self.assertEqual(nodes_w_public_count, 5)
def test_removing_from_cluster(self):

View File

@ -19,8 +19,10 @@ from nailgun import consts
from nailgun.db.sqlalchemy.models import Task
from nailgun.errors import errors
from nailgun import objects
from nailgun.openstack.common import jsonutils
from nailgun.task.task import CheckBeforeDeploymentTask
from nailgun.test.base import BaseTestCase
from nailgun.test.base import reverse
from nailgun.volumes.manager import VolumeManager
@ -163,6 +165,10 @@ class TestCheckBeforeDeploymentTask(BaseTestCase):
def setUp(self):
super(TestCheckBeforeDeploymentTask, self).setUp()
self.env.create(
cluster_kwargs={
'net_provider': 'neutron',
'net_segment_type': 'gre'
},
nodes_kwargs=[{'roles': ['controller']}])
self.env.create_node()
@ -282,3 +288,71 @@ class TestCheckBeforeDeploymentTask(BaseTestCase):
errors.NotEnoughControllers,
CheckBeforeDeploymentTask._check_controllers_count,
self.task)
def find_net_by_name(self, nets, name):
for net in nets['networks']:
if net['name'] == name:
return net
def test_check_public_networks(self):
cluster = self.env.clusters[0]
self.env.create_nodes(
2, api=True, roles=['controller'], cluster_id=cluster.id)
self.env.create_nodes(
2, api=True, roles=['compute'], cluster_id=cluster.id)
# we have 3 controllers now
self.assertEqual(
sum('controller' in n.all_roles for n in self.env.nodes),
3
)
attrs = cluster.attributes.editable
self.assertEqual(
attrs['public_network_assignment']['assign_to_all_nodes']['value'],
False
)
self.assertFalse(
objects.Cluster.should_assign_public_to_all_nodes(cluster))
resp = self.env.neutron_networks_get(cluster.id)
nets = resp.json_body
# enough IPs for 3 nodes but VIP
self.find_net_by_name(nets, 'public')['ip_ranges'] = \
[["172.16.0.2", "172.16.0.4"]]
resp = self.env.neutron_networks_put(cluster.id, nets)
self.assertEqual(resp.status_code, 202)
self.assertRaises(
errors.NetworkCheckError,
CheckBeforeDeploymentTask._check_public_network,
self.task)
# enough IPs for 3 nodes and VIP
self.find_net_by_name(nets, 'public')['ip_ranges'] = \
[["172.16.0.2", "172.16.0.5"]]
resp = self.env.neutron_networks_put(cluster.id, nets)
self.assertEqual(resp.status_code, 202)
self.assertNotRaises(
errors.NetworkCheckError,
CheckBeforeDeploymentTask._check_public_network,
self.task)
attrs['public_network_assignment']['assign_to_all_nodes']['value'] = \
True
resp = self.app.patch(
reverse(
'ClusterAttributesHandler',
kwargs={'cluster_id': cluster.id}),
params=jsonutils.dumps({'editable': attrs}),
headers=self.default_headers
)
self.assertEqual(200, resp.status_code)
self.assertTrue(
objects.Cluster.should_assign_public_to_all_nodes(cluster))
self.assertRaises(
errors.NetworkCheckError,
CheckBeforeDeploymentTask._check_public_network,
self.task)