Adds Rackspace DNS Driver
Change-Id: Id49e24364ab0aa39245fc287960451e4233569bc
This commit is contained in:
parent
5b4361bc0b
commit
b893de24de
|
@ -71,13 +71,16 @@ replication_strategy = class:SimpleStrategy, replication_factor:1
|
||||||
[drivers:storage:mockdb]
|
[drivers:storage:mockdb]
|
||||||
database = poppy
|
database = poppy
|
||||||
|
|
||||||
|
|
||||||
[drivers:dns:rackspace]
|
[drivers:dns:rackspace]
|
||||||
project_id = "<operator_project_id>"
|
project_id = "<operator_project_id>"
|
||||||
api_key = "<operator_api_key>"
|
api_key = "<operator_api_key>"
|
||||||
use_shards = True
|
use_shards = True
|
||||||
num_shards = 500
|
num_shards = 499
|
||||||
shard_prefix = "cdn_"
|
shard_prefix = "cdn"
|
||||||
url = "poppycdn.net"
|
url = "poppycdn.net"
|
||||||
|
# You email associated with DNS, for notifications
|
||||||
|
email = "your@email.com"
|
||||||
|
|
||||||
[drivers:provider:fastly]
|
[drivers:provider:fastly]
|
||||||
apikey = "MYAPIKEY"
|
apikey = "MYAPIKEY"
|
||||||
|
|
|
@ -18,4 +18,4 @@ from poppy.dns.base import services
|
||||||
|
|
||||||
|
|
||||||
Driver = driver.DNSDriverBase
|
Driver = driver.DNSDriverBase
|
||||||
ServiceBase = services.ServicesControllerBase
|
ServicesBase = services.ServicesControllerBase
|
||||||
|
|
|
@ -43,14 +43,29 @@ class DNSDriverBase(object):
|
||||||
|
|
||||||
:raises NotImplementedError
|
:raises NotImplementedError
|
||||||
"""
|
"""
|
||||||
|
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractproperty
|
@abc.abstractproperty
|
||||||
def dns_name(self):
|
def dns_name(self):
|
||||||
|
"""Name of this provider.
|
||||||
|
|
||||||
|
:raises NotImplementedError
|
||||||
|
"""
|
||||||
|
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
|
def client(self):
|
||||||
|
"""Client for this provider.
|
||||||
|
|
||||||
|
:raises NotImplementedError
|
||||||
|
"""
|
||||||
|
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractproperty
|
@abc.abstractproperty
|
||||||
def service_controller(self):
|
def services_controller(self):
|
||||||
"""Returns the driver's hostname controller.
|
"""Returns the driver's hostname controller.
|
||||||
|
|
||||||
:raises NotImplementedError
|
:raises NotImplementedError
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
# 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 traceback
|
||||||
|
|
||||||
|
|
||||||
|
class Responder(object):
|
||||||
|
"""Responder Class."""
|
||||||
|
|
||||||
|
def __init__(self, dns_name):
|
||||||
|
self.dns = dns_name
|
||||||
|
|
||||||
|
def failed(self, msg):
|
||||||
|
"""failed.
|
||||||
|
|
||||||
|
:param msg
|
||||||
|
:returns {error, error details}
|
||||||
|
"""
|
||||||
|
|
||||||
|
return {
|
||||||
|
'error': msg,
|
||||||
|
'error_detail': traceback.format_exc()
|
||||||
|
}
|
||||||
|
|
||||||
|
def created(self, dns_details):
|
||||||
|
"""created.
|
||||||
|
|
||||||
|
:param dns_details
|
||||||
|
:returns dns_details
|
||||||
|
"""
|
||||||
|
|
||||||
|
return dns_details
|
||||||
|
|
||||||
|
def updated(self, dns_details):
|
||||||
|
"""updated.
|
||||||
|
|
||||||
|
:param dns_details
|
||||||
|
:returns dns_details
|
||||||
|
"""
|
||||||
|
|
||||||
|
return dns_details
|
||||||
|
|
||||||
|
def deleted(self, dns_details):
|
||||||
|
"""deleted.
|
||||||
|
|
||||||
|
:param dns_details
|
||||||
|
:returns dns_details
|
||||||
|
"""
|
||||||
|
|
||||||
|
return dns_details
|
|
@ -18,6 +18,7 @@ import abc
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from poppy.dns.base import controller
|
from poppy.dns.base import controller
|
||||||
|
from poppy.dns.base import responder
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(abc.ABCMeta)
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
|
@ -27,3 +28,34 @@ class ServicesControllerBase(controller.DNSControllerBase):
|
||||||
|
|
||||||
def __init__(self, driver):
|
def __init__(self, driver):
|
||||||
super(ServicesControllerBase, self).__init__(driver)
|
super(ServicesControllerBase, self).__init__(driver)
|
||||||
|
|
||||||
|
self.responder = responder.Responder(driver.dns_name)
|
||||||
|
|
||||||
|
def update(self, service_old, service_updates, responders):
|
||||||
|
"""update.
|
||||||
|
|
||||||
|
:param service_old: previous service state
|
||||||
|
:param service_updates: updates to service state
|
||||||
|
:param responders: responders from providers
|
||||||
|
:raises NotImplementedError
|
||||||
|
"""
|
||||||
|
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def delete(self, provider_details):
|
||||||
|
"""delete.
|
||||||
|
|
||||||
|
:param provider_details
|
||||||
|
:raises NotImplementedError
|
||||||
|
"""
|
||||||
|
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def create(self, responders):
|
||||||
|
"""create.
|
||||||
|
|
||||||
|
:param responders
|
||||||
|
:raises NotImplementedError
|
||||||
|
"""
|
||||||
|
|
||||||
|
raise NotImplementedError
|
||||||
|
|
|
@ -24,4 +24,4 @@ Field Mappings:
|
||||||
|
|
||||||
from poppy.dns.default import services
|
from poppy.dns.default import services
|
||||||
|
|
||||||
ServiceController = services.ServiceController
|
ServicesController = services.ServicesController
|
||||||
|
|
|
@ -23,17 +23,42 @@ LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DNSProvider(base.Driver):
|
class DNSProvider(base.Driver):
|
||||||
|
"""Default DNS Provider."""
|
||||||
|
|
||||||
def __init__(self, conf):
|
def __init__(self, conf):
|
||||||
super(DNSProvider, self).__init__(conf)
|
super(DNSProvider, self).__init__(conf)
|
||||||
|
|
||||||
def is_alive(self):
|
def is_alive(self):
|
||||||
return False
|
"""is_alive.
|
||||||
|
|
||||||
|
:return boolean
|
||||||
|
"""
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dns_name(self):
|
def dns_name(self):
|
||||||
return "Default"
|
"""DNS provider name.
|
||||||
|
|
||||||
|
:return 'Default'
|
||||||
|
"""
|
||||||
|
|
||||||
|
return 'Default'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def service_controller(self):
|
def client(self):
|
||||||
return controllers.ServiceController(self)
|
"""Client to this provider.
|
||||||
|
|
||||||
|
:return None
|
||||||
|
"""
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def services_controller(self):
|
||||||
|
"""Hook for service controller.
|
||||||
|
|
||||||
|
:return service_controller
|
||||||
|
"""
|
||||||
|
|
||||||
|
return controllers.ServicesController(self)
|
||||||
|
|
|
@ -16,9 +16,64 @@
|
||||||
from poppy.dns import base
|
from poppy.dns import base
|
||||||
|
|
||||||
|
|
||||||
class ServiceController(base.ServiceBase):
|
class ServicesController(base.ServicesBase):
|
||||||
|
|
||||||
def __init__(self, driver):
|
def __init__(self, driver):
|
||||||
super(ServiceController, self).__init__(driver)
|
super(ServicesController, self).__init__(driver)
|
||||||
|
|
||||||
self.driver = driver
|
self.driver = driver
|
||||||
|
|
||||||
|
def update(self, service_old, service_updates, responders):
|
||||||
|
"""Default DNS update.
|
||||||
|
|
||||||
|
:param service_old: previous service state
|
||||||
|
:param service_updates: updates to service state
|
||||||
|
:param responders: responders from providers
|
||||||
|
"""
|
||||||
|
|
||||||
|
dns_details = {}
|
||||||
|
for responder in responders:
|
||||||
|
for provider_name in responder:
|
||||||
|
if 'error' in responder[provider_name]:
|
||||||
|
continue
|
||||||
|
access_urls = []
|
||||||
|
for link in responder[provider_name]['links']:
|
||||||
|
access_url = {
|
||||||
|
'domain': link['domain'],
|
||||||
|
'provider_url': link['href'],
|
||||||
|
'operator_url': link['href']}
|
||||||
|
access_urls.append(access_url)
|
||||||
|
dns_details[provider_name] = {'access_urls': access_urls}
|
||||||
|
return self.responder.created(dns_details)
|
||||||
|
|
||||||
|
def delete(self, provider_details):
|
||||||
|
"""Default DNS delete.
|
||||||
|
|
||||||
|
:param provider_details
|
||||||
|
"""
|
||||||
|
|
||||||
|
dns_details = {}
|
||||||
|
for provider_name in provider_details:
|
||||||
|
dns_details[provider_name] = self.responder.deleted({})
|
||||||
|
return dns_details
|
||||||
|
|
||||||
|
def create(self, responders):
|
||||||
|
"""Default DNS create.
|
||||||
|
|
||||||
|
:param responders: responders from providers
|
||||||
|
"""
|
||||||
|
|
||||||
|
dns_details = {}
|
||||||
|
for responder in responders:
|
||||||
|
for provider_name in responder:
|
||||||
|
if 'error' in responder[provider_name]:
|
||||||
|
continue
|
||||||
|
access_urls = []
|
||||||
|
for link in responder[provider_name]['links']:
|
||||||
|
access_url = {
|
||||||
|
'domain': link['domain'],
|
||||||
|
'provider_url': link['href'],
|
||||||
|
'operator_url': link['href']}
|
||||||
|
access_urls.append(access_url)
|
||||||
|
dns_details[provider_name] = {'access_urls': access_urls}
|
||||||
|
return self.responder.created(dns_details)
|
||||||
|
|
|
@ -24,4 +24,4 @@ Field Mappings:
|
||||||
|
|
||||||
from poppy.dns.designate import services
|
from poppy.dns.designate import services
|
||||||
|
|
||||||
ServiceController = services.ServiceController
|
ServicesController = services.ServicesController
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
from poppy.dns import base
|
from poppy.dns import base
|
||||||
|
|
||||||
|
|
||||||
class ServiceController(base.ServiceBase):
|
class ServicesController(base.ServicesBase):
|
||||||
|
|
||||||
def __init__(self, driver):
|
def __init__(self, driver):
|
||||||
super(ServiceController, self).__init__(driver)
|
super(ServicesController, self).__init__(driver)
|
||||||
|
|
||||||
self.driver = driver
|
self.driver = driver
|
||||||
|
|
|
@ -24,4 +24,4 @@ Field Mappings:
|
||||||
|
|
||||||
from poppy.dns.rackspace import services
|
from poppy.dns.rackspace import services
|
||||||
|
|
||||||
ServiceController = services.ServiceController
|
ServicesController = services.ServicesController
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
"""DNS Provider implementation."""
|
"""DNS Provider implementation."""
|
||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
|
import pyrax
|
||||||
|
|
||||||
from poppy.dns import base
|
from poppy.dns import base
|
||||||
from poppy.dns.rackspace import controllers
|
from poppy.dns.rackspace import controllers
|
||||||
|
@ -34,6 +35,8 @@ RACKSPACE_OPTIONS = [
|
||||||
help='The shard prefix to use'),
|
help='The shard prefix to use'),
|
||||||
cfg.StrOpt('url', default='',
|
cfg.StrOpt('url', default='',
|
||||||
help='The url for customers to CNAME to'),
|
help='The url for customers to CNAME to'),
|
||||||
|
cfg.StrOpt('email', help='The email to be provided to Rackspace DNS for'
|
||||||
|
'creating subdomains'),
|
||||||
]
|
]
|
||||||
|
|
||||||
RACKSPACE_GROUP = 'drivers:dns:rackspace'
|
RACKSPACE_GROUP = 'drivers:dns:rackspace'
|
||||||
|
@ -42,17 +45,51 @@ LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DNSProvider(base.Driver):
|
class DNSProvider(base.Driver):
|
||||||
|
"""Rackspace DNS Provider."""
|
||||||
|
|
||||||
def __init__(self, conf):
|
def __init__(self, conf):
|
||||||
super(DNSProvider, self).__init__(conf)
|
super(DNSProvider, self).__init__(conf)
|
||||||
|
|
||||||
|
self._conf.register_opts(RACKSPACE_OPTIONS, group=RACKSPACE_GROUP)
|
||||||
|
self.rackdns_conf = self._conf[RACKSPACE_GROUP]
|
||||||
|
pyrax.set_setting("identity_type", "rackspace")
|
||||||
|
pyrax.set_credentials(self.rackdns_conf.project_id,
|
||||||
|
self.rackdns_conf.api_key)
|
||||||
|
self.rackdns_client = pyrax.cloud_dns
|
||||||
|
|
||||||
def is_alive(self):
|
def is_alive(self):
|
||||||
|
"""is_alive.
|
||||||
|
|
||||||
|
:return boolean
|
||||||
|
"""
|
||||||
|
|
||||||
|
# TODO(obulpathi): Implement health check
|
||||||
|
# and add DNS to health endpoint
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dns_name(self):
|
def dns_name(self):
|
||||||
return "Rackspace Cloud DNS"
|
"""DNS provider name.
|
||||||
|
|
||||||
|
:return 'Rackspace Cloud DNS'
|
||||||
|
"""
|
||||||
|
|
||||||
|
return 'Rackspace Cloud DNS'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def service_controller(self):
|
def client(self):
|
||||||
return controllers.ServiceController(self)
|
"""Client to this provider.
|
||||||
|
|
||||||
|
:return client
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.rackdns_client
|
||||||
|
|
||||||
|
@property
|
||||||
|
def services_controller(self):
|
||||||
|
"""Hook for service controller.
|
||||||
|
|
||||||
|
:return service_controller
|
||||||
|
"""
|
||||||
|
|
||||||
|
return controllers.ServicesController(self)
|
||||||
|
|
|
@ -13,12 +13,334 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import random
|
||||||
|
import sets
|
||||||
|
|
||||||
|
import pyrax.exceptions as exc
|
||||||
|
|
||||||
from poppy.dns import base
|
from poppy.dns import base
|
||||||
|
from poppy.openstack.common import log
|
||||||
|
|
||||||
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ServiceController(base.ServiceBase):
|
class ServicesController(base.ServicesBase):
|
||||||
|
|
||||||
def __init__(self, driver):
|
def __init__(self, driver):
|
||||||
super(ServiceController, self).__init__(driver)
|
super(ServicesController, self).__init__(driver)
|
||||||
|
|
||||||
self.driver = driver
|
self.client = driver.client
|
||||||
|
|
||||||
|
def _get_subdomain(self, subdomain_name):
|
||||||
|
"""Returns a subdomain, if it does not exist, create it
|
||||||
|
|
||||||
|
:param subdomain_name
|
||||||
|
:return subdomain
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
subdomain = self.client.find(name=subdomain_name)
|
||||||
|
except exc.NotFound:
|
||||||
|
subdomain = self.client.create(
|
||||||
|
name=subdomain_name,
|
||||||
|
emailAddress=self._driver.rackdns_conf.email,
|
||||||
|
ttl=900)
|
||||||
|
return subdomain
|
||||||
|
|
||||||
|
def _create_cname_records(self, links):
|
||||||
|
"""Creates a subdomain
|
||||||
|
|
||||||
|
:param links: Access URLS from providers
|
||||||
|
:return dns_links: Map from provider access URL to DNS access URL
|
||||||
|
"""
|
||||||
|
|
||||||
|
cdn_domain_name = self._driver.rackdns_conf.url
|
||||||
|
shard_prefix = self._driver.rackdns_conf.shard_prefix
|
||||||
|
num_shards = self._driver.rackdns_conf.num_shards
|
||||||
|
|
||||||
|
# randomly select a shard
|
||||||
|
shard_id = random.randint(0, num_shards - 1)
|
||||||
|
subdomain_name = '{0}{1}.{2}'.format(shard_prefix, shard_id,
|
||||||
|
cdn_domain_name)
|
||||||
|
subdomain = self._get_subdomain(subdomain_name)
|
||||||
|
# create CNAME record for adding
|
||||||
|
cname_records = []
|
||||||
|
dns_links = {}
|
||||||
|
for link in links:
|
||||||
|
name = '{0}.{1}'.format(link, subdomain_name)
|
||||||
|
cname_record = {'type': 'CNAME',
|
||||||
|
'name': name,
|
||||||
|
'data': links[link],
|
||||||
|
'ttl': 300}
|
||||||
|
dns_links[links[link]] = name
|
||||||
|
cname_records.append(cname_record)
|
||||||
|
# add the cname records
|
||||||
|
subdomain.add_records(cname_records)
|
||||||
|
return dns_links
|
||||||
|
|
||||||
|
def _delete_cname_record(self, access_url):
|
||||||
|
"""Delete a CNAME record
|
||||||
|
|
||||||
|
:param access_url: DNS Access URL
|
||||||
|
:return error_msg: returns error message, if any
|
||||||
|
"""
|
||||||
|
|
||||||
|
# extract shard name
|
||||||
|
shard_name = access_url.split('.')[-3]
|
||||||
|
subdomain_name = '.'.join([shard_name, self._driver.rackdns_conf.url])
|
||||||
|
# get subdomain
|
||||||
|
subdomain = self.client.find(name=subdomain_name)
|
||||||
|
# search and find the CNAME record
|
||||||
|
name = access_url
|
||||||
|
record_type = 'CNAME'
|
||||||
|
records = self.client.search_records(subdomain, record_type, name)
|
||||||
|
# delete the record
|
||||||
|
# we should get one record,
|
||||||
|
# or none if it has been deleted already
|
||||||
|
if not records:
|
||||||
|
LOG.info('DNS record already deleted: {0}'.format(access_url))
|
||||||
|
elif len(records) == 1:
|
||||||
|
LOG.info('Deleting DNS records for : {0}'.format(access_url))
|
||||||
|
records[0].delete()
|
||||||
|
elif len(records) > 1:
|
||||||
|
error_msg = 'Multiple DNS records found: {0}'.format(access_url)
|
||||||
|
return error_msg
|
||||||
|
return
|
||||||
|
|
||||||
|
def create(self, responders):
|
||||||
|
"""Create CNAME record for a service.
|
||||||
|
|
||||||
|
:param responders: responders from providers
|
||||||
|
:return dns_links: Map from provider urls to DNS urls
|
||||||
|
"""
|
||||||
|
# gather the provider urls and cname them
|
||||||
|
links = {}
|
||||||
|
for responder in responders:
|
||||||
|
for provider_name in responder:
|
||||||
|
if 'error' in responder[provider_name]:
|
||||||
|
continue
|
||||||
|
for link in responder[provider_name]['links']:
|
||||||
|
if link['rel'] == 'access_url':
|
||||||
|
links[link['domain']] = link['href']
|
||||||
|
|
||||||
|
# create CNAME records
|
||||||
|
try:
|
||||||
|
dns_links = self._create_cname_records(links)
|
||||||
|
except Exception as e:
|
||||||
|
error_msg = 'Rackspace DNS Exception: {0}'.format(e)
|
||||||
|
LOG.error(error_msg)
|
||||||
|
return self.responder.failed(error_msg)
|
||||||
|
|
||||||
|
# gather the CNAMED links
|
||||||
|
dns_details = {}
|
||||||
|
for responder in responders:
|
||||||
|
for provider_name in responder:
|
||||||
|
if 'error' in responder[provider_name]:
|
||||||
|
continue
|
||||||
|
access_urls = []
|
||||||
|
for link in responder[provider_name]['links']:
|
||||||
|
if link['rel'] == 'access_url':
|
||||||
|
access_url = {
|
||||||
|
'domain': link['domain'],
|
||||||
|
'provider_url': link['href'],
|
||||||
|
'operator_url': dns_links[link['href']]}
|
||||||
|
access_urls.append(access_url)
|
||||||
|
dns_details[provider_name] = {'access_urls': access_urls}
|
||||||
|
return self.responder.created(dns_details)
|
||||||
|
|
||||||
|
def delete(self, provider_details):
|
||||||
|
"""Delete CNAME records for a service.
|
||||||
|
|
||||||
|
:param provider_details
|
||||||
|
:return dns_details: Map from provider_name to delete errors
|
||||||
|
"""
|
||||||
|
|
||||||
|
dns_details = {}
|
||||||
|
for provider_name in provider_details:
|
||||||
|
error_msg = ''
|
||||||
|
access_urls = provider_details[provider_name].access_urls
|
||||||
|
for access_url in access_urls:
|
||||||
|
try:
|
||||||
|
msg = self._delete_cname_record(access_url['operator_url'])
|
||||||
|
if msg:
|
||||||
|
error_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 to CDN '
|
||||||
|
'subdomain {0}'.format(e))
|
||||||
|
error_msg = (error_msg + 'Can not access subdomain . '
|
||||||
|
'Exception: {0}'.format(e))
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error('Exception: {0}'.format(e))
|
||||||
|
error_msg = error_msg + 'Exception: {0}'.format(e)
|
||||||
|
# format the error or success message for this provider
|
||||||
|
if error_msg:
|
||||||
|
dns_details[provider_name] = self.responder.failed(error_msg)
|
||||||
|
else:
|
||||||
|
dns_details[provider_name] = self.responder.deleted({})
|
||||||
|
return dns_details
|
||||||
|
|
||||||
|
def _update_added_domains(self, responders, added_domains):
|
||||||
|
"""Update added domains."""
|
||||||
|
|
||||||
|
# if no domains are added, return
|
||||||
|
dns_details = {}
|
||||||
|
if not added_domains:
|
||||||
|
for responder in responders:
|
||||||
|
for provider_name in responder:
|
||||||
|
dns_details[provider_name] = {'access_urls': {}}
|
||||||
|
return dns_details
|
||||||
|
|
||||||
|
# gather the provider links for the added domains
|
||||||
|
links = {}
|
||||||
|
for responder in responders:
|
||||||
|
for provider_name in responder:
|
||||||
|
if 'error' in responder[provider_name]:
|
||||||
|
continue
|
||||||
|
for link in responder[provider_name]['links']:
|
||||||
|
domain_added = (link['rel'] == 'access_url' and
|
||||||
|
link['domain'] in added_domains)
|
||||||
|
if domain_added:
|
||||||
|
links[link['domain']] = link['href']
|
||||||
|
|
||||||
|
# create CNAME records for added domains
|
||||||
|
try:
|
||||||
|
dns_links = self._create_cname_records(links)
|
||||||
|
except Exception as e:
|
||||||
|
error_msg = 'Rackspace DNS Exception: {0}'.format(e)
|
||||||
|
LOG.error(error_msg)
|
||||||
|
return self.responder.failed(error_msg)
|
||||||
|
|
||||||
|
# gather the CNAMED links for added domains
|
||||||
|
for responder in responders:
|
||||||
|
for provider_name in responder:
|
||||||
|
if 'error' in responder[provider_name]:
|
||||||
|
continue
|
||||||
|
access_urls = {}
|
||||||
|
for link in responder[provider_name]['links']:
|
||||||
|
if link['domain'] in added_domains:
|
||||||
|
access_urls[link['href']] = dns_links[link['href']]
|
||||||
|
dns_details[provider_name] = {'access_urls': access_urls}
|
||||||
|
return dns_details
|
||||||
|
|
||||||
|
def _update_removed_domains(self, provider_details, removed_domains):
|
||||||
|
"""Update removed domains."""
|
||||||
|
|
||||||
|
# if no domains are removed, return
|
||||||
|
dns_details = {}
|
||||||
|
if not removed_domains:
|
||||||
|
for provider_name in provider_details:
|
||||||
|
dns_details[provider_name] = {'access_urls': {}}
|
||||||
|
return dns_details
|
||||||
|
|
||||||
|
# delete the records for deleted domains
|
||||||
|
for provider_name in provider_details:
|
||||||
|
error_msg = ''
|
||||||
|
provider_detail = provider_details[provider_name]
|
||||||
|
for access_url in provider_detail.access_urls:
|
||||||
|
if access_url['domain'] not in removed_domains:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
msg = self._delete_cname_record(access_url['operator_url'])
|
||||||
|
if msg:
|
||||||
|
error_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 to CDN '
|
||||||
|
'subdomain {0}'.format(e))
|
||||||
|
error_msg = (error_msg + 'Can not access subdomain. '
|
||||||
|
'Exception: {0}'.format(e))
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error('Exception: {0}'.format(e))
|
||||||
|
error_msg = error_msg + 'Exception: {0}'.format(e)
|
||||||
|
# format the error or success message for this provider
|
||||||
|
if error_msg:
|
||||||
|
dns_details[provider_name] = self.responder.failed(error_msg)
|
||||||
|
else:
|
||||||
|
dns_details[provider_name] = self.responder.deleted({})
|
||||||
|
return dns_details
|
||||||
|
|
||||||
|
def update(self, service_old, service_updates, responders):
|
||||||
|
"""Update CNAME records for a service.
|
||||||
|
|
||||||
|
:param service_old: previous service state
|
||||||
|
:param service_updates: updates to service state
|
||||||
|
:param responders: responders from providers
|
||||||
|
|
||||||
|
:return dns_details: Map from provider_name to update errors
|
||||||
|
"""
|
||||||
|
|
||||||
|
# get old domains
|
||||||
|
old_domains = sets.Set()
|
||||||
|
old_access_urls_map = {}
|
||||||
|
provider_details = service_old.provider_details
|
||||||
|
for provider_name in provider_details:
|
||||||
|
provider_detail = provider_details[provider_name]
|
||||||
|
access_urls = provider_detail.access_urls
|
||||||
|
old_access_urls_map[provider_name] = {'access_urls': access_urls}
|
||||||
|
for access_url in access_urls:
|
||||||
|
old_domains.add(access_url['domain'])
|
||||||
|
|
||||||
|
# get new_domains
|
||||||
|
new_domains = sets.Set()
|
||||||
|
for responder in responders:
|
||||||
|
for provider_name in responder:
|
||||||
|
links = responder[provider_name]['links']
|
||||||
|
for link in links:
|
||||||
|
new_domains.add(link['domain'])
|
||||||
|
|
||||||
|
# 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
|
||||||
|
if old_domains == new_domains:
|
||||||
|
return old_access_urls_map
|
||||||
|
|
||||||
|
# get the list of added, removed and common domains
|
||||||
|
added_domains = new_domains.difference(old_domains)
|
||||||
|
removed_domains = old_domains.difference(new_domains)
|
||||||
|
common_domains = new_domains.intersection(old_domains)
|
||||||
|
|
||||||
|
# add new domains
|
||||||
|
dns_links = self._update_added_domains(responders, added_domains)
|
||||||
|
|
||||||
|
# remove CNAME records for deleted domains
|
||||||
|
provider_details = service_old.provider_details
|
||||||
|
self._update_removed_domains(provider_details, removed_domains)
|
||||||
|
|
||||||
|
# gather the CNAMED links and remove stale links
|
||||||
|
dns_details = {}
|
||||||
|
for responder in responders:
|
||||||
|
for provider_name in responder:
|
||||||
|
if 'error' in responder[provider_name]:
|
||||||
|
continue
|
||||||
|
provider_detail = service_old.provider_details[provider_name]
|
||||||
|
old_access_urls = provider_detail.access_urls
|
||||||
|
operator_urls = dns_links[provider_name]['access_urls']
|
||||||
|
access_urls = []
|
||||||
|
for link in responder[provider_name]['links']:
|
||||||
|
if link['domain'] in removed_domains:
|
||||||
|
continue
|
||||||
|
elif link['domain'] in added_domains:
|
||||||
|
operator_url = operator_urls[link['href']]
|
||||||
|
access_url = {
|
||||||
|
'domain': link['domain'],
|
||||||
|
'provider_url': link['href'],
|
||||||
|
'operator_url': operator_url}
|
||||||
|
access_urls.append(access_url)
|
||||||
|
elif link['domain'] in common_domains:
|
||||||
|
# iterate through old access urls and get access url
|
||||||
|
operator_url = None
|
||||||
|
for old_access_url in old_access_urls:
|
||||||
|
if old_access_url['domain'] == link['domain']:
|
||||||
|
operator_url = old_access_url['operator_url']
|
||||||
|
break
|
||||||
|
access_url = {
|
||||||
|
'domain': link['domain'],
|
||||||
|
'provider_url': link['href'],
|
||||||
|
'operator_url': operator_url}
|
||||||
|
access_urls.append(access_url)
|
||||||
|
dns_details[provider_name] = {'access_urls': access_urls}
|
||||||
|
|
||||||
|
return self.responder.updated(dns_details)
|
||||||
|
|
|
@ -29,29 +29,34 @@ def service_create_worker(providers_list, service_controller,
|
||||||
service_obj)
|
service_obj)
|
||||||
responders.append(responder)
|
responders.append(responder)
|
||||||
|
|
||||||
|
# create dns mapping
|
||||||
|
dns = service_controller.dns_controller
|
||||||
|
dns_responder = dns.create(responders)
|
||||||
|
|
||||||
provider_details_dict = {}
|
provider_details_dict = {}
|
||||||
for responder in responders:
|
for responder in responders:
|
||||||
for provider_name in responder:
|
for provider_name in responder:
|
||||||
if 'error' not in responder[provider_name]:
|
if 'error' in responder[provider_name]:
|
||||||
|
error_info = responder[provider_name]['error_detail']
|
||||||
|
provider_details_dict[provider_name] = (
|
||||||
|
provider_details.ProviderDetail(error_info=error_info))
|
||||||
|
provider_details_dict[provider_name].status = 'failed'
|
||||||
|
elif 'error' in dns_responder[provider_name]:
|
||||||
|
error_info = dns_responder[provider_name]['error_detail']
|
||||||
|
provider_details_dict[provider_name] = (
|
||||||
|
provider_details.ProviderDetail(error_info=error_info))
|
||||||
|
provider_details_dict[provider_name].status = 'failed'
|
||||||
|
else:
|
||||||
|
access_urls = dns_responder[provider_name]['access_urls']
|
||||||
provider_details_dict[provider_name] = (
|
provider_details_dict[provider_name] = (
|
||||||
provider_details.ProviderDetail(
|
provider_details.ProviderDetail(
|
||||||
provider_service_id=responder[provider_name]['id'],
|
provider_service_id=responder[provider_name]['id'],
|
||||||
access_urls=[link['href'] for link in
|
access_urls=access_urls))
|
||||||
responder[provider_name]['links']])
|
|
||||||
)
|
|
||||||
if 'status' in responder[provider_name]:
|
if 'status' in responder[provider_name]:
|
||||||
provider_details_dict[provider_name].status = (
|
provider_details_dict[provider_name].status = (
|
||||||
responder[provider_name]['status'])
|
responder[provider_name]['status'])
|
||||||
else:
|
else:
|
||||||
provider_details_dict[provider_name].status = (
|
provider_details_dict[provider_name].status = 'deployed'
|
||||||
'deployed')
|
|
||||||
else:
|
|
||||||
provider_details_dict[provider_name] = (
|
|
||||||
provider_details.ProviderDetail(
|
|
||||||
error_info=responder[provider_name]['error_detail']
|
|
||||||
)
|
|
||||||
)
|
|
||||||
provider_details_dict[provider_name].status = 'failed'
|
|
||||||
|
|
||||||
service_controller.storage_controller.update_provider_details(
|
service_controller.storage_controller.update_provider_details(
|
||||||
project_id,
|
project_id,
|
||||||
|
|
|
@ -31,6 +31,9 @@ def service_delete_worker(provider_details, service_controller,
|
||||||
responders.append(responder)
|
responders.append(responder)
|
||||||
LOG.info('Deleting service from %s complete...' % provider)
|
LOG.info('Deleting service from %s complete...' % provider)
|
||||||
|
|
||||||
|
# delete associated cname records from DNS
|
||||||
|
dns_responder = service_controller.dns_controller.delete(provider_details)
|
||||||
|
|
||||||
for responder in responders:
|
for responder in responders:
|
||||||
# this is the item of responder, if there's "error"
|
# this is the item of responder, if there's "error"
|
||||||
# key in it, it means the deletion for this provider failed.
|
# key in it, it means the deletion for this provider failed.
|
||||||
|
@ -43,13 +46,19 @@ def service_delete_worker(provider_details, service_controller,
|
||||||
(provider_name, service_name))
|
(provider_name, service_name))
|
||||||
# stores the error info for debugging purposes.
|
# stores the error info for debugging purposes.
|
||||||
provider_details[provider_name].error_info = (
|
provider_details[provider_name].error_info = (
|
||||||
responder[provider_name].get('error_info')
|
responder[provider_name].get('error_info'))
|
||||||
)
|
elif 'error' in dns_responder[provider_name]:
|
||||||
|
LOG.info('Delete service from DNS failed')
|
||||||
|
LOG.info('Updating provider detail status of %s for %s'.foramt(
|
||||||
|
(provider_name, service_name)))
|
||||||
|
# stores the error info for debugging purposes.
|
||||||
|
provider_details[provider_name].error_info = (
|
||||||
|
dns_responder[provider_name].get('error_info'))
|
||||||
else:
|
else:
|
||||||
# delete service successful, remove this provider detail record
|
# delete service successful, remove this provider detail record
|
||||||
del provider_details[provider_name]
|
del provider_details[provider_name]
|
||||||
|
|
||||||
service_controller.storage_controller._driver.connect()
|
service_controller.storage_controller._driver.connect()
|
||||||
if provider_details == {}:
|
if provider_details == {}:
|
||||||
# Only if all provider successfully deleted we can delete
|
# Only if all provider successfully deleted we can delete
|
||||||
# the poppy service.
|
# the poppy service.
|
||||||
|
@ -65,4 +74,4 @@ def service_delete_worker(provider_details, service_controller,
|
||||||
service_controller.storage_controller.update_provider_details(
|
service_controller.storage_controller.update_provider_details(
|
||||||
project_id,
|
project_id,
|
||||||
service_name,
|
service_name,
|
||||||
provider_details)
|
provider_details)
|
||||||
|
|
|
@ -32,17 +32,20 @@ def update_worker(service_controller, project_id, service_name,
|
||||||
responders.append(responder)
|
responders.append(responder)
|
||||||
LOG.info(u'Updating service from {0} complete'.format(provider))
|
LOG.info(u'Updating service from {0} complete'.format(provider))
|
||||||
|
|
||||||
|
# create dns mapping
|
||||||
|
dns = service_controller.dns_controller
|
||||||
|
dns_responder = dns.update(service_old, service_updates, responders)
|
||||||
|
|
||||||
# gather links and status for service from providers
|
# gather links and status for service from providers
|
||||||
provider_details_dict = {}
|
provider_details_dict = {}
|
||||||
for responder in responders:
|
for responder in responders:
|
||||||
for provider_name in responder:
|
for provider_name in responder:
|
||||||
if 'error' not in responder[provider_name]:
|
if 'error' not in responder[provider_name]:
|
||||||
|
access_urls = dns_responder[provider_name]['access_urls']
|
||||||
provider_details_dict[provider_name] = (
|
provider_details_dict[provider_name] = (
|
||||||
provider_details.ProviderDetail(
|
provider_details.ProviderDetail(
|
||||||
provider_service_id=responder[provider_name]['id'],
|
provider_service_id=responder[provider_name]['id'],
|
||||||
access_urls=[link['href'] for link in
|
access_urls=access_urls))
|
||||||
responder[provider_name]['links']])
|
|
||||||
)
|
|
||||||
if 'status' in responder[provider_name]:
|
if 'status' in responder[provider_name]:
|
||||||
provider_details_dict[provider_name].status = (
|
provider_details_dict[provider_name].status = (
|
||||||
responder[provider_name]['status'])
|
responder[provider_name]['status'])
|
||||||
|
|
|
@ -32,6 +32,7 @@ class DefaultServicesController(base.ServicesController):
|
||||||
|
|
||||||
self.storage_controller = self._driver.storage.services_controller
|
self.storage_controller = self._driver.storage.services_controller
|
||||||
self.flavor_controller = self._driver.storage.flavors_controller
|
self.flavor_controller = self._driver.storage.flavors_controller
|
||||||
|
self.dns_controller = self._driver.dns.services_controller
|
||||||
|
|
||||||
def _get_provider_details(self, project_id, service_name):
|
def _get_provider_details(self, project_id, service_name):
|
||||||
try:
|
try:
|
||||||
|
@ -86,6 +87,7 @@ class DefaultServicesController(base.ServicesController):
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
self.storage_controller._driver.close_connection()
|
self.storage_controller._driver.close_connection()
|
||||||
|
|
||||||
p = multiprocessing.Process(
|
p = multiprocessing.Process(
|
||||||
name='Process: create poppy service %s for'
|
name='Process: create poppy service %s for'
|
||||||
' project id: %s' %
|
' project id: %s' %
|
||||||
|
@ -141,6 +143,7 @@ class DefaultServicesController(base.ServicesController):
|
||||||
provider_details)
|
provider_details)
|
||||||
|
|
||||||
self.storage_controller._driver.close_connection()
|
self.storage_controller._driver.close_connection()
|
||||||
|
|
||||||
p = multiprocessing.Process(
|
p = multiprocessing.Process(
|
||||||
name=('Process: update poppy service {0} for project id: {1}'
|
name=('Process: update poppy service {0} for project id: {1}'
|
||||||
.format(service_name, project_id)),
|
.format(service_name, project_id)),
|
||||||
|
@ -172,6 +175,7 @@ class DefaultServicesController(base.ServicesController):
|
||||||
provider_details)
|
provider_details)
|
||||||
|
|
||||||
self.storage_controller._driver.close_connection()
|
self.storage_controller._driver.close_connection()
|
||||||
|
|
||||||
p = multiprocessing.Process(
|
p = multiprocessing.Process(
|
||||||
name='Process: delete poppy service %s for'
|
name='Process: delete poppy service %s for'
|
||||||
' project id: %s' %
|
' project id: %s' %
|
||||||
|
@ -184,6 +188,7 @@ class DefaultServicesController(base.ServicesController):
|
||||||
project_id,
|
project_id,
|
||||||
service_name))
|
service_name))
|
||||||
p.start()
|
p.start()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def purge(self, project_id, service_name, purge_url=None):
|
def purge(self, project_id, service_name, purge_url=None):
|
||||||
|
|
|
@ -26,7 +26,7 @@ class ProviderDetail(object):
|
||||||
|
|
||||||
"""ProviderDetail object for each provider."""
|
"""ProviderDetail object for each provider."""
|
||||||
|
|
||||||
def __init__(self, provider_service_id=None, access_urls=[],
|
def __init__(self, provider_service_id=None, access_urls={},
|
||||||
status=u"deploy_in_progress", name=None, error_info=None):
|
status=u"deploy_in_progress", name=None, error_info=None):
|
||||||
self._provider_service_id = provider_service_id
|
self._provider_service_id = provider_service_id
|
||||||
self._id = provider_service_id
|
self._id = provider_service_id
|
||||||
|
@ -44,14 +44,14 @@ class ProviderDetail(object):
|
||||||
def provider_service_id(self, value):
|
def provider_service_id(self, value):
|
||||||
self._provider_service_id = value
|
self._provider_service_id = value
|
||||||
|
|
||||||
@property
|
|
||||||
def access_urls(self):
|
|
||||||
return self._access_urls
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def access_urls(self):
|
||||||
|
return self._access_urls
|
||||||
|
|
||||||
@access_urls.setter
|
@access_urls.setter
|
||||||
def access_urls(self, value):
|
def access_urls(self, value):
|
||||||
self._access_urls = value
|
self._access_urls = value
|
||||||
|
|
|
@ -98,7 +98,8 @@ class ServiceController(base.ServiceBase):
|
||||||
LOG.info('Creating policy %s on domain %s complete' %
|
LOG.info('Creating policy %s on domain %s complete' %
|
||||||
(dp, ','.join(classified_domain)))
|
(dp, ','.join(classified_domain)))
|
||||||
links.append({'href': self.driver.akamai_access_url_link,
|
links.append({'href': self.driver.akamai_access_url_link,
|
||||||
"rel": 'access_url'
|
'rel': 'access_url',
|
||||||
|
'domain': service_obj.name
|
||||||
})
|
})
|
||||||
except Exception:
|
except Exception:
|
||||||
return self.responder.failed("failed to create service")
|
return self.responder.failed("failed to create service")
|
||||||
|
@ -279,7 +280,8 @@ class ServiceController(base.ServiceBase):
|
||||||
LOG.info('Creating/Updateing policy %s on domain %s '
|
LOG.info('Creating/Updateing policy %s on domain %s '
|
||||||
'complete' % (dp, ','.join(classified_domain)))
|
'complete' % (dp, ','.join(classified_domain)))
|
||||||
links.append({'href': self.driver.akamai_access_url_link,
|
links.append({'href': self.driver.akamai_access_url_link,
|
||||||
'rel': 'access_url'
|
'rel': 'access_url',
|
||||||
|
'domain': service_obj.name
|
||||||
})
|
})
|
||||||
except Exception:
|
except Exception:
|
||||||
return self.responder.failed("failed to update service")
|
return self.responder.failed("failed to update service")
|
||||||
|
@ -348,7 +350,9 @@ class ServiceController(base.ServiceBase):
|
||||||
return self.responder.failed("failed to update service")
|
return self.responder.failed("failed to update service")
|
||||||
ids = policies
|
ids = policies
|
||||||
links.append({'href': self.driver.akamai_access_url_link,
|
links.append({'href': self.driver.akamai_access_url_link,
|
||||||
'rel': 'access_url'})
|
'rel': 'access_url',
|
||||||
|
'domain': service_obj.name
|
||||||
|
})
|
||||||
return self.responder.updated(json.dumps(ids), links)
|
return self.responder.updated(json.dumps(ids), links)
|
||||||
|
|
||||||
def delete(self, provider_service_id):
|
def delete(self, provider_service_id):
|
||||||
|
|
|
@ -50,7 +50,8 @@ class ServiceController(base.ServiceBase):
|
||||||
service_version.number)
|
service_version.number)
|
||||||
links = [{"href": '.'.join([domain_check.domain.name,
|
links = [{"href": '.'.join([domain_check.domain.name,
|
||||||
"global.prod.fastly.net"]),
|
"global.prod.fastly.net"]),
|
||||||
"rel": 'access_url'}
|
"rel": 'access_url',
|
||||||
|
"domain": domain_check.domain.name}
|
||||||
for domain_check in domain_checks]
|
for domain_check in domain_checks]
|
||||||
|
|
||||||
for origin in service_obj.origins:
|
for origin in service_obj.origins:
|
||||||
|
|
|
@ -37,6 +37,7 @@ class ServiceController(base.ServiceBase):
|
||||||
service_id = uuid.uuid1()
|
service_id = uuid.uuid1()
|
||||||
return self.responder.created(str(service_id), [{
|
return self.responder.created(str(service_id), [{
|
||||||
"href": "www.mysite.com",
|
"href": "www.mysite.com",
|
||||||
|
"domain": "www.mydomain.com",
|
||||||
'rel': "access_url"}])
|
'rel': "access_url"}])
|
||||||
|
|
||||||
def delete(self, provider_service_id):
|
def delete(self, provider_service_id):
|
||||||
|
|
|
@ -293,7 +293,7 @@ class ServicesController(base.ServicesController):
|
||||||
provider_detail_dict = json.loads(
|
provider_detail_dict = json.loads(
|
||||||
provider_details_result[provider_name])
|
provider_details_result[provider_name])
|
||||||
provider_service_id = provider_detail_dict.get('id', None)
|
provider_service_id = provider_detail_dict.get('id', None)
|
||||||
access_urls = provider_detail_dict.get("access_urls", None)
|
access_urls = provider_detail_dict.get("access_urls", [])
|
||||||
status = provider_detail_dict.get("status", u'creating')
|
status = provider_detail_dict.get("status", u'creating')
|
||||||
error_info = provider_detail_dict.get("error_info", None)
|
error_info = provider_detail_dict.get("error_info", None)
|
||||||
provider_detail_obj = provider_details.ProviderDetail(
|
provider_detail_obj = provider_details.ProviderDetail(
|
||||||
|
|
|
@ -37,16 +37,17 @@ class ServicesController(base.ServicesController):
|
||||||
provider_details = {
|
provider_details = {
|
||||||
'MaxCDN': json.dumps(
|
'MaxCDN': json.dumps(
|
||||||
{'id': 11942,
|
{'id': 11942,
|
||||||
'access_urls': ['mypullzone.netdata.com']}),
|
'access_urls': [{'operator_url': 'mypullzone.netdata.com'}]}),
|
||||||
'Mock': json.dumps(
|
'Mock': json.dumps(
|
||||||
{'id': 73242,
|
{'id': 73242,
|
||||||
'access_urls': ['mycdn.mock.com']}),
|
'access_urls': [{'operator_url': 'mycdn.mock.com'}]}),
|
||||||
'CloudFront': json.dumps(
|
'CloudFront': json.dumps(
|
||||||
{'id': '5ABC892',
|
{'id': '5ABC892',
|
||||||
'access_urls': ['cf123.cloudcf.com']}),
|
'access_urls': [{'operator_url': 'cf123.cloudcf.com'}]}),
|
||||||
'Fastly': json.dumps(
|
'Fastly': json.dumps(
|
||||||
{'id': 3488,
|
{'id': 3488,
|
||||||
'access_urls': ['mockcf123.fastly.prod.com']})}
|
'access_urls':
|
||||||
|
[{'operator_url': 'mockcf123.fastly.prod.com'}]})}
|
||||||
|
|
||||||
services = [{'name': 'mockdb1_service_name',
|
services = [{'name': 'mockdb1_service_name',
|
||||||
'domains': [json.dumps({'domain': 'www.mywebsite.com'})],
|
'domains': [json.dumps({'domain': 'www.mywebsite.com'})],
|
||||||
|
@ -88,16 +89,17 @@ class ServicesController(base.ServicesController):
|
||||||
provider_details = {
|
provider_details = {
|
||||||
'MaxCDN': json.dumps(
|
'MaxCDN': json.dumps(
|
||||||
{'id': 11942,
|
{'id': 11942,
|
||||||
'access_urls': ['mypullzone.netdata.com']}),
|
'access_urls': [{'operator_url': 'mypullzone.netdata.com'}]}),
|
||||||
'Mock': json.dumps(
|
'Mock': json.dumps(
|
||||||
{'id': 73242,
|
{'id': 73242,
|
||||||
'access_urls': ['mycdn.mock.com']}),
|
'access_urls': [{'operator_url': 'mycdn.mock.com'}]}),
|
||||||
'CloudFront': json.dumps(
|
'CloudFront': json.dumps(
|
||||||
{'id': '5ABC892',
|
{'id': '5ABC892',
|
||||||
'access_urls': ['cf123.cloudcf.com']}),
|
'access_urls': [{'operator_url': 'cf123.cloudcf.com'}]}),
|
||||||
'Fastly': json.dumps(
|
'Fastly': json.dumps(
|
||||||
{'id': 3488,
|
{'id': 3488,
|
||||||
'access_urls': ['mockcf123.fastly.prod.com']})}
|
'access_urls':
|
||||||
|
[{'operator_url': 'mockcf123.fastly.prod.com'}]})}
|
||||||
|
|
||||||
service_dict = {'name': service_name,
|
service_dict = {'name': service_name,
|
||||||
'domains': [domain_json],
|
'domains': [domain_json],
|
||||||
|
|
|
@ -49,10 +49,10 @@ class Model(collections.OrderedDict):
|
||||||
request.host_url,
|
request.host_url,
|
||||||
self['name']))),
|
self['name']))),
|
||||||
'self')]
|
'self')]
|
||||||
|
|
||||||
for provider_name in service_obj.provider_details:
|
for provider_name in service_obj.provider_details:
|
||||||
for access_url in (
|
provider_detail = service_obj.provider_details[provider_name]
|
||||||
service_obj.provider_details[provider_name].access_urls):
|
access_urls = provider_detail.access_urls
|
||||||
|
for access_url in access_urls:
|
||||||
self["links"].append(link.Model(
|
self["links"].append(link.Model(
|
||||||
access_url,
|
access_url['operator_url'],
|
||||||
'access_url'))
|
'access_url'))
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
pyrax
|
|
@ -1,8 +1,9 @@
|
||||||
[drivers]
|
[drivers]
|
||||||
providers = mock,cloudfront,fastly
|
providers = mock,maxcdn,cloudfront,fastly
|
||||||
transport = pecan
|
transport = pecan
|
||||||
manager = default
|
manager = default
|
||||||
storage = mockdb
|
storage = mockdb
|
||||||
|
dns = default
|
||||||
|
|
||||||
[drivers:storage:cassandra]
|
[drivers:storage:cassandra]
|
||||||
cluster = "192.168.59.103"
|
cluster = "192.168.59.103"
|
||||||
|
|
Loading…
Reference in New Issue