Add network parameters to Heat template creation.

In order to allow the allocation of a floating IP in the heat
template, we need to give network paremeters as input.

This patch :
- updates the heat template to associate a floating IP to the
created server
- Use python-neutronclient to find the needed network id to pass to
the heat template

Fixes bug 1301324

Change-Id: If6182d1bf6196022b77bfaf26d2563a483f1a460
This commit is contained in:
Julien Vey
2014-04-01 17:35:02 +02:00
parent 1259c76be1
commit be2819e87c
4 changed files with 59 additions and 6 deletions

View File

@@ -25,7 +25,7 @@ At present it is a Stackforge project, and its repository is available on Github
$ cd Solum
$ git clone https://github.com/stackforge/solum
In addition to Solum, your environment will also need Devstack to configure and run the requisite Openstack components, including Keystone, Glance, Nova, and Heat.
In addition to Solum, your environment will also need Devstack to configure and run the requisite Openstack components, including Keystone, Glance, Nova, Neutron, and Heat.
Vagrant (Optional)
------------------
@@ -56,6 +56,10 @@ Using Vagrant is not a requirement for deploying Solum.
You may instead opt to install Solum and Devstack yourself.
The details of integrating Solum with Devstack can be found in :code:`contrib/devstack/README.rst`.
Some additional configuration will be needed for Neutron, see `Neutron's Wiki page for Devstack`__
__ https://wiki.openstack.org/wiki/NeutronDevstack
Create your app
---------------

View File

@@ -21,6 +21,15 @@ parameters:
type: string
default: "5000"
description: Port Number
private_net:
type: string
description: Id of the private network for the compute server
private_subnet:
type: string
description: Id of the private sub network for the compute server
public_net:
type: string
description: Id of the public network for the compute server
resources:
external_access:
@@ -35,6 +44,21 @@ resources:
{IpProtocol: icmp, FromPort: "-1", ToPort: "-1",
CidrIp: "0.0.0.0/0"}]
public_port:
type: OS::Neutron::Port
properties:
network_id: { get_param: private_net }
fixed_ips:
- subnet_id: { get_param: private_subnet }
security_groups:
- {get_resource: external_access}
floating_ip:
type: OS::Neutron::FloatingIP
properties:
floating_network_id: { get_param: public_net }
port_id: { get_resource: public_port }
compute:
type: OS::Nova::Server
properties:
@@ -42,8 +66,8 @@ resources:
image: {get_param: image}
flavor: { get_param: flavor }
key_name: { get_param: key_name }
security_groups:
- {get_resource: external_access}
networks:
- port: { get_resource: public_port }
user_data_format: RAW
user_data:
str_replace:
@@ -59,12 +83,12 @@ resources:
outputs:
public_ip:
description: The public IP address of the newly configured Server.
value: { get_attr: [compute, first_address ] }
value: { get_attr: [ floating_ip, floating_ip_address ] }
URL:
description: The URL for the Server.
value:
str_replace:
template: http://%host%:%port%
params:
"%host%": { get_attr: [ compute, first_address ] }
"%host%": { get_attr: [ floating_ip, floating_ip_address ] }
"%port%": { get_param: port }

View File

@@ -68,6 +68,19 @@ class Handler(object):
template = templ_file.read()
return template
def _get_network_parameters(self, osc):
#TODO(julienvey) In the long term, we should have optional parameters
# if the user wants to override this default behaviour
params = {}
tenant_networks = osc.neutron().list_networks()
for tenant_network in tenant_networks['networks']:
if tenant_network['router:external']:
params['public_net'] = tenant_network['id']
else:
params['private_net'] = tenant_network['id']
params['private_subnet'] = tenant_network['subnets'][0]
return params
def deploy(self, ctxt, assembly_id, image_id):
# TODO(asalkeld) support template flavors (maybe an autoscaling one)
# this could also be stored in glance.
@@ -81,6 +94,7 @@ class Handler(object):
parameters = {'app_name': assem.name,
'image': image_id}
parameters.update(self._get_network_parameters(osc))
created_stack = osc.heat().stacks.create(stack_name=assem.name,
template=template,
parameters=parameters)

View File

@@ -46,14 +46,25 @@ class HandlerTest(base.BaseTestCase):
return_value = {"stack": {"id": "fake_id",
"links": [{"href": "http://fake.ref",
"rel": "self"}]}}
mock_clients.return_value.neutron.return_value.list_networks.\
return_value = {"networks": [{"router:external": True,
"id": "public_net_id"},
{"router:external": False,
"id": "private_net_id",
"subnets": ["private_subnet_id"]}]}
handler._update_assembly_status = mock.MagicMock()
handler.deploy(self.ctx, 77, 'created_image_id')
parameters = {'image': 'created_image_id',
'app_name': 'faker'}
'app_name': 'faker',
'private_net': 'private_net_id',
'public_net': 'public_net_id',
'private_subnet': 'private_subnet_id'}
mock_clients.return_value.heat.return_value.stacks.create.\
assert_called_once_with(stack_name='faker',
template=fake_template,
parameters=parameters)
mock_clients.return_value.neutron.return_value.list_networks.\
assert_called_once_with()
assign_and_create_mock = mock_registry.Component.assign_and_create
assign_and_create_mock.assert_called_once_with(self.ctx,
fake_assembly,