Skip to content

Commit ca97766

Browse files
authored
Merge pull request #201 from cloudify-cosmo/issue-195
Fixes #195
2 parents 6fa2d1f + 50cd60b commit ca97766

4 files changed

Lines changed: 154 additions & 6 deletions

File tree

neutron_plugin/floatingip.py

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,26 @@
2222
get_openstack_id,
2323
add_list_to_runtime_properties,
2424
is_external_relationship,
25-
is_external_relationship_not_conditionally_created
25+
is_external_relationship_not_conditionally_created,
26+
get_single_connected_node_by_openstack_type,
27+
OPENSTACK_ID_PROPERTY
2628
)
2729
from openstack_plugin_common.floatingip import (
2830
use_external_floatingip,
2931
set_floatingip_runtime_properties,
3032
delete_floatingip,
3133
floatingip_creation_validation
3234
)
35+
from network import NETWORK_OPENSTACK_TYPE
3336

3437
FLOATINGIP_OPENSTACK_TYPE = 'floatingip'
38+
FLOATING_NETWORK_ERROR_PREFIX = \
39+
'Network name must be specified by either a floating_network_name, a ' \
40+
'floating_network_id, or a relationship to a Network node template '
41+
FLOATING_NETWORK_ERROR_SUFFIX = \
42+
'(provided: network from relationships={}, floatingip={})'
43+
FLOATING_NETWORK_ERROR_MSG = FLOATING_NETWORK_ERROR_PREFIX +\
44+
FLOATING_NETWORK_ERROR_SUFFIX
3545

3646

3747
@operation
@@ -47,19 +57,46 @@ def create(neutron_client, args, **kwargs):
4757
}
4858
floatingip.update(ctx.node.properties[FLOATINGIP_OPENSTACK_TYPE], **args)
4959

50-
# Sugar: floating_network_name -> (resolve) -> floating_network_id
51-
if 'floating_network_name' in floatingip:
60+
# Do we have a relationship with a network?
61+
62+
connected_network = \
63+
get_single_connected_node_by_openstack_type(
64+
ctx, NETWORK_OPENSTACK_TYPE, True)
65+
66+
if connected_network:
67+
network_from_rel = connected_network.runtime_properties[
68+
OPENSTACK_ID_PROPERTY]
69+
else:
70+
network_from_rel = None
71+
72+
# TODO: Should we check whether this is really an "external" network?
73+
74+
network_name_provided = 'floating_network_name' in floatingip
75+
network_id_provided = 'floating_network_id' in floatingip
76+
provided = [network_name_provided,
77+
network_id_provided,
78+
network_from_rel is not None].count(True)
79+
80+
# At most one is expected.
81+
82+
if provided > 1:
83+
raise NonRecoverableError(FLOATING_NETWORK_ERROR_MSG.format(
84+
network_from_rel, floatingip))
85+
86+
if network_from_rel:
87+
floatingip['floating_network_id'] = network_from_rel
88+
elif network_name_provided:
5289
floatingip['floating_network_id'] = neutron_client.cosmo_get_named(
5390
'network', floatingip['floating_network_name'])['id']
5491
del floatingip['floating_network_name']
55-
elif 'floating_network_id' not in floatingip:
92+
elif not network_id_provided:
5693
provider_context = provider(ctx)
5794
ext_network = provider_context.ext_network
5895
if ext_network:
5996
floatingip['floating_network_id'] = ext_network['id']
6097
else:
61-
raise NonRecoverableError(
62-
'Missing floating network id, name or external network')
98+
raise NonRecoverableError(FLOATING_NETWORK_ERROR_MSG.format(
99+
None, None))
63100

64101
fip = neutron_client.create_floatingip(
65102
{FLOATINGIP_OPENSTACK_TYPE: floatingip})[FLOATINGIP_OPENSTACK_TYPE]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
tosca_definitions_version: cloudify_dsl_1_3
2+
3+
imports:
4+
- http://www.getcloudify.org/spec/cloudify/4.2/types.yaml
5+
- plugin.yaml
6+
7+
dsl_definitions:
8+
- &openstack_config
9+
username: aaa
10+
password: aaa
11+
tenant_name: aaa
12+
auth_url: aaa
13+
14+
node_templates:
15+
network:
16+
type: cloudify.openstack.nodes.Network
17+
properties:
18+
resource_id: abcdef
19+
openstack_config: *openstack_config
20+
21+
fip:
22+
type: cloudify.openstack.nodes.FloatingIP
23+
properties:
24+
openstack_config: *openstack_config
25+
relationships:
26+
- target: network
27+
type: cloudify.relationships.connected_to
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
tosca_definitions_version: cloudify_dsl_1_3
2+
3+
imports:
4+
- http://www.getcloudify.org/spec/cloudify/4.2/types.yaml
5+
- plugin.yaml
6+
7+
dsl_definitions:
8+
- &openstack_config
9+
username: aaa
10+
password: aaa
11+
tenant_name: aaa
12+
auth_url: aaa
13+
14+
node_templates:
15+
network:
16+
type: cloudify.openstack.nodes.Network
17+
properties:
18+
resource_id: abcdef
19+
openstack_config: *openstack_config
20+
21+
fip:
22+
type: cloudify.openstack.nodes.FloatingIP
23+
properties:
24+
openstack_config: *openstack_config
25+
floatingip:
26+
floating_network_id: 'bogus-id'
27+
relationships:
28+
- target: network
29+
type: cloudify.relationships.connected_to
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import os
2+
import unittest
3+
import mock
4+
5+
from cloudify.test_utils import workflow_test
6+
from cloudify.mocks import MockNodeInstanceContext
7+
8+
from neutron_plugin.floatingip import (
9+
FLOATINGIP_OPENSTACK_TYPE, FLOATING_NETWORK_ERROR_PREFIX)
10+
from openstack_plugin_common import OPENSTACK_ID_PROPERTY
11+
12+
13+
class FloatingIPTest(unittest.TestCase):
14+
@mock.patch('neutron_plugin.network.create')
15+
@mock.patch('neutronclient.v2_0.client.Client.create_floatingip')
16+
@workflow_test(os.path.join('resources', 'test_fip_rel.yaml'),
17+
copy_plugin_yaml=True)
18+
def test_network_rel(self, cfy_local, *_):
19+
def _mock_rel(*_):
20+
return MockNodeInstanceContext(runtime_properties={
21+
OPENSTACK_ID_PROPERTY: 'my-id'
22+
})
23+
24+
def _mock_create(_, fip):
25+
self.assertEqual(fip[FLOATINGIP_OPENSTACK_TYPE][
26+
'floating_network_id'], 'my-id')
27+
return {FLOATINGIP_OPENSTACK_TYPE: {
28+
'id': '1234',
29+
'floating_ip_address': '1.2.3.4'
30+
}}
31+
32+
with mock.patch('neutronclient.v2_0.client.Client.create_floatingip',
33+
new=_mock_create):
34+
with mock.patch(
35+
'neutron_plugin.floatingip.get_single_connected_node_by_'
36+
'openstack_type', new=_mock_rel):
37+
cfy_local.execute('install')
38+
39+
@mock.patch('neutron_plugin.network.create')
40+
@mock.patch('neutronclient.v2_0.client.Client.create_floatingip')
41+
@workflow_test(os.path.join('resources', 'test_fip_rel_and_id.yaml'),
42+
copy_plugin_yaml=True)
43+
def test_network_rel_and_id(self, cfy_local, *_):
44+
def _mock_rel(*_):
45+
return MockNodeInstanceContext(runtime_properties={
46+
OPENSTACK_ID_PROPERTY: 'my-id'
47+
})
48+
49+
with mock.patch('neutron_plugin.floatingip.get_single_connected_node_'
50+
'by_openstack_type',
51+
new=_mock_rel):
52+
with self.assertRaises(Exception) as ex:
53+
cfy_local.execute('install')
54+
55+
self.assertTrue(FLOATING_NETWORK_ERROR_PREFIX in str(ex.exception))

0 commit comments

Comments
 (0)