sahara/sahara/tests/unit/service/heat/test_templates.py

168 lines
7.1 KiB
Python

# Copyright (c) 2013 Mirantis Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import mock
from sahara.conductor import resource as r
from sahara.service.heat import templates as h
from sahara.tests.unit import base
from sahara.tests.unit import testutils as tu
class TestClusterTemplate(base.SaharaWithDbTestCase):
"""Checks valid structure of Resources section in generated Heat templates.
1. It checks templates generation with different OpenStack
network installations: Neutron, NovaNetwork with floating Ip auto
assignment set to True or False.
2. Cinder volume attachments.
3. Basic instances creations with multi line user data provided.
4. Anti-affinity feature with proper nova scheduler hints included
into Heat templates.
"""
def _make_node_groups(self, floating_ip_pool=None, volume_type=None):
ng1 = tu.make_ng_dict('master', 42, ['namenode'], 1,
floating_ip_pool=floating_ip_pool, image_id=None,
volumes_per_node=0, volumes_size=0, id="1",
image_username='root', volume_type=None)
ng2 = tu.make_ng_dict('worker', 42, ['datanode'], 1,
floating_ip_pool=floating_ip_pool, image_id=None,
volumes_per_node=2, volumes_size=10, id="2",
image_username='root', volume_type=volume_type)
return ng1, ng2
def _make_cluster(self, mng_network, ng1, ng2, anti_affinity=[]):
return tu.create_cluster("cluster", "tenant1", "general",
"2.6.0", [ng1, ng2],
user_keypair_id='user_key',
neutron_management_network=mng_network,
default_image_id='1', image_id=None,
anti_affinity=anti_affinity)
def _make_heat_template(self, cluster, ng1, ng2):
heat_template = h.ClusterStack(cluster)
heat_template.add_node_group_extra(ng1['id'], 1,
get_ud_generator('line1\nline2'))
heat_template.add_node_group_extra(ng2['id'], 1,
get_ud_generator('line2\nline3'))
return heat_template
def test_get_anti_affinity_scheduler_hints(self):
ng1, ng2 = self._make_node_groups('floating')
cluster = self._make_cluster('private_net', ng1, ng2,
anti_affinity=["datanode"])
heat_template = self._make_heat_template(cluster, ng1, ng2)
ng1 = [ng for ng in cluster.node_groups if ng.name == "master"][0]
ng2 = [ng for ng in cluster.node_groups if ng.name == "worker"][0]
expected = {"scheduler_hints": {"group": {"Ref": "cluster-aa-group"}}}
actual = heat_template._get_anti_affinity_scheduler_hints(ng2)
self.assertEqual(expected, actual)
expected = {}
actual = heat_template._get_anti_affinity_scheduler_hints(ng1)
self.assertEqual(expected, actual)
def test_get_security_groups(self):
ng1, ng2 = self._make_node_groups('floating')
ng1['security_groups'] = ['1', '2']
ng2['security_groups'] = ['3', '4']
ng2['auto_security_group'] = True
cluster = self._make_cluster('private_net', ng1, ng2)
heat_template = self._make_heat_template(cluster, ng1, ng2)
ng1 = [ng for ng in cluster.node_groups if ng.name == "master"][0]
ng2 = [ng for ng in cluster.node_groups if ng.name == "worker"][0]
expected = ['1', '2']
actual = heat_template._get_security_groups(ng1)
self.assertEqual(expected, actual)
expected = ['3', '4', {'Ref': 'cluster-worker-2'}]
actual = heat_template._get_security_groups(ng2)
self.assertEqual(expected, actual)
def _generate_auto_security_group_template(self, use_neutron):
self.override_config('use_neutron', use_neutron)
ng1, ng2 = self._make_node_groups('floating')
cluster = self._make_cluster('private_net', ng1, ng2)
ng1['cluster'] = cluster
ng2['cluster'] = cluster
ng1 = r.NodeGroupResource(ng1)
ng2 = r.NodeGroupResource(ng2)
heat_template = self._make_heat_template(cluster, ng1, ng2)
return heat_template._serialize_auto_security_group(ng1)
@mock.patch('sahara.utils.openstack.neutron.get_private_network_cidrs')
def test_serialize_auto_security_group_neutron(self, patched):
ipv4_cidr = '192.168.0.0/24'
ipv6_cidr = 'fe80::/64'
patched.side_effect = lambda cluster: [ipv4_cidr, ipv6_cidr]
expected_rules = [
('0.0.0.0/0', 'IPv4', 'tcp', '22', '22'),
('::/0', 'IPv6', 'tcp', '22', '22'),
(ipv4_cidr, 'IPv4', 'tcp', '1', '65535'),
(ipv4_cidr, 'IPv4', 'udp', '1', '65535'),
(ipv4_cidr, 'IPv4', 'icmp', '0', '255'),
(ipv6_cidr, 'IPv6', 'tcp', '1', '65535'),
(ipv6_cidr, 'IPv6', 'udp', '1', '65535'),
(ipv6_cidr, 'IPv6', 'icmp', '0', '255'),
]
expected = {'cluster-master-1': {
'type': 'OS::Neutron::SecurityGroup',
'properties': {
'description': 'Auto security group created by Sahara '
'for Node Group \'master\' of cluster \'cluster\'.',
'rules': [{
'remote_ip_prefix': rule[0],
'ethertype': rule[1],
'protocol': rule[2],
'port_range_min': rule[3],
'port_range_max': rule[4]
} for rule in expected_rules]
}
}}
actual = self._generate_auto_security_group_template(True)
self.assertEqual(expected, actual)
def test_serialize_auto_security_group_nova_network(self):
expected = {'cluster-master-1': {
'type': 'AWS::EC2::SecurityGroup',
'properties': {
'GroupDescription': 'Auto security group created by Sahara'
' for Node Group \'master\' of cluster \'cluster\'.',
'SecurityGroupIngress': [{
'ToPort': '22',
'CidrIp': '0.0.0.0/0',
'FromPort': '22',
'IpProtocol': 'tcp'
}, {
'ToPort': '22',
'CidrIp': '::/0',
'FromPort': '22',
'IpProtocol': 'tcp'
}]
}
}}
actual = self._generate_auto_security_group_template(False)
self.assertEqual(expected, actual)
def get_ud_generator(s):
def generator(*args, **kwargs):
return s
return generator