fix: update service when missing provider details
Updating a service that was missing provider details failed to update the service status. This changeset ensures that the service is updated properly. Change-Id: Ifd668d6336dde0ed5528a2be63fafdd076ed7510
This commit is contained in:
parent
fce2fb8718
commit
28d241ceec
|
@ -174,7 +174,8 @@ class DefaultServicesController(base.ServicesController):
|
|||
"""create.
|
||||
|
||||
:param project_id
|
||||
:param service_obj
|
||||
:param auth_token
|
||||
:param service_json
|
||||
:raises LookupError, ValueError
|
||||
"""
|
||||
try:
|
||||
|
@ -236,12 +237,15 @@ class DefaultServicesController(base.ServicesController):
|
|||
|
||||
return service_obj
|
||||
|
||||
def update(self, project_id, service_id, auth_token, service_updates):
|
||||
def update(self, project_id, service_id,
|
||||
auth_token, service_updates, force_update=False):
|
||||
"""update.
|
||||
|
||||
:param project_id
|
||||
:param service_id
|
||||
:param auth_token
|
||||
:param service_updates
|
||||
:param force_update
|
||||
:raises LookupError, ValueError
|
||||
"""
|
||||
# get the current service object
|
||||
|
@ -254,7 +258,10 @@ class DefaultServicesController(base.ServicesController):
|
|||
raise errors.ServiceStatusDisabled(
|
||||
u'Service {0} is disabled'.format(service_id))
|
||||
|
||||
if service_old.status not in [u'deployed', u'failed']:
|
||||
if (
|
||||
service_old.status not in [u'deployed', u'failed'] and
|
||||
force_update is False
|
||||
):
|
||||
raise errors.ServiceStatusNeitherDeployedNorFailed(
|
||||
u'Service {0} neither deployed nor failed'.format(service_id))
|
||||
|
||||
|
@ -434,11 +441,23 @@ class DefaultServicesController(base.ServicesController):
|
|||
project_id=project_id,
|
||||
project_limit=limit)
|
||||
|
||||
def set_service_provider_details(self, project_id, service_id, status):
|
||||
def set_service_provider_details(self, project_id, service_id,
|
||||
auth_token, status):
|
||||
old_service = self.storage_controller.get(project_id, service_id)
|
||||
|
||||
if (
|
||||
old_service.status == 'create_in_progress' and
|
||||
old_service.provider_details == {}
|
||||
):
|
||||
self.update(
|
||||
project_id, service_id, auth_token, [], force_update=True)
|
||||
return 202
|
||||
self.storage_controller.set_service_provider_details(
|
||||
project_id,
|
||||
service_id,
|
||||
status)
|
||||
status
|
||||
)
|
||||
return 201
|
||||
|
||||
def get_services_limit(self, project_id):
|
||||
limit = self.storage_controller.get_service_limit(
|
||||
|
|
|
@ -191,7 +191,7 @@ class CassandraStorageDriver(base.Driver):
|
|||
"""Health check for Cassandra."""
|
||||
|
||||
try:
|
||||
self.session.execute(
|
||||
self.database.execute(
|
||||
"SELECT cluster_name, data_center FROM system.local;")
|
||||
except Exception:
|
||||
return False
|
||||
|
|
|
@ -390,10 +390,14 @@ class ServiceStatusController(base.Controller, hooks.HookController):
|
|||
status = service_state_json['status']
|
||||
services_controller = self._driver.manager.services_controller
|
||||
|
||||
status_code = None
|
||||
try:
|
||||
services_controller.set_service_provider_details(project_id,
|
||||
service_id,
|
||||
status)
|
||||
status_code = services_controller.set_service_provider_details(
|
||||
project_id,
|
||||
service_id,
|
||||
self.auth_token,
|
||||
status
|
||||
)
|
||||
except Exception as e:
|
||||
pecan.abort(404, detail=(
|
||||
'Setting state of service {0} on tenant: {1} '
|
||||
|
@ -403,7 +407,7 @@ class ServiceStatusController(base.Controller, hooks.HookController):
|
|||
status,
|
||||
str(e))))
|
||||
|
||||
return pecan.Response(None, 201)
|
||||
return pecan.Response(None, status_code)
|
||||
|
||||
|
||||
class AdminCertController(base.Controller, hooks.HookController):
|
||||
|
|
|
@ -580,7 +580,7 @@ def is_valid_service_status(request):
|
|||
# supported statuses
|
||||
|
||||
VALID_STATUSES = [
|
||||
u'deploy_in_progress',
|
||||
u'create_in_progress',
|
||||
u'deployed',
|
||||
u'update_in_progress',
|
||||
u'delete_in_progress',
|
||||
|
|
|
@ -53,9 +53,9 @@ class TestGetServiceStatus(base.FunctionalTest):
|
|||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
@ddt.data('deploy_in_progress', 'deployed', 'update_in_progress',
|
||||
@ddt.data('create_in_progress', 'deployed', 'update_in_progress',
|
||||
'delete_in_progress', 'failed')
|
||||
def test_get_service_status_valid_queryparam(self, status):
|
||||
def test_get_service_status_valid_query_param(self, status):
|
||||
# valid status
|
||||
with mock.patch.object(DefaultServicesController,
|
||||
'get_services_by_status'):
|
||||
|
|
|
@ -30,7 +30,78 @@ class TestServicesState(base.FunctionalTest):
|
|||
super(TestServicesState, self).setUp()
|
||||
|
||||
self.project_id = str(uuid.uuid4())
|
||||
self.service_id = str(uuid.uuid4())
|
||||
self.service_name = str(uuid.uuid1())
|
||||
self.flavor_id = str(uuid.uuid1())
|
||||
|
||||
# create a mock flavor to be used by new service creations
|
||||
flavor_json = {
|
||||
"id": self.flavor_id,
|
||||
"providers": [
|
||||
{
|
||||
"provider": "mock",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://mock.cdn",
|
||||
"rel": "provider_url"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
response = self.app.post('/v1.0/flavors',
|
||||
params=json.dumps(flavor_json),
|
||||
headers={
|
||||
"Content-Type": "application/json",
|
||||
"X-Project-ID": self.project_id})
|
||||
|
||||
self.assertEqual(201, response.status_code)
|
||||
|
||||
# create an initial service to be used by the tests
|
||||
self.service_json = {
|
||||
"name": self.service_name,
|
||||
"domains": [
|
||||
{"domain": "test.mocksite.com"},
|
||||
{"domain": "blog.mocksite.com"}
|
||||
],
|
||||
"origins": [
|
||||
{
|
||||
"origin": "mocksite.com",
|
||||
"port": 80,
|
||||
"ssl": False
|
||||
}
|
||||
],
|
||||
"flavor_id": self.flavor_id,
|
||||
"caching": [
|
||||
{
|
||||
"name": "default",
|
||||
"ttl": 3600
|
||||
}
|
||||
],
|
||||
"restrictions": [
|
||||
{
|
||||
"name": "website only",
|
||||
"type": "whitelist",
|
||||
"rules": [
|
||||
{
|
||||
"name": "mocksite.com",
|
||||
"referrer": "www.mocksite.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
response = self.app.post('/v1.0/services',
|
||||
params=json.dumps(self.service_json),
|
||||
headers={
|
||||
'Content-Type': 'application/json',
|
||||
'X-Project-ID': self.project_id})
|
||||
self.assertEqual(202, response.status_code)
|
||||
self.assertTrue('Location' in response.headers)
|
||||
|
||||
self.service_id = (response.headers['Location']
|
||||
[response.headers['Location'].rfind('/') + 1:])
|
||||
|
||||
self.req_body = {
|
||||
'project_id': self.project_id,
|
||||
'service_id': self.service_id,
|
||||
|
@ -38,6 +109,13 @@ class TestServicesState(base.FunctionalTest):
|
|||
|
||||
@ddt.data(u'deployed', u'failed')
|
||||
def test_services_state_valid_states(self, status):
|
||||
response = self.app.get(
|
||||
'/v1.0/services/{0}'.format(self.service_id),
|
||||
headers={'X-Project-ID': self.project_id}
|
||||
)
|
||||
|
||||
self.assertEqual(200, response.status_code)
|
||||
|
||||
self.req_body['status'] = status
|
||||
response = self.app.post(
|
||||
'/v1.0/admin/services/status',
|
||||
|
|
|
@ -20,6 +20,7 @@ import uuid
|
|||
import ddt
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
from oslo_context import context
|
||||
import requests
|
||||
import six
|
||||
|
||||
|
@ -103,8 +104,8 @@ class DefaultManagerServiceTests(base.TestCase):
|
|||
@mock.patch('poppy.storage.base.driver.StorageDriverBase')
|
||||
@mock.patch('poppy.distributed_task.base.driver.DistributedTaskDriverBase')
|
||||
@mock.patch('poppy.metrics.base.driver.MetricsDriverBase')
|
||||
def setUp(self, mock_distributed_task, mock_storage,
|
||||
mock_dns, mock_notification, mock_bootstrap, mock_metrics):
|
||||
def setUp(self, mock_metrics, mock_distributed_task, mock_storage,
|
||||
mock_dns, mock_notification, mock_bootstrap):
|
||||
# NOTE(TheSriram): the mock.patch decorator applies mocks
|
||||
# in the reverse order of the arguments present
|
||||
super(DefaultManagerServiceTests, self).setUp()
|
||||
|
@ -216,6 +217,9 @@ class DefaultManagerServiceTests(base.TestCase):
|
|||
|
||||
self.service_obj = service.load_from_json(self.service_json)
|
||||
|
||||
self.mock_storage = mock_storage
|
||||
self.mock_distributed_task = mock_distributed_task
|
||||
|
||||
@mock.patch('poppy.bootstrap.Bootstrap')
|
||||
def mock_purge_service(self, mock_bootstrap, hard=False):
|
||||
mock_bootstrap.return_value = self.bootstrap_obj
|
||||
|
@ -1005,3 +1009,58 @@ class DefaultManagerServiceTests(base.TestCase):
|
|||
memoized_controllers.task_controllers):
|
||||
self.mock_purge_service(hard=True)
|
||||
self.mock_purge_service(hard=False)
|
||||
|
||||
def test_set_service_provider_details_missing_provider_details(self):
|
||||
context.RequestContext(overwrite=True)
|
||||
mock_service_obj = mock.Mock()
|
||||
mock_service_obj.to_dict.return_value = {
|
||||
'name': 'name',
|
||||
'flavor_id': 'flavor_id',
|
||||
'service_id': 'service_id',
|
||||
'status': 'status',
|
||||
'operator_status': 'operator_status',
|
||||
'provider_details': 'provider_details',
|
||||
'domains': [
|
||||
{'domain': 'www.test.com'}
|
||||
],
|
||||
'origins': [
|
||||
{
|
||||
"origin": "www.tester.com",
|
||||
"port": 80,
|
||||
"ssl": False,
|
||||
"rules": [
|
||||
{
|
||||
"name": "default",
|
||||
"request_url": "/*"
|
||||
}
|
||||
],
|
||||
"hostheadertype": "domain"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
type(mock_service_obj).service_id = mock.PropertyMock(
|
||||
return_value='service_id'
|
||||
)
|
||||
type(mock_service_obj).status = mock.PropertyMock(
|
||||
return_value="create_in_progress"
|
||||
)
|
||||
type(mock_service_obj).provider_details = mock.PropertyMock(
|
||||
return_value=dict()
|
||||
)
|
||||
type(mock_service_obj).domains = mock.PropertyMock(
|
||||
return_value=list()
|
||||
)
|
||||
|
||||
self.mock_storage.services_controller.get.return_value = (
|
||||
mock_service_obj
|
||||
)
|
||||
|
||||
self.sc.set_service_provider_details(
|
||||
"project_id", "service_id", "auth_token", "deployed"
|
||||
)
|
||||
self.assertTrue(self.mock_storage.services_controller.get.called)
|
||||
self.assertTrue(self.mock_storage.services_controller.update.called)
|
||||
self.assertTrue(
|
||||
self.mock_distributed_task.services_controller.submit_task.called
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue