Patch service endpoint

Implements: blueprint patch-service
Change-Id: I2fe9355713a4bf63f515f3e6dad4611722c57fdc
This commit is contained in:
Obulpathi
2014-10-15 11:33:36 -04:00
parent 7fe0197d2b
commit 8a2c731f92
30 changed files with 393 additions and 169 deletions

View File

@@ -29,23 +29,26 @@ class ProviderWrapper(object):
return ext.obj.service_controller.create(service_obj)
def update(self, ext, provider_details, service_json):
def update(self, ext, provider_details, service_old, service_updates,
service_obj):
"""Update a provider
:param ext
:param provider_details
:param service_json
:param service_old
:param service_updates
:param service_obj
"""
try:
provider_detail = provider_details[ext.provider_name]
provider_detail = provider_details[ext.obj.provider_name]
except KeyError:
raise errors.BadProviderDetail(
"No provider detail information."
"Perhaps service has not been created")
provider_service_id = provider_detail.provider_service_id
return ext.obj.service_controller.update(
provider_service_id,
service_json)
provider_service_id, service_old, service_updates, service_obj)
def delete(self, ext, provider_details):
try:

View File

@@ -0,0 +1,65 @@
# Copyright (c) 2014 Rackspace, Inc.
#
# 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.
from poppy.model.helpers import provider_details
from poppy.openstack.common import log
LOG = log.getLogger(__name__)
def update_worker(service_controller, project_id, service_name,
service_old, service_updates, service_obj):
responders = []
# update service with each provider present in provider_details
for provider in service_old.provider_details:
LOG.info(u'Starting to update service from {0}'.format(provider))
responder = service_controller.provider_wrapper.update(
service_controller._driver.providers[provider.lower()],
service_old.provider_details, service_old, service_updates,
service_obj)
responders.append(responder)
LOG.info(u'Updating service from {0} complete'.format(provider))
# gather links and status for service from providers
provider_details_dict = {}
for responder in responders:
for provider_name in responder:
if 'error' not in responder[provider_name]:
provider_details_dict[provider_name] = (
provider_details.ProviderDetail(
provider_service_id=responder[provider_name]['id'],
access_urls=[link['href'] for link in
responder[provider_name]['links']])
)
if 'status' in responder[provider_name]:
provider_details_dict[provider_name].status = (
responder[provider_name]['status'])
else:
provider_details_dict[provider_name].status = (
'deployed')
else:
provider_details_dict[provider_name] = (
provider_details.ProviderDetail(
error_info=responder[provider_name]['error_detail']))
provider_details_dict[provider_name].status = 'failed'
# update the service object
service_controller.storage_controller.update(project_id, service_name,
service_obj)
# update the provider details
service_controller.storage_controller.update_provider_details(
project_id,
service_name,
provider_details_dict)

View File

@@ -13,12 +13,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import copy
import multiprocessing
from poppy.common import errors
from poppy.manager import base
from poppy.manager.default.service_async_workers import create_service_worker
from poppy.manager.default.service_async_workers import delete_service_worker
from poppy.manager.default.service_async_workers import purge_service_worker
from poppy.manager.default.service_async_workers import update_service_worker
class DefaultServicesController(base.ServicesController):
@@ -30,6 +33,16 @@ class DefaultServicesController(base.ServicesController):
self.storage_controller = self._driver.storage.services_controller
self.flavor_controller = self._driver.storage.flavors_controller
def _get_provider_details(self, project_id, service_name):
try:
provider_details = self.storage_controller.get_provider_details(
project_id,
service_name)
except Exception:
raise LookupError(u'Service {0} does not exist'.format(
service_name))
return provider_details
def list(self, project_id, marker=None, limit=None):
"""list.
@@ -61,7 +74,6 @@ class DefaultServicesController(base.ServicesController):
# raise a lookup error if the flavor is not found
except LookupError as e:
raise e
providers = [p.provider_id for p in flavor.providers]
service_name = service_obj.name
@@ -88,26 +100,56 @@ class DefaultServicesController(base.ServicesController):
p.start()
return
def update(self, project_id, service_name, service_obj):
def update(self, project_id, service_name, service_updates):
"""update.
:param project_id
:param service_name
:param service_obj
:param service_updates
"""
self.storage_controller.update(
# get the current service object
service_old = self.storage_controller.get(project_id, service_name)
if service_old.status != u'deployed':
raise errors.ServiceStatusNotDeployed(
u'Service {0} not deployed'.format(service_name))
service_obj = copy.deepcopy(service_old)
# update service object
if service_updates.name:
raise Exception(u'Currently this operation is not supported')
if service_updates.domains:
service_obj.domains = service_updates.domains
if service_updates.origins:
service_obj.origins = service_updates.origins
if service_updates.caching:
raise Exception(u'Currently this operation is not supported')
if service_updates.restrictions:
raise Exception(u'Currently this operation is not supported')
if service_updates.flavor_ref:
raise Exception(u'Currently this operation is not supported')
# get provider details for this service
provider_details = self._get_provider_details(project_id, service_name)
# set status in provider details to u'update_in_progress'
for provider in provider_details:
provider_details[provider].status = u'update_in_progress'
self.storage_controller.update_provider_details(
project_id,
service_name,
service_obj
)
provider_details)
provider_details = self.storage_controller.get_provider_details(
project_id,
service_name)
return self._driver.providers.map(
self.provider_wrapper.update,
provider_details,
service_obj)
self.storage_controller._driver.close_connection()
p = multiprocessing.Process(
name=('Process: update poppy service {0} for project id: {1}'
.format(service_name, project_id)),
target=update_service_worker.update_worker,
args=(self, project_id, service_name, service_old, service_updates,
service_obj))
p.start()
return
def delete(self, project_id, service_name):
"""delete.
@@ -116,12 +158,7 @@ class DefaultServicesController(base.ServicesController):
:param service_name
:raises LookupError
"""
try:
provider_details = self.storage_controller.get_provider_details(
project_id,
service_name)
except Exception:
raise LookupError('Service %s does not exist' % service_name)
provider_details = self._get_provider_details(project_id, service_name)
# change each provider detail's status to delete_in_progress
# TODO(tonytan4ever): what if this provider is in 'failed' status?
@@ -151,12 +188,7 @@ class DefaultServicesController(base.ServicesController):
def purge(self, project_id, service_name, purge_url=None):
'''If purge_url is none, all content of this service will be purge.'''
try:
provider_details = self.storage_controller.get_provider_details(
project_id,
service_name)
except Exception:
raise LookupError('Service %s does not exist' % service_name)
provider_details = self._get_provider_details(project_id, service_name)
# possible validation of purge url here...
self.storage_controller._driver.close_connection()