Merge "Allows admin to patch the certificate status."

This commit is contained in:
Jenkins
2016-06-21 21:08:04 +00:00
committed by Gerrit Code Review
5 changed files with 133 additions and 0 deletions

View File

@@ -77,3 +77,8 @@ class SharedShardsExhausted(Exception):
class ServiceProviderDetailsNotFound(Exception):
"""Raised when provider details for a service is None."""
class CertificateStatusUpdateError(Exception):
"""Raised when errors encountered updating a certificate."""

View File

@@ -19,6 +19,7 @@ import json
from oslo_context import context as context_utils
from oslo_log import log
from poppy.common import errors
from poppy.distributed_task.taskflow.flow import create_ssl_certificate
from poppy.distributed_task.taskflow.flow import delete_ssl_certificate
from poppy.distributed_task.taskflow.flow import recreate_ssl_certificate
@@ -332,3 +333,52 @@ class DefaultSSLCertificateController(base.SSLCertificateController):
certs_by_status = self.storage.get_certs_by_status(status)
return certs_by_status
def update_certificate_status(self, domain_name, certificate_updates):
certificate_old = self.storage.get_certs_by_domain(domain_name)
if not certificate_old:
raise ValueError(
"certificate information not found for {0} ".format(
domain_name
)
)
try:
if (
certificate_updates.get("op") == "replace" and
certificate_updates.get("path") == "status" and
certificate_updates.get("value") is not None
):
if (
certificate_old.get_cert_status() !=
certificate_updates.get("value")
):
new_cert_details = certificate_old.cert_details
# update the certificate for the first provider akamai
# this logic changes when multiple certificate providers
# are supported
first_provider = list(new_cert_details.keys())[0]
first_provider_cert_details = (
list(new_cert_details.values())[0]
)
first_provider_cert_details["extra_info"][
"status"] = certificate_updates.get("value")
new_cert_details[first_provider] = json.dumps(
first_provider_cert_details
)
self.storage.update_certificate(
certificate_old.domain_name,
certificate_old.cert_type,
certificate_old.flavor_id,
new_cert_details
)
except Exception as e:
LOG.error(
"Something went wrong during certificate update: {0}".format(
e
)
)
raise errors.CertificateStatusUpdateError(e)

View File

@@ -18,6 +18,7 @@ import pecan
from pecan import hooks
from poppy.common import errors
from poppy.common import util
from poppy.transport.pecan.controllers import base
from poppy.transport.pecan import hooks as poppy_hooks
from poppy.transport.pecan.models.response import service as resp_service_model
@@ -448,6 +449,45 @@ class AdminCertController(base.Controller, hooks.HookController):
return pecan.Response(json_body=cert_domains, status=200)
@pecan.expose('json')
@decorators.validate(
domain_name=rule.Rule(
helpers.is_valid_domain_by_name(),
helpers.abort_with_message
),
request=rule.Rule(
helpers.json_matches_service_schema(
ssl_certificate.SSLCertificateSchema.get_schema(
"admin_cert_status",
"PATCH"
)
),
helpers.abort_with_message,
stoplight_helpers.pecan_getter)
)
def patch_one(self, domain_name):
ssl_certificate_controller = (
self._driver.manager.ssl_certificate_controller
)
certificate_updates = json.loads(pecan.request.body.decode('utf-8'))[0]
try:
ssl_certificate_controller.update_certificate_status(
domain_name,
certificate_updates
)
except ValueError:
pecan.abort(
status_code=404,
detail='Certificate could not be found for domain: {0}'.format(
domain_name
)
)
except Exception as e:
pecan.abort(status_code=400, detail=util.help_escape(str(e)))
return pecan.Response(body=None, status=204)
class AdminServiceController(base.Controller, hooks.HookController):

View File

@@ -221,6 +221,7 @@ def is_root_domain(domain):
def is_valid_service_configuration(service, schema):
errors_list = list()
if schema is not None:
errors_list = list(
jsonschema.Draft3Validator(schema).iter_errors(service))

View File

@@ -168,4 +168,41 @@ class SSLCertificateSchema(schema_base.SchemaBase):
}
}
},
'admin_cert_status': {
'PATCH': {
'type': 'array',
'minItems': 1,
'maxItems': 1,
'additionalItems': False,
'items': {
'type': 'object',
'additionalProperties': False,
'properties': {
'op': {
'type': 'string',
'enum': [
'replace',
],
'required': True,
},
'path': {
'type': 'string',
'enum': ['status'],
'required': True,
},
'value': {
'type': 'string',
'enum': [
'cancelled',
'create_in_progress',
'deployed',
'failed'
],
'required': True,
}
}
}
}
}
}