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

Commit

Permalink
Merge "Verify domain before requesting property updates"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Aug 29, 2016
2 parents 15f2093 + 8c94600 commit 8c75380
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 4 deletions.
71 changes: 68 additions & 3 deletions poppy/manager/default/background_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from oslo_log import log

from poppy.manager import base
from poppy.model import ssl_certificate
from poppy.notification.mailgun import driver as n_driver
from poppy.provider.akamai.background_jobs.check_cert_status_and_update \
import check_cert_status_and_update_flow
Expand All @@ -40,6 +41,8 @@ def __init__(self, manager):
a_driver.AKAMAI_GROUP].san_cert_cnames
self.notify_email_list = self.driver.conf[
n_driver.MAIL_NOTIFICATION_GROUP].recipients
self.cert_storage = self._driver.storage.certificates_controller
self.service_storage = self._driver.storage.services_controller

def post_job(self, job_type, kwargs):
queue_data = []
Expand Down Expand Up @@ -121,7 +124,58 @@ def post_job(self, job_type, kwargs):
cert_dict = dict()
try:
cert_dict = json.loads(cert)
# add validation that the domain still exists on a
# service and that it has a type of SAN
cert_obj = ssl_certificate.SSLCertificate(
cert_dict['flavor_id'],
cert_dict['domain_name'],
'san',
project_id=cert_dict['project_id']
)

cert_for_domain = self.cert_storage.get_certs_by_domain(
cert_obj.domain_name,
project_id=cert_obj.project_id,
flavor_id=cert_obj.flavor_id,
cert_type=cert_obj.cert_type
)
if cert_for_domain == []:
ignore_list.append(cert_dict)
LOG.info(
"Ignored property update because "
"certificate for {0} does not exist.".format(
cert_obj.domain_name
)
)
continue

service_obj = self.service_storage.\
get_service_details_by_domain_name(
cert_obj.domain_name,
cert_obj.project_id
)
found = False
for domain in service_obj.domains:
if (
domain.domain == cert_obj.domain_name and
domain.protocol == 'https' and
domain.certificate == 'san'
):
found = True
if found is False:
# skip the task for current cert obj is the
# domain doesn't exist on a service with the
# same protocol and certificate.
ignore_list.append(cert_dict)
LOG.info(
"Ignored update property for a "
"domain '{0}' that no longer exists on a service "
"with the same protocol 'https' and certificate "
"type 'san'".format(
cert_obj.domain_name,
)
)
continue
domain_name = cert_dict["domain_name"]
san_cert = (
cert_dict["cert_details"]
Expand Down Expand Up @@ -182,9 +236,20 @@ def post_job(self, job_type, kwargs):
"notify_email_list": self.notify_email_list
}

self.distributed_task_controller.submit_task(
update_property_flow.update_property_flow,
**t_kwargs)
# check to see if there are changes to be made before submitting
# the task, avoids creating a new property version when there are
# no changes to be made.
if len(cname_host_info_list) > 0:
self.distributed_task_controller.submit_task(
update_property_flow.update_property_flow,
**t_kwargs)
else:
LOG.info(
"No tasks submitted to update_property_flow"
"update_info_list was empty: {0}".format(
update_info_list
)
)

return run_list, ignore_list
else:
Expand Down
138 changes: 137 additions & 1 deletion tests/unit/manager/default/test_background_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

from poppy.manager.default import background_job
from poppy.manager.default import driver
from poppy.model.helpers import domain
from poppy.model import service
from poppy.notification.mailgun import driver as n_driver
from poppy.provider.akamai import driver as aka_driver
from tests.unit import base
Expand Down Expand Up @@ -89,6 +91,7 @@ def get_provider_by_name(name):
def provider_membership(key):
return True if key in self.provider_mocks else False

self.mock_storage = mock_storage
self.mock_providers = mock.MagicMock()
self.mock_providers.__getitem__.side_effect = get_provider_by_name
self.mock_providers.__contains__.side_effect = provider_membership
Expand Down Expand Up @@ -220,6 +223,29 @@ def test_post_job_no_akamai_driver(self, job_type):
"akamai_update_papi_property_for_mod_san"
)
def test_post_job_positive(self, job_type):
# mock ssl storage returning a cert
self.mock_storage.certificates_controller.\
get_certs_by_domain.return_value = [
mock.Mock()
]
# mock service storage returning a service with domain with
# correct protocol + cert
self.mock_storage.services_controller. \
get_service_details_by_domain_name.return_value = service.Service(
'service_id',
'name',
[
domain.Domain(
"www.example.com",
protocol='https',
certificate='san'
)
],
[],
'flavor_id',
project_id='project_id'
)

san_mapping_queue = self.manager_driver.providers[
'akamai'].obj.san_mapping_queue
san_mapping_queue.traverse_queue.return_value = [
Expand Down Expand Up @@ -252,8 +278,118 @@ def test_post_job_positive(self, job_type):
self.bgc.distributed_task_controller.submit_task.called
)

def test_post_job_ignored_cert_no_longer_exists(self):
self.mock_storage.certificates_controller.\
get_certs_by_domain.return_value = []

san_mapping_queue = self.manager_driver.providers[
'akamai'].obj.san_mapping_queue
san_mapping_queue.traverse_queue.return_value = [
json.dumps({
"domain_name": "www.example.com",
"flavor_id": "flavor_id",
"project_id": "project_id",
"cert_type": "san",
"cert_details": {
"Akamai": {
"extra_info": {
"san cert": "san.example.com",
"akamai_spsId": 1
}
}
},
'property_activated': True
})
]

run_list, ignore_list = self.bgc.post_job(
"akamai_update_papi_property_for_mod_san",
{'project_id': 'project_id'}
)
self.assertEqual(0, len(run_list))
self.assertEqual(1, len(ignore_list))

self.assertEqual(
False,
self.bgc.distributed_task_controller.submit_task.called
)

def test_post_job_domain_type_modified_on_service(self):
self.mock_storage.certificates_controller.\
get_certs_by_domain.return_value = [
mock.Mock()
]
# simulate domain being changed from https+san to http
self.mock_storage.services_controller. \
get_service_details_by_domain_name.return_value = service.Service(
'service_id',
'name',
[
domain.Domain(
"www.example.com",
protocol='http',
)
],
[],
'flavor_id',
project_id='project_id'
)
san_mapping_queue = self.manager_driver.providers[
'akamai'].obj.san_mapping_queue
san_mapping_queue.traverse_queue.return_value = [
json.dumps({
"domain_name": "www.example.com",
"flavor_id": "flavor_id",
"project_id": "project_id",
"cert_type": "san",
"cert_details": {
"Akamai": {
"extra_info": {
"san cert": "san.example.com",
"akamai_spsId": 1
}
}
},
'property_activated': True
})
]

run_list, ignore_list = self.bgc.post_job(
"akamai_update_papi_property_for_mod_san",
{'project_id': 'project_id'}
)
self.assertEqual(0, len(run_list))
self.assertEqual(1, len(ignore_list))

self.assertEqual(
False,
self.bgc.distributed_task_controller.submit_task.called
)

@ddt.data("akamai_update_papi_property_for_mod_san")
def test_post_job_invalid_san_cert_cname(self, job_type):
# mock ssl storage returning a cert
self.mock_storage.certificates_controller.\
get_certs_by_domain.return_value = [
mock.Mock()
]
# mock service storage returning a service with domain with
# correct protocol + cert
self.mock_storage.services_controller. \
get_service_details_by_domain_name.return_value = service.Service(
'service_id',
'name',
[
domain.Domain(
"www.example.com",
protocol='https',
certificate='san'
)
],
[],
'flavor_id',
project_id='project_id'
)
san_mapping_queue = self.manager_driver.providers[
'akamai'].obj.san_mapping_queue
san_mapping_queue.traverse_queue.return_value = [
Expand Down Expand Up @@ -281,7 +417,7 @@ def test_post_job_invalid_san_cert_cname(self, job_type):
self.assertEqual(1, len(ignore_list))

self.assertEqual(
True,
False,
self.bgc.distributed_task_controller.submit_task.called
)

Expand Down

0 comments on commit 8c75380

Please sign in to comment.