Refactor storage layer to separate cert controller

Move all certificate logic into it's own controller in
the storage layer.

Change-Id: Icc7e457ea2ab8bc9a149e6dedda3e23a202dcf7c
This commit is contained in:
Isaac Mungai 2016-04-26 15:40:54 -04:00
parent 6cb236b17c
commit c1cb52e8c8
31 changed files with 1094 additions and 670 deletions

View File

@ -49,13 +49,18 @@ class CreateProviderServicesTask(task.Task):
service_controller, self.storage_controller = \
memoized_controllers.task_controllers('poppy', 'storage')
_, self.ssl_certificate_manager = \
memoized_controllers.task_controllers('poppy', 'ssl_certificate')
self.ssl_certificate_storage = self.ssl_certificate_manager.storage
providers_list = json.loads(providers_list_json)
try:
service_obj = self.storage_controller.get(project_id, service_id)
for domain in service_obj.domains:
if domain.certificate == 'san':
cert_for_domain = (
self.storage_controller.get_certs_by_domain(
self.ssl_certificate_storage.get_certs_by_domain(
domain.domain,
project_id=project_id,
flavor_id=service_obj.flavor_id,

View File

@ -77,8 +77,9 @@ class SendNotificationTask(task.Task):
class UpdateCertInfoTask(task.Task):
def execute(self, project_id, cert_obj_json, responders):
service_controller, self.storage_controller = \
memoized_controllers.task_controllers('poppy', 'storage')
service_controller, self.ssl_certificate_manager = \
memoized_controllers.task_controllers('poppy', 'ssl_certificate')
self.storage_controller = self.ssl_certificate_manager.storage
cert_details = {}
for responder in responders:
@ -86,24 +87,28 @@ class UpdateCertInfoTask(task.Task):
cert_details[provider] = json.dumps(responder[provider])
cert_obj = ssl_certificate.load_from_json(json.loads(cert_obj_json))
self.storage_controller.update_cert_info(cert_obj.domain_name,
cert_obj.cert_type,
cert_obj.flavor_id,
cert_details)
self.storage_controller.update_certificate(
cert_obj.domain_name,
cert_obj.cert_type,
cert_obj.flavor_id,
cert_details
)
return
class CreateStorageSSLCertificateTask(task.Task):
'''This task is meant to be used in san rerun flow.'''
"""This task is meant to be used in san rerun flow."""
def execute(self, project_id, cert_obj_json):
cert_obj = ssl_certificate.load_from_json(json.loads(cert_obj_json))
service_controller, self.storage_controller = \
memoized_controllers.task_controllers('poppy', 'storage')
service_controller, self.ssl_certificate_manager = \
memoized_controllers.task_controllers('poppy', 'ssl_certificate')
self.storage_controller = self.ssl_certificate_manager.storage
try:
self.storage_controller.create_cert(project_id, cert_obj)
self.storage_controller.create_certificate(project_id, cert_obj)
except ValueError as e:
LOG.exception(e)

View File

@ -57,12 +57,16 @@ class SendNotificationTask(task.Task):
class DeleteStorageSSLCertificateTask(task.Task):
def execute(self, project_id, domain_name, cert_type):
service_controller, self.storage_controller = \
memoized_controllers.task_controllers('poppy', 'storage')
service_controller, self.ssl_certificate_manager = \
memoized_controllers.task_controllers('poppy', 'ssl_certificate')
self.storage_controller = self.ssl_certificate_manager.storage
try:
self.storage_controller.delete_cert(project_id,
domain_name,
cert_type)
self.storage_controller.delete_certificate(
project_id,
domain_name,
cert_type
)
except ValueError as e:
LOG.exception(e)

View File

@ -33,19 +33,19 @@ class ServicesControllerBase(controller.ManagerControllerBase):
self.notification_wrapper = notifications.NotificationWrapper()
@abc.abstractmethod
def list(self, project_id, marker=None, limit=None):
"""list
def get_services(self, project_id, marker=None, limit=None):
"""Get a list of services.
:param project_id
:param marker
:limit
:param limit
:raises: NotImplementedError
"""
raise NotImplementedError
@abc.abstractmethod
def get(self, project_id, service_id):
"""GET
def get_service(self, project_id, service_id):
"""Get a service.
:param project_id
:param service_id
@ -54,22 +54,26 @@ class ServicesControllerBase(controller.ManagerControllerBase):
raise NotImplementedError
@abc.abstractmethod
def create(self, project_id, auth_token, service_obj):
"""create
def create_service(self, project_id, auth_token, service_obj):
"""Create a service.
:param project_id
:param auth_token
:param service_obj
:raises: NotImplementedError
"""
raise NotImplementedError
@abc.abstractmethod
def update(self, project_id, service_id, service_obj):
"""POST
def update_service(self, project_id, service_id,
auth_token, service_updates, force_update=False):
"""Update a service.
:param project_id
:param service_id
:param service_obj
:param auth_token
:param service_updates
:param force_update
:raises: NotImplementedError
"""
raise NotImplementedError
@ -85,8 +89,8 @@ class ServicesControllerBase(controller.ManagerControllerBase):
"""
@abc.abstractmethod
def delete(self, project_id, service_id):
"""DELETE
def delete_service(self, project_id, service_id):
"""Delete a service.
:param project_id
:param service_id
@ -96,5 +100,13 @@ class ServicesControllerBase(controller.ManagerControllerBase):
@abc.abstractmethod
def purge(self, project_id, service_id, hard=False, purge_url=None):
'''If purge_url is none, all content of this service will be purge.'''
"""Purge assets for a service.
If purge_url is none, all content of this service will be purged.
:param project_id
:param service_id
:param hard
:param purge_url
"""
raise NotImplementedError

View File

@ -22,17 +22,38 @@ from poppy.manager.base import controller
@six.add_metaclass(abc.ABCMeta)
class SSLCertificateController(controller.ManagerControllerBase):
"""Home controller base class."""
"""SSL certificate controller base class."""
def __init__(self, manager):
super(SSLCertificateController, self).__init__(manager)
@abc.abstractmethod
def create_ssl_certificate(self, project_id, domain_name, **extras):
"""create_ssl_certificate
def create_ssl_certificate(self, project_id, cert_obj):
"""Create ssl certificate.
:param project_id
:param domain_name
:param cert_obj
:raises: NotImplementedError
"""
raise NotImplementedError
@abc.abstractmethod
def delete_ssl_certificate(self, project_id, domain_name, cert_type):
"""Delete ssl certificate.
:param project_id
:param domain_name
:param cert_type
:raises: NotImplementedError
"""
raise NotImplementedError
@abc.abstractmethod
def get_certs_info_by_domain(self, domain_name, project_id):
"""Get ssl certificate by domain.
:param domain_name:
:param project_id:
:raises: NotImplementedError
"""
raise NotImplementedError

View File

@ -50,6 +50,9 @@ class DefaultServicesController(base.ServicesController):
super(DefaultServicesController, self).__init__(manager)
self.storage_controller = self._driver.storage.services_controller
self.ssl_certificate_storage = (
self._driver.storage.certificates_controller
)
self.flavor_controller = self._driver.storage.flavors_controller
self.dns_controller = self._driver.dns.services_controller
self.distributed_task_controller = (
@ -100,13 +103,6 @@ class DefaultServicesController(base.ServicesController):
return services_project_ids
def get_certs_by_status(self, status):
services_project_ids = \
self.storage_controller.get_certs_by_status(status)
return services_project_ids
def get_domains_by_provider_url(self, provider_url):
domains = \
@ -151,26 +147,26 @@ class DefaultServicesController(base.ServicesController):
request_url='/*')
caching_entry['rules'].append(default_rule.to_dict())
def list(self, project_id, marker=None, limit=None):
"""list.
def get_services(self, project_id, marker=None, limit=None):
"""Get a list of services.
:param project_id
:param marker
:param limit
:return list
"""
return self.storage_controller.list(project_id, marker, limit)
return self.storage_controller.get_services(project_id, marker, limit)
def get(self, project_id, service_id):
def get_service(self, project_id, service_id):
"""get.
:param project_id
:param service_id
:return controller
"""
return self.storage_controller.get(project_id, service_id)
return self.storage_controller.get_service(project_id, service_id)
def create(self, project_id, auth_token, service_json):
def create_service(self, project_id, auth_token, service_json):
"""create.
:param project_id
@ -232,8 +228,7 @@ class DefaultServicesController(base.ServicesController):
raise e
try:
self.storage_controller.create(project_id,
service_obj)
self.storage_controller.create_service(project_id, service_obj)
except ValueError as e:
raise e
@ -252,8 +247,8 @@ class DefaultServicesController(base.ServicesController):
return service_obj
def update(self, project_id, service_id,
auth_token, service_updates, force_update=False):
def update_service(self, project_id, service_id,
auth_token, service_updates, force_update=False):
"""update.
:param project_id
@ -265,7 +260,10 @@ class DefaultServicesController(base.ServicesController):
"""
# get the current service object
try:
service_old = self.storage_controller.get(project_id, service_id)
service_old = self.storage_controller.get_service(
project_id,
service_id
)
except ValueError:
raise errors.ServiceNotFound("Service not found")
@ -292,7 +290,7 @@ class DefaultServicesController(base.ServicesController):
# old domains need to bind as well
elif domain.certificate == 'san':
cert_for_domain = (
self.storage_controller.get_certs_by_domain(
self.ssl_certificate_storage.get_certs_by_domain(
domain.domain,
project_id=project_id,
flavor_id=service_old.flavor_id,
@ -354,7 +352,7 @@ class DefaultServicesController(base.ServicesController):
store)
elif domain.certificate == 'san':
cert_for_domain = (
self.storage_controller.get_certs_by_domain(
self.ssl_certificate_storage.get_certs_by_domain(
domain.domain,
project_id=project_id,
flavor_id=service_new.flavor_id,
@ -404,7 +402,7 @@ class DefaultServicesController(base.ServicesController):
project_id,
new_cert_detail
)
self.storage_controller.create_cert(
self.ssl_certificate_storage.create_certificate(
project_id,
new_cert_obj
)
@ -434,7 +432,11 @@ class DefaultServicesController(base.ServicesController):
for provider in provider_details:
provider_details[provider].status = u'update_in_progress'
service_new.provider_details = provider_details
self.storage_controller.update(project_id, service_id, service_new)
self.storage_controller.update_service(
project_id,
service_id,
service_new
)
kwargs = {
'project_id': project_id,
@ -458,13 +460,16 @@ class DefaultServicesController(base.ServicesController):
def set_service_provider_details(self, project_id, service_id,
auth_token, status):
old_service = self.storage_controller.get(project_id, service_id)
old_service = self.storage_controller.get_service(
project_id,
service_id
)
if (
old_service.status == 'create_in_progress' and
old_service.provider_details == {}
):
self.update(
self.update_service(
project_id, service_id, auth_token, [], force_update=True)
return 202
self.storage_controller.set_service_provider_details(
@ -495,7 +500,7 @@ class DefaultServicesController(base.ServicesController):
if action == 'delete':
LOG.info('Deleting service: %s, project_id: %s' % (
service_obj.service_id, project_id))
self.delete(project_id, service_obj.service_id)
self.delete_service(project_id, service_obj.service_id)
elif action == 'enable':
LOG.info('Enabling service: %s, project_id: %s' % (
service_obj.service_id, project_id))
@ -539,7 +544,11 @@ class DefaultServicesController(base.ServicesController):
return
marker = None
service_batch = self.storage_controller.list(project_id, marker, 10)
service_batch = self.storage_controller.get_services(
project_id,
marker,
10
)
while len(service_batch) > 0:
marker = service_batch[-1].service_id
# process previous batch
@ -547,19 +556,23 @@ class DefaultServicesController(base.ServicesController):
self._action_per_service_obj(project_id=project_id,
action=action,
service_obj=service_obj)
service_batch = self.storage_controller.list(project_id, marker,
10)
service_batch = self.storage_controller.get_services(
project_id,
marker,
10
)
return
def delete(self, project_id, service_id):
def delete_service(self, project_id, service_id):
"""delete.
:param project_id
:param service_id
:raises LookupError
"""
service_obj = self.storage_controller.get(project_id, service_id)
service_obj = self.storage_controller.get_service(
project_id, service_id)
# get provider details for this service
provider_details = self._get_provider_details(project_id, service_id)
@ -569,7 +582,11 @@ class DefaultServicesController(base.ServicesController):
service_obj.provider_details[provider].status = (
u'delete_in_progress')
self.storage_controller.update(project_id, service_id, service_obj)
self.storage_controller.update_service(
project_id,
service_id,
service_obj
)
kwargs = {
"provider_details": json.dumps(
@ -588,7 +605,10 @@ class DefaultServicesController(base.ServicesController):
def purge(self, project_id, service_id, hard=False, purge_url=None):
"""If purge_url is none, all content of this service will be purge."""
try:
service_obj = self.storage_controller.get(project_id, service_id)
service_obj = self.storage_controller.get_service(
project_id,
service_id
)
except ValueError as e:
# This except is hit when service object does not exist
raise LookupError(str(e))
@ -607,7 +627,11 @@ class DefaultServicesController(base.ServicesController):
service_obj.provider_details[provider].status = (
u'update_in_progress')
self.storage_controller.update(project_id, service_id, service_obj)
self.storage_controller.update_service(
project_id,
service_id,
service_obj
)
# possible validation of purge url here...
kwargs = {

View File

@ -36,8 +36,10 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
super(DefaultSSLCertificateController, self).__init__(manager)
self.distributed_task_controller = (
self._driver.distributed_task.services_controller)
self.storage_controller = self._driver.storage.services_controller
self._driver.distributed_task.services_controller
)
self.storage = self._driver.storage.certificates_controller
self.service_storage = self._driver.storage.services_controller
self.flavor_controller = self._driver.storage.flavors_controller
def create_ssl_certificate(self, project_id, cert_obj):
@ -57,9 +59,10 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
raise e
try:
self.storage_controller.create_cert(
self.storage.create_certificate(
project_id,
cert_obj)
cert_obj
)
# ValueError will be raised if the cert_info has already existed
except ValueError as e:
raise e
@ -76,8 +79,7 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
**kwargs)
return kwargs
def delete_ssl_certificate(self, project_id, domain_name,
cert_type):
def delete_ssl_certificate(self, project_id, domain_name, cert_type):
kwargs = {
'project_id': project_id,
'domain_name': domain_name,
@ -91,7 +93,7 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
def get_certs_info_by_domain(self, domain_name, project_id):
try:
certs_info = self.storage_controller.get_certs_by_domain(
certs_info = self.storage.get_certs_by_domain(
domain_name=domain_name,
project_id=project_id)
if not certs_info:
@ -122,7 +124,7 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
def update_san_retry_list(self, queue_data_list):
for r in queue_data_list:
service_obj = self.storage_controller\
service_obj = self.service_storage\
.get_service_details_by_domain_name(r['domain_name'])
if service_obj is None and r.get('validate_service', True):
raise LookupError(u'Domain {0} does not exist on any service, '
@ -131,7 +133,7 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
'to retry this san-retry request forcefully'.
format(r['domain_name'], r))
cert_for_domain = self.storage_controller.get_certs_by_domain(
cert_for_domain = self.storage.get_certs_by_domain(
r['domain_name'])
if cert_for_domain != []:
if cert_for_domain.get_cert_status() == "deployed":
@ -154,7 +156,7 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
akamai_driver.mod_san_queue.put_queue_data(new_queue_data)]
deleted = tuple(x for x in orig if x not in res)
# other provider's retry-list implementaiton goes here
# other provider's retry-list implementation goes here
return res, deleted
def rerun_san_retry_list(self):
@ -168,10 +170,10 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
# remove duplicates
# see http://bit.ly/1mX2Vcb for details
def remove_duplicates(data):
'''Remove duplicates from the data (normally a list).
"""Remove duplicates from the data (normally a list).
The data must be sortable and have an equality operator
'''
"""
data = sorted(data)
return [k for k, _ in itertools.groupby(data)]
retry_list = remove_duplicates(retry_list)
@ -179,7 +181,7 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
# double check in POST. This check should really be first done in
# PUT
for r in retry_list:
service_obj = self.storage_controller\
service_obj = self.service_storage\
.get_service_details_by_domain_name(r['domain_name'])
if service_obj is None and r.get('validate_service', True):
raise LookupError(u'Domain {0} does not exist on any '
@ -189,7 +191,7 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
' san-retry request forcefully'.
format(r['domain_name'], r))
cert_for_domain = self.storage_controller.get_certs_by_domain(
cert_for_domain = self.storage.get_certs_by_domain(
r['domain_name'])
if cert_for_domain != []:
if cert_for_domain.get_cert_status() == "deployed":
@ -207,7 +209,7 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
)
cert_for_domain = (
self.storage_controller.get_certs_by_domain(
self.storage.get_certs_by_domain(
cert_obj.domain_name,
project_id=cert_obj.project_id,
flavor_id=cert_obj.flavor_id,
@ -303,3 +305,8 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
res = {}
return res
def get_certs_by_status(self, status):
services_project_ids = self.storage.get_certs_by_status(status)
return services_project_ids

View File

@ -32,9 +32,11 @@ class GetCertInfoTask(task.Task):
default_provides = "cert_obj_json"
def execute(self, domain_name, cert_type, flavor_id, project_id):
service_controller, self.storage_controller = \
memoized_controllers.task_controllers('poppy', 'storage')
res = self.storage_controller.get_certs_by_domain(
service_controller, self.ssl_certificate_manager = \
memoized_controllers.task_controllers('poppy', 'ssl_certificate')
self.storage = self.ssl_certificate_manager.storage
res = self.storage.get_certs_by_domain(
domain_name, project_id=project_id,
flavor_id=flavor_id, cert_type=cert_type)
if res is None:
@ -103,26 +105,33 @@ class UpdateCertStatusTask(task.Task):
def __init__(self):
super(UpdateCertStatusTask, self).__init__()
service_controller, self.storage_controller = \
memoized_controllers.task_controllers('poppy', 'storage')
service_controller, self.ssl_certificate_manager = \
memoized_controllers.task_controllers('poppy', 'ssl_certificate')
self.storage_controller = (
self.ssl_certificate_manager.storage
)
self.service_storage = service_controller.storage_controller
def execute(self, project_id, cert_obj_json, status_change_to):
if cert_obj_json != "":
cert_obj = ssl_certificate.load_from_json(json.loads(cert_obj_json)
)
cert_obj = ssl_certificate.load_from_json(
json.loads(cert_obj_json)
)
cert_details = cert_obj.cert_details
if status_change_to != "":
cert_details['Akamai']['extra_info']['status'] = (
status_change_to)
cert_details['Akamai'] = json.dumps(cert_details['Akamai'])
self.storage_controller.update_cert_info(cert_obj.domain_name,
cert_obj.cert_type,
cert_obj.flavor_id,
cert_details)
self.storage_controller.update_certificate(
cert_obj.domain_name,
cert_obj.cert_type,
cert_obj.flavor_id,
cert_details
)
service_obj = (
self.storage_controller.
self.service_storage.
get_service_details_by_domain_name(cert_obj.domain_name)
)
# Update provider details
@ -131,7 +140,7 @@ class UpdateCertStatusTask(task.Task):
domains_certificate_status.\
set_domain_certificate_status(cert_obj.domain_name,
status_change_to)
self.storage_controller.update_provider_details(
self.service_storage.update_provider_details(
project_id,
service_obj.service_id,
service_obj.provider_details

View File

@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from poppy.storage.base import certificates
from poppy.storage.base import driver
from poppy.storage.base import flavors
from poppy.storage.base import services
@ -20,5 +21,6 @@ from poppy.storage.base import services
Driver = driver.StorageDriverBase
CertificatesController = certificates.CertificatesControllerBase
FlavorsController = flavors.FlavorsControllerBase
ServicesController = services.ServicesControllerBase

View File

@ -0,0 +1,56 @@
# Copyright (c) 2016 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.
import abc
import six
from poppy.storage.base import controller
@six.add_metaclass(abc.ABCMeta)
class CertificatesControllerBase(controller.StorageControllerBase):
@abc.abstractmethod
def create_certificate(self, project_id, cert_obj):
"""Create a certificate
:param project_id
:param cert_obj
:raise NotImplementedError
"""
raise NotImplementedError
def delete_certificate(self, project_id, domain_name, cert_type):
"""Delete a certificate.
:param project_id
:param domain_name
:param cert_type
:raise NotImplementedError
"""
raise NotImplementedError
@abc.abstractmethod
def update_certificate(self, domain_name, cert_type, flavor_id,
cert_details):
"""update_cert_info.
:param domain_name
:param cert_type
:param flavor_id
:param cert_details
"""
raise NotImplementedError

View File

@ -62,8 +62,8 @@ class StorageDriverBase(object):
raise NotImplementedError
@abc.abstractproperty
def services_controller(self):
"""Returns the driver's hostname controller.
def certificates_controller(self):
"""Returns the driver's certificates controller.
:raise NotImplementedError
"""
@ -71,7 +71,15 @@ class StorageDriverBase(object):
@abc.abstractproperty
def flavors_controller(self):
"""Returns the driver's hostname controller.
"""Returns the driver's flavors controller.
:raise NotImplementedError
"""
raise NotImplementedError
@abc.abstractproperty
def services_controller(self):
"""Returns the driver's services controller.
:raise NotImplementedError
"""

View File

@ -28,8 +28,8 @@ class ServicesControllerBase(controller.StorageControllerBase):
super(ServicesControllerBase, self).__init__(driver)
@abc.abstractmethod
def list(self, project_id, marker=None, limit=None):
"""list
def get_services(self, project_id, marker=None, limit=None):
"""Get a list of services for a project.
:param project_id
:param marker
@ -39,19 +39,18 @@ class ServicesControllerBase(controller.StorageControllerBase):
raise NotImplementedError
@abc.abstractmethod
def create(self, project_id, service_id, service_json):
"""create
def create_service(self, project_id, service_obj):
"""Create a service.
:param project_id
:param service_id
:param service_json
:param service_obj
:raise NotImplementedError
"""
raise NotImplementedError
@abc.abstractmethod
def update(self, project_id, service_id, service_json):
"""update
def update_service(self, project_id, service_id, service_json):
"""Update a service.
:param project_id
:param service_id
@ -64,7 +63,7 @@ class ServicesControllerBase(controller.StorageControllerBase):
@abc.abstractmethod
def update_state(self, project_id, service_id, state):
"""update_state
"""Update service state.
Update service state
@ -76,8 +75,8 @@ class ServicesControllerBase(controller.StorageControllerBase):
raise NotImplementedError
@abc.abstractmethod
def delete(self, project_id, service_id):
"""delete
def delete_service(self, project_id, service_id):
"""Delete a service.
:param project_id
:param service_id
@ -86,8 +85,8 @@ class ServicesControllerBase(controller.StorageControllerBase):
raise NotImplementedError
@abc.abstractmethod
def get(self):
"""get
def get_service(self, project_id, service_id):
"""Get a service object.
:raise NotImplementedError
"""
@ -95,7 +94,7 @@ class ServicesControllerBase(controller.StorageControllerBase):
@abc.abstractmethod
def get_provider_details(self, project_id, service_id):
"""get_provider_details
"""Get provider details for a service.
:param project_id
:param service_id
@ -104,36 +103,17 @@ class ServicesControllerBase(controller.StorageControllerBase):
raise NotImplementedError
@abc.abstractmethod
def update_provider_details(self, provider_details):
"""update_provider_details
:param provider_details
:raise NotImplementedError
"""
raise NotImplementedError
@abc.abstractmethod
def create_cert(self, project_id, cert_obj):
"""create_cert
def update_provider_details(self, project_id, service_id,
provider_details):
"""Update provider details for a service.
:param project_id
:param cert_obj
:param service_id
:param provider_details
:raise NotImplementedError
"""
raise NotImplementedError
@abc.abstractmethod
def update_cert_info(self, domain_name, cert_type, flavor_id,
cert_details):
"""update_cert_info.
:param domain_name
:param cert_type
:param flavor_id
:param cert_info
"""
raise NotImplementedError
@staticmethod
def format_result(result):
"""format_result

View File

@ -0,0 +1,295 @@
# Copyright (c) 2016 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.
import json
from cassandra import query
from oslo_log import log
from six.moves import filterfalse
from poppy.model import ssl_certificate
from poppy.storage import base
LOG = log.getLogger(__name__)
CQL_CREATE_CERT = '''
INSERT INTO certificate_info (project_id,
flavor_id,
cert_type,
domain_name,
cert_details
)
VALUES (%(project_id)s,
%(flavor_id)s,
%(cert_type)s,
%(domain_name)s,
%(cert_details)s)
'''
CQL_SEARCH_CERT_BY_DOMAIN = '''
SELECT project_id,
flavor_id,
cert_type,
domain_name,
cert_details
FROM certificate_info
WHERE domain_name = %(domain_name)s
'''
CQL_GET_CERTS_BY_STATUS = '''
SELECT domain_name
FROM cert_status WHERE status = %(status)s
'''
CQL_DELETE_CERT = '''
DELETE FROM certificate_info
WHERE domain_name = %(domain_name)s
'''
CQL_DELETE_CERT_STATUS = '''
DELETE FROM cert_status
WHERE domain_name = %(domain_name)s
'''
CQL_INSERT_CERT_STATUS = '''
INSERT INTO cert_status (domain_name,
status
)
VALUES (%(domain_name)s,
%(status)s)
'''
CQL_UPDATE_CERT_DETAILS = '''
UPDATE certificate_info
set cert_details = %(cert_details)s
WHERE domain_name = %(domain_name)s
IF cert_type = %(cert_type)s AND flavor_id = %(flavor_id)s
'''
class CertificatesController(base.CertificatesController):
"""Certificates Controller."""
@property
def session(self):
"""Get session.
:returns session
"""
return self._driver.database
def create_certificate(self, project_id, cert_obj):
if self.cert_already_exist(domain_name=cert_obj.domain_name,
comparing_cert_type=cert_obj.cert_type,
comparing_flavor_id=cert_obj.flavor_id,
comparing_project_id=project_id):
raise ValueError('Certificate already exists '
'for {0} '.format(cert_obj.domain_name))
args = {
'project_id': project_id,
'flavor_id': cert_obj.flavor_id,
'cert_type': cert_obj.cert_type,
'domain_name': cert_obj.domain_name,
# when create the cert, cert domain has not been assigned yet
# In future we can tweak the logic to assign cert_domain
# 'cert_domain': '',
'cert_details': cert_obj.cert_details
}
stmt = query.SimpleStatement(
CQL_CREATE_CERT,
consistency_level=self._driver.consistency_level)
self.session.execute(stmt, args)
def delete_certificate(self, project_id, domain_name, cert_type):
args = {
'domain_name': domain_name.lower()
}
stmt = query.SimpleStatement(
CQL_SEARCH_CERT_BY_DOMAIN,
consistency_level=self._driver.consistency_level)
result_set = self.session.execute(stmt, args)
complete_results = list(result_set)
if complete_results:
for r in complete_results:
r_project_id = str(r.get('project_id'))
r_cert_type = str(r.get('cert_type'))
if r_project_id == str(project_id) and \
r_cert_type == str(cert_type):
args = {
'domain_name': str(r.get('domain_name'))
}
stmt = query.SimpleStatement(
CQL_DELETE_CERT,
consistency_level=self._driver.consistency_level)
self.session.execute(stmt, args)
stmt = query.SimpleStatement(
CQL_DELETE_CERT_STATUS,
consistency_level=self._driver.consistency_level)
self.session.execute(stmt, args)
else:
raise ValueError(
"No certificate found for: {0},"
"type: {1}".format(domain_name, cert_type))
def update_certificate(self, domain_name, cert_type, flavor_id,
cert_details):
args = {
'domain_name': domain_name,
'cert_type': cert_type,
'flavor_id': flavor_id,
'cert_details': cert_details
}
stmt = query.SimpleStatement(
CQL_UPDATE_CERT_DETAILS,
consistency_level=self._driver.consistency_level)
self.session.execute(stmt, args)
try:
provider_status = json.loads(cert_details.values()[0])
cert_status = provider_status['extra_info']['status']
except (IndexError, IndexError, ValueError) as e:
LOG.error("Certificate details "
"in inconsistent "
"state: {0}".format(cert_details))
LOG.error(e)
else:
cert_args = {
'domain_name': domain_name,
'status': cert_status
}
stmt = query.SimpleStatement(
CQL_INSERT_CERT_STATUS,
consistency_level=self._driver.consistency_level)
self.session.execute(stmt, cert_args)
def get_certs_by_status(self, status):
LOG.info("Getting domains which have "
"certificate in status : {0}".format(status))
args = {
'status': status
}
stmt = query.SimpleStatement(
CQL_GET_CERTS_BY_STATUS,
consistency_level=self._driver.consistency_level)
resultset = self.session.execute(stmt, args)
complete_results = list(resultset)
return complete_results
def get_certs_by_domain(self, domain_name, project_id=None,
flavor_id=None,
cert_type=None):
LOG.info("Check if cert on '{0}' exists".format(domain_name))
args = {
'domain_name': domain_name.lower()
}
stmt = query.SimpleStatement(
CQL_SEARCH_CERT_BY_DOMAIN,
consistency_level=self._driver.consistency_level)
resultset = self.session.execute(stmt, args)
complete_results = list(resultset)
certs = []
if complete_results:
for r in complete_results:
r_project_id = str(r.get('project_id'))
r_flavor_id = str(r.get('flavor_id'))
r_cert_type = str(r.get('cert_type'))
r_cert_details = {}
# in case cert_details is None
cert_details = r.get('cert_details', {}) or {}
# Need to convert cassandra dict into real dict
# And the value of cert_details is a string dict
for key in cert_details:
r_cert_details[key] = json.loads(cert_details[key])
LOG.info(
"Certificate for domain: {0} with flavor_id: {1}, "
"cert_details : {2} and cert_type: {3} present "
"on project_id: {4}".format(
domain_name,
r_flavor_id,
r_cert_details,
r_cert_type,
r_project_id
)
)
ssl_cert = ssl_certificate.SSLCertificate(
domain_name=domain_name,
flavor_id=r_flavor_id,
cert_details=r_cert_details,
cert_type=r_cert_type,
project_id=r_project_id
)
certs.append(ssl_cert)
non_none_attrs_gen = filterfalse(
lambda x: list(x.values())[0] is None, [{'project_id': project_id},
{'flavor_id': flavor_id},
{'cert_type': cert_type}])
non_none_attrs_list = list(non_none_attrs_gen)
non_none_attrs_dict = {}
if non_none_attrs_list:
for attr in non_none_attrs_list:
non_none_attrs_dict.update(attr)
def argfilter(certificate):
all_conditions = True
if non_none_attrs_dict:
for k, v in non_none_attrs_dict.items():
if getattr(certificate, k) != v:
all_conditions = False
return all_conditions
total_certs = [cert for cert in certs if argfilter(cert)]
if len(total_certs) == 1:
return total_certs[0]
else:
return total_certs
def cert_already_exist(self, domain_name, comparing_cert_type,
comparing_flavor_id, comparing_project_id):
"""cert_already_exist
Check if a cert with this domain name and type has already been
created, or if the domain has been taken by other customers
:param domain_name
:param comparing_cert_type
:param comparing_flavor_id
:param comparing_project_id
:returns Boolean if the cert with same type exists with another user.
"""
cert = self.get_certs_by_domain(
domain_name=domain_name,
cert_type=comparing_cert_type,
flavor_id=comparing_flavor_id
)
if cert:
return True
else:
return False

View File

@ -23,8 +23,10 @@ Field Mappings:
updated and documented in each controller class.
"""
from poppy.storage.cassandra import certificates
from poppy.storage.cassandra import flavors
from poppy.storage.cassandra import services
ServicesController = services.ServicesController
CertificatesController = certificates.CertificatesController
FlavorsController = flavors.FlavorsController
ServicesController = services.ServicesController

View File

@ -220,12 +220,12 @@ class CassandraStorageDriver(base.Driver):
return _connection(self.cassandra_conf, self.datacenter)
@property
def services_controller(self):
"""services_controller.
def certificates_controller(self):
"""certificates_controller.
:returns service controller
:returns certificates controller
"""
return controllers.ServicesController(self)
return controllers.CertificatesController(self)
@property
def flavors_controller(self):
@ -235,6 +235,14 @@ class CassandraStorageDriver(base.Driver):
"""
return controllers.FlavorsController(self)
@property
def services_controller(self):
"""services_controller.
:returns service controller
"""
return controllers.ServicesController(self)
@property
def database(self):
"""database.

View File

@ -22,16 +22,8 @@ except ImportError: # pragma: no cover
import collections # pragma: no cover
from cassandra import query
import six
from oslo_log import log
if six.PY2:
from itertools import ifilterfalse as filterfalse
else:
from itertools import filterfalse
from poppy.model.helpers import cachingrule
from poppy.model.helpers import domain
from poppy.model.helpers import origin
@ -40,7 +32,6 @@ from poppy.model.helpers import restriction
from poppy.model.helpers import rule
from poppy.model import log_delivery as ld
from poppy.model import service
from poppy.model import ssl_certificate
from poppy.storage import base
LOG = log.getLogger(__name__)
@ -190,62 +181,6 @@ CQL_CREATE_SERVICE = '''
%(log_delivery)s)
'''
CQL_CREATE_CERT = '''
INSERT INTO certificate_info (project_id,
flavor_id,
cert_type,
domain_name,
cert_details
)
VALUES (%(project_id)s,
%(flavor_id)s,
%(cert_type)s,
%(domain_name)s,
%(cert_details)s)
'''
CQL_VERIFY_CERT = '''
SELECT project_id,
flavor_id,
cert_type,
domain_name
FROM certificate_info
WHERE domain_name = %(domain_name)s
'''
CQL_SEARCH_CERT_BY_DOMAIN = '''
SELECT project_id,
flavor_id,
cert_type,
domain_name,
cert_details
FROM certificate_info
WHERE domain_name = %(domain_name)s
'''
CQL_DELETE_CERT = '''
DELETE FROM certificate_info
WHERE domain_name = %(domain_name)s
'''
CQL_INSERT_CERT_STATUS = '''
INSERT INTO cert_status (domain_name,
status
)
VALUES (%(domain_name)s,
%(status)s)
'''
CQL_DELETE_CERT_STATUS = '''
DELETE FROM cert_status
WHERE domain_name = %(domain_name)s
'''
CQL_GET_CERTS_BY_STATUS = '''
SELECT domain_name
FROM cert_status WHERE status = %(status)s
'''
CQL_UPDATE_SERVICE = CQL_CREATE_SERVICE
@ -320,7 +255,7 @@ class ServicesController(base.ServicesController):
"""
return self._driver.database
def list(self, project_id, marker, limit):
def get_services(self, project_id, marker, limit):
"""list.
:param project_id
@ -347,11 +282,11 @@ class ServicesController(base.ServicesController):
return services
def get(self, project_id, service_id):
def get_service(self, project_id, service_id):
"""get.
:param project_id
:param service_name
:param service_id
:returns result The requested service
:raises ValueError
@ -364,8 +299,8 @@ class ServicesController(base.ServicesController):
stmt = query.SimpleStatement(
CQL_GET_SERVICE,
consistency_level=self._driver.consistency_level)
resultset = self.session.execute(stmt, args)
complete_result = list(resultset)
result_set = self.session.execute(stmt, args)
complete_result = list(result_set)
if len(complete_result) != 1:
raise ValueError('No service found: %s'
% service_id)
@ -418,30 +353,6 @@ class ServicesController(base.ServicesController):
LOG.exception(ex)
return False
def cert_already_exist(self, domain_name, comparing_cert_type,
comparing_flavor_id,
comparing_project_id):
"""cert_already_exist
Check if a cert with this domain name and type has already been
created, or if the domain has been taken by other customers
:param domain_name
:param comparing_cert_type
:param comparing_flavor_id
:param comparing_project_id
:returns Boolean if the cert with same type exists with another user.
"""
cert = self.get_certs_by_domain(domain_name=domain_name,
cert_type=comparing_cert_type,
flavor_id=comparing_flavor_id)
if cert:
return True
else:
return False
def get_service_count(self, project_id):
"""get_service_count
@ -484,8 +395,8 @@ class ServicesController(base.ServicesController):
CQL_GET_SERVICE_STATUS,
consistency_level=self._driver.consistency_level)
resultset = self.session.execute(stmt, args)
complete_results = list(resultset)
result_set = self.session.execute(stmt, args)
complete_results = list(result_set)
for result in complete_results:
result['service_id'] = str(result['service_id'])
@ -519,9 +430,9 @@ class ServicesController(base.ServicesController):
CQL_GET_BY_PROVIDER_URL,
consistency_level=self._driver.consistency_level)
resultset = self.session.execute(stmt, get_domain_provider_url_args)
result_set = self.session.execute(stmt, get_domain_provider_url_args)
return list(resultset)
return list(result_set)
def delete_provider_url(self, provider_url, domain_name):
@ -562,8 +473,8 @@ class ServicesController(base.ServicesController):
stmt = query.SimpleStatement(
CQL_GET_SERVICE_LIMIT,
consistency_level=self._driver.consistency_level)
resultset = self.session.execute(stmt, args)
complete_results = list(resultset)
result_set = self.session.execute(stmt, args)
complete_results = list(result_set)
if complete_results:
LOG.info("Checking for service limit for project_id: '{0}' "
"existence yielded {1}".format(project_id,
@ -625,7 +536,7 @@ class ServicesController(base.ServicesController):
:param project_id
:param service_id
:param status
"""
LOG.info("Setting service "
@ -656,132 +567,7 @@ class ServicesController(base.ServicesController):
service_id=service_id,
provider_details=provider_details_dict)
def get_certs_by_status(self, status):
LOG.info("Getting domains which have "
"certificate in status : {0}".format(status))
args = {
'status': status
}
stmt = query.SimpleStatement(
CQL_GET_CERTS_BY_STATUS,
consistency_level=self._driver.consistency_level)
resultset = self.session.execute(stmt, args)
complete_results = list(resultset)
return complete_results
def get_certs_by_domain(self, domain_name, project_id=None, flavor_id=None,
cert_type=None):
LOG.info("Check if cert on '{0}' exists".format(domain_name))
args = {
'domain_name': domain_name.lower()
}
stmt = query.SimpleStatement(
CQL_SEARCH_CERT_BY_DOMAIN,
consistency_level=self._driver.consistency_level)
resultset = self.session.execute(stmt, args)
complete_results = list(resultset)
certs = []
if complete_results:
for r in complete_results:
r_project_id = str(r.get('project_id'))
r_flavor_id = str(r.get('flavor_id'))
r_cert_type = str(r.get('cert_type'))
r_cert_details = {}
# in case cert_details is None
cert_details = r.get('cert_details', {}) or {}
# Need to convert cassandra dict into real dict
# And the value of cert_details is a string dict
for key in cert_details:
r_cert_details[key] = json.loads(cert_details[key])
LOG.info("Certificate for domain: {0} "
"with flavor_id: {1}, "
"cert_details : {2} and "
"cert_type: {3} present "
"on project_id: {4}".format(domain_name,
r_flavor_id,
r_cert_details,
r_cert_type,
r_project_id))
ssl_cert = ssl_certificate.SSLCertificate(
domain_name=domain_name,
flavor_id=r_flavor_id,
cert_details=r_cert_details,
cert_type=r_cert_type,
project_id=r_project_id)
certs.append(ssl_cert)
non_none_attrs_gen = filterfalse(
lambda x: list(x.values())[0] is None, [{'project_id': project_id},
{'flavor_id': flavor_id},
{'cert_type': cert_type}])
non_none_attrs_list = list(non_none_attrs_gen)
non_none_attrs_dict = {}
if non_none_attrs_list:
for attr in non_none_attrs_list:
non_none_attrs_dict.update(attr)
def argfilter(certificate):
all_conditions = True
if non_none_attrs_dict:
for k, v in non_none_attrs_dict.items():
if getattr(certificate, k) != v:
all_conditions = False
return all_conditions
total_certs = [cert for cert in certs if argfilter(cert)]
if len(total_certs) == 1:
return total_certs[0]
else:
return total_certs
def delete_cert(self, project_id, domain_name, cert_type):
"""delete_cert
Delete a certificate.
:param project_id
:param domain_name
:param cert_type
:raises ValueError
"""
args = {
'domain_name': domain_name.lower()
}
stmt = query.SimpleStatement(
CQL_SEARCH_CERT_BY_DOMAIN,
consistency_level=self._driver.consistency_level)
resultset = self.session.execute(stmt, args)
complete_results = list(resultset)
if complete_results:
for r in complete_results:
r_project_id = str(r.get('project_id'))
r_cert_type = str(r.get('cert_type'))
if r_project_id == str(project_id) and \
r_cert_type == str(cert_type):
args = {
'domain_name': str(r.get('domain_name'))
}
stmt = query.SimpleStatement(
CQL_DELETE_CERT,
consistency_level=self._driver.consistency_level)
self.session.execute(stmt, args)
stmt = query.SimpleStatement(
CQL_DELETE_CERT_STATUS,
consistency_level=self._driver.consistency_level)
self.session.execute(stmt, args)
else:
raise ValueError("No certificate found for: {0},"
"type: {1}".format(domain_name, cert_type))
def create(self, project_id, service_obj):
def create_service(self, project_id, service_obj):
"""create.
:param project_id
@ -842,7 +628,7 @@ class ServicesController(base.ServicesController):
self.session.execute(batch)
def update(self, project_id, service_id, service_obj):
def update_service(self, project_id, service_id, service_obj):
"""update.
:param project_id
@ -876,8 +662,8 @@ class ServicesController(base.ServicesController):
CQL_GET_SERVICE,
consistency_level=self._driver.consistency_level)
resultset = self.session.execute(stmt, args)
complete_results = list(resultset)
result_set = self.session.execute(stmt, args)
complete_results = list(result_set)
result = complete_results[0]
# updates an existing service
@ -938,9 +724,7 @@ class ServicesController(base.ServicesController):
self.session.execute(stmt, args)
def update_state(self, project_id, service_id, state):
"""update_state
Update service state
"""Update service state
:param project_id
:param service_id
@ -949,13 +733,13 @@ class ServicesController(base.ServicesController):
:returns service_obj
"""
service_obj = self.get(project_id, service_id)
service_obj = self.get_service(project_id, service_id)
service_obj.operator_status = state
self.update(project_id, service_id, service_obj)
self.update_service(project_id, service_id, service_obj)
return service_obj
def delete(self, project_id, service_id):
def delete_service(self, project_id, service_id):
"""delete.
Archive local configuration storage
@ -1033,29 +817,6 @@ class ServicesController(base.ServicesController):
consistency_level=self._driver.consistency_level)
self.session.execute(stmt, delete_args)
def create_cert(self, project_id, cert_obj):
if self.cert_already_exist(domain_name=cert_obj.domain_name,
comparing_cert_type=cert_obj.cert_type,
comparing_flavor_id=cert_obj.flavor_id,
comparing_project_id=project_id):
raise ValueError('Certificate already exists '
'for {0} '.format(cert_obj.domain_name))
args = {
'project_id': project_id,
'flavor_id': cert_obj.flavor_id,
'cert_type': cert_obj.cert_type,
'domain_name': cert_obj.domain_name,
# when create the cert, cert domain has not been assigned yet
# In future we can tweak the logic to assign cert_domain
# 'cert_domain': '',
'cert_details': cert_obj.cert_details
}
stmt = query.SimpleStatement(
CQL_CREATE_CERT,
consistency_level=self._driver.consistency_level)
self.session.execute(stmt, args)
def get_provider_details(self, project_id, service_id):
"""get_provider_details.
@ -1108,6 +869,7 @@ class ServicesController(base.ServicesController):
"""get_provider_details_by_domain_name.
:param domain_name
:param project_id
:returns Provider details
"""
@ -1119,8 +881,8 @@ class ServicesController(base.ServicesController):
stmt = query.SimpleStatement(
CQL_SEARCH_BY_DOMAIN,
consistency_level=self._driver.consistency_level)
resultset = self.session.execute(stmt, args)
complete_results = list(resultset)
result_set = self.session.execute(stmt, args)
complete_results = list(result_set)
# If there is not service with this domain
# return None
details = None
@ -1131,8 +893,8 @@ class ServicesController(base.ServicesController):
"present under "
"project_id: {1}".format(domain_name,
project_id))
service = r.get('service_id')
details = self.get(proj_id, service)
service_id = r.get('service_id')
details = self.get_service(proj_id, service_id)
return details
def update_provider_details(self, project_id, service_id,
@ -1212,45 +974,6 @@ class ServicesController(base.ServicesController):
consistency_level=self._driver.consistency_level)
self.session.execute(stmt, provider_url_args)
def update_cert_info(self, domain_name, cert_type, flavor_id,
cert_details):
"""update_cert_info.
:param domain_name
:param cert_type
:param flavor_id
:param cert_info
"""
args = {
'domain_name': domain_name,
'cert_type': cert_type,
'flavor_id': flavor_id,
'cert_details': cert_details
}
stmt = query.SimpleStatement(
CQL_UPDATE_CERT_DETAILS,
consistency_level=self._driver.consistency_level)
self.session.execute(stmt, args)
try:
provider_status = json.loads(cert_details.values()[0])
cert_status = provider_status['extra_info']['status']
except (IndexError, IndexError, ValueError) as e:
LOG.error("Certificate details "
"in inconsistent "
"state: {0}".format(cert_details))
LOG.error(e)
else:
cert_args = {
'domain_name': domain_name,
'status': cert_status
}
stmt = query.SimpleStatement(
CQL_INSERT_CERT_STATUS,
consistency_level=self._driver.consistency_level)
self.session.execute(stmt, cert_args)
@staticmethod
def format_result(result):
"""format_result.

View File

@ -0,0 +1,77 @@
# Copyright (c) 2016 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.
import random
from poppy.model import ssl_certificate
from poppy.storage import base
class CertificatesController(base.CertificatesController):
def __init__(self, driver):
super(CertificatesController, self).__init__(driver)
self.certs = {}
def create_certificate(self, project_id, cert_obj):
key = (cert_obj.flavor_id, cert_obj.domain_name, cert_obj.cert_type)
if key not in self.certs:
self.certs[key] = cert_obj
else:
raise ValueError
def delete_certificate(self, project_id, domain_name, cert_type):
if "non_exist" in domain_name:
raise ValueError("No certs on this domain")
def update_certificate(self, domain_name, cert_type, flavor_id,
cert_details):
key = (flavor_id, domain_name, cert_type)
if key in self.certs:
self.certs[key].cert_details = cert_details
def get_certs_by_domain(self, domain_name, project_id=None,
flavor_id=None,
cert_type=None,
status=u'create_in_progress'):
certs = []
for cert in self.certs:
if domain_name in cert:
certs.append(self.certs[cert])
if project_id:
if flavor_id is not None and cert_type is not None:
return ssl_certificate.SSLCertificate(
"premium",
"blog.testabcd.com",
"san",
project_id=project_id,
cert_details={
'Akamai': {
u'cert_domain': u'secure2.san1.test_123.com',
u'extra_info': {
u'action': u'Waiting for customer domain '
'validation for blog.testabc.com',
u'akamai_spsId': str(random.randint(1, 100000)
),
u'create_at': u'2015-09-29 16:09:12.429147',
u'san cert': u'secure2.san1.test_123.com',
u'status': status}
}
}
)
return [cert for cert in certs if cert.project_id == project_id]
else:
return certs

View File

@ -23,8 +23,10 @@ Field Mappings:
updated and documented in each controller class.
"""
from poppy.storage.mockdb import certificates
from poppy.storage.mockdb import flavors
from poppy.storage.mockdb import services
ServicesController = services.ServicesController
CertificatesController = certificates.CertificatesController
FlavorsController = flavors.FlavorsController
ServicesController = services.ServicesController

View File

@ -59,13 +59,17 @@ class MockDBStorageDriver(base.Driver):
return _connection()
@property
def services_controller(self):
return controllers.ServicesController(self)
def certificates_controller(self):
return controllers.CertificatesController(self)
@property
def flavors_controller(self):
return controllers.FlavorsController(self)
@property
def services_controller(self):
return controllers.ServicesController(self)
@property
def database(self):
return self.connection

View File

@ -14,7 +14,6 @@
# limitations under the License.
import json
import random
from poppy.model.helpers import domain
from poppy.model.helpers import origin
@ -22,28 +21,32 @@ from poppy.model.helpers import provider_details
from poppy.model.helpers import restriction
from poppy.model.helpers import rule
from poppy.model import service
from poppy.model import ssl_certificate
from poppy.storage import base
created_services = {}
created_service_ids = []
claimed_domains = []
project_id_service_limit = {}
service_count_per_project_id = {}
class ServicesController(base.ServicesController):
def __init__(self, driver):
super(ServicesController, self).__init__(driver)
self.created_service_ids = []
self.created_services = {}
self.claimed_domains = []
self.projectid_service_limit = {}
self.created_service_ids = created_service_ids
self.created_services = created_services
self.claimed_domains = claimed_domains
self.project_id_service_limit = project_id_service_limit
self.default_max_service_limit = 20
self.service_count_per_project_id = {}
self.certs = {}
self.service_count_per_project_id = service_count_per_project_id
@property
def session(self):
return self._driver.database
def list(self, project_id, marker=None, limit=None):
def get_services(self, project_id, marker=None, limit=None):
services = []
for service_id in self.created_services:
services.append(self.created_services[service_id])
@ -55,7 +58,7 @@ class ServicesController(base.ServicesController):
return services_result
def get(self, project_id, service_id):
def get_service(self, project_id, service_id):
# get the requested service from storage
if service_id not in self.created_service_ids:
raise ValueError("service {0} does not exist".format(service_id))
@ -65,7 +68,7 @@ class ServicesController(base.ServicesController):
service_result._status = 'deployed'
return service_result
def create(self, project_id, service_obj):
def create_service(self, project_id, service_obj):
if service_obj.service_id in self.created_service_ids:
raise ValueError("Service %s already exists." %
service_obj.service_id)
@ -80,11 +83,11 @@ class ServicesController(base.ServicesController):
self.service_count_per_project_id[project_id] = 1
def set_service_limit(self, project_id, project_limit):
self.projectid_service_limit[project_id] = project_limit
self.project_id_service_limit[project_id] = project_limit
def get_service_limit(self, project_id):
try:
return self.projectid_service_limit[project_id]
return self.project_id_service_limit[project_id]
except KeyError:
return self.default_max_service_limit
@ -106,7 +109,7 @@ class ServicesController(base.ServicesController):
return complete_results
def update(self, project_id, service_id, service_json):
def update_service(self, project_id, service_id, service_json):
# update configuration in storage
if service_json.service_id in self.created_service_ids \
and service_json.service_id == service_id:
@ -132,14 +135,14 @@ class ServicesController(base.ServicesController):
:returns service_obj
"""
service_obj = self.get(project_id, service_id)
service_obj = self.get_service(project_id, service_id)
service_obj.operator_status = state
self.update(project_id, service_id, service_obj)
self.update_service(project_id, service_id, service_obj)
return self.get(project_id, service_id)
return self.get_service(project_id, service_id)
def delete(self, project_id, service_id):
if (service_id in self.created_service_ids):
def delete_service(self, project_id, service_id):
if service_id in self.created_service_ids:
self.created_service_ids.remove(service_id)
try:
self.service_count_per_project_id[project_id] -= 1
@ -179,12 +182,6 @@ class ServicesController(base.ServicesController):
def domain_exists_elsewhere(self, domain_name, service_id):
return domain_name in self.claimed_domains
def update_cert_info(self, domain_name, cert_type, flavor_id,
cert_details):
key = (flavor_id, domain_name, cert_type)
if key in self.certs:
self.certs[key].cert_details = cert_details
def get_service_details_by_domain_name(self, domain_name,
project_id=None):
for service_id in self.created_services:
@ -195,48 +192,6 @@ class ServicesController(base.ServicesController):
service_result._status = 'deployed'
return service_result
def create_cert(self, project_id, cert_obj):
key = (cert_obj.flavor_id, cert_obj.domain_name, cert_obj.cert_type)
if key not in self.certs:
self.certs[key] = cert_obj
else:
raise ValueError
def get_certs_by_domain(self, domain_name, project_id=None, flavor_id=None,
cert_type=None, status=u'create_in_progress'):
certs = []
for cert in self.certs:
if domain_name in cert:
certs.append(self.certs[cert])
if project_id:
if flavor_id is not None and cert_type is not None:
return ssl_certificate.SSLCertificate(
"premium",
"blog.testabcd.com",
"san",
project_id=project_id,
cert_details={
'Akamai': {
u'cert_domain': u'secure2.san1.test_123.com',
u'extra_info': {
u'action': u'Waiting for customer domain '
'validation for blog.testabc.com',
u'akamai_spsId': str(random.randint(1, 100000)
),
u'create_at': u'2015-09-29 16:09:12.429147',
u'san cert': u'secure2.san1.test_123.com',
u'status': status}
}
}
)
return [cert for cert in certs if cert.project_id == project_id]
else:
return certs
def delete_cert(self, project_id, domain_name, cert_type):
if "non_exist" in domain_name:
raise ValueError("No certs on this domain")
@staticmethod
def format_result(result):
service_id = result.get('service_id')

View File

@ -425,16 +425,17 @@ class AdminCertController(base.Controller, hooks.HookController):
stoplight_helpers.pecan_getter)
)
def get(self):
services_controller = self._driver.manager.services_controller
ssl_certificate_controller = (
self._driver.manager.ssl_certificate_controller
)
call_args = getattr(pecan.request.context,
"call_args")
status = call_args.pop('status')
cert_domains = services_controller.get_certs_by_status(
cert_domains = ssl_certificate_controller.get_certs_by_status(
status)
return pecan.Response(json_body=cert_domains,
status=200)
return pecan.Response(json_body=cert_domains, status=200)
class AdminServiceController(base.Controller, hooks.HookController):

View File

@ -173,7 +173,7 @@ class ServicesController(base.Controller, hooks.HookController):
pecan.abort(400, detail="Marker must be a valid UUID")
services_controller = self._driver.manager.services_controller
service_resultset = services_controller.list(
service_resultset = services_controller.get_services(
self.project_id, marker, limit)
results = [
resp_service_model.Model(s, self)
@ -202,7 +202,7 @@ class ServicesController(base.Controller, hooks.HookController):
def get_one(self, service_id):
services_controller = self._driver.manager.services_controller
try:
service_obj = services_controller.get(
service_obj = services_controller.get_service(
self.project_id, service_id)
except ValueError:
pecan.abort(404, detail='service %s could not be found' %
@ -222,9 +222,11 @@ class ServicesController(base.Controller, hooks.HookController):
service_json_dict = json.loads(pecan.request.body.decode('utf-8'))
service_id = None
try:
service_obj = services_controller.create(self.project_id,
self.auth_token,
service_json_dict)
service_obj = services_controller.create_service(
self.project_id,
self.auth_token,
service_json_dict
)
service_id = service_obj.service_id
except errors.SharedShardsExhausted as e:
# domain - shared domains exhausted
@ -253,7 +255,7 @@ class ServicesController(base.Controller, hooks.HookController):
services_controller = self._driver.manager.services_controller
try:
services_controller.delete(self.project_id, service_id)
services_controller.delete_service(self.project_id, service_id)
except LookupError as e:
pecan.abort(404, detail=str(e))
except ValueError as e:
@ -277,7 +279,7 @@ class ServicesController(base.Controller, hooks.HookController):
services_controller = self._driver.manager.services_controller
try:
services_controller.update(
services_controller.update_service(
self.project_id, service_id, self.auth_token, service_updates)
except exceptions.ValidationFailed as e:
pecan.abort(400, detail=u'{0}'.format(e))

View File

@ -20,6 +20,7 @@ from oslo_config import cfg
import webtest
from poppy import bootstrap
from poppy.storage.mockdb import services
from tests.functional import base
@ -34,24 +35,33 @@ class BaseFunctionalTest(base.TestCase):
))))
conf_path = os.path.join(tests_path, 'etc', 'default_functional.conf')
cfg.CONF(args=[], default_config_files=[conf_path])
b_obj = bootstrap.Bootstrap(cfg.CONF)
self.b_obj = bootstrap.Bootstrap(cfg.CONF)
# mock the persistence part for taskflow distributed_task
mock_persistence = mock.Mock()
mock_persistence.__enter__ = mock.Mock()
mock_persistence.__exit__ = mock.Mock()
b_obj.distributed_task.persistence = mock.Mock()
b_obj.distributed_task.persistence.return_value = mock_persistence
b_obj.distributed_task.job_board = mock.Mock()
b_obj.distributed_task.job_board.return_value = (
self.b_obj.distributed_task.persistence = mock.Mock()
self.b_obj.distributed_task.persistence.return_value = mock_persistence
self.b_obj.distributed_task.job_board = mock.Mock()
self.b_obj.distributed_task.job_board.return_value = (
mock_persistence.copy())
b_obj.distributed_task.is_alive = mock.Mock(return_value=True)
self.b_obj.distributed_task.is_alive = mock.Mock(return_value=True)
# Note(tonytan4ever):Need this hack to preserve mockdb storage
# controller's service cache
b_obj.manager.ssl_certificate_controller.storage_controller = (
b_obj.manager.services_controller.storage_controller
)
poppy_wsgi = b_obj.transport.app
# b_obj.manager.ssl_certificate_controller.storage_controller = (
# b_obj.manager.services_controller.storage_controller
# )
poppy_wsgi = self.b_obj.transport.app
self.app = webtest.app.TestApp(poppy_wsgi)
def tearDown(self):
super(BaseFunctionalTest, self).tearDown()
services.created_services = {}
services.created_service_ids = []
services.claimed_domains = []
services.project_id_service_limit = {}
services.service_count_per_project_id = {}
FunctionalTest = BaseFunctionalTest

View File

@ -21,7 +21,8 @@ from hypothesis import strategies
import mock
import six
from poppy.manager.default.services import DefaultServicesController
from poppy.manager.default.ssl_certificate import \
DefaultSSLCertificateController
from tests.functional.transport.pecan import base
@ -56,7 +57,7 @@ class SSLCertificatebyStatusTest(base.FunctionalTest):
@ddt.data(u'create_in_progress', u'deployed', u'failed', u'cancelled')
def test_get_service_status_valid_queryparam(self, status):
# valid status
with mock.patch.object(DefaultServicesController,
with mock.patch.object(DefaultSSLCertificateController,
'get_certs_by_status'):
response = self.app.get('/v1.0/admin/certificates'
'?status={0}'.format(status),

View File

@ -20,7 +20,7 @@ import uuid
import ddt
import mock
from poppy.storage.mockdb import services
from poppy.storage.mockdb import certificates
from tests.functional.transport.pecan import base
@ -100,10 +100,10 @@ class TestRetryList(base.FunctionalTest):
def test_put_retry_list_negative_with_deployed_domain(self):
# A cert already in deployed status will cause 400.
with mock.patch('poppy.storage.mockdb.services.ServicesController.'
'get_certs_by_domain',
with mock.patch('poppy.storage.mockdb.certificates.'
'CertificatesController.get_certs_by_domain',
new=functools.
partial(services.ServicesController.
partial(certificates.CertificatesController.
get_certs_by_domain,
status='deployed')):
self.service_name = str(uuid.uuid1())
@ -228,7 +228,7 @@ class TestRetryList(base.FunctionalTest):
'X-Project-ID': self.project_id})
self.assertEqual(202, response.status_code)
# This time the service is present, so the request goes thru
# This time the service is present, so the request goes through
put_data = [
{
"domain_name": "test-san1.cnamecdn.com",
@ -249,7 +249,7 @@ class TestRetryList(base.FunctionalTest):
headers={
'Content-Type': 'application/json',
'X-Project-ID': self.project_id},
expect_errors=True)
)
self.assertEqual(200, response.status_code)
def test_post_retry_list(self):

View File

@ -72,7 +72,10 @@ class TestFlowRuns(base.TestCase):
memoized_controllers.task_controllers('poppy', 'storage')
service_controller, dns_controller = \
memoized_controllers.task_controllers('poppy', 'dns')
return service_controller, storage_controller, dns_controller
service_controller, ssl_cert_controller = \
memoized_controllers.task_controllers('poppy', 'ssl_certificate')
return service_controller, storage_controller, dns_controller, \
ssl_cert_controller
def dns_exceptions_and_succeed(self):
# NOTE(TheSriram): create a chain of mocked return values,
@ -193,12 +196,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_create_flow(service_controller,
@ -235,12 +243,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_update_flow(service_controller, storage_controller,
@ -270,12 +283,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_delete_flow(service_controller, storage_controller,
@ -306,12 +324,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_purge_flow(service_controller, storage_controller,
@ -343,12 +366,17 @@ class TestFlowRuns(base.TestCase):
disable_kwargs = enable_kwargs.copy()
disable_kwargs['state'] = 'disable'
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_service_state_flow(service_controller,
@ -374,12 +402,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_create_flow(service_controller, storage_controller,
@ -424,12 +457,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_update_flow(service_controller, storage_controller,
@ -469,12 +507,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_delete_flow(service_controller, storage_controller,
@ -513,12 +556,17 @@ class TestFlowRuns(base.TestCase):
disable_kwargs = enable_kwargs.copy()
disable_kwargs['state'] = 'disable'
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_service_state_flow(service_controller,
@ -574,12 +622,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_update_flow(service_controller, storage_controller,
@ -621,12 +674,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_update_flow(service_controller, storage_controller,
@ -654,12 +712,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_create_flow(service_controller, storage_controller,
@ -687,12 +750,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_create_flow(service_controller, storage_controller,
@ -730,12 +798,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_delete_flow(service_controller, storage_controller,
@ -770,12 +843,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_delete_flow(service_controller, storage_controller,
@ -812,12 +890,17 @@ class TestFlowRuns(base.TestCase):
disable_kwargs = enable_kwargs.copy()
disable_kwargs['state'] = 'disable'
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_service_state_flow(service_controller,
@ -860,12 +943,17 @@ class TestFlowRuns(base.TestCase):
disable_kwargs = enable_kwargs.copy()
disable_kwargs['state'] = 'disable'
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_service_state_flow(service_controller,
storage_controller,
@ -902,12 +990,17 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_create_ssl_certificate_flow(service_controller,
@ -934,12 +1027,17 @@ class TestFlowRuns(base.TestCase):
'cert_obj_json': json.dumps(cert_obj_json.to_dict()),
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_recreate_ssl_certificate_flow(service_controller,
@ -962,16 +1060,25 @@ class TestFlowRuns(base.TestCase):
'context_dict': context_utils.RequestContext().to_dict()
}
service_controller, storage_controller, dns_controller = \
self.all_controllers()
(
service_controller,
storage_controller,
dns_controller,
ssl_cert_controller
) = self.all_controllers()
with MonkeyPatchControllers(service_controller,
dns_controller,
storage_controller,
ssl_cert_controller,
memoized_controllers.task_controllers):
self.patch_create_ssl_certificate_flow(service_controller,
storage_controller,
dns_controller)
engines.run(delete_ssl_certificate.delete_ssl_certificate(),
store=kwargs)
self.patch_create_ssl_certificate_flow(
service_controller,
storage_controller,
dns_controller
)
engines.run(
delete_ssl_certificate.delete_ssl_certificate(),
store=kwargs
)

View File

@ -76,10 +76,11 @@ class MonkeyPatchControllers(object):
def __init__(self, service_controller,
dns_controller,
storage_controller, func):
storage_controller, ssl_cert_controller, func):
self.service_controller = service_controller
self.dns_controller = dns_controller
self.storage_controller = storage_controller
self.ssl_cert_controller = ssl_cert_controller
self.func = func
def __enter__(self):
@ -89,6 +90,8 @@ class MonkeyPatchControllers(object):
return self.service_controller, self.storage_controller
if controller == 'dns':
return self.service_controller, self.dns_controller
if controller == 'ssl_certificate':
return self.service_controller, self.ssl_cert_controller
else:
return self.service_controller
@ -437,14 +440,17 @@ class DefaultManagerServiceTests(base.TestCase):
self.sc.storage_controller.get_service_count = mock.Mock(
return_value=1)
service_obj = self.sc.create(self.project_id,
self.auth_token,
self.service_json)
service_obj = self.sc.create_service(
self.project_id,
self.auth_token,
self.service_json
)
# ensure the manager calls the storage driver with the appropriate data
self.sc.storage_controller.create.assert_called_once_with(
self.sc.storage_controller.create_service.assert_called_once_with(
self.project_id,
service_obj)
service_obj
)
@ddt.file_data('data_provider_details.json')
def test_create_service_worker(self, provider_details_json):
@ -518,6 +524,7 @@ class DefaultManagerServiceTests(base.TestCase):
with MonkeyPatchControllers(self.sc,
self.sc.dns_controller,
self.sc.storage_controller,
self.sc.ssl_certificate_storage,
memoized_controllers.task_controllers):
self.mock_create_service(provider_details_json)
@ -621,6 +628,7 @@ class DefaultManagerServiceTests(base.TestCase):
with MonkeyPatchControllers(self.sc,
self.sc.dns_controller,
self.sc.storage_controller,
self.sc.ssl_certificate_storage,
memoized_controllers.task_controllers):
# NOTE(TheSriram): Successful update
@ -675,7 +683,7 @@ class DefaultManagerServiceTests(base.TestCase):
service_obj = service.load_from_json(self.service_json)
service_obj.status = u'deployed'
self.sc.storage_controller.get.return_value = service_obj
self.sc.storage_controller.get_service.return_value = service_obj
service_updates = json.dumps([
{
"op": "replace",
@ -684,13 +692,15 @@ class DefaultManagerServiceTests(base.TestCase):
}
])
self.sc.update(self.project_id,
self.service_id,
self.auth_token,
service_updates)
self.sc.update_service(
self.project_id,
self.service_id,
self.auth_token,
service_updates
)
# ensure the manager calls the storage driver with the appropriate data
self.sc.storage_controller.update.assert_called_once()
self.sc.storage_controller.update_service.assert_called_once()
@ddt.file_data('data_provider_details.json')
def test_delete(self, provider_details_json):
@ -710,16 +720,21 @@ class DefaultManagerServiceTests(base.TestCase):
self.service_obj.provider_details = self.provider_details
sc = self.sc.storage_controller
sc.get.return_value = self.service_obj
sc.get_service.return_value = self.service_obj
self.sc.delete(self.project_id, self.service_id)
self.sc.delete_service(self.project_id, self.service_id)
# ensure the manager calls the storage driver with the appropriate data
sc.get.assert_called_once_with(self.project_id, self.service_id)
sc.update.assert_called_once_with(self.project_id,
self.service_id,
self.service_obj)
sc.get_service.assert_called_once_with(
self.project_id,
self.service_id
)
sc.update_service.assert_called_once_with(
self.project_id,
self.service_id,
self.service_obj
)
# break into 2 lines.
sc = self.sc.storage_controller
@ -791,6 +806,7 @@ class DefaultManagerServiceTests(base.TestCase):
with MonkeyPatchControllers(self.sc,
self.sc.dns_controller,
self.sc.storage_controller,
self.sc.ssl_certificate_storage,
memoized_controllers.task_controllers):
self.mock_delete_service()
@ -854,6 +870,7 @@ class DefaultManagerServiceTests(base.TestCase):
with MonkeyPatchControllers(self.sc,
self.sc.dns_controller,
self.sc.storage_controller,
self.sc.ssl_certificate_storage,
memoized_controllers.task_controllers):
self.mock_delete_service()
@ -878,7 +895,7 @@ class DefaultManagerServiceTests(base.TestCase):
)
self.service_obj.provider_details = self.provider_details
self.sc.storage_controller.get.return_value = (
self.sc.storage_controller.get_service.return_value = (
self.service_obj
)
@ -952,6 +969,7 @@ class DefaultManagerServiceTests(base.TestCase):
with MonkeyPatchControllers(self.sc,
self.sc.dns_controller,
self.sc.storage_controller,
self.sc.ssl_certificate_storage,
memoized_controllers.task_controllers):
self.mock_purge_service(hard=True)
self.mock_purge_service(hard=False)
@ -1005,6 +1023,7 @@ class DefaultManagerServiceTests(base.TestCase):
with MonkeyPatchControllers(self.sc,
self.sc.dns_controller,
self.sc.storage_controller,
self.sc.ssl_certificate_storage,
memoized_controllers.task_controllers):
self.mock_purge_service(hard=True)
self.mock_purge_service(hard=False)
@ -1051,15 +1070,19 @@ class DefaultManagerServiceTests(base.TestCase):
return_value=list()
)
self.mock_storage.services_controller.get.return_value = (
self.mock_storage.services_controller.get_service.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_storage.services_controller.get_service.called
)
self.assertTrue(
self.mock_storage.services_controller.update_service.called
)
self.assertTrue(
self.mock_distributed_task.services_controller.submit_task.called
)

View File

@ -87,6 +87,12 @@ class MockManager(mock.Mock):
def services_controller(self):
return self.get_services_controller()
@staticmethod
def get_ssl_certificate_controller():
sc = mock.Mock()
sc.ssl_certificate_controller = MockStorageController()
return sc
@staticmethod
def get_services_controller():
sc = mock.Mock()

View File

@ -43,12 +43,18 @@ class TestAkamaiBJFlowRuns(base.TestCase):
akamai_mocks.MockManager.get_services_controller().
storage_controller
)
if args[1] == 'ssl_certificate':
return (
akamai_mocks.MockManager.get_services_controller(),
akamai_mocks.MockManager.
get_ssl_certificate_controller().
ssl_certificate_controller
)
mock_task_controllers = mock.Mock()
mock_task_controllers.task_controllers.side_effect = (
task_controllers_side_effect
)
memo_controllers_patcher = mock.patch(
# 'poppy.distributed_task.utils.memoized_controllers',
'poppy.provider.akamai.background_jobs.'
'check_cert_status_and_update.'
'check_cert_status_and_update_tasks.memoized_controllers',

View File

@ -0,0 +1,106 @@
# 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.
import uuid
import cassandra
import ddt
import mock
from oslo_config import cfg
from poppy.model import ssl_certificate
from poppy.storage.cassandra import certificates
from poppy.storage.cassandra import driver
from tests.unit import base
@ddt.ddt
class CassandraStorageServiceTests(base.TestCase):
def setUp(self):
super(CassandraStorageServiceTests, self).setUp()
# mock arguments to use
self.project_id = '123456'
self.service_id = uuid.uuid4()
self.service_name = 'mocksite'
# create mocked config and driver
conf = cfg.ConfigOpts()
conf.register_opt(
cfg.StrOpt(
'datacenter',
default='',
help='datacenter where the C* cluster hosted'))
conf.register_opts(driver.CASSANDRA_OPTIONS,
group=driver.CASSANDRA_GROUP)
cassandra_driver = driver.CassandraStorageDriver(conf)
migrations_patcher = mock.patch(
'cdeploy.migrator.Migrator'
)
migrations_patcher.start()
self.addCleanup(migrations_patcher.stop)
# stubbed cassandra driver
self.cc = certificates.CertificatesController(cassandra_driver)
@ddt.file_data('data_get_certs_by_domain.json')
@mock.patch.object(certificates.CertificatesController, 'session')
@mock.patch.object(cassandra.cluster.Session, 'execute')
def test_get_certs_by_domain(self, cert_details_json,
mock_session, mock_execute):
# mock the response from cassandra
mock_execute.execute.return_value = cert_details_json[0]
actual_response = self.cc.get_certs_by_domain(
domain_name="www.mydomain.com"
)
self.assertEqual(len(actual_response), 2)
self.assertTrue(all([isinstance(ssl_cert,
ssl_certificate.SSLCertificate)
for ssl_cert in actual_response]))
mock_execute.execute.return_value = cert_details_json[1]
actual_response = self.cc.get_certs_by_domain(
domain_name="www.example.com",
flavor_id="flavor1")
self.assertEqual(len(actual_response), 2)
self.assertTrue(all([isinstance(ssl_cert,
ssl_certificate.SSLCertificate)
for ssl_cert in actual_response]))
mock_execute.execute.return_value = cert_details_json[2]
actual_response = self.cc.get_certs_by_domain(
domain_name="www.mydomain.com",
flavor_id="flavor1",
cert_type="san")
self.assertTrue(isinstance(actual_response,
ssl_certificate.SSLCertificate))
@mock.patch.object(certificates.CertificatesController, 'session')
@mock.patch.object(cassandra.cluster.Session, 'execute')
def test_get_certs_by_status(self, mock_session, mock_execute):
# mock the response from cassandra
mock_execute.execute.return_value = \
[{"domain_name": "www.example.com"}]
actual_response = self.cc.get_certs_by_status(
status="deployed")
self.assertEqual(actual_response,
[{"domain_name": "www.example.com"}])
mock_execute.execute.return_value = \
[{"domain_name": "www.example1.com"}]
actual_response = self.cc.get_certs_by_status(
status="failed")
self.assertEqual(actual_response,
[{"domain_name": "www.example1.com"}])

View File

@ -26,7 +26,6 @@ import mock
from oslo_config import cfg
from poppy.model.helpers import provider_details
from poppy.model import ssl_certificate
from poppy.storage.cassandra import driver
from poppy.storage.cassandra import services
from poppy.transport.pecan.models.request import service as req_service
@ -73,7 +72,7 @@ class CassandraStorageServiceTests(base.TestCase):
value[0]['service_id'] = self.service_id
mock_execute.execute.return_value = value
actual_response = self.sc.get(self.project_id, self.service_id)
actual_response = self.sc.get_service(self.project_id, self.service_id)
# TODO(amitgandhinz): assert the response
# matches the expectation (using jsonschema)
@ -86,8 +85,12 @@ class CassandraStorageServiceTests(base.TestCase):
# mock the response from cassandra
mock_execute.execute.return_value = []
self.assertRaises(ValueError, self.sc.get,
self.project_id, self.service_id)
self.assertRaises(
ValueError,
self.sc.get_service,
self.project_id,
self.service_id
)
@ddt.file_data('../data/data_create_service.json')
@mock.patch.object(services.ServicesController,
@ -98,7 +101,7 @@ class CassandraStorageServiceTests(base.TestCase):
def test_create_service(self, value,
mock_check, mock_session, mock_execute):
service_obj = req_service.load_from_json(value)
responses = self.sc.create(self.project_id, service_obj)
responses = self.sc.create_service(self.project_id, service_obj)
# Expect the response to be None as there are no providers passed
# into the driver to respond to this call
@ -117,9 +120,11 @@ class CassandraStorageServiceTests(base.TestCase):
service_obj = req_service.load_from_json(value)
self.sc.get = mock.Mock(return_value=service_obj)
self.assertRaises(ValueError,
self.sc.create,
self.project_id, service_obj)
self.assertRaises(
ValueError,
self.sc.create_service,
self.project_id, service_obj
)
@ddt.file_data('data_list_services.json')
@mock.patch.object(services.ServicesController, 'session')
@ -130,7 +135,7 @@ class CassandraStorageServiceTests(base.TestCase):
mock_execute.prepare.return_value = mock.Mock()
mock_execute.execute.return_value = value
actual_response = self.sc.list(self.project_id, None, None)
actual_response = self.sc.get_services(self.project_id, None, None)
# TODO(amitgandhinz): assert the response
# matches the expectation (using jsonschema)
@ -142,7 +147,10 @@ class CassandraStorageServiceTests(base.TestCase):
def test_delete_service(self, mock_session, mock_execute):
# mock the response from cassandra
mock_execute.execute.return_value = iter([{}])
actual_response = self.sc.delete(self.project_id, self.service_id)
actual_response = self.sc.delete_service(
self.project_id,
self.service_id
)
# Expect the response to be None as there are no providers passed
# into the driver to respond to this call
@ -173,9 +181,11 @@ class CassandraStorageServiceTests(base.TestCase):
}
mock_session.execute.return_value = iter([{}])
service_obj = req_service.load_from_json(service_json)
actual_response = self.sc.update(self.project_id,
self.service_id,
service_obj)
actual_response = self.sc.update_service(
self.project_id,
self.service_id,
service_obj
)
# Expect the response to be None as there are no
# providers passed into the driver to respond to this call
@ -196,53 +206,6 @@ class CassandraStorageServiceTests(base.TestCase):
self.assertTrue("CloudFront" in actual_response)
self.assertTrue("Fastly" in actual_response)
@ddt.file_data('data_get_certs_by_domain.json')
@mock.patch.object(services.ServicesController, 'session')
@mock.patch.object(cassandra.cluster.Session, 'execute')
def test_get_certs_by_domain(self, cert_details_json,
mock_session, mock_execute):
# mock the response from cassandra
mock_execute.execute.return_value = cert_details_json[0]
actual_response = self.sc.get_certs_by_domain(
domain_name="www.mydomain.com")
self.assertEqual(len(actual_response), 2)
self.assertTrue(all([isinstance(ssl_cert,
ssl_certificate.SSLCertificate)
for ssl_cert in actual_response]))
mock_execute.execute.return_value = cert_details_json[1]
actual_response = self.sc.get_certs_by_domain(
domain_name="www.example.com",
flavor_id="flavor1")
self.assertEqual(len(actual_response), 2)
self.assertTrue(all([isinstance(ssl_cert,
ssl_certificate.SSLCertificate)
for ssl_cert in actual_response]))
mock_execute.execute.return_value = cert_details_json[2]
actual_response = self.sc.get_certs_by_domain(
domain_name="www.mydomain.com",
flavor_id="flavor1",
cert_type="san")
self.assertTrue(isinstance(actual_response,
ssl_certificate.SSLCertificate))
@mock.patch.object(services.ServicesController, 'session')
@mock.patch.object(cassandra.cluster.Session, 'execute')
def test_get_certs_by_status(self, mock_session, mock_execute):
# mock the response from cassandra
mock_execute.execute.return_value = \
[{"domain_name": "www.example.com"}]
actual_response = self.sc.get_certs_by_status(
status="deployed")
self.assertEqual(actual_response,
[{"domain_name": "www.example.com"}])
mock_execute.execute.return_value = \
[{"domain_name": "www.example1.com"}]
actual_response = self.sc.get_certs_by_status(
status="failed")
self.assertEqual(actual_response,
[{"domain_name": "www.example1.com"}])
@ddt.file_data('data_provider_details.json')
@mock.patch.object(services.ServicesController, 'session')
@mock.patch.object(cassandra.cluster.Session, 'execute')