Implement NovaFloatingIpAssociation res updatable

Implement handle_update for NovaFloatingIPAssociation
resource, allows to update NovaFloatingIpAssociation with
new server_id and new floatingip_id.

Change-Id: I75d361e2f0381f50ab83b54d752ffc080fe337fa
Implements: blueprint handle-update-for-floatingip
This commit is contained in:
huangtianhua 2014-05-13 16:19:25 +08:00
parent ac9ea4caf9
commit 7309c967d1
2 changed files with 140 additions and 2 deletions

View File

@ -99,12 +99,14 @@ class NovaFloatingIpAssociation(resource.Resource):
SERVER: properties.Schema(
properties.Schema.STRING,
_('Server to assign floating IP to.'),
required=True
required=True,
update_allowed=True
),
FLOATING_IP: properties.Schema(
properties.Schema.STRING,
_('ID of the floating IP to assign to the server.'),
required=True
required=True,
update_allowed=True
),
}
@ -131,6 +133,26 @@ class NovaFloatingIpAssociation(resource.Resource):
except clients.novaclient.exceptions.NotFound:
pass
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
if prop_diff:
# If floating_ip in prop_diff, we need to remove the old floating
# ip from the old server, and then to add the new floating ip
# to the old/new(if the server_id is changed) server.
# If prop_diff only has the server_id, no need to remove the
# floating ip from the old server, nova does this automatically
# when calling add_floating_ip().
if self.FLOATING_IP in prop_diff:
self.handle_delete()
server_id = (prop_diff.get(self.SERVER) or
self.properties[self.SERVER])
fl_ip_id = (prop_diff.get(self.FLOATING_IP) or
self.properties[self.FLOATING_IP])
server = self.nova().servers.get(server_id)
fl_ip = self.nova().floating_ips.get(fl_ip_id)
self.nova().servers.add_floating_ip(server, fl_ip.ip)
self.resource_id_set('%s-%s' % (fl_ip.id, fl_ip.ip))
def resource_mapping():
return {

View File

@ -11,6 +11,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
from novaclient import exceptions as ncli_ex
from novaclient.v1_1 import client as novaclient
@ -193,3 +195,117 @@ class NovaFloatingIPTest(HeatTestCase):
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
def test_floating_ip_assoc_update_server_id(self):
rsrc = self.prepare_floating_ip_assoc()
# for create
self.novaclient.servers.add_floating_ip(None, '11.0.0.1')
# for update
self.novaclient.servers.get(
'2146dfbf-ba77-4083-8e86-d052f671ece5').AndReturn('server')
self.novaclient.floating_ips.get('1').AndReturn(
self._make_obj(**{
'id': '1',
'ip': '11.0.0.1',
'pool': 'public'
})
)
self.novaclient.servers.add_floating_ip('server', '11.0.0.1')
self.m.ReplayAll()
rsrc.validate()
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
# update with the new server_id
update_snippet = copy.deepcopy(rsrc.parsed_template())
update_server_id = '2146dfbf-ba77-4083-8e86-d052f671ece5'
update_snippet['Properties']['server_id'] = update_server_id
scheduler.TaskRunner(rsrc.update, update_snippet)()
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
def test_floating_ip_assoc_update_fl_ip(self):
rsrc = self.prepare_floating_ip_assoc()
# for create
self.novaclient.servers.add_floating_ip(None, '11.0.0.1')
# mock for delete the old association
self.novaclient.servers.get(
'67dc62f9-efde-4c8b-94af-013e00f5dc57').AndReturn('server')
self.novaclient.floating_ips.get('1').AndReturn(
self._make_obj(**{
'id': '1',
'ip': '11.0.0.1',
'pool': 'public'
})
)
self.novaclient.servers.remove_floating_ip('server', '11.0.0.1')
# mock for new association
self.novaclient.servers.get(
'67dc62f9-efde-4c8b-94af-013e00f5dc57').AndReturn('server')
self.novaclient.floating_ips.get('2').AndReturn(
self._make_obj(**{
'id': '2',
'ip': '11.0.0.2',
'pool': 'public'
})
)
self.novaclient.servers.add_floating_ip('server', '11.0.0.2')
self.m.ReplayAll()
rsrc.validate()
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
# update with the new floatingip
update_snippet = copy.deepcopy(rsrc.parsed_template())
update_flip_id = '2'
update_snippet['Properties']['floating_ip'] = update_flip_id
scheduler.TaskRunner(rsrc.update, update_snippet)()
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
def test_floating_ip_assoc_update_both(self):
rsrc = self.prepare_floating_ip_assoc()
# for create
self.novaclient.servers.add_floating_ip(None, '11.0.0.1')
# mock for delete the old association
self.novaclient.servers.get(
'67dc62f9-efde-4c8b-94af-013e00f5dc57').AndReturn('server')
self.novaclient.floating_ips.get('1').AndReturn(
self._make_obj(**{
'id': '1',
'ip': '11.0.0.1',
'pool': 'public'
})
)
self.novaclient.servers.remove_floating_ip('server', '11.0.0.1')
# mock for new association
self.novaclient.servers.get(
'2146dfbf-ba77-4083-8e86-d052f671ece5').AndReturn('new_server')
self.novaclient.floating_ips.get('2').AndReturn(
self._make_obj(**{
'id': '2',
'ip': '11.0.0.2',
'pool': 'public'
})
)
self.novaclient.servers.add_floating_ip('new_server', '11.0.0.2')
self.m.ReplayAll()
rsrc.validate()
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
# update with the new floatingip
update_snippet = copy.deepcopy(rsrc.parsed_template())
update_flip_id = '2'
update_server_id = '2146dfbf-ba77-4083-8e86-d052f671ece5'
update_snippet['Properties']['floating_ip'] = update_flip_id
update_snippet['Properties']['server_id'] = update_server_id
scheduler.TaskRunner(rsrc.update, update_snippet)()
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()