Add admin endpoint to patch access urls
Change-Id: I30da22d2a229b346212e53abd7bff50884929ab6
This commit is contained in:
parent
0458de585d
commit
18f6f0ec86
@ -68,10 +68,8 @@ class ServicesController(base.ServicesBase):
|
|||||||
# ex. cdnXXX.altcdn.com
|
# ex. cdnXXX.altcdn.com
|
||||||
subdomain_name = '{0}{1}.{2}'.format(shard_prefix, shard_id,
|
subdomain_name = '{0}{1}.{2}'.format(shard_prefix, shard_id,
|
||||||
cdn_domain_name)
|
cdn_domain_name)
|
||||||
subdomain = self._get_subdomain(subdomain_name)
|
|
||||||
# create CNAME record for adding
|
# create CNAME record for adding
|
||||||
cname_records = []
|
cname_records = []
|
||||||
|
|
||||||
dns_links = {}
|
dns_links = {}
|
||||||
|
|
||||||
shared_ssl_subdomain_name = None
|
shared_ssl_subdomain_name = None
|
||||||
@ -85,40 +83,13 @@ class ServicesController(base.ServicesBase):
|
|||||||
name = domain_name
|
name = domain_name
|
||||||
else:
|
else:
|
||||||
if old_operator_url is not None:
|
if old_operator_url is not None:
|
||||||
# verify sub-domain exists
|
created_dns_links = self._create_preferred_cname_record(
|
||||||
regex_match = re.match(
|
domain_name,
|
||||||
r'^.*(' + shard_prefix + '[0-9]+\.' +
|
certificate,
|
||||||
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,
|
old_operator_url,
|
||||||
links[link]
|
links[link]
|
||||||
)
|
)
|
||||||
)
|
dns_links.update(created_dns_links)
|
||||||
|
|
||||||
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
|
continue
|
||||||
else:
|
else:
|
||||||
name = '{0}.{1}'.format(domain_name, subdomain_name)
|
name = '{0}.{1}'.format(domain_name, subdomain_name)
|
||||||
@ -140,11 +111,71 @@ class ServicesController(base.ServicesBase):
|
|||||||
else:
|
else:
|
||||||
cname_records.append(cname_record)
|
cname_records.append(cname_record)
|
||||||
# add the cname records
|
# add the cname records
|
||||||
if cname_records != []:
|
if len(cname_records) > 0:
|
||||||
|
subdomain = self._get_subdomain(subdomain_name)
|
||||||
LOG.info("Creating DNS Record - {0}".format(cname_records))
|
LOG.info("Creating DNS Record - {0}".format(cname_records))
|
||||||
subdomain.add_records(cname_records)
|
subdomain.add_records(cname_records)
|
||||||
return dns_links
|
return dns_links
|
||||||
|
|
||||||
|
def _create_preferred_cname_record(
|
||||||
|
self, domain_name, certificate, operator_url, provider_url):
|
||||||
|
"""Creates a CNAME chain with designated operator_url
|
||||||
|
|
||||||
|
:param domain_name: domain name that CNAME chain is created for
|
||||||
|
:param certificate: certificate type
|
||||||
|
:operator_url: The preferred operator url
|
||||||
|
:provider_url: provider url
|
||||||
|
:return dns_links: Map from provider access URL to DNS access URL
|
||||||
|
"""
|
||||||
|
|
||||||
|
shard_prefix = self._driver.rackdns_conf.shard_prefix
|
||||||
|
cdn_domain_name = self._driver.rackdns_conf.url
|
||||||
|
|
||||||
|
dns_links = {}
|
||||||
|
|
||||||
|
# verify sub-domain exists
|
||||||
|
regex_match = re.match(
|
||||||
|
r'^.*(' + shard_prefix + '[0-9]+\.' +
|
||||||
|
re.escape(cdn_domain_name) + ')$',
|
||||||
|
operator_url
|
||||||
|
)
|
||||||
|
my_sub_domain_name = regex_match.groups(-1)[0]
|
||||||
|
|
||||||
|
if my_sub_domain_name is None:
|
||||||
|
raise ValueError('Unable to parse old operator url')
|
||||||
|
|
||||||
|
# add to cname record
|
||||||
|
my_sub_domain = self._get_subdomain(my_sub_domain_name)
|
||||||
|
LOG.info(
|
||||||
|
"Updating dns record {0}. "
|
||||||
|
"CNAME create/update from {1} to {2}".format(
|
||||||
|
my_sub_domain_name,
|
||||||
|
operator_url,
|
||||||
|
provider_url
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
old_dns_record = my_sub_domain.find_record('CNAME', operator_url)
|
||||||
|
except exc.DomainRecordNotFound:
|
||||||
|
my_sub_domain.add_records(
|
||||||
|
[{
|
||||||
|
'type': 'CNAME',
|
||||||
|
'name': operator_url,
|
||||||
|
'data': provider_url,
|
||||||
|
'ttl': 300
|
||||||
|
}]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
my_sub_domain.update_record(old_dns_record, data=provider_url)
|
||||||
|
|
||||||
|
dns_links[(domain_name, certificate, operator_url)] = {
|
||||||
|
'provider_url': provider_url,
|
||||||
|
'operator_url': operator_url
|
||||||
|
}
|
||||||
|
|
||||||
|
return dns_links
|
||||||
|
|
||||||
def _search_cname_record(self, access_url, shared_ssl_flag):
|
def _search_cname_record(self, access_url, shared_ssl_flag):
|
||||||
"""Search a CNAME record
|
"""Search a CNAME record
|
||||||
|
|
||||||
@ -158,7 +189,7 @@ class ServicesController(base.ServicesBase):
|
|||||||
suffix = self._driver.rackdns_conf.shared_ssl_domain_suffix
|
suffix = self._driver.rackdns_conf.shared_ssl_domain_suffix
|
||||||
else:
|
else:
|
||||||
suffix = self._driver.rackdns_conf.url
|
suffix = self._driver.rackdns_conf.url
|
||||||
# Note: use rindex to find last occurence of the suffix
|
# Note: use rindex to find last occurrence of the suffix
|
||||||
shard_name = access_url[:access_url.rindex(suffix)-1].split('.')[-1]
|
shard_name = access_url[:access_url.rindex(suffix)-1].split('.')[-1]
|
||||||
subdomain_name = '.'.join([shard_name, suffix])
|
subdomain_name = '.'.join([shard_name, suffix])
|
||||||
|
|
||||||
@ -184,6 +215,8 @@ class ServicesController(base.ServicesBase):
|
|||||||
:param shared_ssl_flag: flag indicating if this is a shared ssl domain
|
:param shared_ssl_flag: flag indicating if this is a shared ssl domain
|
||||||
:return error_msg: returns error message, if any
|
:return error_msg: returns error message, if any
|
||||||
"""
|
"""
|
||||||
|
LOG.info('Attempting to delete DNS records for : {0}'.format(
|
||||||
|
access_url))
|
||||||
|
|
||||||
records = self._search_cname_record(access_url, shared_ssl_flag)
|
records = self._search_cname_record(access_url, shared_ssl_flag)
|
||||||
# delete the record
|
# delete the record
|
||||||
|
@ -812,3 +812,81 @@ class DefaultServicesController(base.ServicesController):
|
|||||||
is_upgrade = True
|
is_upgrade = True
|
||||||
break
|
break
|
||||||
return is_upgrade
|
return is_upgrade
|
||||||
|
|
||||||
|
def update_access_url_service(
|
||||||
|
self, project_id, service_id, access_url_changes):
|
||||||
|
try:
|
||||||
|
service_old = self.storage_controller.get_service(
|
||||||
|
project_id,
|
||||||
|
service_id
|
||||||
|
)
|
||||||
|
except ValueError as e:
|
||||||
|
# If service is not found
|
||||||
|
LOG.warning('Get service {0} failed. '
|
||||||
|
'Error message: {1}'.format(service_id, e))
|
||||||
|
raise errors.ServiceNotFound(e)
|
||||||
|
|
||||||
|
updated_details = False
|
||||||
|
provider_details = service_old.provider_details
|
||||||
|
domain_name = access_url_changes.get('domain_name')
|
||||||
|
for provider in provider_details:
|
||||||
|
for access_url in provider_details[provider].access_urls:
|
||||||
|
if access_url.get('domain') == domain_name:
|
||||||
|
if (
|
||||||
|
'operator_url' in access_url and
|
||||||
|
'provider_url' in access_url
|
||||||
|
):
|
||||||
|
new_access_url = access_url_changes['operator_url']
|
||||||
|
new_provider_url = access_url_changes['provider_url']
|
||||||
|
if access_url.get('shared_ssl_flag', False) is True:
|
||||||
|
raise errors.InvalidOperation(
|
||||||
|
'Changing access urls for shared ssl domains '
|
||||||
|
'is not supported.')
|
||||||
|
if not new_access_url.startswith(domain_name):
|
||||||
|
LOG.info('Invalid access_url/domain_name.')
|
||||||
|
raise errors.InvalidResourceName(
|
||||||
|
'Invalid access_url/domain_name.')
|
||||||
|
if new_access_url == access_url['operator_url']:
|
||||||
|
LOG.info(
|
||||||
|
"No changes made, both old and new access "
|
||||||
|
"urls are the same. "
|
||||||
|
"Domain '{0}'.".format(domain_name))
|
||||||
|
return False
|
||||||
|
if new_provider_url != access_url['provider_url']:
|
||||||
|
raise errors.InvalidOperation(
|
||||||
|
'Please use the migrate domain functionality '
|
||||||
|
'to migrate the domain to a new cert.'
|
||||||
|
)
|
||||||
|
certificate = (
|
||||||
|
"shared"
|
||||||
|
if access_url.get('shared_ssl_flag', False) is True
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
self.dns_controller._create_preferred_cname_record(
|
||||||
|
domain_name,
|
||||||
|
certificate,
|
||||||
|
new_access_url,
|
||||||
|
new_provider_url
|
||||||
|
)
|
||||||
|
self.dns_controller._delete_cname_record(
|
||||||
|
access_url['operator_url'],
|
||||||
|
access_url.get('shared_ssl_flag', False)
|
||||||
|
)
|
||||||
|
access_url['provider_url'] = new_provider_url
|
||||||
|
access_url['operator_url'] = new_access_url
|
||||||
|
updated_details = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if updated_details is True:
|
||||||
|
self.storage_controller.update_provider_details(
|
||||||
|
project_id,
|
||||||
|
service_id,
|
||||||
|
provider_details
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
err_msg = 'Domain {0} could not be found on service {1}.'.format(
|
||||||
|
domain_name, service_id)
|
||||||
|
LOG.error(err_msg)
|
||||||
|
raise ValueError(err_msg)
|
||||||
|
|
||||||
|
return updated_details
|
||||||
|
@ -21,7 +21,9 @@ CERTIFICATE_OPTIONS = [
|
|||||||
None,
|
None,
|
||||||
u'shared',
|
u'shared',
|
||||||
u'san',
|
u'san',
|
||||||
u'custom']
|
u'sni',
|
||||||
|
u'custom'
|
||||||
|
]
|
||||||
|
|
||||||
from poppy.model import common
|
from poppy.model import common
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ class ProviderDetail(common.DictSerializableModel):
|
|||||||
"""Return an access url object for a domain.
|
"""Return an access url object for a domain.
|
||||||
|
|
||||||
:param domain: domain to use as search key
|
:param domain: domain to use as search key
|
||||||
:type domain: poppy.model.helpers.domain.Domain
|
:type domain: str
|
||||||
|
|
||||||
:returns: access_url -- dict containing matching domain
|
:returns: access_url -- dict containing matching domain
|
||||||
"""
|
"""
|
||||||
|
@ -25,6 +25,7 @@ from poppy.transport.pecan.models.response import service as resp_service_model
|
|||||||
from poppy.transport.validators import helpers
|
from poppy.transport.validators import helpers
|
||||||
from poppy.transport.validators.schemas import background_jobs
|
from poppy.transport.validators.schemas import background_jobs
|
||||||
from poppy.transport.validators.schemas import domain_migration
|
from poppy.transport.validators.schemas import domain_migration
|
||||||
|
from poppy.transport.validators.schemas import provider_details_update
|
||||||
from poppy.transport.validators.schemas import service_action
|
from poppy.transport.validators.schemas import service_action
|
||||||
from poppy.transport.validators.schemas import service_limit
|
from poppy.transport.validators.schemas import service_limit
|
||||||
from poppy.transport.validators.schemas import service_status
|
from poppy.transport.validators.schemas import service_status
|
||||||
@ -77,6 +78,60 @@ class DomainMigrationController(base.Controller, hooks.HookController):
|
|||||||
return pecan.Response(None, 202)
|
return pecan.Response(None, 202)
|
||||||
|
|
||||||
|
|
||||||
|
class AdminProviderDetailsController(base.Controller, hooks.HookController):
|
||||||
|
__hooks__ = [poppy_hooks.Context(), poppy_hooks.Error()]
|
||||||
|
|
||||||
|
def __init__(self, driver):
|
||||||
|
super(AdminProviderDetailsController, self).__init__(driver)
|
||||||
|
|
||||||
|
@pecan.expose('json')
|
||||||
|
@decorators.validate(
|
||||||
|
service_id=rule.Rule(
|
||||||
|
helpers.is_valid_service_id(),
|
||||||
|
helpers.abort_with_message),
|
||||||
|
request=rule.Rule(
|
||||||
|
helpers.json_matches_service_schema(
|
||||||
|
provider_details_update.ProviderDetailsUpdateSchema.get_schema(
|
||||||
|
"update_provider_access_url", "PATCH")
|
||||||
|
),
|
||||||
|
helpers.abort_with_message,
|
||||||
|
stoplight_helpers.pecan_getter))
|
||||||
|
def patch_one(self, service_id):
|
||||||
|
request_json = json.loads(pecan.request.body.decode('utf-8'))
|
||||||
|
project_id = request_json.get('project_id', None)
|
||||||
|
domain_name = request_json.get('domain_name', None)
|
||||||
|
operator_url = request_json.get('operator_url', None)
|
||||||
|
provider_url = request_json.get('provider_url', None)
|
||||||
|
|
||||||
|
if not helpers.is_valid_domain_name(domain_name):
|
||||||
|
pecan.abort(400, detail='Domain {0} is not valid'.format(
|
||||||
|
domain_name))
|
||||||
|
|
||||||
|
changes_made = False
|
||||||
|
try:
|
||||||
|
changes_made = self._driver.manager.services_controller.\
|
||||||
|
update_access_url_service(
|
||||||
|
project_id,
|
||||||
|
service_id,
|
||||||
|
access_url_changes={
|
||||||
|
'domain_name': domain_name,
|
||||||
|
'operator_url': operator_url,
|
||||||
|
'provider_url': provider_url
|
||||||
|
}
|
||||||
|
)
|
||||||
|
except errors.ServiceNotFound:
|
||||||
|
pecan.abort(404, detail='Service {0} could not be found'.format(
|
||||||
|
service_id))
|
||||||
|
except (errors.InvalidOperation, errors.InvalidResourceName) as e:
|
||||||
|
pecan.abort(400, detail='{0}'.format(e))
|
||||||
|
except (LookupError, ValueError):
|
||||||
|
pecan.abort(404, detail='Domain {0} could not be found'.format(
|
||||||
|
domain_name))
|
||||||
|
|
||||||
|
status_code = 201 if changes_made is True else 202
|
||||||
|
return pecan.Response(None, status=status_code)
|
||||||
|
|
||||||
|
|
||||||
class BackgroundJobController(base.Controller, hooks.HookController):
|
class BackgroundJobController(base.Controller, hooks.HookController):
|
||||||
__hooks__ = [poppy_hooks.Context(), poppy_hooks.Error()]
|
__hooks__ = [poppy_hooks.Context(), poppy_hooks.Error()]
|
||||||
|
|
||||||
@ -552,6 +607,9 @@ class AdminServiceController(base.Controller, hooks.HookController):
|
|||||||
super(AdminServiceController, self).__init__(driver)
|
super(AdminServiceController, self).__init__(driver)
|
||||||
self.__class__.action = OperatorServiceActionController(driver)
|
self.__class__.action = OperatorServiceActionController(driver)
|
||||||
self.__class__.status = ServiceStatusController(driver)
|
self.__class__.status = ServiceStatusController(driver)
|
||||||
|
self.__class__.provider_details = AdminProviderDetailsController(
|
||||||
|
driver
|
||||||
|
)
|
||||||
|
|
||||||
@pecan.expose('json')
|
@pecan.expose('json')
|
||||||
@decorators.validate(
|
@decorators.validate(
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
# Copyright (c) 2015 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 poppy.transport.validators import schema_base
|
||||||
|
|
||||||
|
|
||||||
|
class ProviderDetailsUpdateSchema(schema_base.SchemaBase):
|
||||||
|
|
||||||
|
"""JSON Schema validation for /admin/services/provider_details."""
|
||||||
|
|
||||||
|
schema = {
|
||||||
|
'update_provider_access_url': {
|
||||||
|
'PATCH': {
|
||||||
|
'type': 'object',
|
||||||
|
'additionalProperties': False,
|
||||||
|
'properties': {
|
||||||
|
'project_id': {
|
||||||
|
'type': 'string',
|
||||||
|
'required': True
|
||||||
|
},
|
||||||
|
'domain_name': {
|
||||||
|
'type': 'string',
|
||||||
|
'required': True,
|
||||||
|
'minLength': 3,
|
||||||
|
'maxLength': 253
|
||||||
|
},
|
||||||
|
'operator_url': {
|
||||||
|
'type': 'string',
|
||||||
|
'required': True,
|
||||||
|
'minLength': 3,
|
||||||
|
'maxLength': 253
|
||||||
|
},
|
||||||
|
'provider_url': {
|
||||||
|
'type': 'string',
|
||||||
|
'required': True,
|
||||||
|
'minLength': 3,
|
||||||
|
'maxLength': 253
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -973,6 +973,115 @@ class TestServicesUpdate(base.TestCase):
|
|||||||
self.assertIsNotNone(
|
self.assertIsNotNone(
|
||||||
access_urls_map[provider_name][domain_new.domain])
|
access_urls_map[provider_name][domain_new.domain])
|
||||||
|
|
||||||
|
@mock.patch('re.match')
|
||||||
|
def test_update_add_domains_https_upgrade_regex_exception(self, re_mock):
|
||||||
|
re_mock.return_value.groups.return_value = (None,)
|
||||||
|
subdomain = mock.Mock()
|
||||||
|
subdomain.add_records = mock.Mock()
|
||||||
|
self.client.find = mock.Mock(return_value=subdomain)
|
||||||
|
|
||||||
|
domains_new = [
|
||||||
|
domain.Domain('test.domain.com'),
|
||||||
|
domain.Domain('blog.domain.com')
|
||||||
|
]
|
||||||
|
|
||||||
|
self.service_old.domains = domains_new
|
||||||
|
service_new = service.Service(
|
||||||
|
service_id=self.service_old.service_id,
|
||||||
|
name='myservice',
|
||||||
|
domains=domains_new,
|
||||||
|
origins=[],
|
||||||
|
flavor_id='standard')
|
||||||
|
|
||||||
|
responders = [{
|
||||||
|
'Fastly': {
|
||||||
|
'id': str(uuid.uuid4()),
|
||||||
|
'links': [
|
||||||
|
{
|
||||||
|
'domain': u'test.domain.com',
|
||||||
|
'href': u'test.domain.com.global.prod.fastly.net',
|
||||||
|
'rel': 'access_url'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'domain': u'blog.domain.com',
|
||||||
|
'href': u'blog.domain.com.global.prod.fastly.net',
|
||||||
|
'rel': 'access_url',
|
||||||
|
'certificate': 'san',
|
||||||
|
'old_operator_url': 'old.operator.url.cdn99.mycdn.com'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
}]
|
||||||
|
|
||||||
|
dns_details = self.controller.update(
|
||||||
|
self.service_old,
|
||||||
|
service_new,
|
||||||
|
responders
|
||||||
|
)
|
||||||
|
self.assertTrue('error' in dns_details['Fastly'])
|
||||||
|
self.assertTrue('error_detail' in dns_details['Fastly'])
|
||||||
|
self.assertTrue('error_class' in dns_details['Fastly'])
|
||||||
|
self.assertTrue('ValueError' in dns_details['Fastly']['error_class'])
|
||||||
|
|
||||||
|
def test_update_add_domains_https_upgrade_create_cname_record(self):
|
||||||
|
subdomain = mock.Mock()
|
||||||
|
subdomain.add_records = mock.Mock()
|
||||||
|
subdomain.find_record.side_effect = exc.DomainRecordNotFound(
|
||||||
|
"Mock -- couldn't find cname record."
|
||||||
|
)
|
||||||
|
self.client.find = mock.Mock(return_value=subdomain)
|
||||||
|
|
||||||
|
domains_new = [
|
||||||
|
domain.Domain('test.domain.com'),
|
||||||
|
domain.Domain('blog.domain.com')
|
||||||
|
]
|
||||||
|
|
||||||
|
self.service_old.domains = domains_new
|
||||||
|
service_new = service.Service(
|
||||||
|
service_id=self.service_old.service_id,
|
||||||
|
name='myservice',
|
||||||
|
domains=domains_new,
|
||||||
|
origins=[],
|
||||||
|
flavor_id='standard')
|
||||||
|
|
||||||
|
responders = [{
|
||||||
|
'Fastly': {
|
||||||
|
'id': str(uuid.uuid4()),
|
||||||
|
'links': [
|
||||||
|
{
|
||||||
|
'domain': u'test.domain.com',
|
||||||
|
'href': u'test.domain.com.global.prod.fastly.net',
|
||||||
|
'rel': 'access_url'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'domain': u'blog.domain.com',
|
||||||
|
'href': u'blog.domain.com.global.prod.fastly.net',
|
||||||
|
'rel': 'access_url',
|
||||||
|
'certificate': 'san',
|
||||||
|
'old_operator_url': 'old.operator.url.cdn99.mycdn.com'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
}]
|
||||||
|
|
||||||
|
dns_details = self.controller.update(
|
||||||
|
self.service_old,
|
||||||
|
service_new,
|
||||||
|
responders
|
||||||
|
)
|
||||||
|
|
||||||
|
access_urls_map = {}
|
||||||
|
for provider_name in dns_details:
|
||||||
|
access_urls_map[provider_name] = {}
|
||||||
|
access_urls_list = dns_details[provider_name]['access_urls']
|
||||||
|
for access_urls in access_urls_list:
|
||||||
|
access_urls_map[provider_name][access_urls['domain']] = (
|
||||||
|
access_urls['operator_url'])
|
||||||
|
|
||||||
|
for responder in responders:
|
||||||
|
for provider_name in responder:
|
||||||
|
for domain_new in domains_new:
|
||||||
|
self.assertIsNotNone(
|
||||||
|
access_urls_map[provider_name][domain_new.domain])
|
||||||
|
|
||||||
def test_update_add_domains_keeps_log_delivery(self):
|
def test_update_add_domains_keeps_log_delivery(self):
|
||||||
subdomain = mock.Mock()
|
subdomain = mock.Mock()
|
||||||
subdomain.add_records = mock.Mock()
|
subdomain.add_records = mock.Mock()
|
||||||
|
@ -1724,3 +1724,272 @@ class DefaultManagerServiceTests(base.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(domains,
|
self.assertEqual(domains,
|
||||||
self.sc.get_domains_by_provider_url('provider_url'))
|
self.sc.get_domains_by_provider_url('provider_url'))
|
||||||
|
|
||||||
|
def test_update_access_url_positive(self):
|
||||||
|
service_obj = service.load_from_json(self.service_json)
|
||||||
|
service_obj.status = u'deployed'
|
||||||
|
service_obj.provider_details = {
|
||||||
|
'Akamai': provider_details.ProviderDetail(
|
||||||
|
provider_service_id=[
|
||||||
|
{
|
||||||
|
"protocol": "http",
|
||||||
|
"certificate": None,
|
||||||
|
"policy_name": "www.test1.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
access_urls=[
|
||||||
|
{
|
||||||
|
"provider_url": "altcdn.com.mdc.edgesuite.net",
|
||||||
|
"domain": "www.test1.com",
|
||||||
|
"operator_url": "www.test1.com.cdn136.myraxcdn.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
status="deployed",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
self.sc.storage_controller.get_service.return_value = service_obj
|
||||||
|
|
||||||
|
updated = self.sc.update_access_url_service(
|
||||||
|
"project_id",
|
||||||
|
"service_id",
|
||||||
|
{
|
||||||
|
'domain_name': 'www.test1.com',
|
||||||
|
'operator_url': 'www.test1.com.cdn137.myraxcdn.net',
|
||||||
|
'provider_url': 'altcdn.com.mdc.edgesuite.net'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(updated)
|
||||||
|
|
||||||
|
def test_update_access_url_service_not_found(self):
|
||||||
|
self.sc.storage_controller.get_service.side_effect = (
|
||||||
|
ValueError('Mock -- Service not found.')
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
errors.ServiceNotFound,
|
||||||
|
self.sc.update_access_url_service,
|
||||||
|
"project_id",
|
||||||
|
"service_id",
|
||||||
|
{
|
||||||
|
'domain_name': 'www.test1.com',
|
||||||
|
'operator_url': 'www.test1.com.cdn137.myraxcdn.net',
|
||||||
|
'provider_url': 'altcdn.com.mdc.edgesuite.net'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_update_access_url_no_op_patch(self):
|
||||||
|
service_obj = service.load_from_json(self.service_json)
|
||||||
|
service_obj.status = u'deployed'
|
||||||
|
service_obj.provider_details = {
|
||||||
|
'Akamai': provider_details.ProviderDetail(
|
||||||
|
provider_service_id=[
|
||||||
|
{
|
||||||
|
"protocol": "http",
|
||||||
|
"certificate": None,
|
||||||
|
"policy_name": "www.test1.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
access_urls=[
|
||||||
|
{
|
||||||
|
"provider_url": "altcdn.com.mdc.edgesuite.net",
|
||||||
|
"domain": "www.test1.com",
|
||||||
|
"operator_url": "www.test1.com.cdn136.myraxcdn.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
status="deployed",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
self.sc.storage_controller.get_service.return_value = service_obj
|
||||||
|
|
||||||
|
updated = self.sc.update_access_url_service(
|
||||||
|
"project_id",
|
||||||
|
"service_id",
|
||||||
|
{
|
||||||
|
'domain_name': 'www.test1.com',
|
||||||
|
'operator_url': 'www.test1.com.cdn136.myraxcdn.net',
|
||||||
|
'provider_url': 'altcdn.com.mdc.edgesuite.net'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertFalse(updated)
|
||||||
|
|
||||||
|
def test_update_access_url_provider_url_mismatch(self):
|
||||||
|
service_obj = service.load_from_json(self.service_json)
|
||||||
|
service_obj.status = u'deployed'
|
||||||
|
service_obj.provider_details = {
|
||||||
|
'Akamai': provider_details.ProviderDetail(
|
||||||
|
provider_service_id=[
|
||||||
|
{
|
||||||
|
"protocol": "http",
|
||||||
|
"certificate": None,
|
||||||
|
"policy_name": "www.test1.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
access_urls=[
|
||||||
|
{
|
||||||
|
"provider_url": "altcdn.com.mdc.edgesuite.net",
|
||||||
|
"domain": "www.test1.com",
|
||||||
|
"operator_url": "www.test1.com.cdn136.myraxcdn.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
status="deployed",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
self.sc.storage_controller.get_service.return_value = service_obj
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
errors.InvalidOperation,
|
||||||
|
self.sc.update_access_url_service,
|
||||||
|
"project_id",
|
||||||
|
"service_id",
|
||||||
|
{
|
||||||
|
'domain_name': 'www.test1.com',
|
||||||
|
'operator_url': 'www.test1.com.cdn137.myraxcdn.net',
|
||||||
|
'provider_url': 'raxcdn.com.mdc.edgesuite.net'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_update_access_url_mismatch_access_url_and_domain(self):
|
||||||
|
service_obj = service.load_from_json(self.service_json)
|
||||||
|
service_obj.status = u'deployed'
|
||||||
|
service_obj.provider_details = {
|
||||||
|
'Akamai': provider_details.ProviderDetail(
|
||||||
|
provider_service_id=[
|
||||||
|
{
|
||||||
|
"protocol": "http",
|
||||||
|
"certificate": None,
|
||||||
|
"policy_name": "www.test1.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
access_urls=[
|
||||||
|
{
|
||||||
|
"provider_url": "altcdn.com.mdc.edgesuite.net",
|
||||||
|
"domain": "www.test1.com",
|
||||||
|
"operator_url": "www.test1.com.cdn136.myraxcdn.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
status="deployed",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
self.sc.storage_controller.get_service.return_value = service_obj
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
errors.InvalidResourceName,
|
||||||
|
self.sc.update_access_url_service,
|
||||||
|
"project_id",
|
||||||
|
"service_id",
|
||||||
|
{
|
||||||
|
'domain_name': 'www.test1.com',
|
||||||
|
'operator_url': 'www.test2.com.cdn137.myraxcdn.net',
|
||||||
|
'provider_url': 'altcdn.com.mdc.edgesuite.net'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_update_access_url_missing_provider_url(self):
|
||||||
|
service_obj = service.load_from_json(self.service_json)
|
||||||
|
service_obj.status = u'deployed'
|
||||||
|
service_obj.provider_details = {
|
||||||
|
'Akamai': provider_details.ProviderDetail(
|
||||||
|
provider_service_id=[
|
||||||
|
{
|
||||||
|
"protocol": "http",
|
||||||
|
"certificate": None,
|
||||||
|
"policy_name": "www.test1.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
access_urls=[
|
||||||
|
{
|
||||||
|
"domain": "www.test1.com",
|
||||||
|
"operator_url": "www.test1.com.cdn136.myraxcdn.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
status="deployed",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
self.sc.storage_controller.get_service.return_value = service_obj
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
ValueError,
|
||||||
|
self.sc.update_access_url_service,
|
||||||
|
"project_id",
|
||||||
|
"service_id",
|
||||||
|
{
|
||||||
|
'domain_name': 'www.test1.com',
|
||||||
|
'operator_url': 'www.test1.com.cdn137.myraxcdn.net',
|
||||||
|
'provider_url': 'altcdn.com.mdc.edgesuite.net'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_update_access_url_no_matching_access_urls(self):
|
||||||
|
service_obj = service.load_from_json(self.service_json)
|
||||||
|
service_obj.status = u'deployed'
|
||||||
|
service_obj.provider_details = {
|
||||||
|
'Akamai': provider_details.ProviderDetail(
|
||||||
|
provider_service_id=[
|
||||||
|
{
|
||||||
|
"protocol": "http",
|
||||||
|
"certificate": None,
|
||||||
|
"policy_name": "www.test1.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
access_urls=[
|
||||||
|
{
|
||||||
|
"provider_url": "altcdn.com.mdc.edgesuite.net",
|
||||||
|
"domain": "www.test2.com",
|
||||||
|
"operator_url": "www.test2.com.cdn136.myraxcdn.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
status="deployed",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
self.sc.storage_controller.get_service.return_value = service_obj
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
ValueError,
|
||||||
|
self.sc.update_access_url_service,
|
||||||
|
"project_id",
|
||||||
|
"service_id",
|
||||||
|
{
|
||||||
|
'domain_name': 'www.test1.com',
|
||||||
|
'operator_url': 'www.test1.com.cdn137.myraxcdn.net',
|
||||||
|
'provider_url': 'altcdn.com.mdc.edgesuite.net'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_update_access_url_shared_ssl_domain(self):
|
||||||
|
service_obj = service.load_from_json(self.service_json)
|
||||||
|
service_obj.status = u'deployed'
|
||||||
|
service_obj.provider_details = {
|
||||||
|
'Akamai': provider_details.ProviderDetail(
|
||||||
|
provider_service_id=[
|
||||||
|
{
|
||||||
|
"protocol": "https",
|
||||||
|
"certificate": "shared",
|
||||||
|
"policy_name": "test99.scdn1.secure.cdn.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
access_urls=[
|
||||||
|
{
|
||||||
|
"provider_url": "scdn1.secure.cdn.net.edgekey.net",
|
||||||
|
"domain": "test99.scdn1.secure.cdn.net",
|
||||||
|
"shared_ssl_flag": True,
|
||||||
|
"operator_url": "test99.scdn1.secure.cdn.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
status="deployed",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
self.sc.storage_controller.get_service.return_value = service_obj
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
errors.InvalidOperation,
|
||||||
|
self.sc.update_access_url_service,
|
||||||
|
"project_id",
|
||||||
|
"service_id",
|
||||||
|
{
|
||||||
|
'domain_name': 'test99.scdn1.secure.cdn.net',
|
||||||
|
'operator_url': 'test99.scdn2.secure.cdn.net',
|
||||||
|
'provider_url': 'scdn2.secure.cdn.net.edgekey.net'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user