Make sure NetworkInterfaces and SubnetId updatable
We should make the properties 'NetworkInterfaces' and 'SubnetId' updatable for AWS::EC2::Instance resource, so we can update the networks for an instance. Change-Id: I4a475fee6416696558807c189473a90d7517cfc0 Closes-Bug: #1280151
This commit is contained in:
parent
f18bb8b5af
commit
0ddd9e0d9f
@ -12,6 +12,8 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import copy
|
||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
|
|
||||||
cfg.CONF.import_opt('instance_user', 'heat.common.config')
|
cfg.CONF.import_opt('instance_user', 'heat.common.config')
|
||||||
@ -208,7 +210,8 @@ class Instance(resource.Resource):
|
|||||||
),
|
),
|
||||||
NETWORK_INTERFACES: properties.Schema(
|
NETWORK_INTERFACES: properties.Schema(
|
||||||
properties.Schema.LIST,
|
properties.Schema.LIST,
|
||||||
_('Network interfaces to associate with instance.')
|
_('Network interfaces to associate with instance.'),
|
||||||
|
update_allowed=True
|
||||||
),
|
),
|
||||||
SOURCE_DEST_CHECK: properties.Schema(
|
SOURCE_DEST_CHECK: properties.Schema(
|
||||||
properties.Schema.BOOLEAN,
|
properties.Schema.BOOLEAN,
|
||||||
@ -217,7 +220,8 @@ class Instance(resource.Resource):
|
|||||||
),
|
),
|
||||||
SUBNET_ID: properties.Schema(
|
SUBNET_ID: properties.Schema(
|
||||||
properties.Schema.STRING,
|
properties.Schema.STRING,
|
||||||
_('Subnet ID to launch instance in.')
|
_('Subnet ID to launch instance in.'),
|
||||||
|
update_allowed=True
|
||||||
),
|
),
|
||||||
TAGS: properties.Schema(
|
TAGS: properties.Schema(
|
||||||
properties.Schema.LIST,
|
properties.Schema.LIST,
|
||||||
@ -523,10 +527,18 @@ class Instance(resource.Resource):
|
|||||||
return ((vol[self.VOLUME_ID],
|
return ((vol[self.VOLUME_ID],
|
||||||
vol[self.VOLUME_DEVICE]) for vol in volumes)
|
vol[self.VOLUME_DEVICE]) for vol in volumes)
|
||||||
|
|
||||||
|
def _remove_matched_ifaces(self, old_network_ifaces, new_network_ifaces):
|
||||||
|
# find matches and remove them from old and new ifaces
|
||||||
|
old_network_ifaces_copy = copy.deepcopy(old_network_ifaces)
|
||||||
|
for iface in old_network_ifaces_copy:
|
||||||
|
if iface in new_network_ifaces:
|
||||||
|
new_network_ifaces.remove(iface)
|
||||||
|
old_network_ifaces.remove(iface)
|
||||||
|
|
||||||
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
|
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
|
||||||
if 'Metadata' in tmpl_diff:
|
if 'Metadata' in tmpl_diff:
|
||||||
self.metadata = tmpl_diff['Metadata']
|
self.metadata = tmpl_diff['Metadata']
|
||||||
|
checkers = []
|
||||||
server = None
|
server = None
|
||||||
if self.TAGS in prop_diff:
|
if self.TAGS in prop_diff:
|
||||||
server = self.nova().servers.get(self.resource_id)
|
server = self.nova().servers.get(self.resource_id)
|
||||||
@ -541,11 +553,82 @@ class Instance(resource.Resource):
|
|||||||
server = self.nova().servers.get(self.resource_id)
|
server = self.nova().servers.get(self.resource_id)
|
||||||
checker = scheduler.TaskRunner(nova_utils.resize, server, flavor,
|
checker = scheduler.TaskRunner(nova_utils.resize, server, flavor,
|
||||||
flavor_id)
|
flavor_id)
|
||||||
checker.start()
|
checkers.append(checker)
|
||||||
return checker
|
if self.NETWORK_INTERFACES in prop_diff:
|
||||||
|
new_network_ifaces = prop_diff.get(self.NETWORK_INTERFACES)
|
||||||
|
old_network_ifaces = self.properties.get(self.NETWORK_INTERFACES)
|
||||||
|
subnet_id = (
|
||||||
|
prop_diff.get(self.SUBNET_ID) or
|
||||||
|
self.properties.get(self.SUBNET_ID))
|
||||||
|
security_groups = self._get_security_groups()
|
||||||
|
if not server:
|
||||||
|
server = self.nova().servers.get(self.resource_id)
|
||||||
|
# if there is entrys in old_network_ifaces and new_network_ifaces,
|
||||||
|
# remove the same entrys from old and new ifaces
|
||||||
|
if old_network_ifaces and new_network_ifaces:
|
||||||
|
# there are four situations:
|
||||||
|
# 1.old includes new, such as: old = 2,3, new = 2
|
||||||
|
# 2.new includes old, such as: old = 2,3, new = 1,2,3
|
||||||
|
# 3.has overlaps, such as: old = 2,3, new = 1,2
|
||||||
|
# 4.different, such as: old = 2,3, new = 1,4
|
||||||
|
# detach unmatched ones in old, attach unmatched ones in new
|
||||||
|
self._remove_matched_ifaces(old_network_ifaces,
|
||||||
|
new_network_ifaces)
|
||||||
|
if old_network_ifaces:
|
||||||
|
old_nics = self._build_nics(old_network_ifaces)
|
||||||
|
for nic in old_nics:
|
||||||
|
checker = scheduler.TaskRunner(
|
||||||
|
server.interface_detach,
|
||||||
|
nic['port-id'])
|
||||||
|
checkers.append(checker)
|
||||||
|
if new_network_ifaces:
|
||||||
|
new_nics = self._build_nics(new_network_ifaces)
|
||||||
|
for nic in new_nics:
|
||||||
|
checker = scheduler.TaskRunner(
|
||||||
|
server.interface_attach,
|
||||||
|
nic['port-id'],
|
||||||
|
None, None)
|
||||||
|
checkers.append(checker)
|
||||||
|
# if the interfaces not come from property 'NetworkInterfaces',
|
||||||
|
# the situation is somewhat complex, so to detach the old ifaces,
|
||||||
|
# and then attach the new ones.
|
||||||
|
else:
|
||||||
|
interfaces = server.interface_list()
|
||||||
|
for iface in interfaces:
|
||||||
|
checker = scheduler.TaskRunner(server.interface_detach,
|
||||||
|
iface.port_id)
|
||||||
|
checkers.append(checker)
|
||||||
|
nics = self._build_nics(new_network_ifaces,
|
||||||
|
security_groups=security_groups,
|
||||||
|
subnet_id=subnet_id)
|
||||||
|
# 'SubnetId' property is empty(or None) and
|
||||||
|
# 'NetworkInterfaces' property is empty(or None),
|
||||||
|
# _build_nics() will return nics = None,we should attach
|
||||||
|
# first free port, according to similar behavior during
|
||||||
|
# instance creation
|
||||||
|
if not nics:
|
||||||
|
checker = scheduler.TaskRunner(server.interface_attach,
|
||||||
|
None, None, None)
|
||||||
|
checkers.append(checker)
|
||||||
|
else:
|
||||||
|
for nic in nics:
|
||||||
|
checker = scheduler.TaskRunner(
|
||||||
|
server.interface_attach,
|
||||||
|
nic['port-id'], None, None)
|
||||||
|
checkers.append(checker)
|
||||||
|
|
||||||
def check_update_complete(self, checker):
|
if checkers:
|
||||||
return checker.step() if checker is not None else True
|
checkers[0].start()
|
||||||
|
return checkers
|
||||||
|
|
||||||
|
def check_update_complete(self, checkers):
|
||||||
|
'''Push all checkers to completion in list order.'''
|
||||||
|
for checker in checkers:
|
||||||
|
if not checker.started():
|
||||||
|
checker.start()
|
||||||
|
if not checker.step():
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def metadata_update(self, new_metadata=None):
|
def metadata_update(self, new_metadata=None):
|
||||||
'''
|
'''
|
||||||
|
@ -377,6 +377,270 @@ class InstancesTest(HeatTestCase):
|
|||||||
self.assertEqual((instance.UPDATE, instance.FAILED), instance.state)
|
self.assertEqual((instance.UPDATE, instance.FAILED), instance.state)
|
||||||
self.m.VerifyAll()
|
self.m.VerifyAll()
|
||||||
|
|
||||||
|
def create_fake_iface(self, port, net, ip):
|
||||||
|
class fake_interface():
|
||||||
|
def __init__(self, port_id, net_id, fixed_ip):
|
||||||
|
self.port_id = port_id
|
||||||
|
self.net_id = net_id
|
||||||
|
self.fixed_ips = [{'ip_address': fixed_ip}]
|
||||||
|
|
||||||
|
return fake_interface(port, net, ip)
|
||||||
|
|
||||||
|
def test_instance_update_network_interfaces(self):
|
||||||
|
"""
|
||||||
|
Instance.handle_update supports changing the NetworkInterfaces,
|
||||||
|
and makes the change making a resize API call against Nova.
|
||||||
|
"""
|
||||||
|
return_server = self.fc.servers.list()[1]
|
||||||
|
return_server.id = 1234
|
||||||
|
instance = self._create_test_instance(return_server,
|
||||||
|
'ud_network_interfaces')
|
||||||
|
# if new overlaps with old, detach the different ones in old, and
|
||||||
|
# attach the different ones in new
|
||||||
|
old_interfaces = [
|
||||||
|
{'NetworkInterfaceId': 'ea29f957-cd35-4364-98fb-57ce9732c10d',
|
||||||
|
'DeviceIndex': '2'},
|
||||||
|
{'NetworkInterfaceId': 'd1e9c73c-04fe-4e9e-983c-d5ef94cd1a46',
|
||||||
|
'DeviceIndex': '1'}]
|
||||||
|
new_interfaces = [
|
||||||
|
{'NetworkInterfaceId': 'ea29f957-cd35-4364-98fb-57ce9732c10d',
|
||||||
|
'DeviceIndex': '2'},
|
||||||
|
{'NetworkInterfaceId': '34b752ec-14de-416a-8722-9531015e04a5',
|
||||||
|
'DeviceIndex': '3'}]
|
||||||
|
|
||||||
|
instance.t['Properties']['NetworkInterfaces'] = old_interfaces
|
||||||
|
update_template = copy.deepcopy(instance.t)
|
||||||
|
update_template['Properties']['NetworkInterfaces'] = new_interfaces
|
||||||
|
|
||||||
|
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||||
|
self.fc.servers.get(1234).AndReturn(return_server)
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_detach')
|
||||||
|
return_server.interface_detach(
|
||||||
|
'd1e9c73c-04fe-4e9e-983c-d5ef94cd1a46').AndReturn(None)
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_attach')
|
||||||
|
return_server.interface_attach('34b752ec-14de-416a-8722-9531015e04a5',
|
||||||
|
None, None).AndReturn(None)
|
||||||
|
self.m.ReplayAll()
|
||||||
|
|
||||||
|
scheduler.TaskRunner(instance.update, update_template)()
|
||||||
|
self.assertEqual((instance.UPDATE, instance.COMPLETE), instance.state)
|
||||||
|
self.m.VerifyAll()
|
||||||
|
|
||||||
|
def test_instance_update_network_interfaces_old_include_new(self):
|
||||||
|
"""
|
||||||
|
Instance.handle_update supports changing the NetworkInterfaces,
|
||||||
|
and makes the change making a resize API call against Nova.
|
||||||
|
"""
|
||||||
|
return_server = self.fc.servers.list()[1]
|
||||||
|
return_server.id = 1234
|
||||||
|
instance = self._create_test_instance(return_server,
|
||||||
|
'ud_network_interfaces')
|
||||||
|
# if old include new, just detach the different ones in old
|
||||||
|
old_interfaces = [
|
||||||
|
{'NetworkInterfaceId': 'ea29f957-cd35-4364-98fb-57ce9732c10d',
|
||||||
|
'DeviceIndex': '2'},
|
||||||
|
{'NetworkInterfaceId': 'd1e9c73c-04fe-4e9e-983c-d5ef94cd1a46',
|
||||||
|
'DeviceIndex': '1'}]
|
||||||
|
new_interfaces = [
|
||||||
|
{'NetworkInterfaceId': 'ea29f957-cd35-4364-98fb-57ce9732c10d',
|
||||||
|
'DeviceIndex': '2'}]
|
||||||
|
|
||||||
|
instance.t['Properties']['NetworkInterfaces'] = old_interfaces
|
||||||
|
update_template = copy.deepcopy(instance.t)
|
||||||
|
update_template['Properties']['NetworkInterfaces'] = new_interfaces
|
||||||
|
|
||||||
|
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||||
|
self.fc.servers.get(1234).AndReturn(return_server)
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_detach')
|
||||||
|
return_server.interface_detach(
|
||||||
|
'd1e9c73c-04fe-4e9e-983c-d5ef94cd1a46').AndReturn(None)
|
||||||
|
|
||||||
|
self.m.ReplayAll()
|
||||||
|
|
||||||
|
scheduler.TaskRunner(instance.update, update_template)()
|
||||||
|
self.assertEqual((instance.UPDATE, instance.COMPLETE), instance.state)
|
||||||
|
|
||||||
|
def test_instance_update_network_interfaces_new_include_old(self):
|
||||||
|
"""
|
||||||
|
Instance.handle_update supports changing the NetworkInterfaces,
|
||||||
|
and makes the change making a resize API call against Nova.
|
||||||
|
"""
|
||||||
|
return_server = self.fc.servers.list()[1]
|
||||||
|
return_server.id = 1234
|
||||||
|
instance = self._create_test_instance(return_server,
|
||||||
|
'ud_network_interfaces')
|
||||||
|
# if new include old, just attach the different ones in new
|
||||||
|
old_interfaces = [
|
||||||
|
{'NetworkInterfaceId': 'ea29f957-cd35-4364-98fb-57ce9732c10d',
|
||||||
|
'DeviceIndex': '2'}]
|
||||||
|
new_interfaces = [
|
||||||
|
{'NetworkInterfaceId': 'ea29f957-cd35-4364-98fb-57ce9732c10d',
|
||||||
|
'DeviceIndex': '2'},
|
||||||
|
{'NetworkInterfaceId': 'd1e9c73c-04fe-4e9e-983c-d5ef94cd1a46',
|
||||||
|
'DeviceIndex': '1'}]
|
||||||
|
|
||||||
|
instance.t['Properties']['NetworkInterfaces'] = old_interfaces
|
||||||
|
update_template = copy.deepcopy(instance.t)
|
||||||
|
update_template['Properties']['NetworkInterfaces'] = new_interfaces
|
||||||
|
|
||||||
|
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||||
|
self.fc.servers.get(1234).AndReturn(return_server)
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_attach')
|
||||||
|
return_server.interface_attach('d1e9c73c-04fe-4e9e-983c-d5ef94cd1a46',
|
||||||
|
None, None).AndReturn(None)
|
||||||
|
|
||||||
|
self.m.ReplayAll()
|
||||||
|
|
||||||
|
scheduler.TaskRunner(instance.update, update_template)()
|
||||||
|
self.assertEqual((instance.UPDATE, instance.COMPLETE), instance.state)
|
||||||
|
|
||||||
|
def test_instance_update_network_interfaces_new_old_all_different(self):
|
||||||
|
"""
|
||||||
|
Instance.handle_update supports changing the NetworkInterfaces,
|
||||||
|
and makes the change making a resize API call against Nova.
|
||||||
|
"""
|
||||||
|
return_server = self.fc.servers.list()[1]
|
||||||
|
return_server.id = 1234
|
||||||
|
instance = self._create_test_instance(return_server,
|
||||||
|
'ud_network_interfaces')
|
||||||
|
# if different, detach the old ones and attach the new ones
|
||||||
|
old_interfaces = [
|
||||||
|
{'NetworkInterfaceId': 'ea29f957-cd35-4364-98fb-57ce9732c10d',
|
||||||
|
'DeviceIndex': '2'}]
|
||||||
|
new_interfaces = [
|
||||||
|
{'NetworkInterfaceId': '34b752ec-14de-416a-8722-9531015e04a5',
|
||||||
|
'DeviceIndex': '3'},
|
||||||
|
{'NetworkInterfaceId': 'd1e9c73c-04fe-4e9e-983c-d5ef94cd1a46',
|
||||||
|
'DeviceIndex': '1'}]
|
||||||
|
|
||||||
|
instance.t['Properties']['NetworkInterfaces'] = old_interfaces
|
||||||
|
update_template = copy.deepcopy(instance.t)
|
||||||
|
update_template['Properties']['NetworkInterfaces'] = new_interfaces
|
||||||
|
|
||||||
|
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||||
|
self.fc.servers.get(1234).AndReturn(return_server)
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_detach')
|
||||||
|
return_server.interface_detach(
|
||||||
|
'ea29f957-cd35-4364-98fb-57ce9732c10d').AndReturn(None)
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_attach')
|
||||||
|
return_server.interface_attach('d1e9c73c-04fe-4e9e-983c-d5ef94cd1a46',
|
||||||
|
None, None).AndReturn(None)
|
||||||
|
return_server.interface_attach('34b752ec-14de-416a-8722-9531015e04a5',
|
||||||
|
None, None).AndReturn(None)
|
||||||
|
|
||||||
|
self.m.ReplayAll()
|
||||||
|
|
||||||
|
scheduler.TaskRunner(instance.update, update_template)()
|
||||||
|
self.assertEqual((instance.UPDATE, instance.COMPLETE), instance.state)
|
||||||
|
|
||||||
|
def test_instance_update_network_interfaces_no_old(self):
|
||||||
|
"""
|
||||||
|
Instance.handle_update supports changing the NetworkInterfaces,
|
||||||
|
and makes the change making a resize API call against Nova.
|
||||||
|
"""
|
||||||
|
return_server = self.fc.servers.list()[1]
|
||||||
|
return_server.id = 1234
|
||||||
|
instance = self._create_test_instance(return_server,
|
||||||
|
'ud_network_interfaces')
|
||||||
|
new_interfaces = [
|
||||||
|
{'NetworkInterfaceId': 'ea29f957-cd35-4364-98fb-57ce9732c10d',
|
||||||
|
'DeviceIndex': '2'},
|
||||||
|
{'NetworkInterfaceId': '34b752ec-14de-416a-8722-9531015e04a5',
|
||||||
|
'DeviceIndex': '3'}]
|
||||||
|
iface = self.create_fake_iface('d1e9c73c-04fe-4e9e-983c-d5ef94cd1a46',
|
||||||
|
'c4485ba1-283a-4f5f-8868-0cd46cdda52f',
|
||||||
|
'10.0.0.4')
|
||||||
|
|
||||||
|
update_template = copy.deepcopy(instance.t)
|
||||||
|
update_template['Properties']['NetworkInterfaces'] = new_interfaces
|
||||||
|
|
||||||
|
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||||
|
self.fc.servers.get(1234).AndReturn(return_server)
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_list')
|
||||||
|
return_server.interface_list().AndReturn([iface])
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_detach')
|
||||||
|
return_server.interface_detach(
|
||||||
|
'd1e9c73c-04fe-4e9e-983c-d5ef94cd1a46').AndReturn(None)
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_attach')
|
||||||
|
return_server.interface_attach('ea29f957-cd35-4364-98fb-57ce9732c10d',
|
||||||
|
None, None).AndReturn(None)
|
||||||
|
return_server.interface_attach('34b752ec-14de-416a-8722-9531015e04a5',
|
||||||
|
None, None).AndReturn(None)
|
||||||
|
|
||||||
|
self.m.ReplayAll()
|
||||||
|
|
||||||
|
scheduler.TaskRunner(instance.update, update_template)()
|
||||||
|
self.assertEqual((instance.UPDATE, instance.COMPLETE), instance.state)
|
||||||
|
self.m.VerifyAll()
|
||||||
|
|
||||||
|
def test_instance_update_network_interfaces_no_old_no_new(self):
|
||||||
|
"""
|
||||||
|
Instance.handle_update supports changing the NetworkInterfaces,
|
||||||
|
and makes the change making a resize API call against Nova.
|
||||||
|
"""
|
||||||
|
return_server = self.fc.servers.list()[1]
|
||||||
|
return_server.id = 1234
|
||||||
|
instance = self._create_test_instance(return_server,
|
||||||
|
'ud_network_interfaces')
|
||||||
|
iface = self.create_fake_iface('d1e9c73c-04fe-4e9e-983c-d5ef94cd1a46',
|
||||||
|
'c4485ba1-283a-4f5f-8868-0cd46cdda52f',
|
||||||
|
'10.0.0.4')
|
||||||
|
|
||||||
|
update_template = copy.deepcopy(instance.t)
|
||||||
|
update_template['Properties']['NetworkInterfaces'] = []
|
||||||
|
|
||||||
|
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||||
|
self.fc.servers.get(1234).AndReturn(return_server)
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_list')
|
||||||
|
return_server.interface_list().AndReturn([iface])
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_detach')
|
||||||
|
return_server.interface_detach(
|
||||||
|
'd1e9c73c-04fe-4e9e-983c-d5ef94cd1a46').AndReturn(None)
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_attach')
|
||||||
|
return_server.interface_attach(None, None, None).AndReturn(None)
|
||||||
|
self.m.ReplayAll()
|
||||||
|
|
||||||
|
scheduler.TaskRunner(instance.update, update_template)()
|
||||||
|
self.assertEqual((instance.UPDATE, instance.COMPLETE), instance.state)
|
||||||
|
self.m.VerifyAll()
|
||||||
|
|
||||||
|
def test_instance_update_network_interfaces_no_old_new_with_subnet(self):
|
||||||
|
"""
|
||||||
|
Instance.handle_update supports changing the NetworkInterfaces,
|
||||||
|
and makes the change making a resize API call against Nova.
|
||||||
|
"""
|
||||||
|
return_server = self.fc.servers.list()[1]
|
||||||
|
return_server.id = 1234
|
||||||
|
instance = self._create_test_instance(return_server,
|
||||||
|
'ud_network_interfaces')
|
||||||
|
iface = self.create_fake_iface('d1e9c73c-04fe-4e9e-983c-d5ef94cd1a46',
|
||||||
|
'c4485ba1-283a-4f5f-8868-0cd46cdda52f',
|
||||||
|
'10.0.0.4')
|
||||||
|
subnet_id = '8c1aaddf-e49e-4f28-93ea-ca9f0b3c6240'
|
||||||
|
nics = [{'port-id': 'ea29f957-cd35-4364-98fb-57ce9732c10d'}]
|
||||||
|
update_template = copy.deepcopy(instance.t)
|
||||||
|
update_template['Properties']['NetworkInterfaces'] = []
|
||||||
|
update_template['Properties']['SubnetId'] = subnet_id
|
||||||
|
|
||||||
|
self.m.StubOutWithMock(self.fc.servers, 'get')
|
||||||
|
self.fc.servers.get(1234).AndReturn(return_server)
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_list')
|
||||||
|
return_server.interface_list().AndReturn([iface])
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_detach')
|
||||||
|
return_server.interface_detach(
|
||||||
|
'd1e9c73c-04fe-4e9e-983c-d5ef94cd1a46').AndReturn(None)
|
||||||
|
self.m.StubOutWithMock(instance, '_build_nics')
|
||||||
|
instance._build_nics([], security_groups=None,
|
||||||
|
subnet_id=subnet_id).AndReturn(nics)
|
||||||
|
self.m.StubOutWithMock(return_server, 'interface_attach')
|
||||||
|
return_server.interface_attach('ea29f957-cd35-4364-98fb-57ce9732c10d',
|
||||||
|
None, None).AndReturn(None)
|
||||||
|
self.m.ReplayAll()
|
||||||
|
|
||||||
|
scheduler.TaskRunner(instance.update, update_template)()
|
||||||
|
self.assertEqual((instance.UPDATE, instance.COMPLETE), instance.state)
|
||||||
|
self.m.VerifyAll()
|
||||||
|
|
||||||
def test_instance_update_replace(self):
|
def test_instance_update_replace(self):
|
||||||
return_server = self.fc.servers.list()[1]
|
return_server = self.fc.servers.list()[1]
|
||||||
instance = self._create_test_instance(return_server,
|
instance = self._create_test_instance(return_server,
|
||||||
|
Loading…
Reference in New Issue
Block a user