diff --git a/poppy/provider/akamai/domain_san_mapping_queue/zk_san_mapping_queue.py b/poppy/provider/akamai/domain_san_mapping_queue/zk_san_mapping_queue.py index 03db4a87..4f65b2c0 100644 --- a/poppy/provider/akamai/domain_san_mapping_queue/zk_san_mapping_queue.py +++ b/poppy/provider/akamai/domain_san_mapping_queue/zk_san_mapping_queue.py @@ -47,8 +47,28 @@ class ZookeeperSanMappingQueue(base.SanMappingQueue): + """Store ``domain to san cert`` mappings. + + Once a domain name is added to san cert, the mapping + of domain to san cert will be stored in this queue. + + A background job that runs at pre-defined intervals + will process this queue and will trigger task that + uses these mappings to update the Akamai configuration. + + The queue is implemented using ``zookeeper`` and + is a ``locking queue``. + + The path for the queue is read from the section + ``drivers:provider:akamai:queue]`` in ``poppy.conf`` + """ def __init__(self, conf): + """Initialize Zookeeper locking queue. + + :param conf: Poppy configuration + :type conf: oslo_config.ConfigOpts + """ super(ZookeeperSanMappingQueue, self).__init__(conf) self._conf.register_opts(AKAMAI_OPTIONS, @@ -57,18 +77,63 @@ def __init__(self, conf): @decorators.lazy_property(write=False) def san_mapping_queue_backend(self): + """Return Zookeeper locking queue. + + :return: Locking queue object + :rtype: kazoo.recipe.queue.LockingQueue + """ return queue.LockingQueue( self.zk_client, self.akamai_conf.san_mapping_queue_path) @decorators.lazy_property(write=False) def zk_client(self): + """Create and Return zookeeper client. + + :return: Zookeeper client + :rtype: kazoo.client.KazooClient + """ return utils.connect_to_zookeeper_queue_backend(self.akamai_conf) def enqueue_san_mapping(self, san_domain_map): + """Put mapping details into queue. + + Example input ``san_domain_map``. (Serialize + the dict and use it as an input to store the + mapping details into the queue.) + + .. code-block:: python + + '{ + "domain_name": "test-san1.cnamecdn.com", + "flavor_id": "premium", + "project_id": "003", + "cert_type": "san", + "cert_details": { + "Akamai": { + "extra_info": { + "san cert": "san1.example.com", + "akamai_spsId": 1 + } + } + } + }' + + :param str san_domain_map: Serialized dictionary + with mapping details + """ self.san_mapping_queue_backend.put(san_domain_map) def traverse_queue(self, consume=False): + """Get list of all items in the queue. + + :param bool consume: (Default False) If set to + ``True``, the queue will be emptied. Otherwise, + queue will be intact. + + :return: List of mapping in the queue + :rtype: list[str] + """ res = [] while len(self.san_mapping_queue_backend) > 0: item = self.san_mapping_queue_backend.get() @@ -79,9 +144,18 @@ def traverse_queue(self, consume=False): 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 + """Replace the Queue with new incoming data. + + All the existing data in the queue will be + deleted and replaced with the supplied + ``queue_data``. + + :param list queue_data: The new data to replace + the queue with. + + :return: New items present in the queue. + :rtype: list + """ while len(self.san_mapping_queue_backend) > 0: self.san_mapping_queue_backend.get() self.san_mapping_queue_backend.consume() @@ -90,6 +164,35 @@ def put_queue_data(self, queue_data): return queue_data def dequeue_san_mapping(self, consume=True): + """Returns entry from the queue. + + Example return. + + .. code-block:: python + + '{ + "domain_name": "test-san1.cnamecdn.com", + "flavor_id": "premium", + "project_id": "003", + "cert_type": "san", + "cert_details": { + "Akamai": { + "extra_info": { + "san cert": "san1.example.com", + "akamai_spsId": 1 + } + } + } + }' + + :param bool consume: (Default True) If set to + ``True``, the entry from the queue will be + deleted. Else, only entry will be returned. + + :return: Serialized dictionary + with mapping details + :rtype: str + """ res = self.san_mapping_queue_backend.get() if consume: self.san_mapping_queue_backend.consume() diff --git a/poppy/provider/akamai/http_policy_queue/http_policy_queue.py b/poppy/provider/akamai/http_policy_queue/http_policy_queue.py index b2d32f8e..7db551ef 100644 --- a/poppy/provider/akamai/http_policy_queue/http_policy_queue.py +++ b/poppy/provider/akamai/http_policy_queue/http_policy_queue.py @@ -47,8 +47,27 @@ class ZookeeperHttpPolicyQueue(base.HttpPolicyQueue): + """Queue to store old HTTP policies. + + Store the obsolete HTTP policies to mark them + for deletion; below are the scenarios in which + we mark the policies for the deletion: + - Whenever a domain is migrated from http to + https + - Updating services + + The queue is implemented using ``zookeeper`` and + is a ``locking queue``. + + The path for the queue is read from ``poppy.conf`` + """ def __init__(self, conf): + """Initialize Zookeeper locking queue. + + :param conf: Poppy configuration + :type conf: oslo_config.ConfigOpts + """ super(ZookeeperHttpPolicyQueue, self).__init__(conf) self._conf.register_opts(AKAMAI_OPTIONS, @@ -57,18 +76,55 @@ def __init__(self, conf): @decorators.lazy_property(write=False) def http_policy_queue_backend(self): + """Return Zookeeper locking queue. + + :return: Locking queue object + :rtype: kazoo.recipe.queue.LockingQueue + """ + return queue.LockingQueue( self.zk_client, self.akamai_conf.http_policy_queue_path) @decorators.lazy_property(write=False) def zk_client(self): + """Create and Return zookeeper client. + + :return: Zookeeper client + :rtype: kazoo.client.KazooClient + """ return utils.connect_to_zookeeper_queue_backend(self.akamai_conf) def enqueue_http_policy(self, http_policy): + """Put http policy details into queue. + + Example input ``http_policy``. (Serialize + the dict and use it as parameter to store + the policy into queue.) + + .. code-block:: python + + '{ + "configuration_number": 1, + "policy_name": "www.abc.com", + "project_id": "12345" + }' + + :param str http_policy: Serialized dictionary + with policy details + """ self.http_policy_queue_backend.put(http_policy) def traverse_queue(self, consume=False): + """Get list of all items in the queue. + + :param bool consume: (Default False) If set to + ``True``, the queue will be emptied. Otherwise, + queue will be intact. + + :return: List of policies in the queue + :rtype: list[str] + """ res = [] while len(self.http_policy_queue_backend) > 0: item = self.http_policy_queue_backend.get() @@ -79,9 +135,18 @@ def traverse_queue(self, consume=False): 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 + """Replace the Queue with new incoming data. + + All the existing data in the queue will be + deleted and replaced with the supplied + ``queue_data``. + + :param list queue_data: The new data to replace + the queue with. + + :return: New items present in the queue. + :rtype: list + """ while len(self.http_policy_queue_backend) > 0: self.http_policy_queue_backend.get() self.http_policy_queue_backend.consume() @@ -90,6 +155,27 @@ def put_queue_data(self, queue_data): return queue_data def dequeue_http_policy(self, consume=True): + """Returns entry from the queue. + + Example return: + + .. code-block:: python + + '{ + "configuration_number": 1, + "policy_name": "www.abc.com", + "project_id": "12345" + }' + + :param bool consume: (Default True) If set to + ``True``, the entry from the queue will be + deleted. Else, entry will be returned only. + + :return: Serialized dictionary + with policy details + :rtype: str + """ + res = self.http_policy_queue_backend.get() if consume: self.http_policy_queue_backend.consume() diff --git a/poppy/provider/akamai/mod_san_queue/zookeeper_queue.py b/poppy/provider/akamai/mod_san_queue/zookeeper_queue.py index 2790f890..6ea8302f 100644 --- a/poppy/provider/akamai/mod_san_queue/zookeeper_queue.py +++ b/poppy/provider/akamai/mod_san_queue/zookeeper_queue.py @@ -39,8 +39,31 @@ class ZookeeperModSanQueue(base.ModSanQueue): + """Buffer Mod San requests. + + We have configured list of SAN certificate names + in ``poppy.conf``. Whenever a request to add a + domain comes, One of SAN certificate will be choosen + from the list to add the domain; making that SAN + cert status ``pending`` for some time. In such + scenario where there is no ``Available`` certificate + present from the list and if a new request comes to add + another domain, then that request will be stored in + this ``mod san queue`` for future processing. + + The queue is implemented using ``zookeeper`` and + is a ``locking queue``. + + The path for the queue is read from the section + ``drivers:provider:akamai:queue]`` in ``poppy.conf`` + """ def __init__(self, conf): + """Initialize Zookeeper locking queue. + + :param conf: Poppy configuration + :type conf: oslo_config.ConfigOpts + """ super(ZookeeperModSanQueue, self).__init__(conf) self._conf.register_opts(AKAMAI_OPTIONS, @@ -49,18 +72,54 @@ def __init__(self, conf): @decorators.lazy_property(write=False) def mod_san_queue_backend(self): + """Return Zookeeper locking queue. + + :return: Locking queue object + :rtype: kazoo.recipe.queue.LockingQueue + """ return queue.LockingQueue( self.zk_client, self.akamai_conf.mod_san_queue_path) @decorators.lazy_property(write=False) def zk_client(self): + """Create and Return zookeeper client. + + :return: Zookeeper client + :rtype: kazoo.client.KazooClient + """ return utils.connect_to_zookeeper_queue_backend(self.akamai_conf) def enqueue_mod_san_request(self, cert_obj_json): + """Put certificate details into queue. + + Example input ``cert_obj_json``. (Serialize + the dict and use it as an input to store the + certificate details into the queue.) + + .. code-block:: python + + '{ + "cert_type": "san", + "domain_name": "www.abc.com", + "flavor_id": "premium" + }' + + :param str cert_obj_json: Serialized dictionary + with certificate details + """ self.mod_san_queue_backend.put(cert_obj_json) def traverse_queue(self): + """Get list of all items in the queue. + + Even though the queue is emptied while traversing, + all the items will be put back into queue. So, the + queue will be intact after the traversal. + + :return: List of certificates in the queue + :rtype: list[str] + """ res = [] while len(self.mod_san_queue_backend) > 0: item = self.mod_san_queue_backend.get() @@ -70,9 +129,18 @@ def traverse_queue(self): 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 + """Replace the Queue with new incoming data. + + All the existing data in the queue will be + deleted and replaced with the supplied + ``queue_data``. + + :param list queue_data: The new data to replace + the queue with. + + :return: New items present in the queue. + :rtype: list + """ while len(self.mod_san_queue_backend) > 0: self.mod_san_queue_backend.get() self.mod_san_queue_backend.consume() @@ -81,6 +149,26 @@ def put_queue_data(self, queue_data): return queue_data def dequeue_mod_san_request(self, consume=True): + """Returns entry from the queue. + + Example return. + + .. code-block:: python + + '{ + "cert_type": "san", + "domain_name": "www.abc.com", + "flavor_id": "premium" + }' + + :param bool consume: (Default True) If set to + ``True``, the entry from the queue will be + deleted. Else, entry will be returned only. + + :return: Serialized dictionary + with certificate details + :rtype: str + """ res = self.mod_san_queue_backend.get() if consume: self.mod_san_queue_backend.consume()