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

Commit

Permalink
Merge "DNS updates for http to https+san upgrade"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Aug 22, 2016
2 parents 6fa8a59 + 23fcb0d commit 9e5b400
Show file tree
Hide file tree
Showing 16 changed files with 668 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
class CreateProviderSSLCertificateTask(task.Task):
default_provides = "responders"

def execute(self, providers_list_json, cert_obj_json, enqueue=True):
def execute(self, providers_list_json, cert_obj_json, enqueue=True,
https_upgrade=False):
service_controller = memoized_controllers.task_controllers('poppy')

# call provider create_ssl_certificate function
Expand All @@ -46,7 +47,8 @@ def execute(self, providers_list_json, cert_obj_json, enqueue=True):
responder = service_controller.provider_wrapper.create_certificate(
service_controller._driver.providers[provider],
cert_obj,
enqueue
enqueue,
https_upgrade
)
responders.append(responder)

Expand All @@ -55,7 +57,7 @@ def execute(self, providers_list_json, cert_obj_json, enqueue=True):

class SendNotificationTask(task.Task):

def execute(self, project_id, responders):
def execute(self, project_id, responders, upgrade=False):
service_controller = memoized_controllers.task_controllers('poppy')

notification_content = ""
Expand All @@ -65,6 +67,13 @@ def execute(self, project_id, responders):
"Project ID: %s, Provider: %s, Detail: %s" %
(project_id, provider, str(responder[provider])))

if upgrade is True:
notification_content += (
" The domain was upgraded from HTTP to HTTPS SAN. "
"If applicable, take note of the domain name and "
"delete the old HTTP policy in the provider."
)

for n_driver in service_controller._driver.notification:
service_controller.notification_wrapper.send(
n_driver,
Expand Down
156 changes: 136 additions & 20 deletions poppy/dns/rackspace/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# limitations under the License.

import random
import re
try:
set
except NameError: # noqa pragma: no cover
Expand Down Expand Up @@ -64,6 +65,7 @@ def _create_cname_records(self, links):

# randomly select a shard
shard_id = random.randint(1, num_shards)
# ex. cdnXXX.altcdn.com
subdomain_name = '{0}{1}.{2}'.format(shard_prefix, shard_id,
cdn_domain_name)
subdomain = self._get_subdomain(subdomain_name)
Expand All @@ -75,14 +77,51 @@ def _create_cname_records(self, links):
shared_ssl_subdomain_name = None
for link in links:
# pick out shared ssl domains here
domain_name, certificate = link
domain_name, certificate, old_operator_url = link
if certificate == "shared":
shared_ssl_subdomain_name = (
'.'.join(domain_name.split('.')[1:]))
# perform shared ssl cert logic
name = domain_name
else:
name = '{0}.{1}'.format(domain_name, subdomain_name)
if old_operator_url is not None:
# verify sub-domain exists
regex_match = re.match(
r'^.*(' + shard_prefix + '[0-9]+\.' +
re.escape(cdn_domain_name) + ')$',
old_operator_url
)
my_sub_domain_name = regex_match.groups(-1)[0]
if my_sub_domain_name is None:
raise ValueError('Unable to parse old provider url')

# add to cname record
my_sub_domain = self._get_subdomain(my_sub_domain_name)
LOG.info(
"Updating DNS Record for HTTPS upgrade "
"domain {0}. CNAME update from {1} to {2}".format(
my_sub_domain_name,
old_operator_url,
links[link]
)
)

old_dns_record = my_sub_domain.find_record(
'CNAME',
old_operator_url
)
my_sub_domain.update_record(
old_dns_record,
data=links[link]
)

dns_links[link] = {
'provider_url': links[link],
'operator_url': old_operator_url
}
continue
else:
name = '{0}.{1}'.format(domain_name, subdomain_name)

cname_record = {'type': 'CNAME',
'name': name,
Expand Down Expand Up @@ -245,8 +284,11 @@ def create(self, responders):
# We need to distinguish shared ssl domains in
# which case the we will use different shard prefix and
# and shard number
links[(link['domain'], link.get('certificate',
None))] = link['href']
links[(
link['domain'],
link.get('certificate', None),
None # new link no pref operator url
)] = link['href']

# create CNAME records
try:
Expand All @@ -269,14 +311,16 @@ def create(self, responders):
if link['rel'] == 'access_url':
access_url = {
'domain': link['domain'],
'provider_url':
dns_links[(link['domain'],
link.get('certificate', None)
)]['provider_url'],
'operator_url':
dns_links[(link['domain'],
link.get('certificate', None)
)]['operator_url']}
'provider_url': dns_links[(
link['domain'],
link.get('certificate', None),
None
)]['provider_url'],
'operator_url': dns_links[(
link['domain'],
link.get('certificate', None),
None
)]['operator_url']}
# Need to indicate if this access_url is a shared ssl
# access url, since its has different shard_prefix and
# num_shard
Expand Down Expand Up @@ -310,7 +354,7 @@ def delete(self, provider_details):
access_url['operator_url'],
access_url.get('shared_ssl_flag', False))
if msg:
error_msg = error_msg + msg
error_msg += msg
except exc.NotFound as e:
LOG.error('Can not access the subdomain. Please make '
'sure it exists and you have permissions '
Expand All @@ -320,8 +364,8 @@ def delete(self, provider_details):
error_class = e.__class__
except Exception as e:
LOG.error('Rackspace DNS Exception: {0}'.format(e))
error_msg = error_msg + 'Rackspace DNS ' \
'Exception: {0}'.format(e)
error_msg += 'Rackspace DNS ' \
'Exception: {0}'.format(e)
error_class = e.__class__
# format the error message for this provider
if not error_msg:
Expand Down Expand Up @@ -361,8 +405,11 @@ def _update_added_domains(self, responders, added_domains):
domain_added = (link['rel'] == 'access_url' and
link['domain'] in added_domains)
if domain_added:
links[(link['domain'], link.get('certificate',
None))] = link['href']
links[(
link['domain'],
link.get('certificate', None),
link.get('old_operator_url', None)
)] = link['href']

# create CNAME records for added domains
try:
Expand All @@ -387,11 +434,13 @@ def _update_added_domains(self, responders, added_domains):
'domain': link['domain'],
'provider_url':
dns_links[(link['domain'],
link.get('certificate', None)
link.get('certificate', None),
link.get('old_operator_url', None)
)]['provider_url'],
'operator_url':
dns_links[(link['domain'],
link.get('certificate', None)
link.get('certificate', None),
link.get('old_operator_url', None)
)]['operator_url']}
# Need to indicate if this access_url is a shared ssl
# access url, since its has different shard_prefix and
Expand Down Expand Up @@ -497,11 +546,43 @@ def update(self, service_old, service_updates, responders):
for link in links:
new_domains.add(link['domain'])

# find http -> https+san upgrade domains
upgraded_domains = set()
for domain in service_updates.domains:
for old_domain in service_old.domains:
if old_domain.domain == domain.domain:
if (
old_domain.protocol == 'http' and
domain.protocol == 'https' and
domain.certificate == 'san'
):
upgraded_domains.add(domain.domain)
break

# if domains have not been updated, return
if not service_updates.domains:
return old_access_urls_map

# if the old set of domains is the same as new set of domains, return
# force dns update when we encounter an upgraded domain
common_domains = new_domains.intersection(old_domains)
for domain_name in common_domains:
upgrade = False
for responder in responders:
for provider_name in responder:
links = responder[provider_name]['links']
for link in links:
if (
link['domain'] == domain_name and
link.get('certificate', None) == 'san' and
link['href'] is not None and
link['old_operator_url'] is not None
):
upgrade = True

if upgrade is True:
old_domains.remove(domain_name)

# if the old set of domains is the same as new set of domains return
if old_domains == new_domains:
return old_access_urls_map

Expand All @@ -510,6 +591,10 @@ def update(self, service_old, service_updates, responders):
removed_domains = old_domains.difference(new_domains)
common_domains = new_domains.intersection(old_domains)

# prevent dns records for upgrade domains from being deleted
retain_domains = removed_domains.intersection(upgraded_domains)
removed_domains = removed_domains.difference(retain_domains)

LOG.info("Added Domains : {0} on service_id : {1} "
"for project_id: {2}".format(added_domains,
service_id,
Expand Down Expand Up @@ -589,6 +674,37 @@ def update(self, service_old, service_updates, responders):
if old_access_url.get('shared_ssl_flag', False):
access_url['shared_ssl_flag'] = True
access_urls.append(access_url)

# find upgraded domains and create placeholders for them
for domain in service_updates.domains:
is_upgrade = False
for old_domain in service_old.domains:
if old_domain.domain == domain.domain:
if (
old_domain.protocol == 'http' and
domain.protocol == 'https' and
domain.certificate == 'san'
):
is_upgrade = True
break
if is_upgrade is True:
old_access_url_for_domain = (
service_old.provider_details.values()[0].
get_domain_access_url(domain.domain))

# add placeholder access url for upgraded domain
# the access_url dict here should be missing an entry
# for http san domain since provider url is
# determined only after an ssl cert is provisioned
access_urls.append({
'domain': domain.domain,
'provider_url': None,
'operator_url': None,
'old_operator_url': old_access_url_for_domain[
'operator_url'
]
})

dns_details[provider_name] = {'access_urls': access_urls}

return self.responder.updated(dns_details)
Expand Down
5 changes: 3 additions & 2 deletions poppy/manager/base/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def purge(self, ext, service_obj, provider_details,
hard,
purge_url)

def create_certificate(self, ext, cert_obj, enqueue):
def create_certificate(self, ext, cert_obj, enqueue, https_upgrade):
"""Create a certificate
:param ext
Expand All @@ -84,5 +84,6 @@ def create_certificate(self, ext, cert_obj, enqueue):

return ext.obj.certificate_controller.create_certificate(
cert_obj,
enqueue
enqueue,
https_upgrade
)

0 comments on commit 9e5b400

Please sign in to comment.