fuel-web/nailgun/nailgun/test/integration/test_orchestrator_serialize...

506 lines
19 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2015 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 copy import deepcopy
import mock
import six
import nailgun
from nailgun import consts
from nailgun.db.sqlalchemy import models
from nailgun import objects
from nailgun import rpc
from nailgun.orchestrator.deployment_graph import AstuteGraph
from nailgun.orchestrator.deployment_serializers import \
get_serializer_for_cluster
from nailgun.orchestrator.neutron_serializers import \
NeutronNetworkDeploymentSerializer80
from nailgun.orchestrator.neutron_serializers import \
NeutronNetworkTemplateSerializer80
from nailgun.test.integration.test_orchestrator_serializer import \
BaseDeploymentSerializer
from nailgun.test.integration.test_orchestrator_serializer import \
TestSerializeInterfaceDriversData
from nailgun.test.integration.test_orchestrator_serializer_70 import \
TestDeploymentHASerializer70
class TestSerializer80Mixin(object):
env_version = "liberty-8.0"
def _check_baremetal_neutron_attrs(self, cluster):
self.env._set_additional_component(cluster, 'ironic', True)
self.env.create_node(cluster_id=cluster.id,
roles=['controller'])
objects.Cluster.prepare_for_deployment(cluster)
serialized_for_astute = self.serializer.serialize(
cluster, cluster.nodes)
for node in serialized_for_astute:
expected_network = {
"network_type": "flat",
"segment_id": None,
"router_ext": False,
"physnet": "physnet-ironic"
}
self.assertEqual(expected_network, node['quantum_settings']
['predefined_networks']['baremetal']['L2'])
self.assertIn("physnet-ironic",
node['quantum_settings']['L2']['phys_nets'])
self.assertEqual(consts.DEFAULT_BRIDGES_NAMES.br_ironic,
(node['quantum_settings']['L2']['phys_nets']
["physnet-ironic"]["bridge"]))
class TestNetworkTemplateSerializer80(
TestSerializer80Mixin,
BaseDeploymentSerializer
):
env_version = 'liberty-8.0'
def setUp(self, *args):
super(TestNetworkTemplateSerializer80, self).setUp()
cluster = self.env.create(
release_kwargs={'version': self.env_version},
cluster_kwargs={
'mode': consts.CLUSTER_MODES.ha_compact,
'net_provider': consts.CLUSTER_NET_PROVIDERS.neutron,
'net_segment_type': consts.NEUTRON_SEGMENT_TYPES.vlan})
self.net_template = self.env.read_fixtures(['network_template_80'])[0]
self.cluster = self.db.query(models.Cluster).get(cluster['id'])
def test_get_net_provider_serializer(self):
serializer = get_serializer_for_cluster(self.cluster)
self.cluster.network_config.configuration_template = None
net_serializer = serializer.get_net_provider_serializer(self.cluster)
self.assertIs(net_serializer, NeutronNetworkDeploymentSerializer80)
self.cluster.network_config.configuration_template = \
self.net_template
net_serializer = serializer.get_net_provider_serializer(self.cluster)
self.assertIs(net_serializer, NeutronNetworkTemplateSerializer80)
def test_baremetal_neutron_attrs(self):
brmtl_template = deepcopy(
self.net_template['adv_net_template']['default'])
brmtl_template['network_assignments']['baremetal'] = {
'ep': 'br-baremetal'}
brmtl_template['templates_for_node_role']['controller'].append(
'baremetal')
brmtl_template['nic_mapping']['default']['if8'] = 'eth7'
brmtl_template['network_scheme']['baremetal'] = {
'endpoints': ['br-baremetal'],
'transformations': [],
'roles': {'baremetal': 'br-baremetal'}}
self.cluster.network_config.configuration_template = {
'adv_net_template': {'default': brmtl_template}, 'pk': 1}
serializer_type = get_serializer_for_cluster(self.cluster)
self.serializer = serializer_type(AstuteGraph(self.cluster))
self._check_baremetal_neutron_attrs(self.cluster)
class TestDeploymentTasksSerialization80(
TestSerializer80Mixin,
BaseDeploymentSerializer
):
manifests_to_rerun = set([
"/etc/puppet/modules/osnailyfacter/modular/globals/globals.pp",
"/etc/puppet/modules/osnailyfacter/modular/netconfig/netconfig.pp"])
def setUp(self):
super(TestDeploymentTasksSerialization80, self).setUp()
cluster = self.env.create(
release_kwargs={'version': self.env_version},
cluster_kwargs={
'mode': consts.CLUSTER_MODES.ha_compact,
'net_provider': consts.CLUSTER_NET_PROVIDERS.neutron,
'net_segment_type': consts.NEUTRON_SEGMENT_TYPES.vlan,
'status': consts.CLUSTER_STATUSES.operational},
nodes_kwargs=[
{'roles': ['controller'],
'status': consts.NODE_STATUSES.ready}]
)
self.cluster = self.db.query(models.Cluster).get(cluster['id'])
def add_node(self, role):
return self.env.create_node(
cluster_id=self.cluster.id,
pending_roles=[role],
pending_addition=True
)
def get_deployment_info(self):
self.env.launch_deployment()
args, kwargs = nailgun.task.manager.rpc.cast.call_args
return args[1][1]['args']['deployment_info']
@mock.patch('nailgun.rpc.cast')
def test_add_compute(self, _):
new_node = self.add_node('compute')
rpc_deploy_message = self.get_deployment_info()
for node in rpc_deploy_message:
tasks_for_node = set(t['parameters']['puppet_manifest']
for t in node['tasks'])
if node['tasks'][0]['uids'] == [str(new_node.id)]:
# all tasks are run on a new node
self.assertTrue(
self.manifests_to_rerun.issubset(tasks_for_node))
else:
# only selected tasks are run on a deployed node
self.assertEqual(self.manifests_to_rerun, tasks_for_node)
@mock.patch('nailgun.rpc.cast')
def test_add_controller(self, _):
self.add_node('controller')
rpc_deploy_message = self.get_deployment_info()
for node in rpc_deploy_message:
tasks_for_node = set(t['parameters']['puppet_manifest']
for t in node['tasks'])
# controller is redeployed when other one is added
# so all tasks are run on all nodes
self.assertTrue(
self.manifests_to_rerun.issubset(tasks_for_node))
class TestDeploymentAttributesSerialization80(
TestSerializer80Mixin,
BaseDeploymentSerializer
):
env_version = 'liberty-8.0'
def setUp(self):
super(TestDeploymentAttributesSerialization80, self).setUp()
self.cluster = self.env.create(
release_kwargs={'version': self.env_version},
cluster_kwargs={
'mode': consts.CLUSTER_MODES.ha_compact,
'net_provider': consts.CLUSTER_NET_PROVIDERS.neutron,
'net_segment_type': consts.NEUTRON_SEGMENT_TYPES.vlan})
self.cluster_db = self.db.query(models.Cluster).get(self.cluster['id'])
serializer_type = get_serializer_for_cluster(self.cluster_db)
self.serializer = serializer_type(AstuteGraph(self.cluster_db))
def test_neutron_attrs(self):
self.env.create_node(
cluster_id=self.cluster_db.id,
roles=['controller'], primary_roles=['controller']
)
objects.Cluster.prepare_for_deployment(self.cluster_db)
serialized_for_astute = self.serializer.serialize(
self.cluster_db, self.cluster_db.nodes)
for node in serialized_for_astute:
self.assertEqual(
{
"bridge": consts.DEFAULT_BRIDGES_NAMES.br_floating,
"vlan_range": None
},
node['quantum_settings']['L2']['phys_nets']['physnet1']
)
l2 = (node["quantum_settings"]["predefined_networks"]
[self.cluster_db.network_config.floating_name]["L2"])
self.assertEqual("physnet1", l2["physnet"])
self.assertEqual("flat", l2["network_type"])
def test_baremetal_transformations(self):
self.env._set_additional_component(self.cluster_db, 'ironic', True)
self.env.create_node(cluster_id=self.cluster_db.id,
roles=['primary-controller'])
objects.Cluster.prepare_for_deployment(self.cluster_db)
serialized_for_astute = self.serializer.serialize(
self.cluster_db, self.cluster_db.nodes)
for node in serialized_for_astute:
transformations = node['network_scheme']['transformations']
baremetal_brs = filter(lambda t: t.get('name') ==
consts.DEFAULT_BRIDGES_NAMES.br_baremetal,
transformations)
baremetal_ports = filter(lambda t: t.get('name') == "eth0.104",
transformations)
expected_patch = {
'action': 'add-patch',
'bridges': [consts.DEFAULT_BRIDGES_NAMES.br_ironic,
consts.DEFAULT_BRIDGES_NAMES.br_baremetal],
'provider': 'ovs'}
self.assertEqual(len(baremetal_brs), 1)
self.assertEqual(len(baremetal_ports), 1)
self.assertEqual(baremetal_ports[0]['bridge'],
consts.DEFAULT_BRIDGES_NAMES.br_baremetal)
self.assertIn(expected_patch, transformations)
def test_disks_attrs(self):
disks = [
{
"model": "TOSHIBA MK1002TS",
"name": "sda",
"disk": "sda",
"size": 1004886016
},
]
expected_node_volumes_hash = [
{
u'name': u'sda',
u'extra': [],
u'free_space': 330,
u'volumes': [
{
u'type': u'boot',
u'size': 300
},
{
u'mount': u'/boot',
u'type': u'partition',
u'file_system': u'ext2',
u'name': u'Boot',
u'size': 200
},
{
u'type': u'lvm_meta_pool',
u'size': 64
},
{
u'vg': u'os',
u'type': u'pv',
u'lvm_meta_size': 64,
u'size': 394
},
{
u'vg': u'vm',
u'type': u'pv',
u'lvm_meta_size': 0,
u'size': 0
}
],
u'type': u'disk',
u'id': u'sda',
u'size': 958
},
{
u'_allocate_size': u'min',
u'label': u'Base System',
u'min_size': 19456,
u'volumes': [
{
u'mount': u'/',
u'size': -3766,
u'type': u'lv',
u'name': u'root',
u'file_system': u'ext4'
},
{
u'mount': u'swap',
u'size': 4096,
u'type': u'lv',
u'name': u'swap',
u'file_system': u'swap'
}
],
u'type': u'vg',
u'id': u'os'
},
{
u'_allocate_size': u'all',
u'label': u'Virtual Storage',
u'min_size': 5120,
u'volumes': [
{
u'mount': u'/var/lib/nova',
u'size': 0,
u'type': u'lv',
u'name': u'nova',
u'file_system': u'xfs'
}
],
u'type': u'vg',
u'id': u'vm'
}
]
self.env.create_node(
cluster_id=self.cluster_db.id,
roles=['compute'],
meta={"disks": disks},
)
objects.Cluster.prepare_for_deployment(self.cluster_db)
serialized_for_astute = self.serializer.serialize(
self.cluster_db, self.cluster_db.nodes)
for node in serialized_for_astute:
self.assertIn("node_volumes", node)
self.assertItemsEqual(
expected_node_volumes_hash, node["node_volumes"])
def test_attributes_contains_plugins(self):
self.env.create_plugin(
cluster=self.cluster_db,
name='plugin_1',
package_version='4.0.0',
fuel_version=['8.0'])
self.env.create_plugin(
cluster=self.cluster_db,
name='plugin_2',
package_version='4.0.0',
fuel_version=['8.0'])
self.env.create_plugin(
cluster=self.cluster_db,
enabled=False,
name='plugin_3',
package_version='4.0.0',
fuel_version=['8.0'])
expected_plugins_list = ['plugin_1', 'plugin_2']
self.env.create_node(
cluster_id=self.cluster_db.id,
roles=['compute']
)
objects.Cluster.prepare_for_deployment(self.cluster_db)
serialized_for_astute = self.serializer.serialize(
self.cluster_db, self.cluster_db.nodes)
for node in serialized_for_astute:
self.assertIn('plugins', node)
self.assertItemsEqual(
expected_plugins_list, node['plugins'])
class TestMultiNodeGroupsSerialization80(BaseDeploymentSerializer):
env_version = 'liberty-8.0'
def setUp(self):
super(TestMultiNodeGroupsSerialization80, self).setUp()
cluster = self.env.create(
release_kwargs={'version': self.env_version},
cluster_kwargs={
'net_provider': consts.CLUSTER_NET_PROVIDERS.neutron,
'net_segment_type': consts.NEUTRON_SEGMENT_TYPES.vlan}
)
self.env.create_nodes_w_interfaces_count(
nodes_count=3,
if_count=2,
roles=['controller', 'cinder'],
pending_addition=True,
cluster_id=cluster['id'])
self.cluster_db = self.db.query(models.Cluster).get(cluster['id'])
serializer_type = get_serializer_for_cluster(self.cluster_db)
self.serializer = serializer_type(AstuteGraph(self.cluster_db))
def _add_node_group_with_node(self, cidr_start, node_address):
node_group = self.env.create_node_group(
api=False, cluster_id=self.cluster_db.id,
name='ng_' + cidr_start + '_' + str(node_address))
with mock.patch.object(rpc, 'cast'):
resp = self.env.setup_networks_for_nodegroup(
cluster_id=self.cluster_db.id, node_group=node_group,
cidr_start=cidr_start)
self.assertEqual(resp.status_code, 200)
self.db.query(models.Task).filter_by(
name=consts.TASK_NAMES.update_dnsmasq
).delete(synchronize_session=False)
self.env.create_nodes_w_interfaces_count(
nodes_count=1,
if_count=2,
roles=['compute'],
pending_addition=True,
cluster_id=self.cluster_db.id,
group_id=node_group.id,
ip='{0}.9.{1}'.format(cidr_start, node_address))
def _check_routes_count(self, count):
objects.Cluster.prepare_for_deployment(self.cluster_db)
facts = self.serializer.serialize(
self.cluster_db, self.cluster_db.nodes)
for node in facts:
endpoints = node['network_scheme']['endpoints']
for name, descr in six.iteritems(endpoints):
if descr['IP'] == 'none':
self.assertNotIn('routes', descr)
else:
self.assertEqual(len(descr['routes']), count)
def test_routes_with_no_shared_networks_2_nodegroups(self):
self._add_node_group_with_node('199.99', 3)
# all networks have different CIDRs
self._check_routes_count(1)
def test_routes_with_no_shared_networks_3_nodegroups(self):
self._add_node_group_with_node('199.99', 3)
self._add_node_group_with_node('199.77', 3)
# all networks have different CIDRs
self._check_routes_count(2)
def test_routes_with_shared_networks_3_nodegroups(self):
self._add_node_group_with_node('199.99', 3)
self._add_node_group_with_node('199.99', 4)
# networks in two racks have equal CIDRs
self._check_routes_count(1)
class TestBlockDeviceDevicesSerialization80(BaseDeploymentSerializer):
env_version = 'liberty-8.0'
def setUp(self):
super(TestBlockDeviceDevicesSerialization80, self).setUp()
self.cluster = self.env.create(
release_kwargs={'version': self.env_version},
cluster_kwargs={
'mode': consts.CLUSTER_MODES.ha_compact,
'net_provider': consts.CLUSTER_NET_PROVIDERS.neutron,
'net_segment_type': consts.NEUTRON_SEGMENT_TYPES.vlan})
self.cluster_db = self.db.query(models.Cluster).get(self.cluster['id'])
serializer_type = get_serializer_for_cluster(self.cluster_db)
self.serializer = serializer_type(AstuteGraph(self.cluster_db))
def test_block_device_disks(self):
self.env.create_node(
cluster_id=self.cluster_db.id,
roles=['cinder-block-device']
)
self.env.create_node(
cluster_id=self.cluster_db.id,
roles=['controller']
)
objects.Cluster.prepare_for_deployment(self.cluster_db)
serialized_for_astute = self.serializer.serialize(
self.cluster_db, self.cluster_db.nodes)
for node in serialized_for_astute:
self.assertIn("node_volumes", node)
for node_volume in node["node_volumes"]:
if node_volume["id"] == "cinder-block-device":
self.assertEqual(node_volume["volumes"], [])
else:
self.assertNotEqual(node_volume["volumes"], [])
class TestSerializeInterfaceDriversData80(
TestSerializer80Mixin,
TestSerializeInterfaceDriversData
):
pass
class TestDeploymentHASerializer80(
TestSerializer80Mixin,
TestDeploymentHASerializer70
):
pass