Update service support a manifest change

Currently, we don't support a manifest change when we update a service.

This patch fix this problem so that we can update the label or other
useful attributes of a service.

Change-Id: Ibecf97ce3a356d1eb83315e5e635e738f06cd47a
Partially-Implements: blueprint magnum-resource-manifest-update
This commit is contained in:
Lan Qi song 2015-04-16 13:35:43 +08:00
parent 1c3027fc52
commit 73000071fe
7 changed files with 38 additions and 6 deletions

View File

@ -281,19 +281,20 @@ class ServicesController(rest.RestController):
raise exception.OperationNotPermitted
rpc_service = api_utils.get_rpc_resource('Service', service_ident)
# Init manifest and manifest_url field because we don't store them
# in database.
rpc_service['manifest'] = None
rpc_service['manifest_url'] = None
try:
service_dict = rpc_service.as_dict()
service = Service(**api_utils.apply_jsonpatch(service_dict, patch))
if service.manifest or service.manifest_url:
service.parse_manifest()
except api_utils.JSONPATCH_EXCEPTIONS as e:
raise exception.PatchError(patch=patch, reason=e)
# Update only the fields that have changed
for field in objects.Service.fields:
# ignore manifest_url as it was used for create service
if field == 'manifest_url':
continue
if field == 'manifest':
continue
try:
patch_val = getattr(service, field)
except AttributeError:
@ -304,7 +305,10 @@ class ServicesController(rest.RestController):
if rpc_service[field] != patch_val:
rpc_service[field] = patch_val
rpc_service.save()
if service.manifest or service.manifest_url:
pecan.request.rpcapi.service_update(rpc_service)
else:
rpc_service.save()
return Service.convert_with_links(rpc_service)
@wsme_pecan.wsexpose(None, types.uuid_or_name, status_code=204)

View File

@ -68,6 +68,9 @@ class API(rpc_service.API):
def service_create(self, service):
return self._call('service_create', service=service)
def service_update(self, service):
return self._call('service_update', service=service)
def service_list(self, context, limit, marker, sort_key, sort_dir):
# TODO(pkilambi): return kubectl results once we parse appropriately
# or figure out a clean way to interact with k8s.

View File

@ -111,6 +111,7 @@ class Handler(object):
return None
# call the service object to persist in db
service.refresh(context)
service.save()
return service
def service_delete(self, context, uuid):

View File

@ -191,6 +191,10 @@ class Service(base.MagnumObject):
"""
current = self.__class__.get_by_uuid(self._context, uuid=self.uuid)
for field in self.fields:
if field == 'manifest_url':
continue
if field == 'manifest':
continue
if (hasattr(self, base.get_attrname(field)) and
self[field] != current[field]):
self[field] = current[field]

View File

@ -193,6 +193,18 @@ class TestPatch(api_base.FunctionalTest):
self.assertEqual('application/json', response.content_type)
self.assertTrue(response.json['error_message'])
@mock.patch.object(rpcapi.API, 'service_update')
@mock.patch.object(api_service.Service, 'parse_manifest')
def test_replace_with_manifest(self, parse_manifest, service_update):
response = self.patch_json('/services/%s' % self.service.uuid,
[{'path': '/manifest',
'value': '{}',
'op': 'replace'}])
self.assertEqual(200, response.status_int)
self.assertEqual('application/json', response.content_type)
parse_manifest.assert_called_once_with()
self.assertTrue(service_update.is_called)
def test_add_non_existent_property(self):
response = self.patch_json('/services/%s' % self.service.uuid,
[{'path': '/foo', 'value': 'bar', 'op': 'add'}],

View File

@ -421,6 +421,7 @@ class TestKube(base.TestCase):
expected_service = self.mock_service()
expected_service.uuid = 'test-uuid'
expected_service.refresh = mock.MagicMock()
expected_service.save = mock.MagicMock()
mock_retrieve_k8s_master_url.return_value = expected_master_url
with patch.object(self.kube_handler, 'kube_cli') as mock_kube_cli:
@ -430,6 +431,7 @@ class TestKube(base.TestCase):
mock_kube_cli.service_update.assert_called_once_with(
expected_master_url, expected_service)
expected_service.refresh.assert_called_once_with(self.context)
expected_service.save.assert_called_once_with()
@patch('magnum.conductor.handlers.kube._retrieve_k8s_master_url')
def test_service_update_with_failure(self,

View File

@ -102,6 +102,12 @@ class RPCAPITestCase(base.DbTestCase):
version='1.0',
service=self.fake_service)
def test_service_update(self):
self._test_rpcapi('service_update',
'call',
version='1.0',
service=self.fake_service)
def test_service_delete(self):
self._test_rpcapi('service_delete',
'call',