Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

Commit

Permalink
Merge "feat: add endpoints to put/get san_mapping_list"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Mar 23, 2016
2 parents 0922c7b + 5f9ba21 commit 603859f
Show file tree
Hide file tree
Showing 13 changed files with 436 additions and 8 deletions.
1 change: 1 addition & 0 deletions etc/poppy.conf
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ queue_backend_type = zookeeper
queue_backend_host = <your_transport_server(s)>
queue_backend_port = <your_transport_port>
mod_san_queue_path = '/mod_san_queue'
san_mapping_queue_path = '/san_mapping_queue'

[drivers:notification:mailgun]
mailgun_api_key = "<operator_api_key>"
Expand Down
28 changes: 28 additions & 0 deletions poppy/manager/default/background_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,31 @@ def post_job(self, job_type, kwargs):
**t_kwargs)
else:
raise NotImplementedError('job type: %s has not been implemented')

def get_san_mapping_list(self):
res = []
if 'akamai' in self._driver.providers:
akamai_driver = self._driver.providers['akamai'].obj
res = akamai_driver.san_mapping_queue.traverse_queue()
# other provider's san_mapping_list implementation goes here

res = [json.loads(r) for r in res]
return res

def put_san_mapping_list(self, san_mapping_list):
new_queue_data = [json.dumps(r) for r in san_mapping_list]
res, deleted = [], []
if 'akamai' in self._driver.providers:
akamai_driver = self._driver.providers['akamai'].obj
orig = [
json.loads(r) for r in
akamai_driver.san_mapping_queue.traverse_queue()
]
res = [
json.loads(r) for r in
akamai_driver.san_mapping_queue.put_queue_data(new_queue_data)
]

deleted = tuple(x for x in orig if x not in res)
# other provider's san_mapping_list implementation goes here
return res, deleted
2 changes: 1 addition & 1 deletion poppy/manager/default/ssl_certificate.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def get_san_retry_list(self):
if 'akamai' in self._driver.providers:
akamai_driver = self._driver.providers['akamai'].obj
res = akamai_driver.mod_san_queue.traverse_queue()
# For other providers san_retry_list implementaion goes here
# For other providers san_retry_list implementation goes here
else:
# if not using akamai driver just return an empty list
return []
Expand Down
Empty file.
59 changes: 59 additions & 0 deletions poppy/provider/akamai/domain_san_mapping_queue/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# 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 abc

import six


@six.add_metaclass(abc.ABCMeta)
class SanMappingQueue(object):
"""Interface definition for Akamai Domain san cert mapping.
The purpose of this queue is to buffer the client's
domain to san certificate mapping. The mapping is used to kick
off a task that updates akamai configuration at pre-defined intervals.
"""

def __init__(self, conf):
self._conf = conf

def enqueue_san_mapping(self, san_domain_map):
"""Add new SAN mapping element to the queue.
:param san_domain_map: a new element to add to the queue
:type san_domain_map: dict
"""
raise NotImplementedError

def dequeue_san_mapping(self, consume=True):
"""Remove and return an item from the queue.
:param consume: if true the mapping is removed from the list and
returned otherwise the mapping is retrieved queue
"""
raise NotImplementedError

def traverse_queue(self):
"""Traverse queue and return all items on the queue in a list"""
raise NotImplementedError

def put_queue_data(self, queue_data_list):
"""Clear the queue and put new queue data list in the queue.
:param queue_data_list: new queue data to replace current queue data
:type queue_data_list: [dict()] -- list of dictionaries
"""
raise NotImplementedError
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Copyright (c) 2014 Rackspace, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from kazoo.recipe import queue
from oslo_config import cfg

from poppy.common import decorators
from poppy.provider.akamai.domain_san_mapping_queue import base
from poppy.provider.akamai import utils


AKAMAI_OPTIONS = [
# queue backend configs
cfg.StrOpt(
'queue_backend_type',
help='SAN Cert Queueing backend'),
cfg.ListOpt(
'queue_backend_host',
default=['localhost'],
help='default queue backend server hosts'),
cfg.IntOpt(
'queue_backend_port',
default=2181,
help='default'
' default queue backend server port (e.g: 2181)'),
cfg.StrOpt(
'san_mapping_queue_path',
default='/san_mapping_queue',
help='Zookeeper path '
'for san_mapping_queue'
),
]

AKAMAI_GROUP = 'drivers:provider:akamai:queue'


class ZookeeperSanMappingQueue(base.SanMappingQueue):

def __init__(self, conf):
super(ZookeeperSanMappingQueue, self).__init__(conf)

self._conf.register_opts(AKAMAI_OPTIONS,
group=AKAMAI_GROUP)
self.akamai_conf = self._conf[AKAMAI_GROUP]

@decorators.lazy_property(write=False)
def san_mapping_queue_backend(self):
return queue.LockingQueue(
self.zk_client,
self.akamai_conf.san_mapping_queue_path)

@decorators.lazy_property(write=False)
def zk_client(self):
return utils.connect_to_zookeeper_queue_backend(self.akamai_conf)

def enqueue_san_mapping(self, san_domain_map):
self.san_mapping_queue_backend.put(san_domain_map)

def traverse_queue(self):
res = []
while len(self.san_mapping_queue_backend) > 0:
item = self.san_mapping_queue_backend.get()
self.san_mapping_queue_backend.consume()
res.append(item)
self.san_mapping_queue_backend.put_all(res)
return res

def put_queue_data(self, queue_data):
# put queue data will replace all existing
# queue data with the incoming new queue_data
# dequeue all the existing data
while len(self.san_mapping_queue_backend) > 0:
self.san_mapping_queue_backend.get()
self.san_mapping_queue_backend.consume()
# put in all the new data
self.san_mapping_queue_backend.put_all(queue_data)
return queue_data

def dequeue_san_mapping(self, consume=True):
res = self.san_mapping_queue_backend.get()
if consume:
self.san_mapping_queue_backend.consume()
return res
4 changes: 4 additions & 0 deletions poppy/provider/akamai/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

from poppy.common import decorators
from poppy.provider.akamai import controllers
from poppy.provider.akamai.domain_san_mapping_queue import zk_san_mapping_queue
from poppy.provider.akamai import geo_zone_code_mapping
from poppy.provider.akamai.mod_san_queue import zookeeper_queue
from poppy.provider import base
Expand Down Expand Up @@ -196,6 +197,9 @@ def __init__(self, conf):
self.akamai_sub_customer_api_client = self.akamai_policy_api_client
self.mod_san_queue = (
zookeeper_queue.ZookeeperModSanQueue(self._conf))
self.san_mapping_queue = zk_san_mapping_queue.ZookeeperSanMappingQueue(
self._conf
)

self.metrics_resolution = self.akamai_conf.metrics_resolution

Expand Down
20 changes: 15 additions & 5 deletions poppy/provider/akamai/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ def san_info_storage(self):
def mod_san_queue(self):
return self.driver.mod_san_queue

@property
def san_mapping_queue(self):
return self.driver.san_mapping_queue

@property
def san_cert_cnames(self):
return self.driver.san_cert_cnames
Expand Down Expand Up @@ -92,7 +96,7 @@ def create(self, service_obj):
# we do not have to use copy here, since caching is only used once
# caching_rules = copy.deepcopy(service_obj.caching)

# Traverse existing rules list to add caching rules necessarys
# Traverse existing rules list to add caching rules as necessary
self._process_caching_rules(
service_obj.caching, post_data['rules'])
self._process_restriction_rules(
Expand Down Expand Up @@ -261,9 +265,9 @@ def _policy(self, provider_service_id, service_obj,

# implementing caching-rules for akamai
# we need deep copy since caching rules will be used in late
# upadate objects
# update objects
# caching_rules = copy.deepcopy(service_obj.caching)
# Traverse existing rules list to add caching rules necessarys
# Traverse existing rules list to add caching rules as necessary
self._process_caching_rules(
service_obj.caching, policy_content['rules'])
self._process_restriction_rules(
Expand Down Expand Up @@ -502,7 +506,7 @@ def delete(self, project_id, provider_service_id):
format(provider_service_id))
return self.responder.failed(str(e))
else:
LOG.info("Sucessfully Deleted Service - {0}".
LOG.info("Successfully Deleted Service - {0}".
format(provider_service_id))
return self.responder.deleted(provider_service_id)

Expand Down Expand Up @@ -649,6 +653,12 @@ def create_certificate(self, cert_obj, enqueue=True):
self.san_info_storage.save_cert_last_spsid(
san_cert_name,
this_sps_id)
self.san_mapping_queue.enqueue_san_mapping(
{
'san_cert_domain': san_cert_name,
'domain_name': cert_obj.domain_name,
}
)
return self.responder.ssl_certificate_provisioned(
san_cert_name, {
'status': 'create_in_progress',
Expand All @@ -670,7 +680,7 @@ def create_certificate(self, cert_obj, enqueue=True):
'action': 'No available san cert for %s right now,'
' or no san cert info available. Support:'
'Please write down the domain and keep an'
' eye on next availabe freed-up SAN certs.'
' eye on next available freed-up SAN certs.'
' More provisioning might be needed' %
(cert_obj.domain_name)
})
Expand Down
46 changes: 46 additions & 0 deletions poppy/transport/pecan/controllers/v1/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class BackgroundJobController(base.Controller, hooks.HookController):

def __init__(self, driver):
super(BackgroundJobController, self).__init__(driver)
self.__class__.san_mapping = AkamaiSanMappingListController(driver)

@pecan.expose('json')
@decorators.validate(
Expand All @@ -107,6 +108,51 @@ def post(self):
return pecan.Response(None, 202)


class AkamaiSanMappingListController(base.Controller, hooks.HookController):
__hooks__ = [poppy_hooks.Context(), poppy_hooks.Error()]

def __init__(self, driver):
super(AkamaiSanMappingListController, self).__init__(driver)

self.manager = self._driver.manager

@pecan.expose('json')
def get_all(self):
try:
return (
self.manager.background_job_controller.get_san_mapping_list())
except Exception as e:
pecan.abort(404, str(e))

@pecan.expose('json')
@decorators.validate(
request=rule.Rule(
helpers.json_matches_service_schema(
ssl_certificate.SSLCertificateSchema.get_schema(
"san_mapping_list", "PUT")),
helpers.abort_with_message,
stoplight_helpers.pecan_getter))
def put(self):
"""The input of the queue data must be a list of dictionaries:
(after json loaded)
[
{ "domain_name": <domain_name>,
"san_cert_name": <san_cert_name>
}
]
"""
try:
san_mapping_list = json.loads(pecan.request.body.decode('utf-8'))
res, deleted = (
self.manager.background_job_controller.
put_san_mapping_list(san_mapping_list))
# queue is the new queue, and deleted is deleted items
return {"queue": res, "deleted": deleted}
except Exception as e:
pecan.abort(400, str(e))


class AkamaiRetryListController(base.Controller, hooks.HookController):
__hooks__ = [poppy_hooks.Context(), poppy_hooks.Error()]

Expand Down
29 changes: 27 additions & 2 deletions poppy/transport/validators/schemas/ssl_certificate.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

class SSLCertificateSchema(schema_base.SchemaBase):

'''JSON Schmema validation for /ssl_certificate.'''
'''JSON Schema validation for /ssl_certificate.'''

schema = {
'ssl_certificate': {
Expand Down Expand Up @@ -103,5 +103,30 @@ class SSLCertificateSchema(schema_base.SchemaBase):
}
}
}
}
},

'san_mapping_list': {
'PUT': {
'type': 'array',
"uniqueItems": True,
'items': {
'type': 'object',
'additionalProperties': False,
'properties': {
'domain_name': {
'type': 'string',
'required': True,
'minLength': 3,
'maxLength': 253
},
'san_cert_name': {
'type': 'string',
'required': True,
'minLength': 3,
'maxLength': 253
}
}
}
}
},
}

0 comments on commit 603859f

Please sign in to comment.