heat/heat/tests/aws/test_eip.py

907 lines
36 KiB
Python

#
# 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 copy
import mock
from neutronclient.common import exceptions as q_exceptions
from neutronclient.v2_0 import client as neutronclient
import six
from heat.common import exception
from heat.common import short_id
from heat.common import template_format
from heat.engine.clients.os import nova
from heat.engine import node_data
from heat.engine import resource
from heat.engine.resources.aws.ec2 import eip
from heat.engine import rsrc_defn
from heat.engine import scheduler
from heat.engine import stack as parser
from heat.engine import stk_defn
from heat.engine import template as tmpl
from heat.tests import common
from heat.tests.openstack.nova import fakes as fakes_nova
from heat.tests import utils
eip_template = '''
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "EIP Test",
"Parameters" : {},
"Resources" : {
"IPAddress" : {
"Type" : "AWS::EC2::EIP",
"Properties" : {
"InstanceId" : { "Ref" : "WebServer" }
}
},
"WebServer": {
"Type": "AWS::EC2::Instance",
}
}
}
'''
eip_template_ipassoc = '''
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "EIP Test",
"Parameters" : {},
"Resources" : {
"IPAddress" : {
"Type" : "AWS::EC2::EIP"
},
"IPAssoc" : {
"Type" : "AWS::EC2::EIPAssociation",
"Properties" : {
"InstanceId" : { "Ref" : "WebServer" },
"EIP" : { "Ref" : "IPAddress" }
}
},
"WebServer": {
"Type": "AWS::EC2::Instance",
}
}
}
'''
eip_template_ipassoc2 = '''
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "EIP Test",
"Parameters" : {},
"Resources" : {
"the_eip" : {
"Type" : "AWS::EC2::EIP",
"Properties" : {
"Domain": "vpc"
}
},
"IPAssoc" : {
"Type" : "AWS::EC2::EIPAssociation",
"Properties" : {
"AllocationId" : 'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
"NetworkInterfaceId" : { "Ref" : "the_nic" }
}
},
"the_vpc" : {
"Type" : "AWS::EC2::VPC",
"Properties" : {
"CidrBlock" : "10.0.0.0/16"
}
},
"the_subnet" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"CidrBlock" : "10.0.0.0/24",
"VpcId" : { "Ref" : "the_vpc" }
}
},
"the_nic" : {
"Type" : "AWS::EC2::NetworkInterface",
"Properties" : {
"PrivateIpAddress": "10.0.0.100",
"SubnetId": { "Ref": "the_subnet" }
}
},
}
}
'''
eip_template_ipassoc3 = '''
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "EIP Test",
"Parameters" : {},
"Resources" : {
"the_eip" : {
"Type" : "AWS::EC2::EIP",
"Properties" : {
"Domain": "vpc"
}
},
"IPAssoc" : {
"Type" : "AWS::EC2::EIPAssociation",
"Properties" : {
"AllocationId" : 'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
"InstanceId" : '1fafbe59-2332-4f5f-bfa4-517b4d6c1b65'
}
}
}
}
'''
ipassoc_template_validate = '''
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "EIP Test",
"Parameters" : {},
"Resources" : {
"eip" : {
"Type" : "AWS::EC2::EIP",
"Properties" : {
"Domain": "vpc"
}
},
"IPAssoc" : {
"Type" : "AWS::EC2::EIPAssociation",
"Properties" : {
"EIP" : {'Ref': 'eip'},
"InstanceId" : '1fafbe59-2332-4f5f-bfa4-517b4d6c1b65'
}
}
}
}
'''
class EIPTest(common.HeatTestCase):
def setUp(self):
# force Nova, will test Neutron below
super(EIPTest, self).setUp()
self.fc = fakes_nova.FakeClient()
self.patchobject(nova.NovaClientPlugin, 'client',
return_value=self.fc)
self.mock_list_net = self.patchobject(neutronclient.Client,
'list_networks')
self.mock_create_fip = self.patchobject(neutronclient.Client,
'create_floatingip')
self.mock_show_fip = self.patchobject(neutronclient.Client,
'show_floatingip')
self.patchobject(neutronclient.Client, 'update_floatingip')
self.patchobject(neutronclient.Client, 'delete_floatingip')
self.mock_list_fips = self.patchobject(neutronclient.Client,
'list_floatingips')
def mock_interface(self, port, ip):
class MockIface(object):
def __init__(self, port_id, fixed_ip):
self.port_id = port_id
self.fixed_ips = [{'ip_address': fixed_ip}]
return MockIface(port, ip)
def mock_list_floatingips(self):
self.mock_list_fips.return_value = {
'floatingips': [{'id':
"fc68ea2c-b60b-4b4f-bd82-94ec81110766"}]}
def mock_create_floatingip(self):
self.mock_list_net.return_value = {'networks': [{
'status': 'ACTIVE',
'subnets': [],
'name': 'nova',
'router:external': True,
'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
'admin_state_up': True,
'shared': True,
'id': 'eeee'
}]}
self.mock_create_fip.return_value = {'floatingip': {
"status": "ACTIVE",
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
"floating_ip_address": "11.0.0.1"
}}
def mock_show_floatingip(self):
self.mock_show_fip.return_value = {'floatingip': {
'router_id': None,
'tenant_id': 'e936e6cd3e0b48dcb9ff853a8f253257',
'floating_network_id': 'eeee',
'fixed_ip_address': None,
'floating_ip_address': '11.0.0.1',
'port_id': None,
'id': 'ffff'
}}
def create_eip(self, t, stack, resource_name):
resource_defns = stack.t.resource_definitions(stack)
rsrc = eip.ElasticIp(resource_name,
resource_defns[resource_name],
stack)
self.assertIsNone(rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
stk_defn.update_resource_data(stack.defn, resource_name,
rsrc.node_data())
return rsrc
def create_association(self, t, stack, resource_name):
resource_defns = stack.t.resource_definitions(stack)
rsrc = eip.ElasticIpAssociation(resource_name,
resource_defns[resource_name],
stack)
self.assertIsNone(rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
stk_defn.update_resource_data(stack.defn, resource_name,
rsrc.node_data())
return rsrc
def test_eip(self):
mock_server = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get',
return_value=mock_server)
self.mock_create_floatingip()
iface = self.mock_interface('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'1.2.3.4')
self.patchobject(mock_server, 'interface_list', return_value=[iface])
t = template_format.parse(eip_template)
stack = utils.parse_stack(t)
rsrc = self.create_eip(t, stack, 'IPAddress')
try:
self.assertEqual('11.0.0.1', rsrc.FnGetRefId())
rsrc.refid = None
self.assertEqual('11.0.0.1', rsrc.FnGetRefId())
self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
rsrc.FnGetAtt('AllocationId'))
self.assertRaises(exception.InvalidTemplateAttribute,
rsrc.FnGetAtt, 'Foo')
finally:
scheduler.TaskRunner(rsrc.destroy)()
def test_eip_update(self):
server_old = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get',
return_value=server_old)
iface = self.mock_interface('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'1.2.3.4')
self.patchobject(server_old, 'interface_list', return_value=[iface])
self.mock_create_floatingip()
t = template_format.parse(eip_template)
stack = utils.parse_stack(t)
rsrc = self.create_eip(t, stack, 'IPAddress')
self.assertEqual('11.0.0.1', rsrc.FnGetRefId())
# update with the new InstanceId
server_update = self.fc.servers.list()[1]
self.patchobject(self.fc.servers, 'get',
return_value=server_update)
self.patchobject(server_update, 'interface_list', return_value=[iface])
props = copy.deepcopy(rsrc.properties.data)
update_server_id = '5678'
props['InstanceId'] = update_server_id
update_snippet = rsrc_defn.ResourceDefinition(rsrc.name, rsrc.type(),
props)
scheduler.TaskRunner(rsrc.update, update_snippet)()
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
self.assertEqual('11.0.0.1', rsrc.FnGetRefId())
# update without InstanceId
props = copy.deepcopy(rsrc.properties.data)
props.pop('InstanceId')
update_snippet = rsrc_defn.ResourceDefinition(rsrc.name, rsrc.type(),
props)
scheduler.TaskRunner(rsrc.update, update_snippet)()
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
def test_association_eip(self):
mock_server = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get',
return_value=mock_server)
iface = self.mock_interface('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'1.2.3.4')
self.patchobject(mock_server, 'interface_list', return_value=[iface])
self.mock_create_floatingip()
self.mock_show_floatingip()
self.mock_list_floatingips()
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
rsrc = self.create_eip(t, stack, 'IPAddress')
association = self.create_association(t, stack, 'IPAssoc')
try:
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.assertEqual((association.CREATE, association.COMPLETE),
association.state)
self.assertEqual(utils.PhysName(stack.name, association.name),
association.FnGetRefId())
self.assertEqual('11.0.0.1', association.properties['EIP'])
finally:
scheduler.TaskRunner(association.delete)()
scheduler.TaskRunner(rsrc.delete)()
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
self.assertEqual((association.DELETE, association.COMPLETE),
association.state)
def test_eip_with_exception(self):
self.mock_list_net.return_value = {'networks': [{
'status': 'ACTIVE',
'subnets': [],
'name': 'nova',
'router:external': True,
'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
'admin_state_up': True,
'shared': True,
'id': 'eeee'
}]}
self.patchobject(neutronclient.Client, 'create_floatingip',
side_effect=neutronclient.exceptions.NotFound)
t = template_format.parse(eip_template)
stack = utils.parse_stack(t)
resource_name = 'IPAddress'
resource_defns = stack.t.resource_definitions(stack)
rsrc = eip.ElasticIp(resource_name,
resource_defns[resource_name],
stack)
self.assertRaises(neutronclient.exceptions.NotFound,
rsrc.handle_create)
@mock.patch.object(eip.ElasticIp, '_ipaddress')
def test_FnGetRefId_resource_name(self, mock_ipaddr):
t = template_format.parse(ipassoc_template_validate)
stack = utils.parse_stack(t)
rsrc = stack['eip']
mock_ipaddr.return_value = None
self.assertEqual('eip', rsrc.FnGetRefId())
@mock.patch.object(eip.ElasticIp, '_ipaddress')
def test_FnGetRefId_resource_ip(self, mock_ipaddr):
t = template_format.parse(ipassoc_template_validate)
stack = utils.parse_stack(t)
rsrc = stack['eip']
mock_ipaddr.return_value = 'x.x.x.x'
self.assertEqual('x.x.x.x', rsrc.FnGetRefId())
def test_FnGetRefId_convergence_cache_data(self):
t = template_format.parse(ipassoc_template_validate)
template = tmpl.Template(t)
stack = parser.Stack(utils.dummy_context(), 'test', template,
cache_data={
'eip': node_data.NodeData.from_dict({
'uuid': mock.ANY,
'id': mock.ANY,
'action': 'CREATE',
'status': 'COMPLETE',
'reference_id': '1.1.1.1'})})
rsrc = stack.defn['eip']
self.assertEqual('1.1.1.1', rsrc.FnGetRefId())
class AllocTest(common.HeatTestCase):
def setUp(self):
super(AllocTest, self).setUp()
self.fc = fakes_nova.FakeClient()
self.patchobject(nova.NovaClientPlugin, 'client',
return_value=self.fc)
self.mock_list_net = self.patchobject(neutronclient.Client,
'list_networks')
self.mock_create_fip = self.patchobject(neutronclient.Client,
'create_floatingip')
self.mock_show_fip = self.patchobject(neutronclient.Client,
'show_floatingip')
self.patchobject(neutronclient.Client, 'update_floatingip')
self.patchobject(neutronclient.Client, 'delete_floatingip')
self.mock_list_fips = self.patchobject(neutronclient.Client,
'list_floatingips')
self.patchobject(neutronclient.Client, 'add_gateway_router')
self.mock_list_ports = self.patchobject(neutronclient.Client,
'list_ports')
self.mock_show_net = self.patchobject(neutronclient.Client,
'show_network')
self.mock_list_routers = self.patchobject(neutronclient.Client,
'list_routers')
self.patchobject(neutronclient.Client,
'remove_gateway_router')
def mock_interface(self, port, ip):
class MockIface(object):
def __init__(self, port_id, fixed_ip):
self.port_id = port_id
self.fixed_ips = [{'ip_address': fixed_ip}]
return MockIface(port, ip)
def _setup_test_stack_validate(self, stack_name):
t = template_format.parse(ipassoc_template_validate)
template = tmpl.Template(t)
stack = parser.Stack(utils.dummy_context(), stack_name,
template, stack_id='12233',
stack_user_project_id='8888')
stack.validate()
return template, stack
def _validate_properties(self, stack, template, expected):
resource_defns = template.resource_definitions(stack)
rsrc = eip.ElasticIpAssociation('validate_eip_ass',
resource_defns['IPAssoc'],
stack)
exc = self.assertRaises(exception.StackValidationFailed,
rsrc.validate)
self.assertIn(expected, six.text_type(exc))
def mock_show_network(self):
vpc_name = utils.PhysName('test_stack', 'the_vpc')
self.mock_show_net.return_value = {"network": {
"status": "BUILD",
"subnets": [],
"name": vpc_name,
"admin_state_up": False,
"shared": False,
"tenant_id": "c1210485b2424d48804aad5d39c61b8f",
"id": "22c26451-cf27-4d48-9031-51f5e397b84e"
}}
def create_eip(self, t, stack, resource_name):
rsrc = eip.ElasticIp(resource_name,
stack.defn.resource_definition(resource_name),
stack)
self.assertIsNone(rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
stk_defn.update_resource_data(stack.defn, resource_name,
rsrc.node_data())
return rsrc
def create_association(self, t, stack, resource_name):
resource_defn = stack.defn.resource_definition(resource_name)
rsrc = eip.ElasticIpAssociation(resource_name,
resource_defn,
stack)
self.assertIsNone(rsrc.validate())
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
stk_defn.update_resource_data(stack.defn, resource_name,
rsrc.node_data())
return rsrc
def mock_create_floatingip(self):
self.mock_list_net.return_value = {'networks': [{
'status': 'ACTIVE',
'subnets': [],
'name': 'nova',
'router:external': True,
'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
'admin_state_up': True,
'shared': True,
'id': 'eeee'
}]}
self.mock_create_fip.return_value = {'floatingip': {
"status": "ACTIVE",
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
"floating_ip_address": "11.0.0.1"
}}
def mock_list_floatingips(self):
self.mock_list_fips.return_value = {
'floatingips': [{'id':
"fc68ea2c-b60b-4b4f-bd82-94ec81110766"}]}
def mock_show_floatingip(self):
self.mock_show_fip.return_value = {'floatingip': {
'router_id': None,
'tenant_id': 'e936e6cd3e0b48dcb9ff853a8f253257',
'floating_network_id': 'eeee',
'fixed_ip_address': None,
'floating_ip_address': '11.0.0.1',
'port_id': None,
'id': 'ffff'
}}
def mock_list_ports(self):
self.mock_list_ports.return_value = {"ports": [{
"status": "DOWN",
"binding:host_id": "null",
"name": "wp-NIC-yu7fc7l4g5p6",
"admin_state_up": True,
"network_id": "22c26451-cf27-4d48-9031-51f5e397b84e",
"tenant_id": "ecf538ec1729478fa1f97f1bf4fdcf7b",
"binding:vif_type": "ovs",
"device_owner": "",
"binding:capabilities": {"port_filter": True},
"mac_address": "fa:16:3e:62:2d:4f",
"fixed_ips": [{"subnet_id": "mysubnetid-70ec",
"ip_address": "192.168.9.2"}],
"id": "a000228d-b40b-4124-8394-a4082ae1b76b",
"security_groups": ["5c6f529d-3186-4c36-84c0-af28b8daac7b"],
"device_id": ""
}]}
def mock_list_instance_ports(self):
self.mock_list_ports.return_value = {"ports": [{
"status": "DOWN",
"binding:host_id": "null",
"name": "wp-NIC-yu7fc7l4g5p6",
"admin_state_up": True,
"network_id": "22c26451-cf27-4d48-9031-51f5e397b84e",
"tenant_id": "ecf538ec1729478fa1f97f1bf4fdcf7b",
"binding:vif_type": "ovs",
"device_owner": "",
"binding:capabilities": {"port_filter": True},
"mac_address": "fa:16:3e:62:2d:4f",
"fixed_ips": [{"subnet_id": "mysubnetid-70ec",
"ip_address": "192.168.9.2"}],
"id": "a000228d-b40b-4124-8394-a4082ae1b76c",
"security_groups": ["5c6f529d-3186-4c36-84c0-af28b8daac7b"],
"device_id": ""
}]}
def mock_router_for_vpc(self):
vpc_name = utils.PhysName('test_stack', 'the_vpc')
self.mock_list_routers.return_value = {
"routers": [{
"status": "ACTIVE",
"external_gateway_info": {
"network_id": "zzzz",
"enable_snat": True},
"name": vpc_name,
"admin_state_up": True,
"tenant_id": "3e21026f2dc94372b105808c0e721661",
"routes": [],
"id": "bbbb"
}]
}
def mock_no_router_for_vpc(self):
self.mock_list_routers.return_value = {
"routers": []
}
def test_association_allocationid(self):
self.mock_create_floatingip()
self.mock_router_for_vpc()
self.mock_show_network()
self.mock_list_ports()
self.mock_show_floatingip()
t = template_format.parse(eip_template_ipassoc2)
stack = utils.parse_stack(t)
rsrc = self.create_eip(t, stack, 'the_eip')
association = self.create_association(t, stack, 'IPAssoc')
scheduler.TaskRunner(association.delete)()
scheduler.TaskRunner(rsrc.delete)()
self.assertEqual((association.DELETE, association.COMPLETE),
association.state)
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
def test_association_allocationid_with_instance(self):
server = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get', return_value=server)
self.mock_show_network()
self.mock_create_floatingip()
self.mock_list_instance_ports()
self.mock_no_router_for_vpc()
t = template_format.parse(eip_template_ipassoc3)
stack = utils.parse_stack(t)
rsrc = self.create_eip(t, stack, 'the_eip')
association = self.create_association(t, stack, 'IPAssoc')
scheduler.TaskRunner(association.delete)()
scheduler.TaskRunner(rsrc.delete)()
self.assertEqual((association.DELETE, association.COMPLETE),
association.state)
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
def test_validate_properties_EIP_and_AllocationId(self):
server = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get', return_value=server)
template, stack = self._setup_test_stack_validate(
stack_name='validate_EIP_AllocationId')
properties = template.t['Resources']['IPAssoc']['Properties']
# test with EIP and AllocationId
properties['AllocationId'] = 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
expected = ("Either 'EIP' or 'AllocationId' must be provided.")
self._validate_properties(stack, template, expected)
# test without EIP and AllocationId
properties.pop('AllocationId')
properties.pop('EIP')
self._validate_properties(stack, template, expected)
def test_validate_EIP_and_InstanceId(self):
server = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get', return_value=server)
template, stack = self._setup_test_stack_validate(
stack_name='validate_EIP_InstanceId')
properties = template.t['Resources']['IPAssoc']['Properties']
# test with EIP and no InstanceId
properties.pop('InstanceId')
expected = ("Must specify 'InstanceId' if you specify 'EIP'.")
self._validate_properties(stack, template, expected)
def test_validate_without_NetworkInterfaceId_and_InstanceId(self):
server = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get', return_value=server)
template, stack = self._setup_test_stack_validate(
stack_name='validate_EIP_InstanceId')
properties = template.t['Resources']['IPAssoc']['Properties']
# test without NetworkInterfaceId and InstanceId
properties.pop('InstanceId')
properties.pop('EIP')
allocation_id = '1fafbe59-2332-4f5f-bfa4-517b4d6c1b65'
properties['AllocationId'] = allocation_id
resource_defns = template.resource_definitions(stack)
rsrc = eip.ElasticIpAssociation('validate_eip_ass',
resource_defns['IPAssoc'],
stack)
exc = self.assertRaises(exception.PropertyUnspecifiedError,
rsrc.validate)
self.assertIn('At least one of the following properties '
'must be specified: InstanceId, NetworkInterfaceId',
six.text_type(exc))
def test_delete_association_successful_if_create_failed(self):
server = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get', return_value=server)
self.mock_create_floatingip()
self.mock_show_floatingip()
self.patchobject(server, 'interface_list',
side_effect=[q_exceptions.NotFound('Not FOund')])
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
self.create_eip(t, stack, 'IPAddress')
resource_defns = stack.t.resource_definitions(stack)
rsrc = eip.ElasticIpAssociation('IPAssoc',
resource_defns['IPAssoc'],
stack)
self.assertIsNone(rsrc.validate())
self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(rsrc.create))
self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
scheduler.TaskRunner(rsrc.delete)()
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
def test_update_association_with_InstanceId(self):
server = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get', return_value=server)
iface = self.mock_interface('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'1.2.3.4')
self.patchobject(server, 'interface_list', return_value=[iface])
self.mock_create_floatingip()
self.mock_list_floatingips()
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
self.create_eip(t, stack, 'IPAddress')
ass = self.create_association(t, stack, 'IPAssoc')
self.assertEqual('11.0.0.1', ass.properties['EIP'])
server_update = self.fc.servers.list()[1]
self.patchobject(self.fc.servers, 'get', return_value=server_update)
self.patchobject(server_update, 'interface_list', return_value=[iface])
# update with the new InstanceId
props = copy.deepcopy(ass.properties.data)
update_server_id = '5678'
props['InstanceId'] = update_server_id
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack.defn,
props))
scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
def test_update_association_with_EIP(self):
server = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get', return_value=server)
iface = self.mock_interface('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'1.2.3.4')
self.patchobject(server, 'interface_list', return_value=[iface])
self.mock_create_floatingip()
self.mock_list_floatingips()
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
self.create_eip(t, stack, 'IPAddress')
ass = self.create_association(t, stack, 'IPAssoc')
# update with the new EIP
props = copy.deepcopy(ass.properties.data)
update_eip = '11.0.0.2'
props['EIP'] = update_eip
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack.defn,
props))
scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
def test_update_association_with_AllocationId_or_EIP(self):
server = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get', return_value=server)
iface = self.mock_interface('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'1.2.3.4')
self.patchobject(server, 'interface_list', return_value=[iface])
self.mock_create_floatingip()
self.mock_list_floatingips()
self.mock_list_instance_ports()
self.mock_show_network()
self.mock_no_router_for_vpc()
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
self.create_eip(t, stack, 'IPAddress')
ass = self.create_association(t, stack, 'IPAssoc')
self.assertEqual('11.0.0.1', ass.properties['EIP'])
# change EIP to AllocationId
props = copy.deepcopy(ass.properties.data)
update_allocationId = 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
props['AllocationId'] = update_allocationId
props.pop('EIP')
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack.defn,
props))
scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
stk_defn.update_resource_data(stack.defn, ass.name, ass.node_data())
# change AllocationId to EIP
props = copy.deepcopy(ass.properties.data)
update_eip = '11.0.0.2'
props['EIP'] = update_eip
props.pop('AllocationId')
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack.defn,
props))
scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
def test_update_association_needs_update_InstanceId(self):
server = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get', return_value=server)
iface = self.mock_interface('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'1.2.3.4')
self.patchobject(server, 'interface_list', return_value=[iface])
self.mock_create_floatingip()
self.mock_list_floatingips()
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
self.create_eip(t, stack, 'IPAddress')
before_props = {'InstanceId': {'Ref': 'WebServer'},
'EIP': '11.0.0.1'}
after_props = {'InstanceId': {'Ref': 'WebServer2'},
'EIP': '11.0.0.1'}
before = self.create_association(t, stack, 'IPAssoc')
after = rsrc_defn.ResourceDefinition(before.name, before.type(),
after_props)
self.assertTrue(resource.UpdateReplace,
before._needs_update(after, before, after_props,
before_props, None))
def test_update_association_needs_update_InstanceId_EIP(self):
server = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get', return_value=server)
iface = self.mock_interface('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'1.2.3.4')
self.patchobject(server, 'interface_list', return_value=[iface])
self.mock_list_floatingips()
self.mock_create_floatingip()
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
self.create_eip(t, stack, 'IPAddress')
after_props = {'InstanceId': '5678',
'EIP': '11.0.0.2'}
before = self.create_association(t, stack, 'IPAssoc')
after = rsrc_defn.ResourceDefinition(before.name, before.type(),
after_props)
updater = scheduler.TaskRunner(before.update, after)
self.assertRaises(resource.UpdateReplace, updater)
def test_update_association_with_NetworkInterfaceId_or_InstanceId(self):
server = self.fc.servers.list()[0]
self.patchobject(self.fc.servers, 'get', return_value=server)
iface = self.mock_interface('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
'1.2.3.4')
self.patchobject(server, 'interface_list', return_value=[iface])
self.mock_create_floatingip()
self.mock_list_ports()
self.mock_show_network()
self.mock_no_router_for_vpc()
t = template_format.parse(eip_template_ipassoc2)
stack = utils.parse_stack(t)
self.create_eip(t, stack, 'the_eip')
ass = self.create_association(t, stack, 'IPAssoc')
upd_server = self.fc.servers.list()[1]
self.patchobject(self.fc.servers, 'get', return_value=upd_server)
self.mock_list_instance_ports()
# update with the new NetworkInterfaceId
props = copy.deepcopy(ass.properties.data)
update_networkInterfaceId = 'a000228d-b40b-4124-8394-a4082ae1b76b'
props['NetworkInterfaceId'] = update_networkInterfaceId
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack.defn,
props))
scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
# update with the InstanceId
props = copy.deepcopy(ass.properties.data)
instance_id = '5678'
props.pop('NetworkInterfaceId')
props['InstanceId'] = instance_id
update_snippet = rsrc_defn.ResourceDefinition(ass.name, ass.type(),
stack.t.parse(stack.defn,
props))
scheduler.TaskRunner(ass.update, update_snippet)()
self.assertEqual((ass.UPDATE, ass.COMPLETE), ass.state)
def test_eip_allocation_refid_resource_name(self):
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
rsrc = stack['IPAssoc']
rsrc.id = '123'
rsrc.uuid = '9bfb9456-3fe8-41f4-b318-9dba18eeef74'
rsrc.action = 'CREATE'
expected = '%s-%s-%s' % (rsrc.stack.name,
rsrc.name,
short_id.get_id(rsrc.uuid))
self.assertEqual(expected, rsrc.FnGetRefId())
def test_eip_allocation_refid_resource_id(self):
t = template_format.parse(eip_template_ipassoc)
stack = utils.parse_stack(t)
rsrc = stack['IPAssoc']
rsrc.resource_id = 'phy-rsrc-id'
self.assertEqual('phy-rsrc-id', rsrc.FnGetRefId())
def test_eip_allocation_refid_convergence_cache_data(self):
t = template_format.parse(eip_template_ipassoc)
cache_data = {'IPAssoc': node_data.NodeData.from_dict({
'uuid': mock.ANY,
'id': mock.ANY,
'action': 'CREATE',
'status': 'COMPLETE',
'reference_id': 'convg_xyz'
})}
stack = utils.parse_stack(t, cache_data=cache_data)
rsrc = stack.defn['IPAssoc']
self.assertEqual('convg_xyz', rsrc.FnGetRefId())