Rearrange network models parameters

Implements: blueprint nailgun-rearrange-network-parameters

Change-Id: Ib70d1764e783a32423df0d136e8075a66d7cd773
This commit is contained in:
Aleksey Kasatkin 2014-03-13 17:36:06 +02:00
parent d593b43f02
commit 63b2f0ecff
33 changed files with 872 additions and 1056 deletions

View File

@ -172,7 +172,7 @@ class NeutronNetworkConfigurationHandler(ProviderHandler):
json.dumps(data)
)
if 'neutron_parameters' in data:
if 'networking_parameters' in data:
self.validator.validate_neutron_params(
json.dumps(data),
cluster_id=cluster_id

View File

@ -28,7 +28,6 @@ class ClusterSerializer(BasicSerializer):
"grouping",
"is_customized",
"net_provider",
"net_segment_type",
"release_id"
)

View File

@ -21,8 +21,8 @@ from nailgun.api.serializers.base import BasicSerializer
class NetworkConfigurationSerializer(BasicSerializer):
fields = ('id', 'cluster_id', 'name', 'cidr', 'netmask',
'gateway', 'vlan_start', 'network_size', 'amount', 'meta')
fields = ('id', 'cluster_id', 'name', 'cidr',
'gateway', 'vlan_start', 'meta')
@classmethod
def serialize_network_group(cls, instance, fields=None):
@ -33,7 +33,6 @@ class NetworkConfigurationSerializer(BasicSerializer):
data_dict["ip_ranges"] = [
[ir.first, ir.last] for ir in instance.ip_ranges
]
data_dict.setdefault("netmask", "")
data_dict.setdefault("gateway", "")
return data_dict
@ -57,37 +56,37 @@ class NetworkConfigurationSerializer(BasicSerializer):
net_manager.assign_vip(cluster.id, ng.name)
return result
@classmethod
def serialize_network_params(cls, cluster):
return BasicSerializer.serialize(
cluster.network_config,
cls.network_cfg_fields)
class NovaNetworkConfigurationSerializer(NetworkConfigurationSerializer):
network_cfg_fields = (
'dns_nameservers', 'net_manager', 'fixed_networks_cidr',
'fixed_networks_vlan_start', 'fixed_network_size',
'fixed_networks_amount', 'floating_ranges')
@classmethod
def serialize_for_cluster(cls, cluster):
result = cls.serialize_net_groups_and_vips(cluster)
result['net_manager'] = cluster.net_manager
if cluster.dns_nameservers:
result['dns_nameservers'] = {
"nameservers": cluster.dns_nameservers
}
result['networking_parameters'] = cls.serialize_network_params(
cluster)
return result
class NeutronNetworkConfigurationSerializer(NetworkConfigurationSerializer):
network_cfg_fields = (
'dns_nameservers', 'segmentation_type', 'net_l23_provider',
'floating_ranges', 'vlan_range', 'gre_id_range',
'base_mac', 'internal_cidr', 'internal_gateway')
@classmethod
def serialize_for_cluster(cls, cluster):
result = cls.serialize_net_groups_and_vips(cluster)
result['net_provider'] = cluster.net_provider
result['net_l23_provider'] = cluster.net_l23_provider
result['net_segment_type'] = cluster.net_segment_type
result['neutron_parameters'] = {
'predefined_networks': cluster.neutron_config.predefined_networks,
'L2': cluster.neutron_config.L2,
'segmentation_type': cluster.neutron_config.segmentation_type
}
result['networking_parameters'] = cls.serialize_network_params(cluster)
return result

View File

@ -57,7 +57,7 @@ class ClusterValidator(BasicValidator):
@classmethod
def validate_update(cls, data, instance):
d = cls._validate_common(data)
for k in ("net_provider", "net_segment_type"):
for k in ("net_provider",):
if k in d and getattr(instance, k) != d[k]:
raise errors.InvalidData(
u"Changing '{0}' for environment is prohibited".format(k),

View File

@ -13,9 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from netaddr import AddrFormatError
from netaddr import IPNetwork
from nailgun.api.validators.base import BasicValidator
from nailgun.consts import NETWORK_INTERFACE_TYPES
from nailgun.consts import OVS_BOND_MODES
@ -51,15 +48,6 @@ class NetworkConfigurationValidator(BasicValidator):
"No 'id' param presents for '{0}' network".format(i),
log_message=True
)
if i.get('name') == 'public':
try:
IPNetwork('0.0.0.0/' + i['netmask'])
except (AddrFormatError, KeyError):
raise errors.InvalidData(
"Invalid netmask for public network",
log_message=True
)
return d
@ -91,12 +79,12 @@ class NeutronNetworkConfigurationValidator(NetworkConfigurationValidator):
@classmethod
def validate_neutron_params(cls, data, **kwargs):
d = cls.validate_json(data)
np = d.get('neutron_parameters')
np = d.get('networking_parameters')
cluster_id = kwargs.get("cluster_id")
if cluster_id:
cluster = db().query(Cluster).get(cluster_id)
if cluster and cluster.neutron_config:
cfg = cluster.neutron_config
if cluster and cluster.network_config:
cfg = cluster.network_config
for k in ("segmentation_type",):
if k in np and getattr(cfg, k) != np[k]:
raise errors.InvalidData(

View File

@ -45,7 +45,7 @@ CLUSTER_STATUSES = Enum(
'remove'
)
CLUSTER_NET_MANAGERS = Enum(
NOVA_NET_MANAGERS = Enum(
'FlatDHCPManager',
'VlanManager'
)
@ -61,12 +61,11 @@ CLUSTER_NET_PROVIDERS = Enum(
'neutron'
)
CLUSTER_NET_L23_PROVIDERS = Enum(
NEUTRON_L23_PROVIDERS = Enum(
'ovs'
)
CLUSTER_NET_SEGMENT_TYPES = Enum(
'none',
NEUTRON_SEGMENT_TYPES = Enum(
'vlan',
'gre'
)

View File

@ -55,6 +55,24 @@ new_task_names_options = sorted(
)
)
old_network_group_name = (
'fuelweb_admin',
'storage',
'management',
'public',
'floating',
'fixed',
'private'
)
new_network_group_name = (
'fuelweb_admin',
'storage',
'management',
'public',
'fixed',
'private'
)
def upgrade_enum(table, column_name, enum_name, old_options, new_options):
old_type = sa.Enum(*old_options, name=enum_name)
@ -165,6 +183,58 @@ def upgrade():
sa.PrimaryKeyConstraint('id')
)
op.create_table(
'networking_configs',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('discriminator', sa.String(length=50), nullable=True),
sa.Column('cluster_id', sa.Integer(), nullable=True),
sa.Column('dns_nameservers', JSON(), nullable=True),
sa.Column('floating_ranges', JSON(), nullable=True),
sa.ForeignKeyConstraint(['cluster_id'],
['clusters.id'],
ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
op.create_table(
'nova_network_config',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('fixed_networks_cidr', sa.String(length=25), nullable=True),
sa.Column('fixed_networks_vlan_start', sa.Integer(), nullable=True),
sa.Column('fixed_network_size', sa.Integer(), nullable=False),
sa.Column('fixed_networks_amount', sa.Integer(), nullable=False),
sa.Column('net_manager',
sa.Enum('FlatDHCPManager',
'VlanManager',
name='net_manager'),
nullable=False),
sa.ForeignKeyConstraint(['id'], ['networking_configs.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table(
'neutron_config',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('vlan_range', JSON(), nullable=True),
sa.Column('gre_id_range', JSON(), nullable=True),
sa.Column('base_mac', LowercaseString(length=17), nullable=False),
sa.Column('internal_cidr', sa.String(length=25), nullable=True),
sa.Column('internal_gateway', sa.String(length=25), nullable=True),
sa.Column('segmentation_type',
sa.Enum('vlan',
'gre',
name='segmentation_type'),
nullable=False),
sa.Column('net_l23_provider',
sa.Enum('ovs',
name='net_l23_provider'),
nullable=False),
sa.ForeignKeyConstraint(['id'], ['networking_configs.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.add_column('nodes', sa.Column(
'agent_checksum', sa.String(40), nullable=True
))
# CLUSTER STATUS ENUM UPGRADE
upgrade_enum(
"clusters", # table
@ -183,15 +253,29 @@ def upgrade():
new_task_names_options # new options
)
op.add_column('nodes', sa.Column(
'agent_checksum', sa.String(40), nullable=True
))
# NETWORK NAME ENUM UPGRADE
upgrade_enum(
"network_groups", # table
"name", # column
"network_group_name", # ENUM name
old_network_group_name, # old options
new_network_group_name # new options
)
op.add_column('nodes', sa.Column(
'uuid', sa.String(length=36), nullable=False
))
op.create_unique_constraint("uq_node_uuid", "nodes", ["uuid"])
op.drop_column(u'clusters', u'net_manager')
op.drop_column(u'clusters', u'dns_nameservers')
op.drop_column(u'clusters', u'net_segment_type')
op.drop_column(u'clusters', u'net_l23_provider')
op.drop_column(u'network_groups', u'network_size')
op.drop_column(u'network_groups', u'amount')
op.drop_column(u'network_groups', u'netmask')
op.drop_table(u'neutron_configs')
### end Alembic commands ###
@ -242,6 +326,79 @@ def downgrade():
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
op.add_column(u'network_groups',
sa.Column(u'amount',
sa.INTEGER(),
nullable=True))
op.add_column(u'network_groups',
sa.Column(u'network_size',
sa.INTEGER(),
nullable=True))
op.add_column(u'network_groups',
sa.Column(u'netmask',
sa.String(length=25),
nullable=True))
op.add_column(u'clusters',
sa.Column(u'net_l23_provider',
sa.ENUM(u'ovs'),
nullable=False))
op.add_column(u'clusters',
sa.Column(u'net_segment_type',
sa.ENUM(u'none',
u'vlan',
u'gre',
name='net_segment_type'),
nullable=False))
op.add_column(u'clusters',
sa.Column(u'dns_nameservers',
sa.TEXT(),
nullable=True))
op.add_column(u'clusters',
sa.Column(u'net_manager',
sa.ENUM(u'FlatDHCPManager',
u'VlanManager',
name='net_manager'),
nullable=False))
op.create_table(
u'neutron_configs',
sa.Column(u'id',
sa.INTEGER(),
server_default="nextval('neutron_configs_id_seq'::regclass)",
nullable=False),
sa.Column(u'cluster_id',
sa.INTEGER(),
autoincrement=False,
nullable=True),
sa.Column(u'parameters',
sa.TEXT(),
autoincrement=False,
nullable=True),
sa.Column(u'L2',
sa.TEXT(),
autoincrement=False,
nullable=True),
sa.Column(u'L3',
sa.TEXT(),
autoincrement=False,
nullable=True),
sa.Column(u'predefined_networks',
sa.TEXT(),
autoincrement=False,
nullable=True),
sa.Column(u'segmentation_type',
sa.ENUM(u'vlan',
u'gre',
name='segmentation_type'),
autoincrement=False,
nullable=False),
sa.ForeignKeyConstraint(['cluster_id'],
[u'clusters.id'],
name=u'neutron_configs_cluster_id_fkey'),
sa.PrimaryKeyConstraint(u'id',
name=u'neutron_configs_pkey')
)
# CLUSTER STATUS ENUM DOWNGRADE
upgrade_enum(
"clusters", # table
@ -260,17 +417,33 @@ def downgrade():
old_task_names_options # new options
)
# NETWORK NAME ENUM DOWNGRADE
upgrade_enum(
"network_groups", # table
"name", # column
"network_group_name", # ENUM name
new_network_group_name, # old options
old_network_group_name # new options
)
op.drop_column(
u'node_nic_interfaces',
'parent_id'
)
op.drop_column(
'nodes',
'agent_checksum')
op.rename_table(
'net_nic_assignments',
'net_assignments'
)
op.drop_table('net_bond_assignments')
op.drop_table('node_bond_interfaces')
drop_enum('bond_mode')
op.drop_column('nodes', 'agent_checksum')
op.drop_column('nodes', 'uuid')
op.drop_table('neutron_config')
op.drop_table('nova_network_config')
op.drop_table('networking_configs')
### end Alembic commands ###

View File

@ -35,7 +35,9 @@ from nailgun.db.sqlalchemy.models.network import IPAddrRange
from nailgun.db.sqlalchemy.models.network import NetworkNICAssignment
from nailgun.db.sqlalchemy.models.network import NetworkBondAssignment
from nailgun.db.sqlalchemy.models.neutron import NeutronConfig
from nailgun.db.sqlalchemy.models.network_config import NetworkingConfig
from nailgun.db.sqlalchemy.models.network_config import NeutronConfig
from nailgun.db.sqlalchemy.models.network_config import NovaNetworkConfig
from nailgun.db.sqlalchemy.models.notification import Notification

View File

@ -64,22 +64,10 @@ class Cluster(Base):
nullable=False,
default=consts.CLUSTER_NET_PROVIDERS.nova_network
)
net_l23_provider = Column(
Enum(*consts.CLUSTER_NET_L23_PROVIDERS, name='net_l23_provider'),
nullable=False,
default=consts.CLUSTER_NET_L23_PROVIDERS.ovs
)
net_segment_type = Column(
Enum(*consts.CLUSTER_NET_SEGMENT_TYPES,
name='net_segment_type'),
nullable=False,
default=consts.CLUSTER_NET_SEGMENT_TYPES.vlan
)
net_manager = Column(
Enum(*consts.CLUSTER_NET_MANAGERS, name='cluster_net_manager'),
nullable=False,
default=consts.CLUSTER_NET_MANAGERS.FlatDHCPManager
)
network_config = relationship("NetworkingConfig",
backref=backref("cluster"),
cascade="all,delete",
uselist=False)
grouping = Column(
Enum(*consts.CLUSTER_GROUPING, name='cluster_grouping'),
nullable=False,
@ -107,19 +95,10 @@ class Cluster(Base):
cascade="delete",
order_by="NetworkGroup.id"
)
dns_nameservers = Column(JSON, default=[
"8.8.8.8",
"8.8.4.4"
])
replaced_deployment_info = Column(JSON, default={})
replaced_provisioning_info = Column(JSON, default={})
is_customized = Column(Boolean, default=False)
neutron_config = relationship("NeutronConfig",
backref=backref("cluster"),
cascade="all,delete",
uselist=False)
def replace_provisioning_info(self, data):
self.replaced_provisioning_info = data
self.is_customized = True

View File

@ -55,8 +55,6 @@ class NetworkGroup(Base):
'management',
'public',
# VM networks
'floating',
# private in terms of fuel
'fixed',
'private'
@ -68,12 +66,9 @@ class NetworkGroup(Base):
release = Column(Integer, ForeignKey('releases.id'))
# can be nullable only for fuelweb admin net
cluster_id = Column(Integer, ForeignKey('clusters.id'))
network_size = Column(Integer, default=256)
amount = Column(Integer, default=1)
vlan_start = Column(Integer)
cidr = Column(String(25))
gateway = Column(String(25))
netmask = Column(String(25))
ip_ranges = relationship(
"IPAddrRange",
backref="network_group",

View File

@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
# Copyright 2014 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.
from sqlalchemy import Column
from sqlalchemy import Enum
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import String
from nailgun import consts
from nailgun.db.sqlalchemy.models.base import Base
from nailgun.db.sqlalchemy.models.fields import JSON
from nailgun.db.sqlalchemy.models.fields import LowercaseString
class NetworkingConfig(Base):
__tablename__ = 'networking_configs'
id = Column(Integer, primary_key=True)
discriminator = Column(String(50))
cluster_id = Column(
Integer,
ForeignKey('clusters.id', ondelete="CASCADE")
)
dns_nameservers = Column(JSON, default=[
"8.8.4.4",
"8.8.8.8"
])
floating_ranges = Column(JSON, default=[])
__mapper_args__ = {
'polymorphic_on': discriminator
}
class NeutronConfig(NetworkingConfig):
__tablename__ = 'neutron_config'
__mapper_args__ = {
'polymorphic_identity': 'neutron_config',
}
id = Column(Integer, ForeignKey('networking_configs.id'), primary_key=True)
vlan_range = Column(JSON, default=[])
gre_id_range = Column(JSON, default=[])
base_mac = Column(LowercaseString(17), nullable=False)
internal_cidr = Column(String(25))
internal_gateway = Column(String(25))
segmentation_type = Column(
Enum(*consts.NEUTRON_SEGMENT_TYPES,
name='segmentation_type'),
nullable=False,
default=consts.NEUTRON_SEGMENT_TYPES.vlan
)
net_l23_provider = Column(
Enum(*consts.NEUTRON_L23_PROVIDERS, name='net_l23_provider'),
nullable=False,
default='ovs'
)
class NovaNetworkConfig(NetworkingConfig):
__tablename__ = 'nova_network_config'
__mapper_args__ = {
'polymorphic_identity': 'nova_network_config',
}
id = Column(Integer, ForeignKey('networking_configs.id'), primary_key=True)
fixed_networks_cidr = Column(String(25))
fixed_networks_vlan_start = Column(Integer)
fixed_network_size = Column(Integer, nullable=False, default=256)
fixed_networks_amount = Column(Integer, nullable=False, default=1)
net_manager = Column(
Enum(*consts.NOVA_NET_MANAGERS, name='cluster_net_manager'),
nullable=False,
default=consts.NOVA_NET_MANAGERS.FlatDHCPManager
)

View File

@ -1,44 +0,0 @@
# -*- 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.
from sqlalchemy import Column
from sqlalchemy import Enum
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from nailgun.db.sqlalchemy.models.base import Base
from nailgun.db.sqlalchemy.models.fields import JSON
class NeutronConfig(Base):
__tablename__ = 'neutron_configs'
NET_SEGMENT_TYPES = ('vlan', 'gre')
id = Column(Integer, primary_key=True)
cluster_id = Column(
Integer,
ForeignKey('clusters.id', ondelete="CASCADE")
)
parameters = Column(JSON, default={})
L2 = Column(JSON, default={})
L3 = Column(JSON, default={})
predefined_networks = Column(JSON, default={})
segmentation_type = Column(
Enum(*NET_SEGMENT_TYPES,
name='segmentation_type'),
nullable=False,
default='vlan'
)

View File

@ -5,8 +5,6 @@
"fields": {
"name": "fuelweb_admin",
"cidr": "{{settings.ADMIN_NETWORK['cidr']}}",
"netmask": "{{settings.ADMIN_NETWORK['netmask']}}",
"network_size": "{{settings.ADMIN_NETWORK['size']}}",
"vlan_start": null,
"meta": {
"use_gateway": false,
@ -15,6 +13,7 @@
"render_addr_mask": null,
"map_priority": 0,
"unmovable": true,
"configurable": false,
"assign_vip": false
}
}

View File

@ -29,30 +29,17 @@
networks_metadata:
nova_network:
networks:
- name: "floating"
cidr: "172.16.0.0/24"
ip_range: ["172.16.0.128", "172.16.0.254"]
vlan_start: null
use_gateway: false
notation: "ip_ranges"
render_type: "ip_ranges"
render_addr_mask: null
use_same_vlan_nic: 1
map_priority: 1
assign_vip: false
- name: "public"
cidr: "172.16.0.0/24"
netmask: "255.255.255.0"
gateway: "172.16.0.1"
ip_range: ["172.16.0.2", "172.16.0.127"]
vlan_start: null
use_gateway: true
notation: "ip_ranges"
calculate_cidr: true
render_type: null
render_addr_mask: "public"
use_same_vlan_nic: 1
map_priority: 1
configurable: true
assign_vip: true
- name: "management"
cidr: "192.168.0.0/24"
@ -62,6 +49,7 @@
render_type: "cidr"
render_addr_mask: "internal"
map_priority: 2
configurable: true
assign_vip: true
- name: "storage"
cidr: "192.168.1.0/24"
@ -71,17 +59,25 @@
render_type: "cidr"
render_addr_mask: "storage"
map_priority: 2
configurable: true
assign_vip: false
- name: "fixed"
cidr: "10.0.0.0/16"
network_size: 256
vlan_start: 103
use_gateway: true
notation: "cidr"
render_type: "cidr"
vlan_start: null
use_gateway: false
notation: null
render_type: null
render_addr_mask: null
map_priority: 2
ext_vlan_tag: "fixed_networks_vlan_start"
configurable: false
assign_vip: false
config:
net_manager: "FlatDHCPManager"
fixed_networks_cidr: "10.0.0.0/16"
fixed_networks_vlan_start: 103
fixed_network_size: 256
fixed_networks_amount: 1
floating_ranges: [["172.16.0.128", "172.16.0.254"]]
volumes_metadata:
volumes_roles_mapping:
controller:
@ -332,10 +328,11 @@
vlan_start: null
use_gateway: true
notation: "ip_ranges"
calculate_cidr: true
render_type: null
render_addr_mask: "public"
map_priority: 1
configurable: true
floating_range_var: "floating_ranges"
assign_vip: true
- name: "management"
cidr: "192.168.0.0/24"
@ -345,6 +342,7 @@
render_type: "cidr"
render_addr_mask: "internal"
map_priority: 2
configurable: true
assign_vip: true
- name: "storage"
cidr: "192.168.1.0/24"
@ -354,6 +352,7 @@
render_type: "cidr"
render_addr_mask: "storage"
map_priority: 2
configurable: true
assign_vip: false
- name: "private"
seg_type: "vlan"
@ -364,8 +363,15 @@
render_addr_mask: null
map_priority: 2
neutron_vlan_range: true
configurable: false
assign_vip: false
config:
vlan_range: [1000, 1030]
gre_id_range: [2, 65535]
base_mac: "fa:16:3e:00:00:00"
internal_cidr: "192.168.111.0/24"
internal_gateway: "192.168.111.1"
floating_ranges: [["172.16.0.130", "172.16.0.254"]]
parameters:
amqp:
provider: "rabbitmq"

View File

@ -24,6 +24,10 @@ from nailgun import objects
from nailgun.api.serializers.network_configuration \
import NetworkConfigurationSerializer
from nailgun.api.serializers.network_configuration \
import NeutronNetworkConfigurationSerializer
from nailgun.api.serializers.network_configuration \
import NovaNetworkConfigurationSerializer
from nailgun.db.sqlalchemy.models import NetworkGroup
from nailgun.errors import errors
from nailgun.logger import logger
@ -57,11 +61,19 @@ class NetworkCheck(object):
for data_net in data['networks']:
for net in self.networks:
if data_net['id'] == net['id']:
if data_net.get('meta'):
data_net.pop('meta')
net.update(data_net)
break
else:
raise errors.NetworkCheckError(
u"Invalid network ID: {0}".format(data_net['id']))
# get common networking parameters
serializer = {'neutron': NeutronNetworkConfigurationSerializer,
'nova_network': NovaNetworkConfigurationSerializer}
self.network_config = serializer[self.net_provider].\
serialize_network_params(self.cluster)
self.network_config.update(data.get('networking_parameters', {}))
self.result = []
self.err_msgs = []
@ -74,13 +86,16 @@ class NetworkCheck(object):
def check_untagged_intersection(self):
"""check if there are 2 or more untagged networks on the same interface
except public and floating networks (nova-net)
except public and floating networks
(both nova-net and neutron)
"""
netw_untagged = lambda n: (n['vlan_start'] is None) \
and (not n['meta'].get('ext_vlan_tag')) \
and (not n['meta'].get('neutron_vlan_range'))
untagged_nets = set([n['name'] for n in self.networks
if n['vlan_start'] is None])
if netw_untagged(n)])
# check only if we have 2 or more untagged networks
pub_flt = set(['public', 'floating'])
if len(untagged_nets) >= 2 and untagged_nets != pub_flt:
if len(untagged_nets) >= 2:
logger.info(
"Untagged networks found, "
"checking intersection between them...")
@ -96,7 +111,7 @@ class NetworkCheck(object):
if n.id == ng['id']][0]
for n in iface.assigned_networks_list]
crossed_nets = set(nets) & untagged_nets
if len(crossed_nets) > 1 and crossed_nets != pub_flt:
if len(crossed_nets) > 1:
err_net_names = ['"{0}"'.format(i)
for i in crossed_nets]
found_intersection.append(
@ -117,55 +132,56 @@ class NetworkCheck(object):
"errors": []})
self.expose_error_messages()
def check_public_floating_assignment(self):
"""check public and floating are on the same interface (nova-net)
"""
err_nodes = []
for node in self.cluster.nodes:
pr_fl_nic = []
for nic in node.interfaces:
pr_fl_nic += [nic.id for n in nic.assigned_networks_list
if n.name in ('public', 'floating')]
if len(pr_fl_nic) == 2 and pr_fl_nic[0] != pr_fl_nic[1]:
err_nodes.append(node.name)
if err_nodes:
self.err_msgs.append(
u"Public and floating networks are not assigned to the "
u"same physical interface. These networks must be assigned "
u"to the same physical interface. "
u"Affected nodes:\n{0}".format(", ".join(err_nodes)))
self.result.append({"ids": [],
"errors": []})
self.expose_error_messages()
def check_network_address_spaces_intersection(self):
"""check intersection of networks address spaces for all networks
(nova-net)
"""
def addr_space(ng, ng_pair):
if ng['name'] == 'floating':
return [netaddr.IPRange(v[0], v[1])
for v in ng['ip_ranges']]
elif ng['name'] == 'public':
if ng_pair['name'] == 'floating':
return [netaddr.IPRange(v[0], v[1])
for v in ng['ip_ranges']]
return [netaddr.IPNetwork(ng['cidr']).cidr]
for ngs in combinations(self.networks, 2):
for addrs in product(addr_space(ngs[0], ngs[1]),
addr_space(ngs[1], ngs[0])):
if self.net_man.is_range_intersection(addrs[0], addrs[1]):
self.err_msgs.append(
u"Address space intersection between "
"networks:\n{0}.".format(
", ".join([ngs[0]['name'], ngs[1]['name']])
)
nets_w_cidr = filter(lambda n: n['cidr'], self.networks)
for ngs in combinations(nets_w_cidr, 2):
addrs = [netaddr.IPNetwork(ngs[0]['cidr']).cidr,
netaddr.IPNetwork(ngs[1]['cidr']).cidr]
if self.net_man.is_range_intersection(addrs[0], addrs[1]):
self.err_msgs.append(
u"Address space intersection between "
"networks:\n{0}.".format(
", ".join([ngs[0]['name'], ngs[1]['name']])
)
self.result.append({
"ids": [int(ngs[0]["id"]), int(ngs[1]["id"])],
"errors": ["cidr", "ip_ranges"]
})
)
self.result.append({
"ids": [int(ngs[0]["id"]), int(ngs[1]["id"])],
"errors": ["cidr"]
})
# Check for intersection with 'fixed' networks
fixed_cidr = netaddr.IPNetwork(
self.network_config['fixed_networks_cidr']).cidr
for ng in nets_w_cidr:
if self.net_man.is_range_intersection(
fixed_cidr, netaddr.IPNetwork(ng['cidr']).cidr):
self.err_msgs.append(
u"Address space intersection between "
"networks:\nfixed, {0}.".format(ng['name'])
)
self.result.append({
"ids": [int(ng["id"])],
"errors": ["cidr"]
})
# Check for intersection with floating ranges
nets_w_cidr = filter(lambda n: n['meta']['notation'] == 'cidr',
self.networks)
fl_ranges = [netaddr.IPRange(v[0], v[1])
for v in self.network_config['floating_ranges']]
for net_vs_range in product(nets_w_cidr, fl_ranges):
cidr = netaddr.IPNetwork(net_vs_range[0]['cidr']).cidr
if self.net_man.is_range_intersection(cidr, net_vs_range[1]):
self.err_msgs.append(
u"Address space intersection between floating range '{0}'"
" and '{1}' network.".format(
net_vs_range[1], net_vs_range[0]['name'])
)
self.result.append({
"ids": [int(net_vs_range[0]["id"])],
"errors": ["cidr", "floating_ranges"]
})
self.expose_error_messages()
def check_public_floating_ranges_intersection(self):
@ -175,56 +191,61 @@ class NetworkCheck(object):
3. Check that Public IP ranges are in Public CIDR
(nova-net)
"""
ng = [ng for ng in self.networks
if ng['name'] == 'public'][0]
pub_gw = netaddr.IPAddress(ng['gateway'])
pub_cidr = objects.Cluster.get_network_manager(
self.cluster
).calc_cidr_from_gw_mask(ng)
if not pub_cidr:
self.err_msgs.append(
u"Invalid gateway or netmask for public network")
self.result.append({"ids": [int(ng["id"])],
"errors": ["gateway", "netmask"]})
self.expose_error_messages()
ng['cidr'] = pub_cidr
pub = [ng for ng in self.networks
if ng['name'] == 'public'][0]
# Check intersection of networks address spaces inside
# Public and Floating network
pub_ranges_err = False
for ng in self.networks:
if ng['name'] in ['public', 'floating']:
nets = [netaddr.IPRange(v[0], v[1])
for v in ng['ip_ranges']]
for npair in combinations(nets, 2):
if self.net_man.is_range_intersection(npair[0], npair[1]):
nets = {
'public': [netaddr.IPRange(v[0], v[1])
for v in pub['ip_ranges']],
'floating': [netaddr.IPRange(v[0], v[1])
for v in self.network_config['floating_ranges']]
}
for name, ranges in nets.iteritems():
ids = [pub['id']] if name == 'public' else []
for npair in combinations(ranges, 2):
if self.net_man.is_range_intersection(npair[0], npair[1]):
self.err_msgs.append(
u"Address space intersection between ranges "
u"of {0} network.".format(name)
)
self.result.append({"ids": ids,
"errors": ["ip_ranges"]})
for net in ranges:
# Check intersection of public GW and pub/float IP ranges
if netaddr.IPAddress(pub['gateway']) in net:
self.err_msgs.append(
u"Address intersection between "
u"public gateway and IP range "
u"of {0} network.".format(name)
)
self.result.append({"ids": ids,
"errors": ["gateway",
"ip_ranges"]})
# Check that public IP ranges are in public CIDR
if name == 'public':
if net not in netaddr.IPNetwork(pub['cidr']) \
and not pub_ranges_err:
pub_ranges_err = True
self.err_msgs.append(
u"Address space intersection between ranges "
"of {0} network.".format(ng['name'])
u"Public gateway and public ranges "
u"are not in one CIDR."
)
self.result.append({"ids": [int(ng["id"])],
"errors": ["ip_ranges"]})
for net in nets:
# Check intersection of public GW and pub/float IP ranges
if pub_gw in net:
self.err_msgs.append(
u"Address intersection between "
u"public gateway and IP range "
u"of {0} network.".format(ng['name'])
)
self.result.append({"ids": [int(ng["id"])],
self.result.append({"ids": ids,
"errors": ["gateway",
"ip_ranges"]})
# Check that public IP ranges are in public CIDR
if ng['name'] == 'public':
if net not in pub_cidr and not pub_ranges_err:
pub_ranges_err = True
self.err_msgs.append(
u"Public gateway and public ranges "
u"are not in one CIDR."
)
self.result.append({"ids": [int(ng["id"])],
"errors": ["gateway",
"ip_ranges"]})
self.expose_error_messages()
# Check intersection of public and floating ranges
for npair in combinations(nets['public'] + nets['floating'], 2):
if self.net_man.is_range_intersection(npair[0], npair[1]):
self.err_msgs.append(
u"Address space intersection between range "
u"of public network and floating range."
)
self.result.append({"ids": [pub['id']],
"errors": ["ip_ranges"]})
self.expose_error_messages()
def check_vlan_ids_range_and_intersection(self):
@ -233,13 +254,15 @@ class NetworkCheck(object):
(nova-net)
"""
tagged_nets = dict(
(n['name'], [int(n['vlan_start']),
int(n['amount']) - 1])
(n['name'], [int(n['vlan_start']), 0])
for n in self.networks
if n['vlan_start'] is not None)
for name, range in tagged_nets.iteritems():
tagged_nets['fixed'] = [
self.network_config['fixed_networks_vlan_start'],
self.network_config['fixed_networks_amount'] - 1]
for name, vlan_range in tagged_nets.iteritems():
# check VLAN ID range against [2-4094]
if range[0] < 2 or range[0] + range[1] > 4094:
if vlan_range[0] < 2 or vlan_range[0] + vlan_range[1] > 4094:
self.err_msgs.append(
u"VLAN ID(s) is out of range for "
"{0} network.".format(name)
@ -250,18 +273,6 @@ class NetworkCheck(object):
for net in combinations(tagged_nets.keys(), 2):
range1 = tagged_nets[net[0]]
range2 = tagged_nets[net[1]]
if set(net) == set(['public', 'floating']):
# public and floating networks always use the same tags
if range1[0] != range2[0] or range1[1] != range2[1]:
self.err_msgs.append(
u"{0} networks don't use the same VLAN ID(s). "
"These networks must use "
"the same VLAN ID(s).".format(", ".join(net)))
self.result.append({"ids": [int(n["id"])
for n in self.networks
if n['name'] in net],
"errors": ["vlan_start"]})
continue
if range1[0] <= range2[0] + range2[1] \
and range2[0] <= range1[0] + range1[1]:
self.err_msgs.append(
@ -275,41 +286,34 @@ class NetworkCheck(object):
self.expose_error_messages()
def check_networks_amount(self):
"""1. check each network group has not more than 1 network
except fixed in case of VLANManager
"""1. check number of fixed networks is one in case of FlatDHCPManager
2. check number of fixed networks fit in fixed CIDR and size of
one fixed network
(nova-net)
"""
netmanager = self.data.get('net_manager') or self.cluster.net_manager
for ng in self.networks:
if ng['amount'] > 1:
if ng['name'] != 'fixed':
self.err_msgs.append(
u"Network amount for '{0}' is more than 1".format(
ng['name'])
)
self.result.append({"ids": [int(ng["id"])],
"errors": ["amount"]})
elif netmanager == 'FlatDHCPManager':
self.err_msgs.append(
u"Network amount for 'fixed' is more than 1 "
"while using FlatDHCP manager."
)
self.result.append({"ids": [int(ng["id"])],
"errors": ["amount"]})
if ng['name'] == 'fixed':
net_size = int(ng.get('network_size'))
net_amount = int(ng.get('amount'))
net_gr_size = netaddr.IPNetwork(ng['cidr']).size
if net_size * net_amount > net_gr_size:
self.err_msgs.append(
u"Number of fixed networks ({0}) doesn't fit into "
u"fixed CIDR ({1}) and size of one fixed network "
u"({2}).".format(net_amount, ng['cidr'], net_size)
)
self.result.append({"ids": [int(ng["id"])],
"errors": ["amount", "network_size"]})
netmanager = self.network_config['net_manager']
if netmanager == 'FlatDHCPManager' and \
self.network_config['fixed_networks_amount'] > 1:
self.err_msgs.append(
u"Network amount for 'fixed' is more than 1 "
"while using FlatDHCP manager."
)
self.result.append({"ids": [],
"errors": ["fixed_networks_amount"]})
net_size = int(self.network_config['fixed_network_size'])
net_amount = int(self.network_config['fixed_networks_amount'])
net_cidr = netaddr.IPNetwork(
self.network_config['fixed_networks_cidr'])
if net_size * net_amount > net_cidr.size:
self.err_msgs.append(
u"Number of fixed networks ({0}) doesn't fit into "
u"fixed CIDR ({1}) and size of one fixed network "
u"({2}).".format(net_amount, net_cidr, net_size)
)
self.result.append({"ids": [],
"errors": ["fixed_network_size",
"fixed_networks_amount"]})
self.expose_error_messages()
def neutron_check_segmentation_ids(self):
@ -322,20 +326,9 @@ class NetworkCheck(object):
lambda n: (n["vlan_start"] is not None), self.networks))
if tagged_nets:
if self.task.cluster.net_segment_type == 'vlan':
if self.task.cluster.network_config.segmentation_type == 'vlan':
# check networks tags not in Neutron L2 private VLAN ID range
if 'neutron_parameters' in self.data:
l2cfg = self.data['neutron_parameters']['L2']
else:
l2cfg = self.task.cluster.neutron_config.L2
for net, net_conf in l2cfg['phys_nets'].iteritems():
vrange = net_conf['vlan_range']
if vrange:
break
else:
err_msg = u"Wrong VLAN range for Neutron L2.\n"
raise errors.NetworkCheckError(err_msg)
vrange = self.network_config['vlan_range']
net_intersect = [name for name, vlan in tagged_nets.iteritems()
if vrange[0] <= vlan <= vrange[1]]
if net_intersect:
@ -357,42 +350,10 @@ class NetworkCheck(object):
u"to every network.".format(", ".join(net_intersect))
raise errors.NetworkCheckError(err_msg)
def neutron_check_network_group_sizes(self):
"""Check networks sizes defined by CIDRs are not smaller then
declared with 'network_size' field (neutron)
"""
for ng in self.networks:
# network_size is calculated in case of public
if ng['name'] not in ('private', 'public'):
# ng['amount'] is always equal 1 for Neutron
if netaddr.IPNetwork(ng['cidr']).size < ng['network_size']:
self.err_msgs.append(
u"CIDR size for network '{0}' "
u"is less than required".format(ng['name'])
)
self.result.append({
"ids": [int(ng["id"])],
"errors": ["network_size"]
})
self.expose_error_messages()
def neutron_check_network_address_spaces_intersection(self):
"""Check intersection between address spaces of all networks
including admin (neutron)
"""
# calculate and check public CIDR
public = filter(lambda ng: ng['name'] == 'public', self.networks)[0]
public_cidr = objects.Cluster.get_network_manager(
self.cluster
).calc_cidr_from_gw_mask(public)
if not public_cidr:
self.err_msgs.append(
u"Invalid gateway or netmask for public network")
self.result.append({"ids": [int(public["id"])],
"errors": ["gateway", "netmask"]})
self.expose_error_messages()
public['cidr'] = str(public_cidr)
# check intersection of address ranges
# between all networks
for ngs in combinations(self.networks, 2):
@ -413,11 +374,9 @@ class NetworkCheck(object):
self.expose_error_messages()
# check Floating Start and Stop IPs belong to Public CIDR
if 'neutron_parameters' in self.data:
pre_net = self.data['neutron_parameters']['predefined_networks']
else:
pre_net = self.task.cluster.neutron_config.predefined_networks
fl_range = pre_net['net04_ext']['L3']['floating']
public = filter(lambda ng: ng['name'] == 'public', self.networks)[0]
public_cidr = netaddr.IPNetwork(public['cidr']).cidr
fl_range = self.network_config['floating_ranges'][0]
fl_ip_range = netaddr.IPRange(fl_range[0], fl_range[1])
if fl_ip_range not in public_cidr:
self.err_msgs.append(
@ -471,88 +430,30 @@ class NetworkCheck(object):
self.expose_error_messages()
# check internal Gateway is in Internal CIDR
internal = pre_net['net04']['L3']
if internal.get('cidr') and internal.get('gateway'):
cidr = netaddr.IPNetwork(internal['cidr'])
if netaddr.IPAddress(internal['gateway']) not in cidr:
self.result.append({"ids": [],
"name": ["internal"],
"errors": ["gateway"]})
self.err_msgs.append(
u"Internal gateway {0} is not in internal "
u"address space {1}.".format(
internal['gateway'], internal['cidr']
)
)
if self.net_man.is_range_intersection(fl_ip_range, cidr):
self.result.append({"ids": [],
"name": ["internal", "external"],
"errors": ["cidr", "ip_ranges"]})
self.err_msgs.append(
u"Intersection between internal CIDR and floating range."
)
else:
cidr = netaddr.IPNetwork(self.network_config['internal_cidr'])
gw = netaddr.IPAddress(self.network_config['internal_gateway'])
if gw not in cidr:
self.result.append({"ids": [],
"name": ["internal"],
"errors": ["cidr", "gateway"]})
"errors": ["gateway"]})
self.err_msgs.append(
u"Internal gateway or CIDR specification is invalid."
u"Internal gateway {0} is not in internal "
u"address space {1}.".format(str(gw), str(cidr))
)
if self.net_man.is_range_intersection(fl_ip_range, cidr):
self.result.append({"ids": [],
"name": ["internal", "external"],
"errors": ["cidr", "ip_ranges"]})
self.err_msgs.append(
u"Intersection between internal CIDR and floating range."
)
self.expose_error_messages()
def neutron_check_interface_mapping(self):
"""Check mapping of networks to NICs (Neutron)
"""
# check untagged networks intersection
untagged_nets = set(
n["id"] for n in filter(
lambda n: (n['vlan_start'] is None) and
(not n['meta'].get('neutron_vlan_range')),
self.networks))
if untagged_nets:
logger.info(
"Untagged networks found, "
"checking intersection between them...")
interfaces = []
for node in self.cluster.nodes:
for iface in node.interfaces:
interfaces.append(iface)
found_intersection = []
for iface in interfaces:
nets = dict(
(n.id, n.name)
for n in iface.assigned_networks_list)
crossed_nets = set(nets.keys()) & untagged_nets
if len(crossed_nets) > 1:
err_net_names = [
'"{0}"'.format(nets[i]) for i in crossed_nets]
found_intersection.append(
[iface.node.name, err_net_names])
if found_intersection:
nodes_with_errors = [
u'Node "{0}": {1}'.format(
name,
", ".join(_networks)
) for name, _networks in found_intersection]
err_msg = u"Some untagged networks are " \
"assigned to the same physical interface. " \
"You should assign them to " \
"different physical interfaces:\n{0}". \
format("\n".join(nodes_with_errors))
raise errors.NetworkCheckError(err_msg)
def neutron_check_l3_addresses_not_match_subnet_and_broadcast(self):
"""check virtual l3 network address ranges and gateway don't intersect
with subnetwork address and broadcast address (neutron)
"""
if 'neutron_parameters' in self.data:
pre_net = self.data['neutron_parameters']['predefined_networks']
else:
pre_net = self.task.cluster.neutron_config.predefined_networks
ext_fl = pre_net['net04_ext']['L3']['floating']
ext_fl = self.network_config['floating_ranges'][0]
ext_fl_r = netaddr.IPRange(ext_fl[0], ext_fl[1])
pub = filter(lambda n: n['name'] == 'public', self.networks)[0]
@ -567,8 +468,8 @@ class NetworkCheck(object):
"name": ["external"],
"errors": ["ip_ranges"]})
int_cidr = netaddr.IPNetwork(pre_net['net04']['L3']['cidr']).cidr
int_gw = netaddr.IPAddress(pre_net['net04']['L3']['gateway'])
int_cidr = netaddr.IPNetwork(self.network_config['internal_cidr']).cidr
int_gw = netaddr.IPAddress(self.network_config['internal_gateway'])
if int_gw == int_cidr.network or int_gw == int_cidr.broadcast:
self.err_msgs.append(
u"Neutron L3 internal network gateway address is equal to "
@ -612,8 +513,7 @@ class NetworkCheck(object):
subnetwork address and broadcast address (both neutron and nova-net)
"""
for n in self.networks:
# TODO(alekseyk) get rid of network names here
if n['name'] in ('public', 'fixed'):
if n['meta']['notation'] == 'ip_ranges':
cidr = netaddr.IPNetwork(n['cidr']).cidr
if n.get('gateway'):
gw = netaddr.IPAddress(n['gateway'])
@ -636,6 +536,17 @@ class NetworkCheck(object):
)
self.result.append({"ids": [int(n["id"])],
"errors": ["ip_ranges"]})
flt_range = self.network_config['floating_ranges']
for r in flt_range:
ipr = netaddr.IPRange(r[0], r[1])
if cidr.network in ipr or cidr.broadcast in ipr:
self.err_msgs.append(
u"{0} network floating IP range [{1}] intersect "
u"with either subnet address or broadcast address "
u"of the network.".format(n["name"], str(ipr))
)
self.result.append({"ids": [int(n["id"])],
"errors": ["ip_ranges"]})
self.expose_error_messages()
def check_bond_slaves_speeds(self):
@ -660,7 +571,6 @@ class NetworkCheck(object):
if self.net_provider == 'neutron':
self.neutron_check_network_address_spaces_intersection()
self.neutron_check_segmentation_ids()
self.neutron_check_network_group_sizes()
self.neutron_check_l3_addresses_not_match_subnet_and_broadcast()
else:
self.check_public_floating_ranges_intersection()
@ -673,10 +583,6 @@ class NetworkCheck(object):
def check_interface_mapping(self):
"""check mapping of networks to NICs
"""
if self.net_provider == 'neutron':
self.neutron_check_interface_mapping()
else:
self.check_untagged_intersection()
self.check_public_floating_assignment()
self.check_untagged_intersection()
self.check_bond_slaves_speeds()
return self.err_msgs

View File

@ -21,7 +21,6 @@ from itertools import ifilter
from itertools import imap
from itertools import islice
from netaddr import AddrFormatError
from netaddr import IPAddress
from netaddr import IPNetwork
from netaddr import IPRange
@ -59,8 +58,6 @@ class NetworkManager(object):
first=str(new_cidr[2]),
last=str(new_cidr[-2]))
network_group.netmask = str(new_cidr.netmask)
db().add(ip_range)
db().commit()
@ -415,23 +412,20 @@ class NetworkManager(object):
if ng_id in allowed_ids]
assigned_ids = set()
untagged_cnt = 0
same_nic_groups = set()
for ng_id in can_assign:
ng = ngs_by_id[ng_id]
dedicated = ng.meta.get('dedicated_nic')
untagged = (ng.vlan_start is None) \
and not ng.meta.get('neutron_vlan_range')
same_nic = ng.meta.get('use_same_vlan_nic')
and not ng.meta.get('neutron_vlan_range') \
and not ng.meta.get('ext_vlan_tag')
if dedicated:
if not assigned_ids:
assigned_ids.add(ng_id)
break
elif untagged:
if untagged_cnt == 0 or same_nic in same_nic_groups:
if untagged_cnt == 0:
assigned_ids.add(ng_id)
untagged_cnt += 1
if same_nic:
same_nic_groups.add(same_nic)
else:
assigned_ids.add(ng_id)
@ -511,21 +505,12 @@ class NetworkManager(object):
interface = cls._get_interface_by_network_name(
node_db.id, net.name)
if net.name == 'public':
# Get prefix from netmask instead of cidr
# for public network
# Convert netmask to prefix
prefix = str(IPNetwork(
'0.0.0.0/' + net.netmask).prefixlen)
netmask = net.netmask
else:
prefix = str(IPNetwork(net.cidr).prefixlen)
netmask = str(IPNetwork(net.cidr).netmask)
prefix = str(IPNetwork(net.cidr).prefixlen)
netmask = str(IPNetwork(net.cidr).netmask)
network_data.append({
'name': net.name,
'vlan': net.vlan_start,
'vlan': cls.get_network_vlan(net, cluster_db),
'ip': ip.ip_addr + '/' + prefix,
'netmask': netmask,
'brd': str(IPNetwork(net.cidr).broadcast),
@ -582,6 +567,11 @@ class NetworkManager(object):
networks,
lambda net: net.cluster_id)
@classmethod
def get_network_vlan(cls, net_db, cl_db):
return net_db.vlan_start if not net_db.meta.get('ext_vlan_tag') \
else getattr(cl_db.network_config, net_db.meta['ext_vlan_tag'])
@classmethod
def get_node_networks_optimized(cls, node_db, ips_db, networks):
"""Method for receiving data for a given node with db data provided
@ -603,21 +593,12 @@ class NetworkManager(object):
net.name
)
# Get prefix from netmask instead of cidr
# for public network
if net.name == 'public':
# Convert netmask to prefix
prefix = str(IPNetwork(
'0.0.0.0/' + net.netmask).prefixlen)
netmask = net.netmask
else:
prefix = str(IPNetwork(net.cidr).prefixlen)
netmask = str(IPNetwork(net.cidr).netmask)
prefix = str(IPNetwork(net.cidr).prefixlen)
netmask = str(IPNetwork(net.cidr).netmask)
network_data.append({
'name': net.name,
'vlan': net.vlan_start,
'vlan': cls.get_network_vlan(net, cluster_db),
'ip': ip.ip_addr + '/' + prefix,
'netmask': netmask,
'brd': str(IPNetwork(net.cidr).broadcast),
@ -633,11 +614,12 @@ class NetworkManager(object):
net.name
)
if net.name == 'fixed' and cluster_db.net_manager == 'VlanManager':
if net.name == 'fixed' \
and cluster_db.network_config.net_manager == 'VlanManager':
continue
network_data.append({
'name': net.name,
'vlan': net.vlan_start,
'vlan': cls.get_network_vlan(net, cluster_db),
'dev': interface.name})
network_data.append(cls._get_admin_network(node_db))
@ -663,11 +645,12 @@ class NetworkManager(object):
net.name
)
if net.name == 'fixed' and cluster_db.net_manager == 'VlanManager':
if net.name == 'fixed' \
and cluster_db.network_config.net_manager == 'VlanManager':
continue
add_net_data.append({
'name': net.name,
'vlan': net.vlan_start,
'vlan': cls.get_network_vlan(net, cluster_db),
'dev': interface.name})
add_net_data.append(cls._get_admin_network(node_db))
@ -972,24 +955,8 @@ class NetworkManager(object):
db().add(new_ip_range)
db().commit()
@staticmethod
def calc_cidr_from_gw_mask(net_group):
try:
return IPNetwork(net_group.get('gateway') + '/' +
net_group.get('netmask')).cidr
except (AddrFormatError, KeyError):
return None
@classmethod
def update_cidr_from_gw_mask(cls, ng_db, ng):
if ng.get('gateway') and ng.get('netmask'):
cidr = cls.calc_cidr_from_gw_mask(ng)
if cidr:
ng_db.cidr = str(cidr)
ng_db.network_size = cidr.size
@classmethod
def create_network_groups(cls, cluster_id):
def create_network_groups(cls, cluster_id, neutron_segment_type):
"""Method for creation of network groups for cluster.
:param cluster_id: Cluster database ID.
@ -1010,18 +977,15 @@ class NetworkManager(object):
used_nets.append(cidr_range)
for net in networks_list:
if "seg_type" in net and \
cluster_db.net_segment_type != net['seg_type']:
if "seg_type" in net \
and neutron_segment_type != net['seg_type']:
continue
vlan_start = net.get("vlan_start")
net_size = net.get('network_size')
cidr, gw, cidr_gw, netmask = None, None, None, None
cidr, gw, cidr_gw = None, None, None
if net.get("notation"):
if net.get("cidr"):
cidr = IPNetwork(net["cidr"]).cidr
cidr_gw = str(cidr[1])
netmask = str(cidr.netmask)
net_size = net_size or cidr.size
if net["notation"] == 'cidr' and cidr:
new_ip_range = IPAddrRange(
first=str(cidr[2]),
@ -1039,7 +1003,6 @@ class NetworkManager(object):
)
gw = net.get('gateway') or cidr_gw \
if net.get('use_gateway') else None
netmask = net.get('netmask') or netmask
check_range_in_use_already(IPRange(new_ip_range.first,
new_ip_range.last))
@ -1047,12 +1010,9 @@ class NetworkManager(object):
release=cluster_db.release.id,
name=net['name'],
cidr=str(cidr) if cidr else None,
netmask=netmask,
gateway=gw,
cluster_id=cluster_id,
vlan_start=vlan_start,
amount=1,
network_size=net_size or 1,
meta=net
)
db().add(nw_group)
@ -1082,15 +1042,33 @@ class NetworkManager(object):
if key != 'meta':
setattr(ng_db, key, value)
if ng_db.meta.get("calculate_cidr"):
cls.update_cidr_from_gw_mask(ng_db, ng)
if ng_db.meta.get("notation"):
cls.cleanup_network_group(ng_db)
Cluster.add_pending_changes(ng_db.cluster, 'networks')
@classmethod
def update(cls, cluster, network_configuration):
cls.update_networks(cluster, network_configuration)
if 'networking_parameters' in network_configuration:
for key, value in network_configuration['networking_parameters'] \
.items():
setattr(cluster.network_config, key, value)
db().flush()
@classmethod
def cluster_has_bonds(cls, cluster_id):
return db().query(Node).filter(
Node.cluster_id == cluster_id
).filter(
Node.bond_interfaces.any()).count() > 0
@classmethod
def create_network_groups_and_config(cls, cluster, data):
cls.create_network_groups(cluster.id,
data.get('net_segment_type'))
if cluster.net_provider == 'neutron':
cls.create_neutron_config(cluster,
data.get('net_segment_type'))
elif cluster.net_provider == 'nova_network':
cls.create_nova_network_config(cluster)

View File

@ -14,8 +14,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from netaddr import IPNetwork
from nailgun.db import db
from nailgun.db.sqlalchemy.models import NetworkGroup
from nailgun.db.sqlalchemy.models import NeutronConfig
@ -25,17 +23,16 @@ from nailgun.network.manager import NetworkManager
class NeutronManager(NetworkManager):
@classmethod
def create_neutron_config(cls, cluster):
meta = cluster.release.networks_metadata["neutron"]["config"]
def create_neutron_config(cls, cluster, segment_type):
neutron_config = NeutronConfig(
cluster_id=cluster.id,
parameters=meta["parameters"],
predefined_networks=cls._generate_predefined_networks(cluster),
L2=cls._generate_l2(cluster),
L3=cls._generate_l3(cluster),
segmentation_type=cluster.net_segment_type,
segmentation_type=segment_type,
)
db().add(neutron_config)
meta = cluster.release.networks_metadata["neutron"]["config"]
for key, value in meta.iteritems():
if hasattr(neutron_config, key):
setattr(neutron_config, key, value)
db().flush()
@classmethod
@ -47,92 +44,90 @@ class NeutronManager(NetworkManager):
cluster_id=cluster.id,
name='public'
).first()
net = IPNetwork(public_cidr)
join_range = lambda r: (":".join(map(str, r)) if r else None)
return {
"L3": {
"cidr": public_cidr,
"subnet": public_cidr,
"gateway": public_gw,
"nameservers": [],
"floating": [
str(net[len(net) / 2 + 2]),
str(net[-2])
]
}
"floating": join_range(
cluster.network_config.floating_ranges[0]),
"enable_dhcp": False
},
"L2": {
"network_type": "flat",
"segment_id": None,
"router_ext": True,
"physnet": "physnet1"
},
"tenant": "admin",
"shared": False
}
@classmethod
def _generate_internal_network(cls, cluster):
return {
"L3": {
"cidr": "192.168.111.0/24",
"gateway": "192.168.111.1",
"nameservers": [
"8.8.4.4",
"8.8.8.8"
],
"floating": []
}
"subnet": cluster.network_config.internal_cidr,
"gateway": cluster.network_config.internal_gateway,
"nameservers": cluster.network_config.dns_nameservers,
"floating": None,
"enable_dhcp": True
},
"L2": {
"network_type": cluster.network_config.segmentation_type,
"segment_id": None,
"router_ext": False,
"physnet": "physnet2"
if cluster.network_config.segmentation_type == "vlan" else None
},
"tenant": "admin",
"shared": False
}
@classmethod
def _generate_predefined_networks(cls, cluster):
def generate_predefined_networks(cls, cluster):
return {
"net04_ext": cls._generate_external_network(cluster),
"net04": cls._generate_internal_network(cluster)
}
@classmethod
def _generate_l2(cls, cluster):
def generate_l2(cls, cluster):
join_range = lambda r: (":".join(map(str, r)) if r else None)
res = {
"base_mac": "fa:16:3e:00:00:00",
"segmentation_type": cluster.net_segment_type,
"base_mac": cluster.network_config.base_mac,
"segmentation_type": cluster.network_config.segmentation_type,
"phys_nets": {
"physnet1": {
"bridge": "br-ex",
"vlan_range": []
"vlan_range": None
}
}
}
if cluster.net_segment_type == 'gre':
res["tunnel_id_ranges"] = [2, 65535]
elif cluster.net_segment_type == 'vlan':
if cluster.network_config.segmentation_type == 'gre':
res["tunnel_id_ranges"] = join_range(
cluster.network_config.gre_id_range)
elif cluster.network_config.segmentation_type == 'vlan':
res["phys_nets"]["physnet2"] = {
"bridge": "br-prv",
"vlan_range": [1000,
1030]
"vlan_range": join_range(cluster.network_config.vlan_range)
}
return res
@classmethod
def _generate_l3(cls, cluster):
return {}
@classmethod
def update(cls, cluster, network_configuration):
cls.update_networks(cluster, network_configuration)
if 'neutron_parameters' in network_configuration:
if 'networks' in network_configuration:
#TODO(NAME) get rid of unmanaged parameters in request
for ng in network_configuration['networks']:
if ng['name'] == 'public':
pre_nets = network_configuration[
'neutron_parameters']['predefined_networks']
pre_nets['net04_ext']['L3']['gateway'] = ng['gateway']
for key, value in network_configuration['neutron_parameters'] \
.items():
setattr(cluster.neutron_config, key, value)
db().add(cluster.neutron_config)
db().flush()
def generate_l3(cls, cluster):
return {
"use_namespaces": True
}
@classmethod
def generate_vlan_ids_list(cls, data, cluster, ng):
if ng.get("name") == "private":
if "neutron_parameters" in data:
l2params = data["neutron_parameters"]["L2"]
if data.get("networking_parameters", {}).get("vlan_range"):
vlan_range = data["networking_parameters"]["vlan_range"]
else:
l2params = cluster.neutron_config.L2
vlan_range = l2params["phys_nets"]["physnet2"]["vlan_range"]
vlan_range = cluster.network_config.vlan_range
return range(vlan_range[0], vlan_range[1] + 1)
return [int(ng.get("vlan_start"))] if ng.get("vlan_start") else []

View File

@ -15,32 +15,32 @@
# under the License.
from nailgun.db import db
from nailgun.db.sqlalchemy.models import NovaNetworkConfig
from nailgun.network.manager import NetworkManager
class NovaNetworkManager(NetworkManager):
@classmethod
def update(cls, cluster, network_configuration):
cls.update_networks(cluster, network_configuration)
if 'net_manager' in network_configuration:
setattr(
cluster,
'net_manager',
network_configuration['net_manager']
)
if 'dns_nameservers' in network_configuration:
setattr(
cluster,
'dns_nameservers',
network_configuration['dns_nameservers']['nameservers']
)
db().commit()
def create_nova_network_config(cls, cluster):
nova_net_config = NovaNetworkConfig(
cluster_id=cluster.id,
)
db().add(nova_net_config)
meta = cluster.release.networks_metadata["nova_network"]["config"]
for key, value in meta.iteritems():
if hasattr(nova_net_config, key):
setattr(nova_net_config, key, value)
db().flush()
@classmethod
def generate_vlan_ids_list(cls, data, cluster, ng):
if ng["name"] == "fixed":
netw_params = data.get("networking_parameters", {})
start = netw_params.get("fixed_networks_vlan_start")
amount = netw_params.get("fixed_networks_amount")
if start and amount:
return range(int(start), int(start) + int(amount))
if ng.get("vlan_start") is None:
return []
return range(int(ng.get("vlan_start")),
int(ng.get("vlan_start")) + int(ng.get("amount")))
return [int(ng.get("vlan_start"))]

View File

@ -97,24 +97,11 @@ class Cluster(NailgunObject):
"type": "string",
"enum": list(consts.CLUSTER_NET_PROVIDERS)
},
"net_l23_provider": {
"type": "string",
"enum": list(consts.CLUSTER_NET_L23_PROVIDERS)
},
"net_segment_type": {
"type": "string",
"enum": list(consts.CLUSTER_NET_SEGMENT_TYPES)
},
"net_manager": {
"type": "string",
"enum": list(consts.CLUSTER_NET_MANAGERS)
},
"grouping": {
"type": "string",
"enum": list(consts.CLUSTER_GROUPING)
},
"release_id": {"type": "number"},
"dns_nameservers": {"type": "array"},
"replaced_deployment_info": {"type": "object"},
"replaced_provisioning_info": {"type": "object"},
"is_customized": {"type": "boolean"}
@ -134,12 +121,9 @@ class Cluster(NailgunObject):
cls.create_attributes(new_cluster)
netmanager = cls.get_network_manager(new_cluster)
try:
netmanager.create_network_groups(new_cluster.id)
if new_cluster.net_provider == 'neutron':
netmanager.create_neutron_config(new_cluster)
cls.get_network_manager(new_cluster).\
create_network_groups_and_config(new_cluster, data)
cls.add_pending_changes(new_cluster, "attributes")
cls.add_pending_changes(new_cluster, "networks")

View File

@ -402,7 +402,6 @@ class NetworkDeploymentSerializer(object):
attrs[net_name] = cls.get_ip_ranges_first_last(net)
elif net.meta.get("render_type") == 'cidr' and net.cidr:
attrs[net_name] = net.cidr
return attrs
@classmethod
@ -450,8 +449,15 @@ class NovaNetworkDeploymentSerializer(NetworkDeploymentSerializer):
@classmethod
def network_provider_cluster_attrs(cls, cluster):
return {'novanetwork_parameters': cls.novanetwork_attrs(cluster),
'dns_nameservers': cluster.dns_nameservers}
return {
'novanetwork_parameters': cls.novanetwork_attrs(cluster),
'dns_nameservers': cluster.network_config.dns_nameservers,
'fixed_network_range': cluster.network_config.fixed_networks_cidr,
'floating_network_range': [
"{0}-{1}".format(ip_range[0], ip_range[1])
for ip_range in cluster.network_config.floating_ranges
]
}
@classmethod
def network_provider_node_attrs(cls, cluster, node):
@ -459,11 +465,11 @@ class NovaNetworkDeploymentSerializer(NetworkDeploymentSerializer):
interfaces = cls.configure_interfaces(node)
cls.__add_hw_interfaces(interfaces, node.meta['interfaces'])
# Interfaces assingment
# Interfaces assignment
attrs = {'network_data': interfaces}
attrs.update(cls.interfaces_list(network_data))
if cluster.net_manager == 'VlanManager':
if cluster.network_config.net_manager == 'VlanManager':
attrs.update(cls.add_vlan_interfaces(node))
return attrs
@ -472,17 +478,16 @@ class NovaNetworkDeploymentSerializer(NetworkDeploymentSerializer):
def novanetwork_attrs(cls, cluster):
"""Network configuration
"""
attrs = {'network_manager': cluster.net_manager}
fixed_net = db().query(NetworkGroup).filter_by(
cluster_id=cluster.id).filter_by(name='fixed').first()
attrs = {'network_manager': cluster.network_config.net_manager}
# network_size is required for all managers, otherwise
# puppet will use default (255)
attrs['network_size'] = fixed_net.network_size
attrs['network_size'] = cluster.network_config.fixed_network_size
if attrs['network_manager'] == 'VlanManager':
attrs['num_networks'] = fixed_net.amount
attrs['vlan_start'] = fixed_net.vlan_start
attrs['num_networks'] = \
cluster.network_config.fixed_networks_amount
attrs['vlan_start'] = \
cluster.network_config.fixed_networks_vlan_start
return attrs
@ -508,30 +513,23 @@ class NovaNetworkDeploymentSerializer(NetworkDeploymentSerializer):
for network in network_data:
network_name = network['name']
# floating and public are on the same interface
# so, just skip floating
if network_name == 'floating':
continue
name = cls.__make_interface_name(network.get('dev'),
network.get('vlan'))
interfaces.setdefault(name, {'interface': name, 'ipaddr': []})
interface = interfaces[name]
if network.get('ip'):
interface['ipaddr'].append(network.get('ip'))
# Add gateway for public
if network_name == 'admin':
admin_ip_addr = cls.get_admin_ip_w_prefix(node)
interface['ipaddr'].append(admin_ip_addr)
elif network_name == 'public' and network.get('gateway'):
interface['gateway'] = network['gateway']
if len(interface['ipaddr']) == 0:
interface['ipaddr'] = 'none'
for if_name, if_data in interfaces.iteritems():
if len(if_data['ipaddr']) == 0:
if_data['ipaddr'] = 'none'
interfaces['lo'] = {'interface': 'lo', 'ipaddr': ['127.0.0.1/8']}
@ -563,11 +561,12 @@ class NovaNetworkDeploymentSerializer(NetworkDeploymentSerializer):
"""
interfaces = {}
for network in network_data:
interfaces['%s_interface' % network['name']] = \
cls.__make_interface_name(
network.get('dev'),
network.get('vlan'))
if_name = cls.__make_interface_name(
network.get('dev'),
network.get('vlan'))
interfaces['%s_interface' % network['name']] = if_name
if network['name'] == 'public':
interfaces['floating_interface'] = if_name
return interfaces
@ -611,77 +610,14 @@ class NeutronNetworkDeploymentSerializer(NetworkDeploymentSerializer):
def neutron_attrs(cls, cluster):
"""Network configuration for Neutron
"""
nm = objects.Cluster.get_network_manager(cluster)
attrs = {}
neutron_config = cluster.neutron_config
attrs['L3'] = neutron_config.L3 or {
'use_namespaces': True
}
attrs['L2'] = neutron_config.L2
attrs['L2']['segmentation_type'] = neutron_config.segmentation_type
join_range = lambda r: (":".join(map(str, r)) if r else None)
for net, net_conf in attrs['L2']['phys_nets'].iteritems():
net_conf['vlan_range'] = join_range(
net_conf['vlan_range']
)
attrs['L2']['phys_nets'][net] = net_conf
if attrs['L2'].get('tunnel_id_ranges'):
attrs['L2']['tunnel_id_ranges'] = join_range(
attrs['L2']['tunnel_id_ranges']
)
attrs['predefined_networks'] = neutron_config.predefined_networks
nets_l2_configs = {
"net04_ext": {
"network_type": "flat",
"segment_id": None,
"router_ext": True,
"physnet": "physnet1"
},
"net04": {
"network_type": cluster.net_segment_type,
"segment_id": None,
"router_ext": False,
"physnet": "physnet2"
if cluster.net_segment_type == "vlan" else None
}
}
pub = filter(lambda ng: ng.name == 'public', cluster.network_groups)[0]
for net, net_conf in attrs['predefined_networks'].iteritems():
cidr = net_conf["L3"].pop("cidr")
if net == "net04_ext":
net_conf["L3"]["subnet"] = pub.cidr
if pub.gateway:
net_conf["L3"]["gateway"] = pub.gateway
else:
net_conf["L3"]["gateway"] = str(IPNetwork(pub.cidr)[1])
else:
net_conf["L3"]["subnet"] = cidr
if not net_conf["L3"]["gateway"]:
net_conf["L3"]["gateway"] = str(IPNetwork(cidr)[1])
net_conf["L3"]["floating"] = join_range(
net_conf["L3"]["floating"]
)
enable_dhcp = False if net == "net04_ext" else True
net_conf['L3']['enable_dhcp'] = enable_dhcp
net_conf["L2"] = nets_l2_configs[net]
net_conf['tenant'] = 'admin'
net_conf["shared"] = False
attrs['predefined_networks'][net] = net_conf
attrs['L3'] = nm.generate_l3(cluster)
attrs['L2'] = nm.generate_l2(cluster)
attrs['predefined_networks'] = nm.generate_predefined_networks(cluster)
if cluster.release.operating_system == 'RHEL':
if 'amqp' not in attrs:
attrs['amqp'] = {}
elif not isinstance(attrs.get('amqp'), dict):
# FIXME Raise some meaningful exception.
pass
attrs['amqp']['provider'] = 'qpid-rh'
attrs['amqp'] = {'provider': 'qpid-rh'}
return attrs
@ -799,7 +735,7 @@ class NeutronNetworkDeploymentSerializer(NetworkDeploymentSerializer):
logger.error('Invalid vlan for network: %s' % str(netgroup))
# Dance around Neutron segmentation type.
if node.cluster.net_segment_type == 'vlan':
if node.cluster.network_config.segmentation_type == 'vlan':
attrs['endpoints']['br-prv'] = {'IP': 'none'}
attrs['roles']['private'] = 'br-prv'
@ -818,14 +754,8 @@ class NeutronNetworkDeploymentSerializer(NetworkDeploymentSerializer):
'br-prv'
]
})
elif node.cluster.net_segment_type == 'gre':
elif node.cluster.network_config.segmentation_type == 'gre':
attrs['roles']['mesh'] = 'br-mgmt'
else:
# FIXME! Should raise some exception I think.
logger.error(
'Invalid Neutron segmentation type: %s' %
node.cluster.net_segment_type
)
return attrs
@ -842,9 +772,7 @@ class NeutronNetworkDeploymentSerializer(NetworkDeploymentSerializer):
if use_vlan_splinters == 'hard':
for ng in iface.assigned_networks_list:
if ng.name == 'private':
vlan_range = cluster.neutron_config.L2.get(
"phys_nets", {}
).get("physnet2", {}).get("vlan_range", ())
vlan_range = cluster.network_config.vlan_range
trunks.extend(xrange(*vlan_range))
trunks.append(vlan_range[1])
else:

View File

@ -17,6 +17,7 @@
"""Provisioning serializers for orchestrator"""
from nailgun import objects
import netaddr
from nailgun.logger import logger
from nailgun.settings import settings
@ -104,7 +105,9 @@ class ProvisioningSerializer(object):
interfaces_extra = {}
net_manager = objects.Node.get_network_manager(node)
admin_ip = net_manager.get_admin_ip_for_node(node)
admin_netmask = net_manager.get_admin_network_group().netmask
admin_netmask = str(netaddr.IPNetwork(
net_manager.get_admin_network_group().cidr
).netmask)
for interface in node.nic_interfaces:
name = interface.name

View File

@ -29,7 +29,6 @@ DATABASE:
# changes should be made in database if required
ADMIN_NETWORK:
cidr: "10.20.0.0/24"
netmask: "255.255.255.0"
size: "256"
first: "10.20.0.129"
last: "10.20.0.254"

View File

@ -18,6 +18,7 @@ from copy import deepcopy
from itertools import izip
import json
from mock import patch
import netaddr
import nailgun
@ -69,8 +70,8 @@ class TestHandlers(BaseIntegrationTest):
'network_size': 256
},
'dns_nameservers': [
"8.8.8.8",
"8.8.4.4"
"8.8.4.4",
"8.8.8.8"
],
'management_interface': 'eth0.101',
@ -275,7 +276,8 @@ class TestHandlers(BaseIntegrationTest):
pnd['interfaces'][i.name]['dns_name'] = n.fqdn
pnd['interfaces_extra'][i.name]['onboot'] = 'yes'
pnd['interfaces'][i.name]['ip_address'] = admin_ip
pnd['interfaces'][i.name]['netmask'] = admin_net.netmask
pnd['interfaces'][i.name]['netmask'] = str(
netaddr.IPNetwork(admin_net.cidr).netmask)
provision_nodes.append(pnd)
@ -641,7 +643,8 @@ class TestHandlers(BaseIntegrationTest):
pnd['interfaces'][i['name']]['dns_name'] = n.fqdn
pnd['interfaces_extra'][i['name']]['onboot'] = 'yes'
pnd['interfaces'][i['name']]['ip_address'] = admin_ip
pnd['interfaces'][i['name']]['netmask'] = admin_net.netmask
pnd['interfaces'][i['name']]['netmask'] = str(
netaddr.IPNetwork(admin_net.cidr).netmask)
provision_nodes.append(pnd)
@ -819,10 +822,10 @@ class TestHandlers(BaseIntegrationTest):
pub = filter(lambda ng: ng['name'] == 'public',
net_data['networks'])[0]
pub.update({'ip_ranges': [['172.16.10.10', '172.16.10.122']],
'cidr': '172.16.10.0/24',
'gateway': '172.16.10.1'})
virt_nets = net_data['neutron_parameters']['predefined_networks']
virt_nets['net04_ext']['L3']['floating'] = ['172.16.10.130',
'172.16.10.254']
net_data['networking_parameters']['floating_ranges'] = \
[['172.16.10.130', '172.16.10.254']]
resp = self.env.neutron_networks_put(self.env.clusters[0].id, net_data)
self.assertEquals(resp.status_code, 202)
@ -888,6 +891,7 @@ class TestHandlers(BaseIntegrationTest):
net_data = {
"networks": [{
'id': public_network.id,
'cidr': '220.0.1.0/24',
'gateway': '220.0.1.1',
'ip_ranges': [[
'220.0.1.2',

View File

@ -79,14 +79,11 @@ class TestHandlers(BaseIntegrationTest):
{
"networks": [
{
"network_size": 65536,
"name": "management",
"ip_ranges": [
["192.168.0.2", "192.168.255.254"]
],
"amount": 1,
"id": management_net.id,
"netmask": "255.255.255.0",
"cluster_id": clstr.id,
"vlan_start": 101,
"cidr": "192.168.0.0/16",
@ -165,13 +162,6 @@ class TestHandlers(BaseIntegrationTest):
'gateway': net.gateway
})
expected = [
{
'release': release.id,
'name': u'floating',
'vlan_id': None,
'cidr': '172.16.0.0/24',
'gateway': None
},
{
'release': release.id,
'name': u'public',
@ -182,9 +172,9 @@ class TestHandlers(BaseIntegrationTest):
{
'release': release.id,
'name': u'fixed',
'vlan_id': 103,
'cidr': '10.0.0.0/16',
'gateway': '10.0.0.1'
'vlan_id': None,
'cidr': None,
'gateway': None
},
{
'release': release.id,

View File

@ -85,18 +85,6 @@ class TestHandlers(BaseIntegrationTest):
clusters_after = len(self.db.query(Cluster).all())
self.assertEquals(clusters_before, clusters_after)
def test_cluster_updates_network_manager(self):
cluster = self.env.create_cluster(api=False)
self.assertEquals(cluster.net_manager, "FlatDHCPManager")
resp = self.app.put(
reverse('ClusterHandler', kwargs={'obj_id': cluster.id}),
json.dumps({'net_manager': 'VlanManager'}),
headers=self.default_headers
)
self.assertEquals(resp.status_code, 200)
self.db.refresh(cluster)
self.assertEquals(cluster.net_manager, "VlanManager")
def test_cluster_update_fails_on_net_provider_change(self):
cluster = self.env.create_cluster(api=False)
self.assertEquals(cluster.net_provider, "nova_network")
@ -112,25 +100,6 @@ class TestHandlers(BaseIntegrationTest):
"Changing 'net_provider' for environment is prohibited"
)
def test_cluster_update_fails_on_net_segment_type_change(self):
cluster = self.env.create_cluster(
api=False,
net_provider='neutron',
net_segment_type='gre'
)
self.assertEquals(cluster.net_provider, "neutron")
resp = self.app.put(
reverse('ClusterHandler', kwargs={'obj_id': cluster.id}),
json.dumps({'net_segment_type': 'vlan'}),
headers=self.default_headers,
expect_errors=True
)
self.assertEquals(resp.status_code, 400)
self.assertEquals(
resp.body,
"Changing 'net_segment_type' for environment is prohibited"
)
def test_cluster_node_list_update(self):
node1 = self.env.create_node(api=False)
node2 = self.env.create_node(api=False)

View File

@ -37,15 +37,14 @@ class TestNovaNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
data = json.loads(response.body)
cluster = self.db.query(Cluster).get(self.cluster.id)
self.assertEquals(data['net_manager'], self.cluster.net_manager)
self.assertEquals(data['networking_parameters']['net_manager'],
self.cluster.network_config.net_manager)
for network_group in cluster.network_groups:
network = [i for i in data['networks']
if i['id'] == network_group.id][0]
keys = [
'network_size',
'name',
'amount',
'cluster_id',
'vlan_start',
'cidr',
@ -60,18 +59,23 @@ class TestNovaNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
self.assertEquals(404, resp.status_code)
def test_change_net_manager(self):
new_net_manager = {'net_manager': 'VlanManager'}
self.assertEquals(self.cluster.network_config.net_manager,
'FlatDHCPManager')
new_net_manager = {
'networking_parameters': {'net_manager': 'VlanManager'}
}
self.env.nova_networks_put(self.cluster.id, new_net_manager)
self.db.refresh(self.cluster)
self.assertEquals(
self.cluster.net_manager,
new_net_manager['net_manager'])
self.cluster.network_config.net_manager,
new_net_manager['networking_parameters']['net_manager'])
def test_change_dns_nameservers(self):
new_dns_nameservers = {
'dns_nameservers': {
"nameservers": [
'networking_parameters': {
'dns_nameservers': [
"208.67.222.222",
"208.67.220.220"
]
@ -81,8 +85,8 @@ class TestNovaNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
self.db.refresh(self.cluster)
self.assertEquals(
self.cluster.dns_nameservers,
new_dns_nameservers['dns_nameservers']['nameservers']
self.cluster.network_config.dns_nameservers,
new_dns_nameservers['networking_parameters']['dns_nameservers']
)
def test_refresh_mask_on_cidr_change(self):
@ -93,7 +97,6 @@ class TestNovaNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
if n['name'] == 'management'][0]
cidr = mgmt['cidr'].partition('/')[0] + '/25'
mgmt['cidr'] = cidr
mgmt['network_size'] = 128
resp = self.env.nova_networks_put(self.cluster.id, data)
self.assertEquals(resp.status_code, 202)
@ -104,7 +107,6 @@ class TestNovaNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
mgmt_ng = [ng for ng in self.cluster.network_groups
if ng.name == 'management'][0]
self.assertEquals(mgmt_ng.cidr, cidr)
self.assertEquals(mgmt_ng.netmask, '255.255.255.128')
def test_wrong_net_provider(self):
resp = self.app.put(
@ -122,15 +124,17 @@ class TestNovaNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
)
def test_do_not_update_net_manager_if_validation_is_failed(self):
new_net_manager = {'net_manager': 'VlanManager',
'networks': [{'id': 500, 'vlan_start': 500}]}
new_net_manager = {
'networking_parameters': {'net_manager': 'VlanManager'},
'networks': [{'id': 500, 'vlan_start': 500}]
}
self.env.nova_networks_put(self.cluster.id, new_net_manager,
expect_errors=True)
self.db.refresh(self.cluster)
self.assertNotEquals(
self.cluster.net_manager,
new_net_manager['net_manager'])
self.cluster.network_config.net_manager,
new_net_manager['networking_parameters']['net_manager'])
def test_network_group_update_changes_network(self):
network = self.db.query(NetworkGroup).filter(
@ -144,7 +148,6 @@ class TestNovaNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
resp = self.env.nova_networks_put(self.cluster.id, new_nets)
self.assertEquals(resp.status_code, 202)
self.db.refresh(network)
self.assertEquals(network.amount, 1)
self.assertEquals(network.vlan_start, 500)
def test_update_networks_and_net_manager(self):
@ -152,15 +155,15 @@ class TestNovaNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
not_(NetworkGroup.name == "fuelweb_admin")
).first()
new_vlan_id = 500 # non-used vlan id
new_net = {'net_manager': 'VlanManager',
new_net = {'networking_parameters': {'net_manager': 'VlanManager'},
'networks': [{'id': network.id, 'vlan_start': new_vlan_id}]}
self.env.nova_networks_put(self.cluster.id, new_net)
self.db.refresh(self.cluster)
self.db.refresh(network)
self.assertEquals(
self.cluster.net_manager,
new_net['net_manager'])
self.cluster.network_config.net_manager,
new_net['networking_parameters']['net_manager'])
self.assertEquals(network.vlan_start, new_vlan_id)
def test_networks_update_fails_with_wrong_net_id(self):
@ -181,7 +184,7 @@ class TestNovaNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
resp = self.env.nova_networks_get(self.cluster.id)
data = json.loads(resp.body)
for net in data['networks']:
if net['name'] in ('fuelweb_admin', 'public', 'floating'):
if net['name'] in ('fuelweb_admin', 'public', 'fixed'):
self.assertIsNone(net['vlan_start'])
else:
self.assertIsNotNone(net['vlan_start'])
@ -257,18 +260,14 @@ class TestNeutronNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
data = json.loads(response.body)
cluster = self.db.query(Cluster).get(self.cluster.id)
self.assertEquals(data['net_provider'],
self.cluster.net_provider)
self.assertEquals(data['net_segment_type'],
self.cluster.net_segment_type)
self.assertEquals(data['networking_parameters']['segmentation_type'],
self.cluster.network_config.segmentation_type)
for network_group in cluster.network_groups:
network = [i for i in data['networks']
if i['id'] == network_group.id][0]
keys = [
'network_size',
'name',
'amount',
'cluster_id',
'vlan_start',
'cidr',
@ -297,7 +296,6 @@ class TestNeutronNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
if n['name'] == 'management'][0]
cidr = mgmt['cidr'].partition('/')[0] + '/25'
mgmt['cidr'] = cidr
mgmt['network_size'] = 128
resp = self.env.neutron_networks_put(self.cluster.id, data)
self.assertEquals(202, resp.status_code)
@ -308,12 +306,11 @@ class TestNeutronNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
mgmt_ng = [ng for ng in self.cluster.network_groups
if ng.name == 'management'][0]
self.assertEquals(mgmt_ng.cidr, cidr)
self.assertEquals(mgmt_ng.netmask, '255.255.255.128')
def test_do_not_update_net_segmentation_type(self):
resp = self.env.neutron_networks_get(self.cluster.id)
data = json.loads(resp.body)
data['neutron_parameters']['segmentation_type'] = 'vlan'
data['networking_parameters']['segmentation_type'] = 'vlan'
resp = self.env.neutron_networks_put(self.cluster.id, data,
expect_errors=True)
@ -337,7 +334,6 @@ class TestNeutronNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
self.assertEquals(resp.status_code, 202)
self.db.refresh(network)
self.assertEquals(network.amount, 1)
self.assertEquals(network.vlan_start, 500)
def test_update_networks_fails_if_change_net_segmentation_type(self):
@ -347,7 +343,7 @@ class TestNeutronNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
self.assertIsNotNone(network)
data['networks'][0]['vlan_start'] = 500 # non-used vlan id
data['neutron_parameters']['segmentation_type'] = 'vlan'
data['networking_parameters']['segmentation_type'] = 'vlan'
resp = self.env.neutron_networks_put(self.cluster.id, data,
expect_errors=True)
@ -374,17 +370,17 @@ class TestNeutronNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
'Invalid network ID: 500'
)
def test_refresh_public_cidr_on_range_gw_change(self):
def test_refresh_public_cidr_on_its_change(self):
data = json.loads(self.env.neutron_networks_get(self.cluster.id).body)
publ = filter(lambda ng: ng['name'] == 'public', data['networks'])[0]
self.assertEquals(publ['cidr'], '172.16.0.0/24')
publ['cidr'] = '199.61.0.0/24'
publ['gateway'] = '199.61.0.1'
publ['ip_ranges'] = [['199.61.0.11', '199.61.0.33'],
['199.61.0.55', '199.61.0.99']]
virt_nets = data['neutron_parameters']['predefined_networks']
virt_nets['net04_ext']['L3']['floating'] = ['199.61.0.111',
'199.61.0.122']
data['networking_parameters']['floating_ranges'] = \
[['199.61.0.111', '199.61.0.122']]
resp = self.env.neutron_networks_put(self.cluster.id, data)
self.assertEquals(202, resp.status_code)
@ -396,41 +392,6 @@ class TestNeutronNetworkConfigurationHandlerMultinode(BaseIntegrationTest):
self.cluster.network_groups)[0]
self.assertEquals(publ_ng.cidr, '199.61.0.0/24')
def test_refresh_public_cidr_on_netmask_change(self):
data = json.loads(self.env.neutron_networks_get(self.cluster.id).body)
publ = filter(lambda ng: ng['name'] == 'public', data['networks'])[0]
self.assertEquals(publ['cidr'], '172.16.0.0/24')
publ['netmask'] = '255.255.252.0'
resp = self.env.neutron_networks_put(self.cluster.id, data)
self.assertEquals(202, resp.status_code)
task = json.loads(resp.body)
self.assertEquals(task['status'], 'ready')
self.db.refresh(self.cluster)
publ_ng = filter(lambda ng: ng.name == 'public',
self.cluster.network_groups)[0]
self.assertEquals(publ_ng.cidr, '172.16.0.0/22')
def test_do_not_refresh_public_cidr_on_its_change(self):
data = json.loads(self.env.neutron_networks_get(self.cluster.id).body)
publ = filter(lambda ng: ng['name'] == 'public', data['networks'])[0]
self.assertEquals(publ['cidr'], '172.16.0.0/24')
publ['cidr'] = '199.61.39.160/28'
# it is OK as public CIDR is ignored and nothing else is changed
resp = self.env.neutron_networks_put(self.cluster.id, data)
self.assertEquals(202, resp.status_code)
task = json.loads(resp.body)
self.assertEquals(task['status'], 'ready')
self.db.refresh(self.cluster)
publ_ng = filter(lambda ng: ng.name == 'public',
self.cluster.network_groups)[0]
self.assertEquals(publ_ng.cidr, '172.16.0.0/24')
def test_admin_public_untagged_others_tagged(self):
resp = self.env.neutron_networks_get(self.cluster.id)
data = json.loads(resp.body)
@ -497,7 +458,6 @@ class TestAdminNetworkConfiguration(BaseIntegrationTest):
@patch('nailgun.db.sqlalchemy.fixman.settings.ADMIN_NETWORK', {
"cidr": "192.168.0.0/24",
"netmask": "255.255.255.0",
"size": "256",
"first": "192.168.0.129",
"last": "192.168.0.254"

View File

@ -35,7 +35,6 @@ from nailgun.network.neutron import NeutronManager
from nailgun.network.nova_network import NovaNetworkManager
from nailgun.test.base import BaseIntegrationTest
from nailgun.test.base import fake_tasks
from nailgun.test.base import reverse
class TestNetworkManager(BaseIntegrationTest):
@ -150,18 +149,16 @@ class TestNetworkManager(BaseIntegrationTest):
{"pending_addition": True},
]
)
networks_data = {'net_manager': 'VlanManager'}
self.app.put(
reverse('NovaNetworkConfigurationHandler',
kwargs={"cluster_id": cluster['id']}),
json.dumps(networks_data),
headers=self.default_headers
)
networks_data = \
{'networking_parameters': {'net_manager': 'VlanManager'}}
resp = self.env.nova_networks_put(cluster['id'], networks_data)
task = json.loads(resp.body)
self.assertEquals(task['status'], 'ready')
network_data = self.env.network_manager.get_node_networks(
self.env.nodes[0].id
)
self.assertEquals(len(network_data), 5)
self.assertEquals(len(network_data), 4)
fixed_nets = filter(lambda net: net['name'] == 'fixed', network_data)
self.assertEquals(fixed_nets, [])
@ -220,12 +217,12 @@ class TestNetworkManager(BaseIntegrationTest):
networks = self.env.network_manager.get_networks_grouped_by_cluster()
self.assertTrue(isinstance(networks, dict))
self.assertIn(cluster['id'], networks)
self.assertEqual(len(networks[cluster['id']]), 5)
self.assertEqual(len(networks[cluster['id']]), 4)
networks_keys = (n.name for n in networks[cluster['id']])
# NetworkGroup.names[1:6] - all except fuel_admin and private
# private is not used with NovaNetwork
self.assertEqual(sorted(networks_keys),
sorted(NetworkGroup.NAMES[1:6]))
sorted(NetworkGroup.NAMES[1:5]))
def test_group_by_key_and_history_util(self):
"""Verifies that grouping util will return defaultdict(list) with

View File

@ -16,6 +16,12 @@
import json
from nailgun.api.serializers.network_configuration \
import NeutronNetworkConfigurationSerializer
from nailgun.api.serializers.network_configuration \
import NovaNetworkConfigurationSerializer
from nailgun.db.sqlalchemy.models import NeutronConfig
from nailgun.db.sqlalchemy.models import NovaNetworkConfig
from nailgun.test.base import BaseIntegrationTest
from nailgun.test.base import fake_tasks
from nailgun.test.base import reverse
@ -70,3 +76,54 @@ class TestNetworkModels(BaseIntegrationTest):
# it's 400 because we used Nova network
self.assertEquals(resp_neutron_net.status_code, 400)
self.assertEquals(resp_cluster.status_code, 403)
def test_nova_net_networking_parameters(self):
cluster = self.env.create_cluster(api=False)
self.db.delete(cluster.network_config)
kw = {
"net_manager": "VlanManager",
"fixed_networks_cidr": "10.0.0.0/16",
"fixed_networks_vlan_start": 103,
"fixed_network_size": 256,
"fixed_networks_amount": 16,
"floating_ranges": [["172.16.0.128", "172.16.0.254"]],
"dns_nameservers": ["8.8.4.4", "8.8.8.8"],
"cluster_id": cluster.id
}
nc = NovaNetworkConfig(**kw)
self.db.add(nc)
self.db.flush()
self.db.refresh(cluster)
nw_params = NovaNetworkConfigurationSerializer.\
serialize_network_params(cluster)
kw.pop("cluster_id")
self.assertEquals(nw_params, kw)
def test_neutron_networking_parameters(self):
cluster = self.env.create_cluster(api=False,
net_provider='neutron')
self.db.delete(cluster.network_config)
kw = {
"net_l23_provider": "ovs",
"segmentation_type": "gre",
"vlan_range": [1000, 1030],
"gre_id_range": [2, 65534],
"base_mac": "fa:16:3e:00:00:00",
"internal_cidr": "192.168.111.0/24",
"internal_gateway": "192.168.111.1",
"floating_ranges": [["172.16.0.130", "172.16.0.254"]],
"dns_nameservers": ["8.8.4.4", "8.8.8.8"],
"cluster_id": cluster.id
}
nc = NeutronConfig(**kw)
self.db.add(nc)
self.db.flush()
self.db.refresh(cluster)
nw_params = NeutronNetworkConfigurationSerializer. \
serialize_network_params(cluster)
kw.pop("cluster_id")
self.assertEquals(nw_params, kw)

View File

@ -18,9 +18,11 @@ import json
from netaddr import IPAddress
from netaddr import IPNetwork
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.test.base import BaseIntegrationTest
from nailgun.test.base import reverse
class TestNetworkChecking(BaseIntegrationTest):
@ -30,12 +32,16 @@ class TestNetworkChecking(BaseIntegrationTest):
if net['name'] == name:
return net
def check_result_format(self, task):
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)
@ -52,7 +58,7 @@ class TestNetworkChecking(BaseIntegrationTest):
self.assertEquals(task['status'], 'error')
self.assertEquals(task['progress'], 100)
self.assertEquals(task['name'], 'deploy')
self.check_result_format(task)
self.check_result_format(task, cluster_id)
return task
def update_nova_networks_w_error(self, cluster_id, nets):
@ -63,7 +69,7 @@ class TestNetworkChecking(BaseIntegrationTest):
self.assertEquals(task['status'], 'error')
self.assertEquals(task['progress'], 100)
self.assertEquals(task['name'], 'check_networks')
self.check_result_format(task)
self.check_result_format(task, cluster_id)
return task
def update_nova_networks_success(self, cluster_id, nets):
@ -83,7 +89,7 @@ class TestNetworkChecking(BaseIntegrationTest):
self.assertEquals(task['status'], 'error')
self.assertEquals(task['progress'], 100)
self.assertEquals(task['name'], 'check_networks')
self.check_result_format(task)
self.check_result_format(task, cluster_id)
return task
def update_neutron_networks_success(self, cluster_id, nets):
@ -126,7 +132,8 @@ class TestNovaHandlers(TestNetworkChecking):
def test_network_checking_fails_if_admin_intersection(self):
admin_ng = self.env.network_manager.get_admin_network_group()
self.find_net_by_name('fixed')["cidr"] = admin_ng.cidr
self.nets['networking_parameters']["fixed_networks_cidr"] = \
admin_ng.cidr
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertIn(
@ -138,30 +145,16 @@ class TestNovaHandlers(TestNetworkChecking):
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)
self.find_net_by_name('floating')['ip_ranges'] = [
[str(IPAddress(cidr.first + 2)), str(IPAddress(cidr.last))]
]
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.assertIn(
"Address space intersection between networks:\n",
self.assertEquals(
"Address space intersection between floating range '{0}-{1}' and "
"'admin (PXE)' network.".format(flt_r0, flt_r1),
task['message'])
self.assertIn("admin (PXE)", task['message'])
self.assertIn("floating", task['message'])
def test_fails_if_netmask_for_public_network_not_set_or_not_valid(self):
net_without_netmask = self.find_net_by_name('public')
net_with_invalid_netmask = self.find_net_by_name('public')
net_without_netmask['netmask'] = None
net_with_invalid_netmask['netmask'] = '255.255.255.2'
for net in [net_without_netmask, net_with_invalid_netmask]:
task = self.update_nova_networks_w_error(self.cluster.id,
{'networks': [net]})
self.assertEquals(
task['message'],
'Invalid gateway or netmask for public network')
def test_network_checking_fails_if_networks_cidr_intersection(self):
self.find_net_by_name('management')["cidr"] = \
@ -191,7 +184,7 @@ class TestNovaHandlers(TestNetworkChecking):
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')["netmask"] = '255.255.255.0'
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)
@ -205,19 +198,20 @@ class TestNovaHandlers(TestNetworkChecking):
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('floating')["ip_ranges"] = \
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')["netmask"] = '255.255.255.0'
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.143'],
['192.18.17.129', '192.18.17.190']]
[['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.assertEquals(
@ -230,7 +224,7 @@ class TestNovaHandlers(TestNetworkChecking):
[['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')["netmask"] = '255.255.255.0'
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.assertEquals(
@ -243,7 +237,7 @@ class TestNovaHandlers(TestNetworkChecking):
[['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')["netmask"] = '255.255.255.0'
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.assertEquals(
@ -264,9 +258,9 @@ class TestNovaHandlers(TestNetworkChecking):
)
def test_network_checking_fails_if_floating_ranges_intersection(self):
self.find_net_by_name('floating')["ip_ranges"] = \
[['192.18.17.65', '192.18.17.143'],
['192.18.17.129', '192.18.17.190']]
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.assertEquals(
@ -275,9 +269,9 @@ class TestNovaHandlers(TestNetworkChecking):
)
def test_network_checking_fails_if_amount_flatdhcp(self):
net = self.find_net_by_name('fixed')
net["amount"] = 2
net["cidr"] = "10.10.0.0/23"
self.nets['networking_parameters']['fixed_networks_amount'] = 2
self.nets['networking_parameters']['fixed_networks_cidr'] = \
"10.10.0.0/23"
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEquals(
@ -299,10 +293,11 @@ class TestNovaHandlers(TestNetworkChecking):
self.assertIn("public", task['message'])
def test_network_checking_fails_if_vlan_id_in_fixed_vlan_range(self):
self.nets['net_manager'] = 'VLANManager'
self.nets['networking_parameters']['net_manager'] = 'VLANManager'
self.find_net_by_name('public')["vlan_start"] = 1111
self.find_net_by_name('fixed')["vlan_start"] = 1100
self.find_net_by_name('fixed')["amount"] = 20
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(
@ -321,77 +316,16 @@ class TestNovaHandlers(TestNetworkChecking):
"VLAN ID(s) is out of range for public network."
)
def test_network_checking_fails_if_public_floating_vlan_not_equal(self):
self.find_net_by_name('public')["vlan_start"] = 111
self.find_net_by_name('floating')["vlan_start"] = 112
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertIn(
" networks don't use the same VLAN ID(s). "
"These networks must use the same VLAN ID(s).",
task['message']
)
self.assertIn("floating", task['message'])
self.assertIn("public", task['message'])
def test_network_checking_fails_if_public_floating_not_on_one_nic(self):
self.find_net_by_name('public')["vlan_start"] = 111
self.find_net_by_name('floating')["vlan_start"] = 111
self.update_nova_networks_success(self.cluster.id, self.nets)
mac = self.env.generate_random_mac()
meta = self.env.default_metadata()
self.env.set_interfaces_in_meta(
meta,
[{'name': 'eth0', 'mac': mac},
{'name': 'eth1', 'mac': self.env.generate_random_mac()},
{'name': 'eth2', 'mac': self.env.generate_random_mac()}]
)
node = self.env.create_node(api=True, meta=meta, mac=mac)
resp = self.app.put(
reverse('NodeCollectionHandler'),
json.dumps([{'id': node['id'], 'cluster_id': self.cluster.id}]),
headers=self.default_headers
)
self.assertEquals(resp.status_code, 200)
resp = self.app.get(reverse('NodeNICsHandler',
kwargs={'node_id': node['id']}),
headers=self.default_headers)
nics = json.loads(resp.body)
for nic in nics:
if not nic.get('assigned_networks'):
other_nic = nic
for net in nic['assigned_networks']:
if net['name'] == 'public':
public_nic = nic
public = net
public_nic['assigned_networks'].remove(public)
other_nic.setdefault('assigned_networks', []).append(public)
resp = self.app.put(reverse('NodeNICsHandler',
kwargs={'node_id': node['id']}),
json.dumps(nics),
headers=self.default_headers)
self.assertEquals(resp.status_code, 200)
task = self.set_cluster_changes_w_error(self.cluster.id)
self.assertIn(
"Public and floating networks are not assigned to the "
"same physical interface. These networks must be assigned "
"to the same physical interface. Affected nodes:\nUntitled",
task['message']
)
def test_network_size_and_amount_not_fit_cidr(self):
net = self.find_net_by_name('fixed')
net["amount"] = 1
net["cidr"] = "10.10.0.0/24"
net["network_size"] = "128"
self.nets['networking_parameters']['fixed_networks_amount'] = 1
self.nets['networking_parameters']['fixed_networks_cidr'] = \
"10.10.0.0/24"
self.nets['networking_parameters']['fixed_network_size'] = \
"128"
self.update_nova_networks_success(self.cluster.id, self.nets)
net["network_size"] = "512"
self.nets['networking_parameters']['fixed_network_size'] = \
"512"
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEquals(
task['message'],
@ -399,12 +333,13 @@ class TestNovaHandlers(TestNetworkChecking):
"fixed CIDR (10.10.0.0/24) and size of one fixed network (512)."
)
self.nets['net_manager'] = 'VlanManager'
net["amount"] = 8
net["network_size"] = "32"
self.nets['networking_parameters']['net_manager'] = 'VlanManager'
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)
net["amount"] = 32
self.nets['networking_parameters']['fixed_networks_amount'] = 32
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEquals(
task['message'],
@ -469,21 +404,7 @@ class TestNovaHandlers(TestNetworkChecking):
self.find_net_by_name('public')['ip_ranges'] = [['172.16.0.2',
'172.16.0.122']]
self.find_net_by_name('fixed')['gateway'] = '10.0.0.0'
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEquals(
task['message'],
"fixed network gateway address is equal to either subnet address "
"or broadcast address of the network."
)
self.find_net_by_name('fixed')['gateway'] = '10.0.255.255'
task = self.update_nova_networks_w_error(self.cluster.id, self.nets)
self.assertEquals(
task['message'],
"fixed network gateway address is equal to either subnet address "
"or broadcast address of the network."
)
self.update_nova_networks_success(self.cluster.id, self.nets)
class TestNeutronHandlersGre(TestNetworkChecking):
@ -535,23 +456,25 @@ class TestNeutronHandlersGre(TestNetworkChecking):
for n in self.nets['networks']:
n['vlan_start'] = None
self.env.neutron_networks_put(self.cluster.id, self.nets)
self.update_neutron_networks_success(self.cluster.id, self.nets)
task = self.set_cluster_changes_w_error(self.cluster.id)
self.assertEquals(
task['message'].find(
"Some untagged networks are "
"assigned to the same physical interface. "
"You should assign them to "
"different physical interfaces:"),
0
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'
virt_nets = self.nets['neutron_parameters']['predefined_networks']
virt_nets['net04_ext']['L3']['floating'] = ['172.16.10.130',
'172.16.10.254']
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.assertEquals(
@ -564,7 +487,6 @@ class TestNeutronHandlersGre(TestNetworkChecking):
[['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'
self.find_net_by_name('public')["netmask"] = '255.255.255.0'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEquals(
@ -640,33 +562,19 @@ class TestNeutronHandlersGre(TestNetworkChecking):
"of public and external network."
)
def test_network_checking_fails_if_network_cidr_too_small(self):
self.find_net_by_name('management')['cidr'] = '192.168.0.0/25'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEquals(
task['message'],
"CIDR size for network 'management' "
"is less than required"
)
def test_network_checking_public_network_cidr_became_smaller(self):
self.assertEquals(self.find_net_by_name('public')['network_size'], 256)
self.find_net_by_name('public')['netmask'] = '255.255.255.128'
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']]
virt_nets = self.nets['neutron_parameters']['predefined_networks']
virt_nets['net04_ext']['L3']['floating'] = ['172.16.0.99',
'172.16.0.111']
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 = json.loads(resp.body)
self.assertEquals(self.find_net_by_name('public')['cidr'],
'172.16.0.0/25')
self.assertEquals(self.find_net_by_name('public')['network_size'], 128)
def test_network_checking_fails_on_network_vlan_match(self):
self.find_net_by_name('management')['vlan_start'] = '111'
@ -682,8 +590,7 @@ class TestNeutronHandlersGre(TestNetworkChecking):
self.assertIn("storage", task['message'])
def test_network_checking_fails_if_internal_gateway_not_in_cidr(self):
int = self.nets['neutron_parameters']['predefined_networks']['net04']
int['L3']['gateway'] = '172.16.10.1'
self.nets['networking_parameters']['internal_gateway'] = '172.16.10.1'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEquals(
@ -693,9 +600,8 @@ class TestNeutronHandlersGre(TestNetworkChecking):
)
def test_network_checking_fails_if_internal_w_floating_intersection(self):
int = self.nets['neutron_parameters']['predefined_networks']['net04']
int['L3']['cidr'] = '172.16.0.128/26'
int['L3']['gateway'] = '172.16.0.129'
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.assertEquals(
@ -760,9 +666,8 @@ class TestNeutronHandlersGre(TestNetworkChecking):
self.find_net_by_name('public')['ip_ranges'] = [['172.16.0.55',
'172.16.0.99']]
virt_nets = self.nets['neutron_parameters']['predefined_networks']
virt_nets['net04_ext']['L3']['floating'] = ['172.16.0.0',
'172.16.0.33']
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.assertEquals(
task['message'],
@ -771,8 +676,8 @@ class TestNeutronHandlersGre(TestNetworkChecking):
"of public network."
)
virt_nets['net04_ext']['L3']['floating'] = ['172.16.0.155',
'172.16.0.255']
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.assertEquals(
task['message'],
@ -781,10 +686,12 @@ class TestNeutronHandlersGre(TestNetworkChecking):
"of public network."
)
virt_nets['net04_ext']['L3']['floating'] = ['172.16.0.155',
'172.16.0.199']
virt_nets['net04']['L3']['cidr'] = '192.168.111.0/24'
virt_nets['net04']['L3']['gateway'] = '192.168.111.0'
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.assertEquals(
task['message'],
@ -792,7 +699,8 @@ class TestNeutronHandlersGre(TestNetworkChecking):
"either subnet address or broadcast address of the network."
)
virt_nets['net04']['L3']['gateway'] = '192.168.111.255'
self.nets['networking_parameters']['internal_gateway'] = \
'192.168.111.255'
task = self.update_neutron_networks_w_error(self.cluster.id, self.nets)
self.assertEquals(
task['message'],

View File

@ -184,14 +184,14 @@ class TestNodeHandlers(BaseIntegrationTest):
self.assertEquals(resp.status_code, 200)
response = json.loads(resp.body)
net_name_per_nic = [['fuelweb_admin', 'storage', 'fixed'],
['public', 'floating'],
['public'],
['management']]
for i, nic in enumerate(sorted(response, key=lambda x: x['name'])):
net_names = set([net['name'] for net in nic['assigned_networks']])
self.assertEqual(set(net_name_per_nic[i]), net_names)
for net in nets['networks']:
if net['name'] in ('public', 'floating'):
if net['name'] == 'public':
net['vlan_start'] = 111
if net['name'] == 'management':
net['vlan_start'] = 112
@ -221,7 +221,7 @@ class TestNodeHandlers(BaseIntegrationTest):
self.assertEquals(resp.status_code, 200)
response = json.loads(resp.body)
net_name_per_nic = [['fuelweb_admin', 'storage', 'fixed',
'public', 'floating', 'management'],
'public', 'management'],
[], []]
for i, nic in enumerate(sorted(response, key=lambda x: x['name'])):
net_names = set([net['name'] for net in nic['assigned_networks']])

View File

@ -22,7 +22,6 @@ from netaddr import IPRange
from nailgun.consts import OVS_BOND_MODES
from nailgun.db.sqlalchemy.models import Cluster
from nailgun.db.sqlalchemy.models import IPAddrRange
from nailgun.db.sqlalchemy.models import NetworkGroup
from nailgun.db.sqlalchemy.models import Node
from nailgun.orchestrator.deployment_serializers \
@ -173,7 +172,7 @@ class TestNovaOrchestratorSerializer(OrchestratorSerializerTestBase):
def test_vlan_manager(self):
cluster = self.create_env('ha_compact')
data = {'net_manager': 'VlanManager'}
data = {'networking_parameters': {'net_manager': 'VlanManager'}}
url = reverse('NovaNetworkConfigurationHandler',
kwargs={'cluster_id': cluster.id})
self.app.put(url, json.dumps(data),
@ -194,32 +193,16 @@ class TestNovaOrchestratorSerializer(OrchestratorSerializerTestBase):
self.assertEquals(
fact['novanetwork_parameters']['network_size'], 256)
def test_floatin_ranges_generation(self):
def test_floating_ranges_generation(self):
# Set ip ranges for floating ips
ranges = [['172.16.0.2', '172.16.0.4'],
['172.16.0.3', '172.16.0.5'],
['172.16.0.10', '172.16.0.12']]
floating_network_group = self.db.query(NetworkGroup).filter(
NetworkGroup.name == 'floating'
).filter(
NetworkGroup.cluster_id == self.cluster.id).first()
# Remove floating ip addr ranges
self.db.query(IPAddrRange).filter(
IPAddrRange.network_group_id == floating_network_group.id).delete()
# Add new ranges
for ip_range in ranges:
new_ip_range = IPAddrRange(
first=ip_range[0],
last=ip_range[1],
network_group_id=floating_network_group.id)
self.db.add(new_ip_range)
self.cluster.network_config.floating_ranges = ranges
self.db.commit()
facts = self.serializer.serialize(self.cluster, self.cluster.nodes)
facts = self.serializer.serialize(self.cluster, self.cluster.nodes)
for fact in facts:
self.assertEquals(
fact['floating_network_range'],
@ -230,6 +213,7 @@ class TestNovaOrchestratorSerializer(OrchestratorSerializerTestBase):
def test_configure_interfaces_untagged_network(self):
for network in self.db.query(NetworkGroup).all():
network.vlan_start = None
self.cluster.network_config.fixed_networks_vlan_start = None
self.db.commit()
node_db = sorted(self.cluster.nodes, key=lambda n: n.id)[0]
from nailgun.orchestrator.deployment_serializers \
@ -652,8 +636,7 @@ class TestNeutronOrchestratorSerializer(OrchestratorSerializerTestBase):
vlan_set = set(
[ng.vlan_start for ng in cluster.network_groups if ng.vlan_start]
)
private_vlan_range = cluster.neutron_config.L2["phys_nets"][
"physnet2"]["vlan_range"]
private_vlan_range = cluster.network_config["vlan_range"]
vlan_set.update(xrange(*private_vlan_range))
vlan_set.add(private_vlan_range[1])

View File

@ -391,8 +391,7 @@ class TestVerifyNeutronVlan(BaseIntegrationTest):
def test_network_verification_neutron_with_vlan_segmentation(
self, mocked_rpc):
# get Neutron L2 VLAN ID range
l2params = self.env.clusters[0].neutron_config.L2
vlan_rng_be = l2params["phys_nets"]["physnet2"]["vlan_range"]
vlan_rng_be = self.env.clusters[0].network_config.vlan_range
vlan_rng = set(range(vlan_rng_be[0], vlan_rng_be[1] + 1))
# get nodes NICs for private network

View File

@ -57,23 +57,9 @@ class TestHandlers(BaseIntegrationTest):
'networks_metadata': {
"nova_network": {
"networks": [
{
"name": "floating",
"cidr": "172.16.0.0/24",
"netmask": "255.255.255.0",
"gateway": "172.16.0.1",
"ip_range": [
"172.16.0.128",
"172.16.0.254"
],
"vlan_start": 100,
"network_size": 256,
"assign_vip": False
},
{
"name": "storage",
"cidr": "192.168.1.0/24",
"netmask": "255.255.255.0",
"gateway": "192.168.1.1",
"ip_range": [
"192.168.1.1",
@ -83,9 +69,8 @@ class TestHandlers(BaseIntegrationTest):
"assign_vip": False
},
{
"name": "fixed",
"name": "management",
"cidr": "10.0.0.0/16",
"netmask": "255.255.0.0",
"gateway": "10.0.0.1",
"ip_range": [
"10.0.0.2",
@ -113,9 +98,8 @@ class TestHandlers(BaseIntegrationTest):
"nova_network": {
"networks": [
{
"name": "fixed",
"name": "management",
"cidr": "10.0.0.0/16",
"netmask": "255.255.0.0",
"gateway": "10.0.0.1",
"ip_range": [
"10.0.0.2",
@ -154,23 +138,9 @@ class TestHandlers(BaseIntegrationTest):
'networks_metadata': {
"nova_network": {
"networks": [
{
"name": "floating",
"cidr": "172.16.0.0/24",
"netmask": "255.255.255.0",
"gateway": "172.16.0.1",
"ip_range": [
"172.16.0.128",
"172.16.0.254"
],
"vlan_start": 100,
"network_size": 256,
"assign_vip": False
},
{
"name": "storage",
"cidr": "192.168.1.0/24",
"netmask": "255.255.255.0",
"gateway": "192.168.1.1",
"ip_range": [
"192.168.1.1",
@ -180,9 +150,8 @@ class TestHandlers(BaseIntegrationTest):
"assign_vip": False
},
{
"name": "fixed",
"name": "management",
"cidr": "10.0.0.0/16",
"netmask": "255.255.0.0",
"gateway": "10.0.0.1",
"ip_range": [
"10.0.0.2",
@ -210,9 +179,8 @@ class TestHandlers(BaseIntegrationTest):
"nova_network": {
"networks": [
{
"name": "fixed",
"name": "management",
"cidr": "10.0.0.0/16",
"netmask": "255.255.0.0",
"gateway": "10.0.0.1",
"ip_range": [
"10.0.0.2",