[Tech debt] Multiple floating ranges support

* Add 'objects.Release.is_multiple_floating_ranges_enabled' method.
* According to open/closed principle, move logic of 'generate_external_network'
  method to 'NeutronNetworkDeploymentSerializer80' and revert changes made in
  'NeutronNetworkDeploymentSerializer51'.
* Refactor and remove testing redundancy in 'TestNeutronDeploymentSerializer70'
  and 'TestNeutronDeploymentSerializer80'.

Change-Id: I993c22bf2ca65f8e3c01301c92e3f0987b403244
Partial-bug: #1490578
This commit is contained in:
Ivan Kliuk 2015-11-03 19:17:24 +02:00
parent 915a59d82c
commit 5f7a43417a
4 changed files with 54 additions and 54 deletions

View File

@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from distutils.version import StrictVersion
from netaddr import IPNetwork
from oslo_serialization import jsonutils
import six
@ -189,13 +188,11 @@ class NeutronNetworkConfigurationValidator(NetworkConfigurationValidator):
d = cls.validate_json(data)
np = d.get('networking_parameters')
cluster_id = kwargs.get("cluster_id")
cluster = objects.Cluster.get_by_uid(cluster_id)
cluster_version = cluster.release.environment_version
release = cluster.release
if StrictVersion(cluster_version) < StrictVersion(
consts.FUEL_MULTIPLE_FLOATING_IP_RANGES
) and len(np.get('floating_ranges', [])) > 1:
if not objects.Release.is_multiple_floating_ranges_enabled(release) \
and len(np.get('floating_ranges', [])) > 1:
raise errors.InvalidData(
"Setting of multiple floating IP ranges is prohibited. "
"We support it since {0} version of environment."

View File

@ -134,6 +134,17 @@ class Release(NailgunObject):
return (StrictVersion(instance.environment_version) >=
StrictVersion(consts.FUEL_EXTERNAL_MONGO))
@classmethod
def is_multiple_floating_ranges_enabled(cls, instance):
"""Check if usage of multiple floating ranges is available for release
:param instance: a Release instance
:returns: boolean
"""
return (StrictVersion(instance.environment_version) >=
StrictVersion(consts.FUEL_MULTIPLE_FLOATING_IP_RANGES))
@classmethod
def get_deployment_tasks(cls, instance):
"""Get deployment graph based on release version."""

View File

@ -391,12 +391,19 @@ class NeutronNetworkDeploymentSerializer(NetworkDeploymentSerializer):
return iface_attrs
@classmethod
def generate_external_network(
cls, cluster, multiple_floating_ranges=False):
floating_ranges = [
netaddr.IPRange(r1, r2)
for r1, r2 in cluster.network_config.floating_ranges
]
def render_floating_ranges(cls, floating_ranges):
"""Renders floating IP ranges for external networks generator.
:param floating_ranges: a list of strings
:return: rendered string
"""
return utils.join_range(floating_ranges[0])
@classmethod
def generate_external_network(cls, cluster):
floating_ranges = cluster.network_config.floating_ranges
floating_iprange = netaddr.IPRange(
floating_ranges[0][0], floating_ranges[0][1])
floating_cidr, floating_gw = None, None
networks = db().query(
@ -408,24 +415,16 @@ class NeutronNetworkDeploymentSerializer(NetworkDeploymentSerializer):
models.NodeGroup.cluster_id == cluster.id
)
for net in networks:
if net[0] and floating_ranges[0] in netaddr.IPNetwork(net[0]):
if net[0] and floating_iprange in netaddr.IPNetwork(net[0]):
floating_cidr, floating_gw = net[0], net[1]
break
if multiple_floating_ranges:
floating_ranges_rendered = [
utils.join_range(fr)
for fr in cluster.network_config.floating_ranges]
else:
floating_ranges_rendered = utils.join_range(
cluster.network_config.floating_ranges[0])
external_network = {
return {
"L3": {
"subnet": floating_cidr,
"gateway": floating_gw,
"nameservers": [],
"floating": floating_ranges_rendered,
"floating": cls.render_floating_ranges(floating_ranges),
"enable_dhcp": False
},
"L2": {
@ -438,8 +437,6 @@ class NeutronNetworkDeploymentSerializer(NetworkDeploymentSerializer):
"shared": False
}
return external_network
@classmethod
def _generate_internal_network(cls, cluster):
return {
@ -522,12 +519,10 @@ class NeutronNetworkDeploymentSerializer(NetworkDeploymentSerializer):
class NeutronNetworkDeploymentSerializer51(NeutronNetworkDeploymentSerializer):
@classmethod
def generate_external_network(
cls, cluster, multiple_floating_ranges=False):
def generate_external_network(cls, cluster):
ext_netw = super(
NeutronNetworkDeploymentSerializer51, cls
).generate_external_network(
cluster, multiple_floating_ranges=multiple_floating_ranges)
).generate_external_network(cluster)
ext_netw["L2"] = {
"network_type": "local",
"segment_id": None,
@ -1313,13 +1308,10 @@ class NeutronNetworkTemplateSerializer70(
class NeutronNetworkDeploymentSerializer80(
NeutronNetworkDeploymentSerializer70
):
@classmethod
def generate_predefined_networks(cls, cluster):
return {
"net04_ext": cls.generate_external_network(
cluster, multiple_floating_ranges=True),
"net04": cls._generate_internal_network(cluster)
}
def render_floating_ranges(cls, floating_ranges):
return [utils.join_range(x) for x in floating_ranges]
class NeutronNetworkTemplateSerializer80(NeutronNetworkTemplateSerializer70):

View File

@ -22,6 +22,7 @@ CREDS = {'tenant': {'value': 'NONDEFAULT'}}
class BaseTestNeutronDeploymentSerializer(base.BaseTestCase):
env_version = None
serializer = None
def setUp(self):
super(BaseTestNeutronDeploymentSerializer, self).setUp()
@ -31,25 +32,34 @@ class BaseTestNeutronDeploymentSerializer(base.BaseTestCase):
)
self.cluster = self.env.clusters[0]
def check_shared_attrs_of_external_network(self, external_net):
self.assertEqual(
external_net['L2'],
{
'network_type': 'local',
'physnet': None,
'router_ext': True,
'segment_id': None
},
)
self.assertFalse(external_net['shared'])
self.assertEqual(external_net['tenant'], 'admin')
@patch('nailgun.orchestrator.deployment_serializers.objects.Cluster.get_creds',
return_value=CREDS)
class NetworkTenantNameMixin(object):
def verify_network_tenant(self, network):
self.assertEqual(network['tenant'], CREDS['tenant']['value'])
@patch(('nailgun.orchestrator.deployment_serializers.objects.'
'Cluster.get_creds'), return_value=CREDS)
def test_internal_network_changes_tenant_name(self, creds):
int_network = self.serializer._generate_internal_network(self.cluster)
self.verify_network_tenant(int_network)
@patch(('nailgun.orchestrator.deployment_serializers.objects.'
'Cluster.get_creds'), return_value=CREDS)
def test_external_network_changes_tenant_name(self, creds):
ext_network = self.serializer.generate_external_network(self.cluster)
self.verify_network_tenant(ext_network)
@patch(('nailgun.orchestrator.deployment_serializers.objects.'
'Cluster.get_creds'), return_value=CREDS)
def test_predefined_networks_tenant_name(self, creds):
predefined_network = self.serializer.generate_predefined_networks(
self.cluster)
@ -74,10 +84,7 @@ class TestNeutronDeploymentSerializer70(BaseTestNeutronDeploymentSerializer,
]
external_net = self.serializer.generate_external_network(self.cluster)
self.assertEqual(
external_net['L3']['floating'], "172.16.0.130:172.16.0.150")
external_net = self.serializer.generate_external_network(self.cluster)
self.check_shared_attrs_of_external_network(external_net)
self.assertEqual(
external_net['L3'],
{'enable_dhcp': False,
@ -99,16 +106,9 @@ class TestNeutronDeploymentSerializer80(BaseTestNeutronDeploymentSerializer,
["172.16.0.130", "172.16.0.150"],
["172.16.0.200", "172.16.0.254"]
]
external_net = self.serializer.generate_external_network(
self.cluster, multiple_floating_ranges=True)
self.assertEqual(
external_net['L3']['floating'],
['172.16.0.130:172.16.0.150', '172.16.0.200:172.16.0.254'],
)
external_net = self.serializer.generate_external_network(
self.cluster, multiple_floating_ranges=True)
external_net = self.serializer.generate_external_network(self.cluster)
self.check_shared_attrs_of_external_network(external_net)
self.assertEqual(
external_net['L3'],
{'enable_dhcp': False,