Fix working sahara with heat and nova-network
Uses OS::Nova::FloatingIP and OS::Nova::FloatingIPAssociation heat resources for assignment floating ip Added two unit tests: * for nova-network with autoassignment floating ip * for nova-network without autoassignment floating ip Change-Id: I82a28759bc13992d765969ef8143bd364dc7cf2d Closes-bug: #1259176
This commit is contained in:
parent
0baeb0ee5a
commit
727a59e512
13
sahara/resources/nova-floating.heat
Normal file
13
sahara/resources/nova-floating.heat
Normal file
@ -0,0 +1,13 @@
|
||||
"%(floating_ip_name)s": {
|
||||
"Type": "OS::Nova::FloatingIP",
|
||||
"Properties": {
|
||||
"pool": "%(pool)s"
|
||||
}
|
||||
},
|
||||
"%(floating_ip_assoc_name)s": {
|
||||
"Type": "OS::Nova::FloatingIPAssociation",
|
||||
"Properties": {
|
||||
"floating_ip": { "Ref" : "%(floating_ip_name)s" },
|
||||
"server_id": { "Ref" : "%(instance_name)s" }
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
{
|
||||
"AWSTemplateFormatVersion" : "2010-09-09",
|
||||
"Description" : "Hadoop Cluster by Sahara",
|
||||
|
||||
"Resources" : {
|
||||
"cluster-worker-001" : {
|
||||
"Type" : "OS::Nova::Server",
|
||||
"Properties" : {
|
||||
"name" : "cluster-worker-001",
|
||||
"flavor" : "42",
|
||||
"image" : "1",
|
||||
"key_name" : "user_key",
|
||||
"user_data": {
|
||||
"Fn::Join" : ["\n", ["line2", "line3"]]
|
||||
}
|
||||
}
|
||||
},
|
||||
"cluster-worker-001-volume-0" : {
|
||||
"Type" : "OS::Cinder::Volume",
|
||||
"Properties" : {
|
||||
"name" : "cluster-worker-001-volume-0",
|
||||
"size" : "10"
|
||||
}
|
||||
},
|
||||
"cluster-worker-001-volume-attachment-0" : {
|
||||
"Type" : "OS::Cinder::VolumeAttachment",
|
||||
"Properties" : {
|
||||
"instance_uuid" : { "Ref" : "cluster-worker-001" },
|
||||
"volume_id" : { "Ref" : "cluster-worker-001-volume-0" },
|
||||
"mountpoint" : null
|
||||
}
|
||||
},
|
||||
"cluster-worker-001-volume-1" : {
|
||||
"Type" : "OS::Cinder::Volume",
|
||||
"Properties" : {
|
||||
"name" : "cluster-worker-001-volume-1",
|
||||
"size" : "10"
|
||||
}
|
||||
},
|
||||
"cluster-worker-001-volume-attachment-1" : {
|
||||
"Type" : "OS::Cinder::VolumeAttachment",
|
||||
"Properties" : {
|
||||
"instance_uuid" : { "Ref" : "cluster-worker-001" },
|
||||
"volume_id" : { "Ref" : "cluster-worker-001-volume-1" },
|
||||
"mountpoint" : null
|
||||
}
|
||||
},
|
||||
"cluster-master-001" : {
|
||||
"Type" : "OS::Nova::Server",
|
||||
"Properties" : {
|
||||
"name" : "cluster-master-001",
|
||||
"flavor" : "42",
|
||||
"image" : "1",
|
||||
"key_name" : "user_key",
|
||||
"user_data": {
|
||||
"Fn::Join" : ["\n", ["line1", "line2"]]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"Outputs" : {}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
{
|
||||
"AWSTemplateFormatVersion" : "2010-09-09",
|
||||
"Description" : "Hadoop Cluster by Sahara",
|
||||
|
||||
"Resources" : {
|
||||
"cluster-worker-001-floating-assoc" : {
|
||||
"Type" : "OS::Nova::FloatingIPAssociation",
|
||||
"Properties" : {
|
||||
"floating_ip" : { "Ref" : "cluster-worker-001-floating" },
|
||||
"server_id" : { "Ref" : "cluster-worker-001" }
|
||||
}
|
||||
},
|
||||
"cluster-worker-001-floating" : {
|
||||
"Type" : "OS::Nova::FloatingIP",
|
||||
"Properties" : {
|
||||
"pool" : "floating"
|
||||
}
|
||||
},
|
||||
"cluster-worker-001" : {
|
||||
"Type" : "OS::Nova::Server",
|
||||
"Properties" : {
|
||||
"name" : "cluster-worker-001",
|
||||
"flavor" : "42",
|
||||
"image" : "1",
|
||||
"key_name" : "user_key",
|
||||
"user_data": {
|
||||
"Fn::Join" : ["\n", ["line2", "line3"]]
|
||||
}
|
||||
}
|
||||
},
|
||||
"cluster-worker-001-volume-0" : {
|
||||
"Type" : "OS::Cinder::Volume",
|
||||
"Properties" : {
|
||||
"name" : "cluster-worker-001-volume-0",
|
||||
"size" : "10"
|
||||
}
|
||||
},
|
||||
"cluster-worker-001-volume-attachment-0" : {
|
||||
"Type" : "OS::Cinder::VolumeAttachment",
|
||||
"Properties" : {
|
||||
"instance_uuid" : { "Ref" : "cluster-worker-001" },
|
||||
"volume_id" : { "Ref" : "cluster-worker-001-volume-0" },
|
||||
"mountpoint" : null
|
||||
}
|
||||
},
|
||||
"cluster-worker-001-volume-1" : {
|
||||
"Type" : "OS::Cinder::Volume",
|
||||
"Properties" : {
|
||||
"name" : "cluster-worker-001-volume-1",
|
||||
"size" : "10"
|
||||
}
|
||||
},
|
||||
"cluster-worker-001-volume-attachment-1" : {
|
||||
"Type" : "OS::Cinder::VolumeAttachment",
|
||||
"Properties" : {
|
||||
"instance_uuid" : { "Ref" : "cluster-worker-001" },
|
||||
"volume_id" : { "Ref" : "cluster-worker-001-volume-1" },
|
||||
"mountpoint" : null
|
||||
}
|
||||
},
|
||||
"cluster-master-001-floating-assoc" : {
|
||||
"Type" : "OS::Nova::FloatingIPAssociation",
|
||||
"Properties" : {
|
||||
"floating_ip" : { "Ref" : "cluster-master-001-floating" },
|
||||
"server_id" : { "Ref" : "cluster-master-001" }
|
||||
}
|
||||
},
|
||||
"cluster-master-001-floating" : {
|
||||
"Type" : "OS::Nova::FloatingIP",
|
||||
"Properties" : {
|
||||
"pool" : "floating"
|
||||
}
|
||||
},
|
||||
"cluster-master-001" : {
|
||||
"Type" : "OS::Nova::Server",
|
||||
"Properties" : {
|
||||
"name" : "cluster-master-001",
|
||||
"flavor" : "42",
|
||||
"image" : "1",
|
||||
"key_name" : "user_key",
|
||||
"user_data": {
|
||||
"Fn::Join" : ["\n", ["line1", "line2"]]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"Outputs" : {}
|
||||
}
|
@ -34,6 +34,8 @@ class TestHeat(unittest2.TestCase):
|
||||
"cluster-worker-001-port")
|
||||
self.assertEqual(h._get_floating_name(inst_name),
|
||||
"cluster-worker-001-floating")
|
||||
self.assertEqual(h._get_floating_assoc_name(inst_name),
|
||||
"cluster-worker-001-floating-assoc")
|
||||
self.assertEqual(h._get_volume_name(inst_name, 1),
|
||||
"cluster-worker-001-volume-1")
|
||||
self.assertEqual(h._get_volume_attach_name(inst_name, 1),
|
||||
@ -73,30 +75,40 @@ class TestClusterTemplate(base.SaharaWithDbTestCase):
|
||||
into Heat templates.
|
||||
"""
|
||||
|
||||
def _make_node_groups(self, floating_ip_pool=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)
|
||||
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)
|
||||
return ng1, ng2
|
||||
|
||||
def _make_cluster(self, mng_network, ng1, ng2):
|
||||
return tu.create_cluster("cluster", "tenant1", "general",
|
||||
"1.2.1", [ng1, ng2],
|
||||
user_keypair_id='user_key',
|
||||
neutron_management_network=mng_network,
|
||||
default_image_id='1', anti_affinity=[],
|
||||
image_id=None)
|
||||
|
||||
def _make_heat_template(self, cluster, ng1, ng2):
|
||||
heat_template = h.ClusterTemplate(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_load_template_use_neutron(self):
|
||||
"""This test checks Heat cluster template with Neutron enabled.
|
||||
Two NodeGroups used: 'master' with Ephemeral drive attached and
|
||||
'worker' with 2 attached volumes 10GB size each
|
||||
"""
|
||||
|
||||
ng1 = tu.make_ng_dict('master', 42, ['namenode'], 1,
|
||||
floating_ip_pool='floating', image_id=None,
|
||||
volumes_per_node=0, volumes_size=0, id=1)
|
||||
ng2 = tu.make_ng_dict('worker', 42, ['datanode'], 1,
|
||||
floating_ip_pool='floating', image_id=None,
|
||||
volumes_per_node=2, volumes_size=10, id=2)
|
||||
cluster = tu.create_cluster("cluster", "tenant1", "general",
|
||||
"1.2.1", [ng1, ng2],
|
||||
user_keypair_id='user_key',
|
||||
neutron_management_network='private_net',
|
||||
default_image_id='1', anti_affinity=[],
|
||||
image_id=None)
|
||||
heat_template = h.ClusterTemplate(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'))
|
||||
|
||||
ng1, ng2 = self._make_node_groups('floating')
|
||||
cluster = self._make_cluster('private_net', ng1, ng2)
|
||||
heat_template = self._make_heat_template(cluster, ng1, ng2)
|
||||
self.override_config("use_neutron", True)
|
||||
main_template = h._load_template(
|
||||
'main.heat', {'resources':
|
||||
@ -108,6 +120,50 @@ class TestClusterTemplate(base.SaharaWithDbTestCase):
|
||||
"tests/unit/resources/"
|
||||
"test_serialize_resources_use_neutron.heat")))
|
||||
|
||||
def test_load_template_use_nova_network_without_autoassignment(self):
|
||||
"""This test checks Heat cluster template with Nova Network enabled
|
||||
without autoassignment floating ip.
|
||||
Two NodeGroups used: 'master' with Ephemeral drive attached and
|
||||
'worker' with 2 attached volumes 10GB size each
|
||||
"""
|
||||
|
||||
ng1, ng2 = self._make_node_groups('floating')
|
||||
cluster = self._make_cluster(None, ng1, ng2)
|
||||
heat_template = self._make_heat_template(cluster, ng1, ng2)
|
||||
self.override_config("use_neutron", False)
|
||||
main_template = h._load_template(
|
||||
'main.heat', {'resources':
|
||||
heat_template._serialize_resources()})
|
||||
|
||||
self.assertEqual(
|
||||
json.loads(main_template),
|
||||
json.loads(f.get_file_text(
|
||||
"tests/unit/resources/"
|
||||
"test_serialize_resources_use_nn_without_autoassignment.heat"))
|
||||
)
|
||||
|
||||
def test_load_template_use_nova_network_with_autoassignment(self):
|
||||
"""This test checks Heat cluster template with Nova Network enabled
|
||||
with autoassignment floating ip.
|
||||
Two NodeGroups used: 'master' with Ephemeral drive attached and
|
||||
'worker' with 2 attached volumes 10GB size each
|
||||
"""
|
||||
|
||||
ng1, ng2 = self._make_node_groups()
|
||||
cluster = self._make_cluster(None, ng1, ng2)
|
||||
heat_template = self._make_heat_template(cluster, ng1, ng2)
|
||||
self.override_config("use_neutron", False)
|
||||
main_template = h._load_template(
|
||||
'main.heat', {'resources':
|
||||
heat_template._serialize_resources()})
|
||||
|
||||
self.assertEqual(
|
||||
json.loads(main_template),
|
||||
json.loads(f.get_file_text(
|
||||
"tests/unit/resources/"
|
||||
"test_serialize_resources_use_nn_with_autoassignment.heat"))
|
||||
)
|
||||
|
||||
def test_load_template_with_anti_affinity_single_ng(self):
|
||||
"""This test checks Heat cluster template with Neutron enabled
|
||||
and anti-affinity feature enabled for single node process
|
||||
|
@ -47,6 +47,10 @@ def _get_floating_name(inst_name):
|
||||
return '%s-floating' % inst_name
|
||||
|
||||
|
||||
def _get_floating_assoc_name(inst_name):
|
||||
return '%s-floating-assoc' % inst_name
|
||||
|
||||
|
||||
def _get_volume_name(inst_name, volume_idx):
|
||||
return '%s-volume-%i' % (inst_name, volume_idx)
|
||||
|
||||
@ -132,9 +136,6 @@ class ClusterTemplate(object):
|
||||
def _serialize_instance(self, ng, idx, aa_groups):
|
||||
inst_name = _get_inst_name(self.cluster.name, ng.name, idx)
|
||||
|
||||
# TODO(dmitryme): support floating IPs for nova-network without
|
||||
# auto-assignment
|
||||
|
||||
nets = ''
|
||||
if CONF.use_neutron:
|
||||
port_name = _get_port_name(inst_name)
|
||||
@ -144,8 +145,12 @@ class ClusterTemplate(object):
|
||||
nets = '"networks" : [{ "port" : { "Ref" : "%s" }}],' % port_name
|
||||
|
||||
if ng.floating_ip_pool:
|
||||
yield self._serialize_floating(inst_name, port_name,
|
||||
ng.floating_ip_pool)
|
||||
yield self._serialize_neutron_floating(inst_name, port_name,
|
||||
ng.floating_ip_pool)
|
||||
else:
|
||||
if ng.floating_ip_pool:
|
||||
yield self._serialize_nova_floating(inst_name,
|
||||
ng.floating_ip_pool)
|
||||
|
||||
aa_names = []
|
||||
for node_process in ng.node_processes:
|
||||
@ -185,13 +190,24 @@ class ClusterTemplate(object):
|
||||
|
||||
return _load_template('neutron-port.heat', fields)
|
||||
|
||||
def _serialize_floating(self, inst_name, port_name, floating_net_id):
|
||||
def _serialize_neutron_floating(self, inst_name, port_name,
|
||||
floating_net_id):
|
||||
fields = {'floating_ip_name': _get_floating_name(inst_name),
|
||||
'floating_net_id': floating_net_id,
|
||||
'port_name': port_name}
|
||||
|
||||
return _load_template('neutron-floating.heat', fields)
|
||||
|
||||
def _serialize_nova_floating(self, inst_name, floating_pool_name):
|
||||
fields = {
|
||||
'floating_ip_name': _get_floating_name(inst_name),
|
||||
'floating_ip_assoc_name': _get_floating_assoc_name(inst_name),
|
||||
'instance_name': inst_name,
|
||||
'pool': floating_pool_name
|
||||
}
|
||||
|
||||
return _load_template('nova-floating.heat', fields)
|
||||
|
||||
def _serialize_volume(self, inst_name, volume_idx, volumes_size):
|
||||
fields = {'volume_name': _get_volume_name(inst_name, volume_idx),
|
||||
'volumes_size': volumes_size,
|
||||
|
Loading…
Reference in New Issue
Block a user