Use network roles data for assigning of VIPs
Additional information from VIPs description should be included into VIPs data serialized for orchestrator in 7.0. It was correct in case of using Neutron but it was not changed for Nova-Network case sinse 6.1. NovaNetworkManager70 is introduced now and it provides the same VIPs allocation as for NeutronManaget70 but without templates support. Change-Id: Iddb1bb894e72084224a76d7de86c3ad57cf06b25 Closes-Bug: #1480202
This commit is contained in:
parent
3cf4de256d
commit
618a26a67e
|
@ -327,8 +327,6 @@ FUEL_GRANULAR_DEPLOY = '6.1'
|
|||
FUEL_REMOTE_REPOS = '6.1'
|
||||
# version of Fuel when external mongo was added
|
||||
FUEL_EXTERNAL_MONGO = '6.1'
|
||||
# version of Fuel when Nova is not supported anymore. Neutron is left only.
|
||||
FUEL_NEUTRON_ONLY = '7.0'
|
||||
|
||||
# version of Fuel when classic provisioning is not available anymore.
|
||||
FUEL_IMAGE_BASED_ONLY = '7.0'
|
||||
|
|
|
@ -1360,3 +1360,108 @@ class NetworkManager(object):
|
|||
return []
|
||||
return [consts.BOND_MODES.lacp_balance_tcp,
|
||||
consts.BOND_MODES.l_802_3ad]
|
||||
|
||||
|
||||
class AllocateVIPs70Mixin(object):
|
||||
|
||||
@classmethod
|
||||
def find_network_role_by_id(cls, cluster, role_id):
|
||||
"""Returns network role for specified role id.
|
||||
|
||||
:param cluster: Cluster instance
|
||||
:param role_id: Network role id
|
||||
:type role_id: str
|
||||
:return: Network role dict or None if not found
|
||||
"""
|
||||
net_roles = objects.Cluster.get_network_roles(cluster)
|
||||
for role in net_roles:
|
||||
if role['id'] == role_id:
|
||||
return role
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def get_end_point_ip(cls, cluster_id):
|
||||
cluster_db = objects.Cluster.get_by_uid(cluster_id)
|
||||
net_role = cls.find_network_role_by_id(cluster_db, 'public/vip')
|
||||
if net_role:
|
||||
node_group = objects.Cluster.get_controllers_node_group(cluster_db)
|
||||
net_group_mapping = cls.build_role_to_network_group_mapping(
|
||||
cluster_db, node_group.name)
|
||||
net_group = cls.get_network_group_for_role(
|
||||
net_role, net_group_mapping)
|
||||
return cls.assign_vip(cluster_db, net_group, vip_type='public')
|
||||
else:
|
||||
raise errors.CanNotDetermineEndPointIP(
|
||||
u'Can not determine end point IP for cluster %s' %
|
||||
cluster_db.full_name)
|
||||
|
||||
@classmethod
|
||||
def _assign_vips_for_net_groups(cls, cluster):
|
||||
net_roles = objects.Cluster.get_network_roles(cluster)
|
||||
node_group = objects.Cluster.get_controllers_node_group(cluster)
|
||||
net_group_mapping = cls.build_role_to_network_group_mapping(
|
||||
cluster, node_group.name)
|
||||
for role in net_roles:
|
||||
properties = role.get('properties', {})
|
||||
net_group = cls.get_network_group_for_role(role, net_group_mapping)
|
||||
for vip_info in properties.get('vip', ()):
|
||||
vip_name = vip_info['name']
|
||||
vip_addr = cls.assign_vip(
|
||||
cluster, net_group, vip_type=vip_name)
|
||||
|
||||
yield role, vip_info, vip_addr
|
||||
|
||||
@classmethod
|
||||
def assign_vips_for_net_groups_for_api(cls, cluster):
|
||||
"""Calls cls.assign_vip for all vips in network roles.
|
||||
Returns dict with vip definitions in API compatible format::
|
||||
|
||||
{
|
||||
"vip_alias": "172.16.0.1"
|
||||
}
|
||||
|
||||
:param cluster: Cluster instance
|
||||
:type cluster: Cluster model
|
||||
:return: dict with vip definitions
|
||||
"""
|
||||
vips = {}
|
||||
for role, vip_info, vip_addr in cls._assign_vips_for_net_groups(
|
||||
cluster):
|
||||
alias = vip_info.get('alias')
|
||||
if alias:
|
||||
vips[alias] = vip_addr
|
||||
|
||||
return vips
|
||||
|
||||
@classmethod
|
||||
def assign_vips_for_net_groups(cls, cluster):
|
||||
"""Calls cls.assign_vip for all vips in network roles.
|
||||
To be used for the output generation for orchestrator.
|
||||
Returns dict with vip definitions like::
|
||||
|
||||
{
|
||||
"vip_name": {
|
||||
"network_role": "public",
|
||||
"namespace": "haproxy",
|
||||
"ipaddr": "172.16.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
:param cluster: Cluster instance
|
||||
:type cluster: Cluster model
|
||||
:return: dict with vip definitions
|
||||
"""
|
||||
vips = {}
|
||||
for role, vip_info, vip_addr in cls._assign_vips_for_net_groups(
|
||||
cluster):
|
||||
vip_name = vip_info['name']
|
||||
vips[vip_name] = {
|
||||
'network_role': role['id'],
|
||||
'namespace': vip_info.get('namespace'),
|
||||
'ipaddr': vip_addr,
|
||||
'node_roles': vip_info.get('node_roles',
|
||||
['controller',
|
||||
'primary-controller'])
|
||||
}
|
||||
|
||||
return vips
|
||||
|
|
|
@ -19,9 +19,8 @@ import six
|
|||
from nailgun import consts
|
||||
from nailgun.db import db
|
||||
from nailgun.db.sqlalchemy.models import NeutronConfig
|
||||
from nailgun.errors import errors
|
||||
from nailgun import objects
|
||||
|
||||
from nailgun.network.manager import AllocateVIPs70Mixin
|
||||
from nailgun.network.manager import NetworkManager
|
||||
|
||||
|
||||
|
@ -66,10 +65,20 @@ class NeutronManager(NetworkManager):
|
|||
return props
|
||||
|
||||
|
||||
class NeutronManager70(NeutronManager):
|
||||
class NeutronManager70(AllocateVIPs70Mixin, NeutronManager):
|
||||
|
||||
@classmethod
|
||||
def build_role_to_network_group_mapping(cls, cluster, node_group_name):
|
||||
"""Builds network role to network map according to template data if
|
||||
template is loaded. Otherwise, empty map is returned.
|
||||
|
||||
:param cluster: Cluster instance
|
||||
:type cluster: Cluster model
|
||||
:param node_group_name: Node group name
|
||||
:type node_group_name: string
|
||||
:return: Network role to network map
|
||||
:rtype: dict
|
||||
"""
|
||||
template = cluster.network_config.configuration_template
|
||||
if template is None:
|
||||
return {}
|
||||
|
@ -104,105 +113,3 @@ class NeutronManager70(NeutronManager):
|
|||
"""
|
||||
return net_group_mapping.get(
|
||||
network_role['id'], network_role['default_mapping'])
|
||||
|
||||
@classmethod
|
||||
def find_network_role_by_id(cls, cluster, role_id):
|
||||
"""Returns network role for specified role id.
|
||||
|
||||
:param cluster: Cluster instance
|
||||
:param role_id: Network role id
|
||||
:type role_id: str
|
||||
:return: Network role dict or None if not found
|
||||
"""
|
||||
net_roles = objects.Cluster.get_network_roles(cluster)
|
||||
for role in net_roles:
|
||||
if role['id'] == role_id:
|
||||
return role
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def get_end_point_ip(cls, cluster_id):
|
||||
cluster_db = objects.Cluster.get_by_uid(cluster_id)
|
||||
net_role = cls.find_network_role_by_id(cluster_db, 'public/vip')
|
||||
if net_role:
|
||||
node_group = objects.Cluster.get_controllers_node_group(cluster_db)
|
||||
net_group_mapping = cls.build_role_to_network_group_mapping(
|
||||
cluster_db, node_group.name)
|
||||
net_group = cls.get_network_group_for_role(
|
||||
net_role, net_group_mapping)
|
||||
return cls.assign_vip(cluster_db, net_group, vip_type='public')
|
||||
else:
|
||||
raise errors.CanNotDetermineEndPointIP(
|
||||
u'Can not determine end point IP for cluster %s' %
|
||||
cluster_db.full_name)
|
||||
|
||||
@classmethod
|
||||
def _assign_vips_for_net_groups(cls, cluster):
|
||||
net_roles = objects.Cluster.get_network_roles(cluster)
|
||||
node_group = objects.Cluster.get_controllers_node_group(cluster)
|
||||
net_group_mapping = cls.build_role_to_network_group_mapping(
|
||||
cluster, node_group.name)
|
||||
for role in net_roles:
|
||||
properties = role.get('properties', {})
|
||||
net_group = cls.get_network_group_for_role(role, net_group_mapping)
|
||||
for vip_info in properties.get('vip', ()):
|
||||
vip_name = vip_info['name']
|
||||
vip_addr = cls.assign_vip(
|
||||
cluster, net_group, vip_type=vip_name)
|
||||
|
||||
yield role, vip_info, vip_addr
|
||||
|
||||
@classmethod
|
||||
def assign_vips_for_net_groups_for_api(cls, cluster):
|
||||
"""Calls cls.assign_vip for all vips in network roles.
|
||||
Returns dict with vip definitions in API compatible format::
|
||||
|
||||
{
|
||||
"vip_alias": "172.16.0.1"
|
||||
}
|
||||
|
||||
:param cluster: Cluster instance
|
||||
:type cluster: Cluster model
|
||||
:return: dict with vip definitions
|
||||
"""
|
||||
vips = {}
|
||||
for role, vip_info, vip_addr in cls._assign_vips_for_net_groups(
|
||||
cluster):
|
||||
alias = vip_info.get('alias')
|
||||
if alias:
|
||||
vips[alias] = vip_addr
|
||||
|
||||
return vips
|
||||
|
||||
@classmethod
|
||||
def assign_vips_for_net_groups(cls, cluster):
|
||||
"""Calls cls.assign_vip for all vips in network roles.
|
||||
To be used for the output generation for orchestrator.
|
||||
Returns dict with vip definitions like::
|
||||
|
||||
{
|
||||
"vip_name": {
|
||||
"network_role": "public",
|
||||
"namespace": "haproxy",
|
||||
"ipaddr": "172.16.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
:param cluster: Cluster instance
|
||||
:type cluster: Cluster model
|
||||
:return: dict with vip definitions
|
||||
"""
|
||||
vips = {}
|
||||
for role, vip_info, vip_addr in cls._assign_vips_for_net_groups(
|
||||
cluster):
|
||||
vip_name = vip_info['name']
|
||||
vips[vip_name] = {
|
||||
'network_role': role['id'],
|
||||
'namespace': vip_info.get('namespace'),
|
||||
'ipaddr': vip_addr,
|
||||
'node_roles': vip_info.get('node_roles',
|
||||
['controller',
|
||||
'primary-controller'])
|
||||
}
|
||||
|
||||
return vips
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
from nailgun.db import db
|
||||
from nailgun.db.sqlalchemy.models import NovaNetworkConfig
|
||||
|
||||
from nailgun.network.manager import AllocateVIPs70Mixin
|
||||
from nailgun.network.manager import NetworkManager
|
||||
|
||||
|
||||
|
@ -44,3 +46,29 @@ class NovaNetworkManager(NetworkManager):
|
|||
if ng.get("vlan_start") is None:
|
||||
return []
|
||||
return [int(ng.get("vlan_start"))]
|
||||
|
||||
|
||||
class NovaNetworkManager70(AllocateVIPs70Mixin, NovaNetworkManager):
|
||||
|
||||
@classmethod
|
||||
def build_role_to_network_group_mapping(cls, *_):
|
||||
"""Default network role to network mapping is used always so
|
||||
map building is not required.
|
||||
|
||||
:return: Empty network role to network map
|
||||
:rtype: dict
|
||||
"""
|
||||
return {}
|
||||
|
||||
@classmethod
|
||||
def get_network_group_for_role(cls, network_role, _):
|
||||
"""Returns network group to which network role is associated.
|
||||
The default network group from the network role description is
|
||||
returned.
|
||||
|
||||
:param network_role: Network role dict
|
||||
:type network_role: dict
|
||||
:return: Network group name
|
||||
:rtype: str
|
||||
"""
|
||||
return network_role['default_mapping']
|
||||
|
|
|
@ -366,14 +366,17 @@ class Cluster(NailgunObject):
|
|||
from nailgun.network.manager import NetworkManager
|
||||
return NetworkManager
|
||||
|
||||
ver = instance.release.environment_version
|
||||
if instance.net_provider == 'neutron':
|
||||
ver = instance.release.environment_version
|
||||
if StrictVersion(ver) >= StrictVersion(consts.FUEL_NEUTRON_ONLY):
|
||||
if StrictVersion(ver) >= StrictVersion('7.0'):
|
||||
from nailgun.network.neutron import NeutronManager70
|
||||
return NeutronManager70
|
||||
from nailgun.network.neutron import NeutronManager
|
||||
return NeutronManager
|
||||
else:
|
||||
if StrictVersion(ver) >= StrictVersion('7.0'):
|
||||
from nailgun.network.nova_network import NovaNetworkManager70
|
||||
return NovaNetworkManager70
|
||||
from nailgun.network.nova_network import NovaNetworkManager
|
||||
return NovaNetworkManager
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ class TestHandlers(BaseIntegrationTest):
|
|||
|
||||
def test_if_cluster_creates_correct_networks(self):
|
||||
release = Release()
|
||||
release.version = "1.1.1"
|
||||
release.version = "1111-6.0"
|
||||
release.name = u"release_name_" + str(release.version)
|
||||
release.description = u"release_desc" + str(release.version)
|
||||
release.operating_system = "CentOS"
|
||||
|
|
|
@ -25,6 +25,7 @@ from netaddr import IPRange
|
|||
from sqlalchemy import not_
|
||||
|
||||
import nailgun
|
||||
from nailgun import consts
|
||||
from nailgun.errors import errors
|
||||
from nailgun import objects
|
||||
|
||||
|
@ -36,6 +37,7 @@ from nailgun.db.sqlalchemy.models import NodeNICInterface
|
|||
from nailgun.network.neutron import NeutronManager
|
||||
from nailgun.network.neutron import NeutronManager70
|
||||
from nailgun.network.nova_network import NovaNetworkManager
|
||||
from nailgun.network.nova_network import NovaNetworkManager70
|
||||
from nailgun.test.base import BaseIntegrationTest
|
||||
from nailgun.test.base import fake_tasks
|
||||
|
||||
|
@ -603,14 +605,13 @@ class TestNeutronManager70(BaseNetworkManagerTest):
|
|||
super(TestNeutronManager70, self).setUp()
|
||||
self.cluster = self._create_env()
|
||||
self.net_manager = objects.Cluster.get_network_manager(self.cluster)
|
||||
self.assertIs(self.net_manager, NeutronManager70)
|
||||
|
||||
def _create_env(self):
|
||||
return self.env.create(
|
||||
release_kwargs={'version': '1111-7.0'},
|
||||
cluster_kwargs={
|
||||
'api': False,
|
||||
'net_provider': 'neutron'
|
||||
'net_provider': consts.CLUSTER_NET_PROVIDERS.neutron
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -629,6 +630,9 @@ class TestNeutronManager70(BaseNetworkManagerTest):
|
|||
network_role.update(kwargs)
|
||||
return network_role
|
||||
|
||||
def test_get_network_manager(self):
|
||||
self.assertIs(self.net_manager, NeutronManager70)
|
||||
|
||||
def test_get_network_group_for_role(self):
|
||||
net_template = self.env.read_fixtures(['network_template'])[0]
|
||||
objects.Cluster.set_network_template(self.cluster, net_template)
|
||||
|
@ -740,3 +744,46 @@ class TestNeutronManager70(BaseNetworkManagerTest):
|
|||
self.cluster, vips_to_assign)
|
||||
vips = self.net_manager.get_assigned_vips(self.cluster)
|
||||
self.assertEqual(vips_to_assign, vips)
|
||||
|
||||
|
||||
class TestNovaNetworkManager70(TestNeutronManager70):
|
||||
|
||||
def _create_env(self):
|
||||
return self.env.create(
|
||||
release_kwargs={'version': '1111-7.0'},
|
||||
cluster_kwargs={
|
||||
'api': False,
|
||||
'net_provider': consts.CLUSTER_NET_PROVIDERS.nova_network
|
||||
}
|
||||
)
|
||||
|
||||
def test_get_network_manager(self):
|
||||
self.assertIs(self.net_manager, NovaNetworkManager70)
|
||||
|
||||
def test_get_network_group_for_role(self):
|
||||
node_group = objects.Cluster.get_controllers_node_group(self.cluster)
|
||||
net_group_mapping = \
|
||||
self.net_manager.build_role_to_network_group_mapping(
|
||||
self.cluster, node_group.name)
|
||||
|
||||
self.assertEqual(
|
||||
self.net_manager.get_network_group_for_role(
|
||||
self._get_network_role_metadata(id='public/vip'),
|
||||
net_group_mapping),
|
||||
'public')
|
||||
self.assertEqual(
|
||||
self.net_manager.get_network_group_for_role(
|
||||
self._get_network_role_metadata(
|
||||
id='role_not_in_template',
|
||||
default_mapping='default_net_group'), net_group_mapping),
|
||||
'default_net_group')
|
||||
|
||||
def test_get_endpoint_ip(self):
|
||||
vip = '172.16.0.1'
|
||||
|
||||
with patch.object(NovaNetworkManager70, 'assign_vip',
|
||||
return_value=vip) as assign_vip_mock:
|
||||
endpoint_ip = self.net_manager.get_end_point_ip(self.cluster.id)
|
||||
assign_vip_mock.assert_called_once_with(
|
||||
self.cluster, mock.ANY, vip_type='public')
|
||||
self.assertEqual(endpoint_ip, vip)
|
||||
|
|
|
@ -59,7 +59,6 @@ class BaseTestDeploymentAttributesSerialization70(BaseDeploymentSerializer):
|
|||
super(BaseTestDeploymentAttributesSerialization70, self).setUp()
|
||||
self.cluster = self.create_env('ha_compact')
|
||||
|
||||
# NOTE: 'prepare_for_deployment' is going to be changed for 7.0
|
||||
objects.NodeCollection.prepare_for_deployment(
|
||||
self.env.nodes, self.segmentation_type)
|
||||
self.cluster_db = self.db.query(models.Cluster).get(self.cluster['id'])
|
||||
|
@ -82,6 +81,16 @@ class BaseTestDeploymentAttributesSerialization70(BaseDeploymentSerializer):
|
|||
{'roles': ['compute'],
|
||||
'pending_addition': True}])
|
||||
|
||||
def check_vips_serialized(self, vips_data):
|
||||
vips_names = ['vrouter', 'management', 'vrouter_pub', 'public']
|
||||
self.assertItemsEqual(vips_data,
|
||||
vips_names)
|
||||
for vip in vips_names:
|
||||
self.assertItemsEqual(
|
||||
vips_data[vip],
|
||||
['network_role', 'namespace', 'ipaddr', 'node_roles']
|
||||
)
|
||||
|
||||
|
||||
class TestDeploymentAttributesSerialization70(
|
||||
BaseTestDeploymentAttributesSerialization70
|
||||
|
@ -183,6 +192,7 @@ class TestDeploymentAttributesSerialization70(
|
|||
[ip_by_net['private']] * len(self.private))
|
||||
|
||||
self.assertEqual(v['network_roles'], dict(network_roles))
|
||||
self.check_vips_serialized(node_data['network_metadata']['vips'])
|
||||
|
||||
def test_generate_vmware_attributes_data(self):
|
||||
self.check_generate_vmware_attributes_data()
|
||||
|
@ -210,24 +220,13 @@ class TestDeploymentAttributesSerializationSegmentationTun70(
|
|||
segmentation_type = consts.NEUTRON_SEGMENT_TYPES.tun
|
||||
|
||||
|
||||
class TestDeploymentSerializationForNovaNetwork70(BaseDeploymentSerializer):
|
||||
@mock.patch.object(models.Release, 'environment_version',
|
||||
new_callable=mock.PropertyMock(return_value='7.0'))
|
||||
def setUp(self, *args):
|
||||
super(TestDeploymentSerializationForNovaNetwork70, self).setUp()
|
||||
self.cluster = self.create_env('ha_compact')
|
||||
|
||||
# NOTE: 'prepare_for_deployment' is going to be changed for 7.0
|
||||
objects.NodeCollection.prepare_for_deployment(self.env.nodes)
|
||||
cluster_db = self.db.query(models.Cluster).get(self.cluster['id'])
|
||||
serializer_type = get_serializer_for_cluster(cluster_db)
|
||||
self.serializer = serializer_type(AstuteGraph(cluster_db))
|
||||
self.serialized_for_astute = self.serializer.serialize(
|
||||
cluster_db, cluster_db.nodes)
|
||||
self.vm_data = self.env.read_fixtures(['vmware_attributes'])
|
||||
class TestDeploymentSerializationForNovaNetwork70(
|
||||
BaseTestDeploymentAttributesSerialization70
|
||||
):
|
||||
|
||||
def create_env(self, mode):
|
||||
return self.env.create(
|
||||
release_kwargs={'version': '2015.1.0-7.0'},
|
||||
cluster_kwargs={
|
||||
'mode': mode,
|
||||
'net_provider': consts.CLUSTER_NET_PROVIDERS.nova_network},
|
||||
|
@ -355,6 +354,7 @@ class TestDeploymentSerializationForNovaNetwork70(BaseDeploymentSerializer):
|
|||
node_attrs['network_roles'],
|
||||
network_roles
|
||||
)
|
||||
self.check_vips_serialized(node_data['network_metadata']['vips'])
|
||||
|
||||
def test_generate_vmware_attributes_data(self):
|
||||
self.check_generate_vmware_attributes_data()
|
||||
|
|
Loading…
Reference in New Issue