fuel-web/nailgun/nailgun/test/integration/test_network_validation.py

840 lines
35 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2013 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
from netaddr import IPAddress
from netaddr import IPNetwork
import six
from nailgun import consts
from nailgun.db.sqlalchemy.models import Cluster
from nailgun.db.sqlalchemy.models import NetworkGroup
from nailgun.db.sqlalchemy.models import NeutronConfig
from nailgun.db.sqlalchemy.models import NovaNetworkConfig
from nailgun.errors import errors
from nailgun.network.checker import NetworkCheck
from nailgun.test.base import BaseIntegrationTest
class TestNetworkChecking(BaseIntegrationTest):
def find_net_by_name(self, name):
for net in self.nets['networks']:
if net['name'] == name:
return net
def check_result_format(self, task, cluster_id):
if task.get('result'):
result = task['result']
self.assertIsInstance(result, list)
ng_fields = \
NetworkGroup.__mapper__.columns.keys() + ["ip_ranges"]
cluster_db = self.db.query(Cluster).get(cluster_id)
ng_fields += NeutronConfig.__mapper__.columns.keys() \
if cluster_db.net_provider == 'neutron' else \
NovaNetworkConfig.__mapper__.columns.keys()
for res in result:
if 'ids' in res:
self.assertIsInstance(res['ids'], list)
if 'errors' in res:
self.assertIsInstance(res['errors'], list)
for f in res['errors']:
self.assertIn(f, ng_fields)
def set_cluster_changes_w_error(self, cluster_id):
resp = self.env.cluster_changes_put(cluster_id,
expect_errors=True)
self.assertEqual(resp.status_code, 200)
task = resp.json_body
self.assertEqual(task['status'], consts.TASK_STATUSES.error)
self.assertEqual(task['progress'], 100)
self.assertEqual(task['name'], consts.TASK_NAMES.deploy)
self.check_result_format(task, cluster_id)
return task
def update_nova_networks_w_error(self, cluster_id, nets):
resp = self.env.nova_networks_put(cluster_id, nets,
expect_errors=True)
self.assertEqual(resp.status_code, 400)
return resp.json_body
def update_nova_networks_success(self, cluster_id, nets):
resp = self.env.nova_networks_put(cluster_id, nets)
self.assertEqual(resp.status_code, 200)
return resp.json_body
def update_neutron_networks_w_error(self, cluster_id, nets):
resp = self.env.neutron_networks_put(cluster_id, nets,
expect_errors=True)
self.assertEqual(resp.status_code, 400)
return resp.json_body
def update_neutron_networks_success(self, cluster_id, nets):
resp = self.env.neutron_networks_put(cluster_id, nets)
self.assertEqual(resp.status_code, 200)
return resp.json_body
def verify_neutron_networks_w_error(self, nets):
task = self.env.launch_verify_networks(nets)
self.assertEqual(task['status'], consts.TASK_STATUSES.error)
return task
class TestNovaHandlers(TestNetworkChecking):
def setUp(self):
super(TestNovaHandlers, self).setUp()
meta = self.env.default_metadata()
self.env.set_interfaces_in_meta(meta, [
{"name": "eth0", "mac": "00:00:00:00:00:66"},
{"name": "eth1", "mac": "00:00:00:00:00:77"}])
self.env.create(
cluster_kwargs={
'net_provider': consts.CLUSTER_NET_PROVIDERS.nova_network,
},
nodes_kwargs=[
{"api": True,
"meta": meta,
"pending_addition": True},
]
)
self.cluster = self.env.clusters[0]
resp = self.env.nova_networks_get(self.cluster.id)
self.nets = resp.json_body
def test_network_checking(self):
self.update_nova_networks_success(self.cluster.id, self.nets)
ngs_created = self.db.query(NetworkGroup).filter(
NetworkGroup.name.in_([n['name'] for n in self.nets['networks']])
).all()
self.assertEqual(len(ngs_created), len(self.nets['networks']))
def test_network_checking_fails_if_admin_intersection(self):
admin_ng = self.env.network_manager.get_admin_network_group()
self.nets['networking_parameters']["fixed_networks_cidr"] = \
admin_ng.cidr
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertIn(
"Address space intersection between networks:\n",
task['message'])
self.assertIn("admin (PXE)", task['message'])
self.assertIn("fixed", task['message'])
def test_network_checking_fails_if_admin_intersection_ip_range(self):
admin_ng = self.env.network_manager.get_admin_network_group()
cidr = IPNetwork(admin_ng.cidr)
flt_r0 = str(IPAddress(cidr.first + 2))
flt_r1 = str(IPAddress(cidr.last))
self.nets['networking_parameters']['floating_ranges'] = \
[[flt_r0, flt_r1]]
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
"Address space intersection between floating range '{0}-{1}' and "
"'admin (PXE)' network.".format(flt_r0, flt_r1),
task['message'])
def test_network_checking_fails_if_networks_cidr_intersection(self):
self.find_net_by_name('management')["cidr"] = \
self.find_net_by_name('storage')["cidr"]
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertIn(
"Address space intersection between networks:\n",
task['message'])
self.assertIn("management", task['message'])
self.assertIn("storage", task['message'])
def test_network_checking_fails_if_untagged_intersection(self):
self.find_net_by_name('management')["vlan_start"] = None
self.env.nova_networks_put(self.cluster.id, self.nets)
task = self.set_cluster_changes_w_error(self.cluster.id)
self.assertIn(
'Some untagged networks are assigned to the same physical '
'interface. You should assign them to different physical '
'interfaces. Affected:\n',
task['message'])
self.assertIn('"management"', task['message'])
self.assertIn(' networks at node "Untitled', task['message'])
def test_network_checking_fails_if_networks_cidr_range_intersection(self):
self.find_net_by_name('public')["ip_ranges"] = \
[['192.18.17.65', '192.18.17.143']]
self.find_net_by_name('public')["gateway"] = '192.18.17.1'
self.find_net_by_name('public')["cidr"] = '192.18.17.0/24'
self.find_net_by_name('management')["cidr"] = '192.18.17.0/25'
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertIn(
"Address space intersection between networks:\n",
task['message'])
self.assertIn("public", task['message'])
self.assertIn("management", task['message'])
def test_network_checking_no_public_floating_ranges_intersection(self):
self.find_net_by_name('public')["ip_ranges"] = \
[['192.18.17.5', '192.18.17.43'],
['192.18.17.59', '192.18.17.90']]
self.nets['networking_parameters']["floating_ranges"] = \
[['192.18.17.125', '192.18.17.143'],
['192.18.17.159', '192.18.17.190']]
self.find_net_by_name('public')["gateway"] = '192.18.17.1'
self.find_net_by_name('public')["cidr"] = '192.18.17.0/24'
self.update_nova_networks_success(self.cluster.id, self.nets)
def test_network_checking_fails_if_public_ranges_intersection(self):
self.find_net_by_name('public')["ip_ranges"] = \
[['192.18.17.65', '192.18.17.123'],
['192.18.17.99', '192.18.17.129']]
self.find_net_by_name('public')["gateway"] = '192.18.17.1'
self.find_net_by_name('public')["cidr"] = '192.18.17.0/24'
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Address space intersection between ranges of public network."
)
def test_network_checking_fails_if_public_gateway_not_in_cidr(self):
self.find_net_by_name('public')["ip_ranges"] = \
[['192.18.17.5', '192.18.17.43'],
['192.18.17.59', '192.18.17.90']]
self.find_net_by_name('public')["gateway"] = '192.18.18.1'
self.find_net_by_name('public')["cidr"] = '192.18.18.0/24'
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Public gateway and public ranges are not in one CIDR."
)
def test_network_checking_fails_if_public_gateway_range_intersection(self):
self.find_net_by_name('public')["ip_ranges"] = \
[['192.18.17.5', '192.18.17.43'],
['192.18.17.59', '192.18.17.90']]
self.find_net_by_name('public')["gateway"] = '192.18.17.77'
self.find_net_by_name('public')["cidr"] = '192.18.17.0/24'
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Address intersection between public gateway and IP range of "
"public network."
)
self.find_net_by_name('public')["ip_ranges"] = \
[['192.18.17.5', '192.18.17.99']]
self.find_net_by_name('public')["gateway"] = '192.18.17.55'
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Address intersection between public gateway and IP range of "
"public network."
)
def test_network_checking_fails_if_floating_ranges_intersection(self):
self.nets['networking_parameters']["floating_ranges"] = \
[['192.18.17.129', '192.18.17.143'],
['192.18.17.133', '192.18.17.190']]
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Address space intersection between ranges of floating network."
)
def test_network_checking_fails_if_vlan_ids_intersection(self):
self.find_net_by_name('public')["vlan_start"] = 111
self.find_net_by_name('management')["vlan_start"] = 111
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertIn(
" networks use the same VLAN ID(s). "
"You should assign different VLAN IDs to every network.",
task['message'])
self.assertIn("management", task['message'])
self.assertIn("public", task['message'])
def test_network_checking_fails_if_vlan_id_in_fixed_vlan_range(self):
self.nets['networking_parameters']['net_manager'] = \
consts.NOVA_NET_MANAGERS.VlanManager
self.find_net_by_name('public')["vlan_start"] = 1111
self.nets['networking_parameters']['fixed_networks_vlan_start'] = \
1100
self.nets['networking_parameters']['fixed_networks_amount'] = 20
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertIn(
" networks use the same VLAN ID(s). "
"You should assign different VLAN IDs to every network.",
task['message'])
self.assertIn("fixed", task['message'])
self.assertIn("public", task['message'])
def test_network_checking_fails_if_vlan_id_not_in_allowed_range(self):
self.find_net_by_name('public')["vlan_start"] = 5555
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"VLAN ID(s) is out of range for public network."
)
def test_network_size_not_fit_cidr_in_flatdhcp(self):
self.nets['networking_parameters']['net_manager'] = \
consts.NOVA_NET_MANAGERS.FlatDHCPManager
self.nets['networking_parameters']['fixed_networks_cidr'] = \
"10.10.0.0/28"
self.nets['networking_parameters']['fixed_networks_amount'] = 1
self.nets['networking_parameters']['fixed_network_size'] = 256
self.update_nova_networks_success(self.cluster.id, self.nets)
def test_network_size_and_amount_not_fit_cidr(self):
self.nets['networking_parameters']['net_manager'] = \
consts.NOVA_NET_MANAGERS.VlanManager
self.nets['networking_parameters']['fixed_networks_cidr'] = \
"10.10.0.0/24"
self.nets['networking_parameters']['fixed_networks_amount'] = 8
self.nets['networking_parameters']['fixed_network_size'] = 32
self.update_nova_networks_success(self.cluster.id, self.nets)
self.nets['networking_parameters']['fixed_networks_amount'] = 32
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Number of fixed networks (32) doesn't fit into "
"fixed CIDR (10.10.0.0/24) and size of one fixed network (32)."
)
def test_network_fit_abc_classes_exclude_loopback(self):
self.find_net_by_name('management')['cidr'] = '127.19.216.0/24'
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"management network address space is inside loopback range "
"(127.0.0.0/8). It must have no intersection with "
"loopback range."
)
self.find_net_by_name('management')['cidr'] = '227.19.216.0/24'
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"management network address space does not belong to "
"A, B, C network classes. It must belong to either "
"A, B or C network class."
)
def test_network_gw_and_ranges_intersect_w_subnet_or_broadcast(self):
self.find_net_by_name('public')['gateway'] = '172.16.0.0'
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"public network gateway address is equal to either subnet address "
"or broadcast address of the network."
)
self.find_net_by_name('public')['gateway'] = '172.16.0.255'
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"public network gateway address is equal to either subnet address "
"or broadcast address of the network."
)
self.find_net_by_name('public')['gateway'] = '172.16.0.125'
self.find_net_by_name('public')['ip_ranges'] = [['172.16.0.0',
'172.16.0.122']]
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"public network IP range [172.16.0.0-172.16.0.122] intersect "
"with either subnet address or broadcast address of the network."
)
self.nets['networking_parameters']['floating_ranges'] = [
['172.16.0.128', '172.16.0.253']
]
self.find_net_by_name('public')['ip_ranges'] = [['172.16.0.254',
'172.16.0.255']]
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"public network IP range [172.16.0.254-172.16.0.255] intersect "
"with either subnet address or broadcast address of the network."
)
self.find_net_by_name('public')['ip_ranges'] = [['172.16.0.2',
'172.16.0.122']]
self.update_nova_networks_success(self.cluster.id, self.nets)
class TestNeutronHandlersGre(TestNetworkChecking):
def setUp(self):
super(TestNeutronHandlersGre, self).setUp()
meta = self.env.default_metadata()
self.env.set_interfaces_in_meta(meta, [
{"name": "eth0", "mac": "00:00:00:00:00:66"},
{"name": "eth1", "mac": "00:00:00:00:00:77"}])
self.env.create(
cluster_kwargs={
'net_provider': 'neutron',
'net_segment_type': 'gre'
},
nodes_kwargs=[
{'api': True,
'pending_addition': True,
'meta': meta}
]
)
self.cluster = self.env.clusters[0]
resp = self.env.neutron_networks_get(self.cluster.id)
self.nets = resp.json_body
def test_network_checking(self):
self.update_neutron_networks_success(self.cluster.id, self.nets)
ngs_created = self.db.query(NetworkGroup).filter(
NetworkGroup.name.in_([n['name'] for n in self.nets['networks']])
).all()
self.assertEqual(len(ngs_created), len(self.nets['networks']))
# TODO(adanin) Provide a positive test that it's allowed to move any
# network to the Admin interface.
def test_network_checking_fails_if_admin_intersection(self):
admin_ng = self.env.network_manager.get_admin_network_group()
self.find_net_by_name('storage')["cidr"] = admin_ng.cidr
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertIn(
"Address space intersection between networks:\n",
task['message'])
self.assertIn("admin (PXE)", task['message'])
self.assertIn("storage", task['message'])
def test_network_checking_fails_if_untagged_intersection(self):
for n in self.nets['networks']:
n['vlan_start'] = None
self.update_neutron_networks_success(self.cluster.id, self.nets)
task = self.set_cluster_changes_w_error(self.cluster.id)
self.assertIn(
"Some untagged networks are "
"assigned to the same physical interface. "
"You should assign them to "
"different physical interfaces. Affected:\n",
task['message']
)
self.assertIn("admin (PXE)", task['message'])
self.assertIn("storage", task['message'])
self.assertIn("management", task['message'])
def test_network_checking_fails_if_public_gateway_not_in_cidr(self):
self.find_net_by_name('public')['cidr'] = '172.16.10.0/24'
self.find_net_by_name('public')['gateway'] = '172.16.10.1'
self.nets['networking_parameters']['floating_ranges'] = \
[['172.16.10.130', '172.16.10.254']]
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Public gateway and public ranges are not in one CIDR."
)
def test_network_checking_fails_if_public_gateway_range_intersection(self):
self.find_net_by_name('public')["ip_ranges"] = \
[['172.16.0.5', '172.16.0.43'],
['172.16.0.59', '172.16.0.90']]
self.find_net_by_name('public')["gateway"] = '172.16.0.77'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Address intersection between public gateway and IP range of "
"public network."
)
self.find_net_by_name('public')["ip_ranges"] = \
[['172.16.0.5', '172.16.0.99']]
self.find_net_by_name('public')["gateway"] = '172.16.0.55'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Address intersection between public gateway and IP range of "
"public network."
)
def test_network_checking_fails_if_public_float_range_not_in_cidr(self):
self.find_net_by_name('public')['cidr'] = '172.16.10.0/24'
self.find_net_by_name('public')['gateway'] = '172.16.10.1'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Floating address ranges 172.16.0.130-172.16.0.254 "
"are not in the same public CIDR."
)
def test_network_checking_fails_if_network_ranges_intersect(self):
self.find_net_by_name('management')['cidr'] = \
self.find_net_by_name('storage')['cidr']
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertIn(
"Address space intersection between networks:\n",
task['message'])
self.assertIn("management", task['message'])
self.assertIn("storage", task['message'])
def test_network_checking_fails_if_public_gw_ranges_intersect(self):
self.find_net_by_name('public')['gateway'] = '172.16.0.11'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Address intersection between public gateway "
"and IP range of public network."
)
def test_network_checking_fails_if_public_ranges_intersect(self):
self.find_net_by_name('public')['ip_ranges'] = \
[['172.16.0.2', '172.16.0.77'],
['172.16.0.55', '172.16.0.121']]
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Address space intersection between ranges "
"of public network."
)
def test_network_checking_fails_if_public_float_ranges_intersect(self):
self.find_net_by_name('public')['ip_ranges'] = \
[['172.16.0.2', '172.16.0.33'],
['172.16.0.55', '172.16.0.222']]
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Address space intersection between ranges "
"of public and floating network."
)
def test_network_checking_public_network_cidr_became_smaller(self):
self.find_net_by_name('public')['cidr'] = '172.16.0.0/25'
self.find_net_by_name('public')['gateway'] = '172.16.0.1'
self.find_net_by_name('public')['ip_ranges'] = [['172.16.0.2',
'172.16.0.77']]
self.nets['networking_parameters']['floating_ranges'] = \
[['172.16.0.99', '172.16.0.111']]
self.update_neutron_networks_success(self.cluster.id, self.nets)
resp = self.env.neutron_networks_get(self.cluster.id)
self.nets = resp.json_body
self.assertEqual(self.find_net_by_name('public')['cidr'],
'172.16.0.0/25')
def test_network_checking_fails_on_network_vlan_match(self):
self.find_net_by_name('management')['vlan_start'] = 111
self.find_net_by_name('storage')['vlan_start'] = 111
self.update_neutron_networks_success(self.cluster.id, self.nets)
checker = NetworkCheck(mock.Mock(cluster=self.cluster), {})
self.assertRaisesWithMessageIn(
errors.NetworkCheckError,
" networks use the same VLAN tags."
" Different VLAN tags"
" should be assigned to the networks on the same"
" interface.",
checker.check_interface_mapping
)
def test_network_checking_ok_with_template_on_network_vlan_match(self):
self.find_net_by_name('management')['vlan_start'] = 111
self.find_net_by_name('storage')['vlan_start'] = 111
self.update_neutron_networks_success(self.cluster.id, self.nets)
checker = NetworkCheck(mock.Mock(cluster=self.cluster), {})
self.cluster.network_config.configuration_template = {}
self.assertNotRaises(
errors.NetworkCheckError,
checker.check_interface_mapping
)
@mock.patch('nailgun.task.task.rpc.cast')
def test_network_checking_with_equal_vlans_on_multi_groups(self, _):
new_nets = {'management': {'cidr': '199.99.20.0/24'},
'storage': {'cidr': '199.98.20.0/24'},
'private': {'cidr': '199.95.20.0/24'},
'public': {'cidr': '199.96.20.0/24'}}
# save VLAN IDs from networks of default node group
# to set them for networks of new node group
nets = self.env.neutron_networks_get(self.cluster.id).json_body
for net in nets['networks']:
if net['name'] in new_nets:
new_nets[net['name']]['vlan_start'] = net['vlan_start']
resp = self.env.create_node_group()
group_id = resp.json_body['id']
nets = self.env.neutron_networks_get(self.cluster.id).json_body
for net in nets['networks']:
if net['name'] in new_nets:
if net['group_id'] == group_id:
# set CIDRs and VLAN IDs for new networks
# VLAN IDs are equal to those in default node group
for param, value in six.iteritems(new_nets[net['name']]):
net[param] = value
if net['meta']['notation'] == 'ip_ranges':
net['ip_ranges'] = [[
str(IPAddress(IPNetwork(net['cidr']).first + 2)),
str(IPAddress(IPNetwork(net['cidr']).first + 126)),
]]
if not net['meta']['use_gateway']:
net['ip_ranges'] = [[
str(IPAddress(IPNetwork(net['cidr']).first + 2)),
str(IPAddress(IPNetwork(net['cidr']).first + 254)),
]]
net['meta']['use_gateway'] = True
net['gateway'] = str(
IPAddress(IPNetwork(net['cidr']).first + 1))
resp = self.env.neutron_networks_put(self.cluster.id, nets)
self.assertEqual(resp.status_code, 200)
self.env.create_nodes_w_interfaces_count(
nodes_count=3,
if_count=2,
roles=['compute'],
pending_addition=True,
cluster_id=self.cluster.id,
group_id=group_id)
resp = self.env.cluster_changes_put(self.cluster.id)
self.assertEqual(resp.status_code, 202)
task = resp.json_body
self.assertEqual(task['status'], consts.TASK_STATUSES.pending)
self.assertEqual(task['name'], consts.TASK_NAMES.deploy)
def test_network_checking_fails_if_internal_gateway_not_in_cidr(self):
self.nets['networking_parameters']['internal_gateway'] = '172.16.10.1'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Internal gateway 172.16.10.1 is not in "
"internal address space 192.168.111.0/24."
)
def test_network_checking_fails_if_internal_w_floating_intersection(self):
self.nets['networking_parameters']['internal_cidr'] = '172.16.0.128/26'
self.nets['networking_parameters']['internal_gateway'] = '172.16.0.129'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Intersection between internal CIDR 172.16.0.128/26 and "
"floating range 172.16.0.130-172.16.0.254."
)
def test_network_fit_abc_classes_exclude_loopback(self):
self.find_net_by_name('management')['cidr'] = '127.19.216.0/24'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"management network address space is inside loopback range "
"(127.0.0.0/8). It must have no intersection with "
"loopback range."
)
self.find_net_by_name('management')['cidr'] = '227.19.216.0/24'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"management network address space does not belong to "
"A, B, C network classes. It must belong to either "
"A, B or C network class."
)
def test_network_gw_and_ranges_intersect_w_subnet_or_broadcast(self):
self.find_net_by_name('public')['gateway'] = '172.16.0.0'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"public network gateway address is equal to either subnet address "
"or broadcast address of the network."
)
self.find_net_by_name('public')['gateway'] = '172.16.0.255'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"public network gateway address is equal to either subnet address "
"or broadcast address of the network."
)
self.find_net_by_name('public')['gateway'] = '172.16.0.125'
self.find_net_by_name('public')['ip_ranges'] = [['172.16.0.0',
'172.16.0.122']]
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"public network IP range [172.16.0.0-172.16.0.122] intersect "
"with either subnet address or broadcast address of the network."
)
self.nets['networking_parameters']['floating_ranges'] = [
['172.16.0.128', '172.16.0.253']
]
self.find_net_by_name('public')['ip_ranges'] = [['172.16.0.254',
'172.16.0.255']]
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"public network IP range [172.16.0.254-172.16.0.255] intersect "
"with either subnet address or broadcast address of the network."
)
self.find_net_by_name('public')['ip_ranges'] = [['172.16.0.55',
'172.16.0.99']]
self.nets['networking_parameters']['floating_ranges'] = \
[['172.16.0.0', '172.16.0.33']]
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Neutron L3 external floating range [172.16.0.0-172.16.0.33] "
"intersect with either subnet address or broadcast address "
"of public network."
)
self.nets['networking_parameters']['floating_ranges'] = \
[['172.16.0.155', '172.16.0.255']]
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Neutron L3 external floating range [172.16.0.155-172.16.0.255] "
"intersect with either subnet address or broadcast address "
"of public network."
)
self.nets['networking_parameters']['floating_ranges'] = \
[['172.16.0.155', '172.16.0.199']]
self.nets['networking_parameters']['internal_cidr'] = \
'192.168.111.0/24'
self.nets['networking_parameters']['internal_gateway'] = \
'192.168.111.0'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Neutron L3 internal network gateway address is equal to "
"either subnet address or broadcast address of the network."
)
self.nets['networking_parameters']['internal_gateway'] = \
'192.168.111.255'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"Neutron L3 internal network gateway address is equal to "
"either subnet address or broadcast address of the network."
)
class TestNeutronHandlersVlan(TestNetworkChecking):
def setUp(self):
super(TestNeutronHandlersVlan, self).setUp()
meta = self.env.default_metadata()
self.env.set_interfaces_in_meta(meta, [
{"name": "eth0", "mac": "00:00:00:00:00:66"},
{"name": "eth1", "mac": "00:00:00:00:00:77"}])
self.env.create(
cluster_kwargs={
'net_provider': 'neutron',
'net_segment_type': 'vlan'
},
nodes_kwargs=[
{'api': True,
'pending_addition': True,
'meta': meta}
]
)
self.cluster = self.env.clusters[0]
resp = self.env.neutron_networks_get(self.cluster.id)
self.nets = resp.json_body
def test_network_checking(self):
self.update_neutron_networks_success(self.cluster.id, self.nets)
ngs_created = self.db.query(NetworkGroup).filter(
NetworkGroup.name.in_([n['name'] for n in self.nets['networks']])
).all()
self.assertEqual(len(ngs_created), len(self.nets['networks']))
def test_network_checking_failed_if_networks_tags_in_neutron_range(self):
self.find_net_by_name('storage')['vlan_start'] = 1000
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEqual(
task['message'],
"VLAN tags of storage network(s) intersect with "
"VLAN ID range defined for Neutron L2. "
"Networks VLAN tags must not intersect "
"with Neutron L2 VLAN ID range.")
class TestNeutronHandlersTun(TestNetworkChecking):
def setUp(self):
super(TestNeutronHandlersTun, self).setUp()
meta = self.env.default_metadata()
self.env.set_interfaces_in_meta(meta, [
{"name": "eth0", "mac": "00:00:00:00:00:66"},
{"name": "eth1", "mac": "00:00:00:00:00:77"}])
self.env.create(
cluster_kwargs={
'net_provider': 'neutron',
'net_segment_type': 'tun'
},
nodes_kwargs=[
{'api': True,
'pending_addition': True,
'meta': meta}
]
)
self.cluster = self.env.clusters[0]
resp = self.env.neutron_networks_get(self.cluster.id)
self.nets = resp.json_body
def test_network_checking(self):
self.update_neutron_networks_success(self.cluster.id, self.nets)
ngs_created = self.db.query(NetworkGroup).filter(
NetworkGroup.name.in_([n['name'] for n in self.nets['networks']])
).all()
self.assertEqual(len(ngs_created), len(self.nets['networks']))