summaryrefslogtreecommitdiff
path: root/designate
diff options
context:
space:
mode:
Diffstat (limited to 'designate')
-rw-r--r--designate/api/v2/controllers/rest.py5
-rw-r--r--designate/backend/agent.py6
-rw-r--r--designate/backend/base.py11
-rw-r--r--designate/central/service.py47
-rw-r--r--designate/cmd/pool_manager.py61
-rw-r--r--designate/cmd/producer.py8
-rw-r--r--designate/cmd/worker.py8
-rw-r--r--designate/cmd/zone_manager.py61
-rw-r--r--designate/common/memorycache.py84
-rw-r--r--designate/conf/__init__.py2
-rw-r--r--designate/conf/base.py4
-rw-r--r--designate/conf/pool_manager.py112
-rw-r--r--designate/conf/producer.py31
-rw-r--r--designate/conf/worker.py9
-rw-r--r--designate/coordination.py83
-rw-r--r--designate/exceptions.py8
-rw-r--r--designate/manage/database.py18
-rw-r--r--designate/manage/pool.py30
-rw-r--r--designate/manage/pool_manager_cache.py66
-rw-r--r--designate/mdns/base.py5
-rw-r--r--designate/mdns/notify.py22
-rw-r--r--designate/mdns/rpcapi.py2
-rw-r--r--designate/objects/__init__.py1
-rw-r--r--designate/objects/pool.py66
-rw-r--r--designate/objects/pool_manager_status.py43
-rw-r--r--designate/pool_manager/__init__.py71
-rw-r--r--designate/pool_manager/cache/__init__.py27
-rw-r--r--designate/pool_manager/cache/base.py63
-rw-r--r--designate/pool_manager/cache/impl_memcache/__init__.py115
-rw-r--r--designate/pool_manager/cache/impl_noop/__init__.py36
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/__init__.py69
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/README4
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/__init__.py0
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/manage.py23
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/migrate.cfg25
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/001_add_pool_manager_status.py76
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/002_rename_server_to_nameserver.py33
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/003_placeholder.py30
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/004_placeholder.py30
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/005_placeholder.py30
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/006_placeholder.py30
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/007_placeholder.py30
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/008_domain_to_zone_rename.py34
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/__init__.py0
-rw-r--r--designate/pool_manager/cache/impl_sqlalchemy/tables.py50
-rw-r--r--designate/pool_manager/rpcapi.py114
-rw-r--r--designate/pool_manager/service.py976
-rw-r--r--designate/producer/service.py15
-rw-r--r--designate/producer/tasks.py14
-rw-r--r--designate/tests/__init__.py32
-rw-r--r--designate/tests/test_coordination.py108
-rw-r--r--designate/tests/test_pool_manager/__init__.py65
-rw-r--r--designate/tests/test_pool_manager/cache/__init__.py53
-rw-r--r--designate/tests/test_pool_manager/cache/test_memcache.py66
-rw-r--r--designate/tests/test_pool_manager/cache/test_noop.py37
-rw-r--r--designate/tests/test_pool_manager/cache/test_sqlalchemy.py39
-rw-r--r--designate/tests/test_pool_manager/test_rpcapi.py104
-rw-r--r--designate/tests/test_pool_manager/test_service.py480
-rw-r--r--designate/tests/unit/backend/test_agent.py8
-rw-r--r--designate/tests/unit/mdns/test_notify.py19
-rw-r--r--designate/tests/unit/pool_manager/__init__.py0
-rw-r--r--designate/tests/unit/pool_manager/test_service.py326
-rw-r--r--designate/tests/unit/producer/test_service.py5
-rw-r--r--designate/tests/unit/test_central/test_basic.py210
-rw-r--r--designate/tests/unit/test_pool.py112
65 files changed, 62 insertions, 4290 deletions
diff --git a/designate/api/v2/controllers/rest.py b/designate/api/v2/controllers/rest.py
index e23ac31b..e6de3593 100644
--- a/designate/api/v2/controllers/rest.py
+++ b/designate/api/v2/controllers/rest.py
@@ -32,7 +32,6 @@ import pecan.routing
from designate import exceptions
from designate.central import rpcapi as central_rpcapi
-from designate.pool_manager import rpcapi as pool_mgr_rpcapi
class RestController(pecan.rest.RestController):
@@ -50,10 +49,6 @@ class RestController(pecan.rest.RestController):
def central_api(self):
return central_rpcapi.CentralAPI.get_instance()
- @property
- def pool_mgr_api(self):
- return pool_mgr_rpcapi.PoolManagerAPI.get_instance()
-
def _apply_filter_params(self, params, accepted_filters, criterion):
invalid = []
for k in params:
diff --git a/designate/backend/agent.py b/designate/backend/agent.py
index 9005d5de..72f6ce97 100644
--- a/designate/backend/agent.py
+++ b/designate/backend/agent.py
@@ -57,9 +57,9 @@ class AgentPoolBackend(base.Backend):
super(AgentPoolBackend, self).__init__(target)
self.host = self.options.get('host', '127.0.0.1')
self.port = int(self.options.get('port', DEFAULT_AGENT_PORT))
- self.timeout = CONF['service:pool_manager'].poll_timeout
- self.retry_interval = CONF['service:pool_manager'].poll_retry_interval
- self.max_retries = CONF['service:pool_manager'].poll_max_retries
+ self.timeout = CONF['service:worker'].poll_timeout
+ self.retry_interval = CONF['service:worker'].poll_retry_interval
+ self.max_retries = CONF['service:worker'].poll_max_retries
# FIXME: the agent retries creating zones without any interval
diff --git a/designate/backend/base.py b/designate/backend/base.py
index d64687ea..263501ec 100644
--- a/designate/backend/base.py
+++ b/designate/backend/base.py
@@ -25,9 +25,6 @@ from designate.mdns import rpcapi as mdns_api
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
-CONF.import_opt('pool_id', 'designate.pool_manager',
- group='service:pool_manager')
-
class Backend(DriverPlugin):
"""Base class for backend implementations"""
@@ -50,10 +47,10 @@ class Backend(DriverPlugin):
self.admin_context.all_tenants = True
# Options for sending NOTIFYs
- self.timeout = CONF['service:pool_manager'].poll_timeout
- self.retry_interval = CONF['service:pool_manager'].poll_retry_interval
- self.max_retries = CONF['service:pool_manager'].poll_max_retries
- self.delay = CONF['service:pool_manager'].poll_delay
+ self.timeout = CONF['service:worker'].poll_timeout
+ self.retry_interval = CONF['service:worker'].poll_retry_interval
+ self.max_retries = CONF['service:worker'].poll_max_retries
+ self.delay = CONF['service:worker'].poll_delay
def start(self):
LOG.info('Starting %s backend', self.get_canonical_name())
diff --git a/designate/central/service.py b/designate/central/service.py
index 3843de88..2652ec89 100644
--- a/designate/central/service.py
+++ b/designate/central/service.py
@@ -49,7 +49,6 @@ from designate import scheduler
from designate import storage
from designate import utils
from designate.mdns import rpcapi as mdns_rpcapi
-from designate.pool_manager import rpcapi as pool_manager_rpcapi
from designate.storage import transaction
from designate.worker import rpcapi as worker_rpcapi
@@ -243,19 +242,12 @@ class Service(service.RPCService):
return mdns_rpcapi.MdnsAPI.get_instance()
@property
- def pool_manager_api(self):
- return pool_manager_rpcapi.PoolManagerAPI.get_instance()
-
- @property
def worker_api(self):
return worker_rpcapi.WorkerAPI.get_instance()
@property
def zone_api(self):
- # TODO(timsim): Remove this when pool_manager_api is gone
- if cfg.CONF['service:worker'].enabled:
- return self.worker_api
- return self.pool_manager_api
+ return self.worker_api
def _is_valid_zone_name(self, context, zone_name):
# Validate zone name length
@@ -1794,7 +1786,7 @@ class Service(service.RPCService):
# Diagnostics Methods
def _sync_zone(self, context, zone):
- return self.pool_manager_api.update_zone(context, zone)
+ return self.zone_api.update_zone(context, zone)
@rpc.expected_exceptions()
@transaction
@@ -2875,40 +2867,9 @@ class Service(service.RPCService):
created_zone_export = self.storage.create_zone_export(context,
zone_export)
- if not cfg.CONF['service:worker'].enabled:
- # So that we can maintain asynch behavior during the time that this
- # lives in central, we'll return the 'PENDING' object, and then the
- # 'COMPLETE'/'ERROR' status will be available on the first poll.
- export = copy.deepcopy(created_zone_export)
- synchronous = cfg.CONF['service:zone_manager'].export_synchronous
- criterion = {'zone_id': zone_id}
- count = self.storage.count_recordsets(context, criterion)
-
- if synchronous:
- try:
- self.quota.limit_check(
- context, context.project_id, api_export_size=count)
- except exceptions.OverQuota:
- LOG.debug('Zone Export too large to perform synchronously')
- export.status = 'ERROR'
- export.message = 'Zone is too large to export'
- return export
-
- export.location = \
- "designate://v2/zones/tasks/exports/%(eid)s/export" % \
- {'eid': export.id}
-
- export.status = 'COMPLETE'
- else:
- LOG.debug('No method found to export zone')
- export.status = 'ERROR'
- export.message = 'No suitable method for export'
-
- self.update_zone_export(context, export)
- else:
- export = copy.deepcopy(created_zone_export)
- self.worker_api.start_zone_export(context, zone, export)
+ export = copy.deepcopy(created_zone_export)
+ self.worker_api.start_zone_export(context, zone, export)
return created_zone_export
diff --git a/designate/cmd/pool_manager.py b/designate/cmd/pool_manager.py
deleted file mode 100644
index 013af497..00000000
--- a/designate/cmd/pool_manager.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 sys
-
-from oslo_log import log as logging
-from oslo_reports import guru_meditation_report as gmr
-import debtcollector
-
-import designate.conf
-from designate import service
-from designate import utils
-from designate import version
-from designate import hookpoints
-from designate.pool_manager import service as pool_manager_service
-
-LOG = logging.getLogger(__name__)
-CONF = designate.conf.CONF
-CONF.import_opt('workers', 'designate.pool_manager',
- group='service:pool_manager')
-
-
-def main():
- utils.read_config('designate', sys.argv)
-
- logging.setup(CONF, 'designate')
- gmr.TextGuruMeditation.setup_autorun(version)
-
- # NOTE(timsim): This is to ensure people don't start the wrong
- # services when the worker model is enabled.
- if CONF['service:worker'].enabled:
- LOG.error('You have designate-worker enabled, starting '
- 'designate-pool-manager is incompatible with '
- 'designate-worker. You need to start '
- 'designate-worker instead.')
- sys.exit(1)
-
- debtcollector.deprecate('designate-pool-manager is deprecated in favor of '
- 'designate-worker', version='newton',
- removal_version='rocky')
-
- server = pool_manager_service.Service()
- heartbeat = service.Heartbeat(server.service_name, server.tg)
-
- hookpoints.log_hook_setup()
-
- service.serve(server, workers=CONF['service:pool_manager'].workers)
- heartbeat.start()
- service.wait()
diff --git a/designate/cmd/producer.py b/designate/cmd/producer.py
index bd7bbe2b..4bf18732 100644
--- a/designate/cmd/producer.py
+++ b/designate/cmd/producer.py
@@ -35,14 +35,6 @@ def main():
logging.setup(CONF, 'designate')
gmr.TextGuruMeditation.setup_autorun(version)
- # NOTE(timsim): This is to ensure people don't start the wrong
- # services when the worker model is enabled.
- if not CONF['service:worker'].enabled:
- LOG.error('You do not have designate-worker enabled, starting '
- 'designate-producer is not allowed. '
- 'You need to start designate-zone-manager instead.')
- sys.exit(1)
-
hookpoints.log_hook_setup()
server = producer_service.Service()
diff --git a/designate/cmd/worker.py b/designate/cmd/worker.py
index 0560a946..e0046ac2 100644
--- a/designate/cmd/worker.py
+++ b/designate/cmd/worker.py
@@ -35,14 +35,6 @@ def main():
logging.setup(CONF, 'designate')
gmr.TextGuruMeditation.setup_autorun(version)
- # NOTE(timsim): This is to ensure people don't start the wrong
- # services when the worker model is enabled.
- if not CONF['service:worker'].enabled:
- LOG.error('You do not have designate-worker enabled, starting '
- 'designate-worker is not allowed. '
- 'You need to start designate-pool-manager instead.')
- sys.exit(1)
-
hookpoints.log_hook_setup()
server = worker_service.Service()
diff --git a/designate/cmd/zone_manager.py b/designate/cmd/zone_manager.py
deleted file mode 100644
index d09433e4..00000000
--- a/designate/cmd/zone_manager.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2015 Hewlett-Packard Development Company, L.P.
-#
-# Author: Endre Karlson <endre.karlson@hpe.com>
-#
-# 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 sys
-
-from oslo_log import log as logging
-from oslo_reports import guru_meditation_report as gmr
-import debtcollector
-
-import designate.conf
-from designate import service
-from designate import utils
-from designate import version
-from designate.producer import service as producer_service
-
-
-LOG = logging.getLogger(__name__)
-CONF = designate.conf.CONF
-CONF.import_opt('workers', 'designate.producer',
- group='service:zone_manager')
-
-
-def main():
- utils.read_config('designate', sys.argv)
- logging.setup(CONF, 'designate')
- gmr.TextGuruMeditation.setup_autorun(version)
-
- # NOTE(timsim): This is to ensure people don't start the wrong
- # services when the worker model is enabled.
-
- if CONF['service:worker'].enabled:
- LOG.error('You have designate-worker enabled, starting '
- 'designate-zone-manager is incompatible with '
- 'designate-worker. You need to start '
- 'designate-producer instead.')
- sys.exit(1)
-
- debtcollector.deprecate('designate-zone-manager Is deprecated in '
- 'favor of the designate-producer',
- version='newton',
- removal_version='rocky')
-
- LOG.warning('Starting designate-producer under the zone-manager name')
-
- server = producer_service.Service()
- heartbeat = service.Heartbeat(server.service_name, server.tg)
- service.serve(server, workers=CONF['service:zone_manager'].workers)
- heartbeat.start()
- service.wait()
diff --git a/designate/common/memorycache.py b/designate/common/memorycache.py
deleted file mode 100644
index 2b0a9714..00000000
--- a/designate/common/memorycache.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# 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.
-
-"""Super simple fake memcache client."""
-
-from oslo_config import cfg
-from oslo_utils import timeutils
-
-CONF = cfg.CONF
-
-
-def get_client(memcached_servers=None):
- client_cls = Client
-
- if not memcached_servers:
- memcached_servers = CONF.memcached_servers
- if memcached_servers:
- import memcache
- client_cls = memcache.Client
-
- return client_cls(memcached_servers, debug=0)
-
-
-class Client(object):
- """Replicates a tiny subset of memcached client interface."""
-
- def __init__(self, *args, **kwargs):
- """Ignores the passed in args."""
- self.cache = {}
-
- def get(self, key):
- """Retrieves the value for a key or None.
-
- This expunges expired keys during each get.
- """
-
- now = timeutils.utcnow_ts()
- for k in list(self.cache):
- (timeout, _value) = self.cache[k]
- if timeout and now >= timeout:
- del self.cache[k]
-
- return self.cache.get(key, (0, None))[1]
-
- def set(self, key, value, time=0, min_compress_len=0):
- """Sets the value for a key."""
- timeout = 0
- if time != 0:
- timeout = timeutils.utcnow_ts() + time
- self.cache[key] = (timeout, value)
- return True
-
- def add(self, key, value, time=0, min_compress_len=0):
- """Sets the value for a key if it doesn't exist."""
- if self.get(key) is not None:
- return False
- return self.set(key, value, time, min_compress_len)
-
- def incr(self, key, delta=1):
- """Increments the value for a key."""
- value = self.get(key)
- if value is None:
- return None
- new_value = int(value) + delta
- self.cache[key] = (self.cache[key][0], str(new_value))
- return new_value
-
- def delete(self, key, time=0):
- """Deletes the value associated with a key."""
- if key in self.cache:
- del self.cache[key]
diff --git a/designate/conf/__init__.py b/designate/conf/__init__.py
index 5c402980..508d60b7 100644
--- a/designate/conf/__init__.py
+++ b/designate/conf/__init__.py
@@ -31,7 +31,6 @@ from designate.conf import mdns
from designate.conf import metrics
from designate.conf import msdns
from designate.conf import network_api
-from designate.conf import pool_manager
from designate.conf import producer
from designate.conf import proxy
from designate.conf import service_status
@@ -59,7 +58,6 @@ mdns.register_opts(CONF)
metrics.register_opts(CONF)
msdns.register_opts(CONF)
network_api.register_opts(CONF)
-pool_manager.register_opts(CONF)
producer.register_opts(CONF)
proxy.register_opts(CONF)
service_status.register_opts(CONF)
diff --git a/designate/conf/base.py b/designate/conf/base.py
index fee84dfe..d0a2f43e 100644
--- a/designate/conf/base.py
+++ b/designate/conf/base.py
@@ -70,10 +70,6 @@ DESIGNATE_OPTS = [
default='sudo designate-rootwrap /etc/designate/rootwrap.conf',
help='designate-rootwrap configuration'),
- # Memcached
- cfg.ListOpt('memcached_servers',
- help='Memcached servers or None for in process cache.'),
-
cfg.StrOpt('network_api', default='neutron', help='Which API to use.'),
# Notifications
diff --git a/designate/conf/pool_manager.py b/designate/conf/pool_manager.py
deleted file mode 100644
index 8feb564a..00000000
--- a/designate/conf/pool_manager.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 oslo_config import cfg
-from oslo_db import options
-
-POOL_MANAGER_GROUP = cfg.OptGroup(
- name='service:pool_manager',
- title="Configuration for Pool Manager Service"
-)
-
-POOL_MANAGER_SQLALCHEMY_GROUP = cfg.OptGroup(
- name='pool_manager_cache:sqlalchemy',
- title="Configuration for SQLAlchemy Pool Manager Cache"
-)
-
-POOL_MANAGER_MEMCACHE_GROUP = cfg.OptGroup(
- name='pool_manager_cache:memcache',
- title="Configuration for memcache Pool Manager Cache"
-)
-
-POOL_MANAGER_OPTS = [
- cfg.IntOpt('workers',
- help='Number of Pool Manager worker processes to spawn'),
- cfg.IntOpt('threads', default=1000,
- help='Number of Pool Manager greenthreads to spawn'),
- cfg.StrOpt('pool_id', default='794ccc2c-d751-44fe-b57f-8894c9f5c842',
- help='The ID of the pool managed by this instance of the '
- 'Pool Manager'),
- cfg.IntOpt('threshold_percentage', default=100,
- help='The percentage of servers requiring a successful update '
- 'for a zone change to be considered active',
- deprecated_for_removal=True,
- deprecated_reason='Migrated to designate-worker'),
- cfg.IntOpt('poll_timeout', default=30,
- help='The time to wait for a response from a server',
- deprecated_for_removal=True,
- deprecated_reason='Migrated to designate-worker'),
- cfg.IntOpt('poll_retry_interval', default=15,
- help='The time between retrying to send a request and '
- 'waiting for a response from a server',
- deprecated_for_removal=True,
- deprecated_reason='Migrated to designate-worker'),
- cfg.IntOpt('poll_max_retries', default=10,
- help='The maximum number of times to retry sending a request '
- 'and wait for a response from a server',
- deprecated_for_removal=True,
- deprecated_reason='Migrated to designate-worker'),
- cfg.IntOpt('poll_delay', default=5,
- help='The time to wait before sending the first request '
- 'to a server',
- deprecated_for_removal=True,
- deprecated_reason='Migrated to designate-worker'),
- cfg.BoolOpt('enable_recovery_timer', default=True,
- help='The flag for the recovery timer'),
- cfg.IntOpt('periodic_recovery_interval', default=120,
- help='The time between recovering from failures'),
- cfg.BoolOpt('enable_sync_timer', default=True,
- help='The flag for the sync timer'),
- cfg.IntOpt('periodic_sync_interval', default=1800,
- help='The time between synchronizing the servers with storage'),
- cfg.IntOpt('periodic_sync_seconds', default=21600,
- help='Zones Updated within last N seconds will be syncd.'
- 'Use an empty value to sync all zones.'),
- cfg.IntOpt('periodic_sync_max_attempts', default=3,
- help='Number of attempts to update a zone during sync'),
- cfg.IntOpt('periodic_sync_retry_interval', default=30,
- help='Interval between zone update attempts during sync'),
- cfg.StrOpt('cache_driver', default='memcache',
- help='The cache driver to use'),
- cfg.StrOpt('topic', default='pool_manager',
- help='RPC topic name for pool-manager'),
-]
-
-POOL_MANAGER_MEMCACHE_OPTS = [
- cfg.ListOpt('memcached_servers',
- help='Memcached servers or None for in process cache.'),
- cfg.IntOpt('expiration', default=3600,
- help='Time in seconds to expire cache.'),
-]
-
-
-def register_opts(conf):
- conf.register_group(POOL_MANAGER_GROUP)
- conf.register_opts(POOL_MANAGER_OPTS,
- group=POOL_MANAGER_GROUP)
- conf.register_group(POOL_MANAGER_SQLALCHEMY_GROUP)
- conf.register_opts(options.database_opts,
- group=POOL_MANAGER_SQLALCHEMY_GROUP)
- conf.register_group(POOL_MANAGER_MEMCACHE_GROUP)
- conf.register_opts(POOL_MANAGER_MEMCACHE_OPTS,
- group=POOL_MANAGER_MEMCACHE_GROUP)
-
-
-def list_opts():
- return {
- POOL_MANAGER_GROUP: POOL_MANAGER_OPTS,
- POOL_MANAGER_MEMCACHE_GROUP: POOL_MANAGER_MEMCACHE_OPTS,
- POOL_MANAGER_SQLALCHEMY_GROUP: options.database_opts,
- }
diff --git a/designate/conf/producer.py b/designate/conf/producer.py
index 93258482..44f5ec7d 100644
--- a/designate/conf/producer.py
+++ b/designate/conf/producer.py
@@ -20,11 +20,6 @@ PRODUCER_GROUP = cfg.OptGroup(
title='Configuration for Producer Service'
)
-ZONE_MANAGER_GROUP = cfg.OptGroup(
- name='service:zone_manager',
- title='Configuration for Zone Manager Service'
-)
-
PRODUCER_TASK_DELAYED_NOTIFY_GROUP = cfg.OptGroup(
name='producer_task:delayed_notify',
title='Configuration for Producer Task: Delayed Notify'
@@ -67,29 +62,6 @@ PRODUCER_OPTS = [
help='RPC topic name for producer'),
]
-ZONE_MANAGER_OPTS = [
- cfg.IntOpt('workers',
- help='Number of Zone Manager worker processes to spawn',
- deprecated_for_removal=True,
- deprecated_reason='Migrated to designate-worker'),
- cfg.IntOpt('threads', default=1000,
- help='Number of Zone Manager greenthreads to spawn',
- deprecated_for_removal=True,
- deprecated_reason='Migrated to designate-worker'),
- cfg.ListOpt('enabled_tasks',
- help='Enabled tasks to run',
- deprecated_for_removal=True,
- deprecated_reason='Migrated to designate-worker'),
- cfg.StrOpt('storage_driver', default='sqlalchemy',
- help='The storage driver to use',
- deprecated_for_removal=True,
- deprecated_reason='Migrated to designate-worker'),
- cfg.BoolOpt('export_synchronous', default=True,
- help='Whether to allow synchronous zone exports',
- deprecated_for_removal=True,
- deprecated_reason='Migrated to designate-worker'),
-]
-
PRODUCER_TASK_DELAYED_NOTIFY_OPTS = [
cfg.IntOpt('interval', default=5,
help='Run interval in seconds'),
@@ -136,8 +108,6 @@ PRODUCER_TASK_ZONE_PURGE_OPTS = [
def register_opts(conf):
conf.register_group(PRODUCER_GROUP)
conf.register_opts(PRODUCER_OPTS, group=PRODUCER_GROUP)
- conf.register_group(ZONE_MANAGER_GROUP)
- conf.register_opts(ZONE_MANAGER_OPTS, group=ZONE_MANAGER_GROUP)
conf.register_group(PRODUCER_TASK_DELAYED_NOTIFY_GROUP)
conf.register_opts(PRODUCER_TASK_DELAYED_NOTIFY_OPTS,
group=PRODUCER_TASK_DELAYED_NOTIFY_GROUP)
@@ -158,7 +128,6 @@ def register_opts(conf):
def list_opts():
return {
PRODUCER_GROUP: PRODUCER_OPTS,
- ZONE_MANAGER_GROUP: ZONE_MANAGER_OPTS,
PRODUCER_TASK_DELAYED_NOTIFY_GROUP:
PRODUCER_TASK_DELAYED_NOTIFY_OPTS,
PRODUCER_TASK_PERIODIC_EXISTS_GROUP:
diff --git a/designate/conf/worker.py b/designate/conf/worker.py
index 8004bfd6..df6af371 100644
--- a/designate/conf/worker.py
+++ b/designate/conf/worker.py
@@ -20,12 +20,6 @@ WORKER_GROUP = cfg.OptGroup(
)
WORKER_OPTS = [
- cfg.BoolOpt('enabled', default=True,
- help='Whether to send events to worker instead of '
- 'Pool Manager',
- deprecated_for_removal=True,
- deprecated_reason='In Train, this option will disappear'
- 'because pool manager will be removed'),
cfg.IntOpt('workers',
help='Number of Worker worker processes to spawn'),
cfg.IntOpt('threads', default=200,
@@ -49,6 +43,9 @@ WORKER_OPTS = [
help='The time to wait before sending the first request '
'to a server'),
cfg.BoolOpt('notify', default=True,
+ deprecated_for_removal=True,
+ deprecated_reason='This option is being removed to reduce '
+ 'complexity',
help='Whether to allow worker to send NOTIFYs, this will '
'noop NOTIFYs in mdns if true'),
cfg.BoolOpt('export_synchronous', default=True,
diff --git a/designate/coordination.py b/designate/coordination.py
index bbc1556f..f39cc322 100644
--- a/designate/coordination.py
+++ b/designate/coordination.py
@@ -218,86 +218,3 @@ class Partitioner(object):
def unwatch_partition_change(self, callback):
self._callbacks.remove(callback)
-
-
-class LeaderElection(object):
- def __init__(self, coordinator, group_id):
- self._coordinator = coordinator
- self._group_id = group_id
-
- self._callbacks = []
- self._started = False
- self._leader = False
-
- def _warn_no_backend(self):
- LOG.warning('No coordination backend configured, assuming we are the '
- 'leader. Please configure a coordination backend')
-
- def start(self):
- self._started = True
-
- if self._coordinator:
- LOG.info('Starting leader election for group %(group)s',
- {'group': self._group_id})
-
- # Nominate myself for election
- self._coordinator.watch_elected_as_leader(
- self._group_id, self._on_elected_leader)
- else:
- self._warn_no_backend()
- self._leader = True
-
- for callback in self._callbacks:
- callback(None)
-
- def stop(self):
- self._started = False
-
- if self._coordinator:
- LOG.info('Stopping leader election for group %(group)s',
- {'group': self._group_id})
-
- # Remove the elected_as_leader callback
- self._coordinator.unwatch_elected_as_leader(
- self._group_id, self._on_elected_leader)
-
- if self._leader:
- # Tell Tooz we no longer wish to be the leader
- LOG.info('Standing down as leader candidate for group '
- '%(group)s', {'group': self._group_id})
- self._leader = False
- self._coordinator.stand_down_group_leader(self._group_id)
-
- elif self._leader:
- LOG.info('Standing down as leader candidate for group %(group)s',
- {'group': self._group_id})
- self._leader = False
-
- @property
- def is_leader(self):
- return self._leader
-
- def _on_elected_leader(self, event):
- LOG.info('Successfully elected as leader of group %(group)s',
- {'group': self._group_id})
- self._leader = True
-
- for callback in self._callbacks:
- callback(event)
-
- def watch_elected_as_leader(self, callback):
- self._callbacks.append(callback)
-
- if self._started and self._leader:
- # We're started, and we're the leader, we should trigger the
- # callback
- callback(None)
-
- elif self._started and not self._coordinator:
- # We're started, and there's no coordination backend configured,
- # we assume we're leader and call the callback.
- self._warn_no_backend()
- callback(None)
-
- def unwatch_elected_as_leader(self, callback):
- self._callbacks.remove(callback)
diff --git a/designate/exceptions.py b/designate/exceptions.py
index e5e9d7bc..aeb73954 100644
--- a/designate/exceptions.py
+++ b/designate/exceptions.py
@@ -299,10 +299,6 @@ class DuplicateBlacklist(Duplicate):
error_type = 'duplicate_blacklist'
-class DuplicatePoolManagerStatus(Duplicate):
- error_type = 'duplication_pool_manager_status'
-
-
class DuplicatePool(Duplicate):
error_type = 'duplicate_pool'
@@ -419,10 +415,6 @@ class ReportNotFound(NotFound):
error_type = 'report_not_found'
-class PoolManagerStatusNotFound(NotFound):
- error_type = 'pool_manager_status_not_found'
-
-
class PoolNotFound(NotFound):
error_type = 'pool_not_found'
diff --git a/designate/manage/database.py b/designate/manage/database.py
index a089efeb..72108abb 100644
--- a/designate/manage/database.py
+++ b/designate/manage/database.py
@@ -18,7 +18,6 @@ import os
from migrate.versioning import api as versioning_api
from oslo_config import cfg
from oslo_log import log as logging
-from oslo_db import exception
from designate.manage import base
from designate.sqlalchemy import utils
@@ -31,26 +30,13 @@ REPOSITORY = os.path.abspath(os.path.join(os.path.dirname(__file__), '..',
'migrate_repo'))
cfg.CONF.import_opt('connection', 'designate.storage.impl_sqlalchemy',
group='storage:sqlalchemy')
-cfg.CONF.import_opt('connection',
- 'designate.pool_manager.cache.impl_sqlalchemy',
- group='pool_manager_cache:sqlalchemy')
-
CONF = cfg.CONF
INIT_VERSION = 69
def get_manager():
- storage_db = CONF['storage:sqlalchemy'].connection
- pool_manager_cache_db = CONF['pool_manager_cache:sqlalchemy'].connection
- if storage_db == pool_manager_cache_db:
- raise exception.DBMigrationError(
- message=(
- "Storage requires its own database. "
- "Please check your config file."
- ))
- else:
- return utils.get_migration_manager(
- REPOSITORY, CONF['storage:sqlalchemy'].connection, INIT_VERSION)
+ return utils.get_migration_manager(
+ REPOSITORY, CONF['storage:sqlalchemy'].connection, INIT_VERSION)
class DatabaseCommands(base.Commands):
diff --git a/designate/manage/pool.py b/designate/manage/pool.py
index b478c987..40d4aab3 100644
--- a/designate/manage/pool.py
+++ b/designate/manage/pool.py
@@ -61,36 +61,6 @@ class PoolCommands(base.Commands):
default_flow_style=False
)
- @base.args('--file', help='The path to the file the yaml output should be '
- 'writen to',
- default='/etc/designate/pools.yaml')
- def export_from_config(self, file):
- self._startup()
-
- # Avoid circular dependency imports
- from designate import pool_manager
- pool_manager.register_dynamic_pool_options()
-
- try:
- pools = self.central_api.find_pools(self.context)
- except messaging.exceptions.MessagingTimeout:
- LOG.critical("No response received from designate-central. "
- "Check it is running, and retry")
- sys.exit(1)
- r_pools = objects.PoolList()
- for pool in pools:
- r_pool = objects.Pool.from_config(CONF, pool.id)
- r_pool.id = pool.id
- r_pool.ns_records = pool.ns_records
- r_pool.attributes = pool.attributes
- r_pools.append(r_pool)
- with open(file, 'w') as stream:
- yaml.dump(
- DesignateAdapter.render('YAML', r_pools),
- stream,
- default_flow_style=False
- )
-
@base.args('--pool_id', help='ID of the pool to be examined',
default=CONF['service:central'].default_pool_id)
def show_config(self, pool_id):
diff --git a/designate/manage/pool_manager_cache.py b/designate/manage/pool_manager_cache.py
deleted file mode 100644
index c0c997e8..00000000
--- a/designate/manage/pool_manager_cache.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2012 Managed I.T.
-#
-# Author: Kiall Mac Innes <kiall@managedit.ie>
-#
-# 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 os
-
-
-from migrate.versioning import api as versioning_api
-from oslo_config import cfg
-from oslo_db import exception
-
-from designate.manage import base
-from designate.sqlalchemy import utils
-
-
-REPOSITORY = os.path.abspath(os.path.join(os.path.dirname(__file__), '..',
- 'pool_manager',
- 'cache', 'impl_sqlalchemy',
- 'migrate_repo'))
-cfg.CONF.import_opt('connection',
- 'designate.pool_manager.cache.impl_sqlalchemy',
- group='pool_manager_cache:sqlalchemy')
-
-cfg.CONF.import_opt('connection',
- 'designate.storage.impl_sqlalchemy',
- group='storage:sqlalchemy')
-
-CONF = cfg.CONF
-
-
-def get_manager():
- storage_db = CONF['storage:sqlalchemy'].connection
- pool_manager_cache_db = CONF['pool_manager_cache:sqlalchemy'].connection
- if storage_db == pool_manager_cache_db:
- raise exception.DBMigrationError(
- message=(
- "Pool Manager Cache requires its own database."
- " Please check your config file."
- ))
- else:
- return utils.get_migration_manager(REPOSITORY, pool_manager_cache_db)
-
-
-class DatabaseCommands(base.Commands):
- def version(self):
- current = get_manager().version()
- latest = versioning_api.version(repository=REPOSITORY).value
- print("Current: %s Latest: %s" % (current, latest))
-
- def sync(self):
- get_manager().upgrade(None)
-
- @base.args('revision', nargs='?')
- def upgrade(self, revision):
- get_manager().upgrade(revision)
diff --git a/designate/mdns/base.py b/designate/mdns/base.py
index 86641b2a..c49440a4 100644
--- a/designate/mdns/base.py
+++ b/designate/mdns/base.py
@@ -16,7 +16,6 @@
import oslo_messaging as messaging
from oslo_log import log as logging
-from designate.pool_manager import rpcapi as pool_mngr_api
from designate.central import rpcapi as central_api
LOG = logging.getLogger(__name__)
@@ -37,7 +36,3 @@ class BaseEndpoint(object):
@property
def central_api(self):
return central_api.CentralAPI.get_instance()
-
- @property
- def pool_manager_api(self):
- return pool_mngr_api.PoolManagerAPI.get_instance()
diff --git a/designate/mdns/notify.py b/designate/mdns/notify.py
index 0de21f5c..0d66970d 100644
--- a/designate/mdns/notify.py
+++ b/designate/mdns/notify.py
@@ -72,27 +72,7 @@ class NotifyEndpoint(base.BaseEndpoint):
def poll_for_serial_number(self, context, zone, nameserver, timeout,
retry_interval, max_retries, delay):
- """Get the serial number of a zone on a resolver, then call update_status
- on Pool Manager to update the zone status.
-
- :param context: The user context.
- :param zone: The designate zone object. This contains the zone
- name. zone.serial = expected_serial
- :param nameserver: Destination for the poll
- :param timeout: The time (in seconds) to wait for a SOA response from
- nameserver.
- :param retry_interval: The time (in seconds) between retries.
- :param max_retries: The maximum number of retries mindns would do for
- an expected serial number. After this many retries, mindns returns
- an ERROR.
- :param delay: The time to wait before sending the first request.
- :return: None
- """
- status, actual_serial, retries = self.get_serial_number(
- context, zone, nameserver.host, nameserver.port, timeout,
- retry_interval, max_retries, delay)
- self.pool_manager_api.update_status(
- context, zone, nameserver, status, actual_serial)
+ return
def get_serial_number(self, context, zone, host, port, timeout,
retry_interval, max_retries, delay):
diff --git a/designate/mdns/rpcapi.py b/designate/mdns/rpcapi.py
index e3956af7..d65f7cc4 100644
--- a/designate/mdns/rpcapi.py
+++ b/designate/mdns/rpcapi.py
@@ -77,7 +77,7 @@ class MdnsAPI(object):
def notify_zone_changed(self, context, zone, host, port, timeout,
retry_interval, max_retries, delay):
- if CONF['service:worker'].notify and CONF['service:worker'].enabled:
+ if CONF['service:worker'].notify:
LOG.debug('Letting worker send NOTIFYs instead')
return True
diff --git a/designate/objects/__init__.py b/designate/objects/__init__.py
index 451231a6..07accd43 100644
--- a/designate/objects/__init__.py
+++ b/designate/objects/__init__.py
@@ -21,7 +21,6 @@ from designate.objects.zone import Zone, ZoneList # noqa
from designate.objects.zone_attribute import ZoneAttribute, ZoneAttributeList # noqa
from designate.objects.zone_master import ZoneMaster, ZoneMasterList # noqa
from designate.objects.floating_ip import FloatingIP, FloatingIPList # noqa
-from designate.objects.pool_manager_status import PoolManagerStatus, PoolManagerStatusList # noqa
from designate.objects.pool import Pool, PoolList # noqa
from designate.objects.pool_also_notify import PoolAlsoNotify, PoolAlsoNotifyList # noqa
from designate.objects.pool_attribute import PoolAttribute, PoolAttributeList # noqa
diff --git a/designate/objects/pool.py b/designate/objects/pool.py
index d9dfb089..d54ef61d 100644
--- a/designate/objects/pool.py
+++ b/designate/objects/pool.py
@@ -13,7 +13,6 @@
# 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 designate import utils
from designate.objects import base
from designate.objects import fields
@@ -35,71 +34,6 @@ class Pool(base.DictObjectMixin, base.PersistentObjectMixin,
nullable=True),
}
- @classmethod
- def from_config(cls, CONF, pool_id):
- pool_target_ids = CONF['pool:%s' % pool_id].targets
- pool_nameserver_ids = CONF['pool:%s' % pool_id].nameservers
- pool_also_notifies = CONF['pool:%s' % pool_id].also_notifies
-
- # Build Base Pool
- pool = {
- 'id': pool_id,
- 'description': 'Pool built from configuration on %s' % CONF.host,
- 'targets': [],
- 'nameservers': [],
- 'also_notifies': [],
- }
-
- # Build Pool Also Notifies
- for pool_also_notify in pool_also_notifies:
- host, port = utils.split_host_port(pool_also_notify)
- pool['also_notifies'].append({
- 'host': host,
- 'port': port,
- })
-
- # Build Pool Targets
- for pool_target_id in pool_target_ids:
- pool_target_group = 'pool_target:%s' % pool_target_id
-
- pool_target = {
- 'id': pool_target_id,
- 'type': CONF[pool_target_group].type,
- 'masters': [],
- 'options': [],
- }
-
- # Build Pool Target Masters
- for pool_target_master in CONF[pool_target_group].masters:
- host, port = utils.split_host_port(pool_target_master)
- pool_target['masters'].append({
- 'host': host,
- 'port': port,
- })
-
- # Build Pool Target Options
- for k, v in CONF[pool_target_group].options.items():
- pool_target['options'].append({
- 'key': k,
- 'value': v,
- })
-
- pool['targets'].append(pool_target)
-
- # Build Pool Nameservers
- for pool_nameserver_id in pool_nameserver_ids:
- pool_nameserver_group = 'pool_nameserver:%s' % pool_nameserver_id
-
- pool_nameserver = {
- 'id': pool_nameserver_id,
- 'host': CONF[pool_nameserver_group].host,
- 'port': CONF[pool_nameserver_group].port,
- }
-
- pool['nameservers'].append(pool_nameserver)
-
- return cls.from_dict(pool)
-
STRING_KEYS = [
'id', 'name'
]
diff --git a/designate/objects/pool_manager_status.py b/designate/objects/pool_manager_status.py
deleted file mode 100644
index f3bca78a..00000000
--- a/designate/objects/pool_manager_status.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 designate.objects import base
-from designate.objects import fields
-
-
-@base.DesignateRegistry.register
-class PoolManagerStatus(base.DictObjectMixin, base.PersistentObjectMixin,
- base.DesignateObject):
- fields = {
- 'nameserver_id': fields.UUIDFields(),
- 'zone_id': fields.UUIDFields(),
- 'status': fields.EnumField(['ACTIVE', 'PENDING', 'ERROR',
- 'SUCCESS', 'COMPLETE'], nullable=True),
- 'serial_number': fields.IntegerFields(minimum=0, maximum=4294967295),
- 'action': fields.EnumField(['CREATE', 'DELETE',
- 'UPDATE', 'NONE'], nullable=True),
- }
-
- STRING_KEYS = [
- 'id', 'action', 'status', 'server_id', 'zone_id'
- ]
-
-
-@base.DesignateRegistry.register
-class PoolManagerStatusList(base.ListObjectMixin, base.DesignateObject):
- LIST_ITEM_TYPE = PoolManagerStatus
- fields = {
- 'objects': fields.ListOfObjectsField('PoolManagerStatus'),
- }
diff --git a/designate/pool_manager/__init__.py b/designate/pool_manager/__init__.py
deleted file mode 100644
index 8d619ac8..00000000
--- a/designate/pool_manager/__init__.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 oslo_config import cfg
-
-CONF = cfg.CONF
-
-
-def register_dynamic_pool_options():
- # Pool Options Registration Pass One
-
- # Find the Current Pool ID
- pool_id = CONF['service:pool_manager'].pool_id
-
- # Build the [pool:<id>] config section
- pool_group = cfg.OptGroup('pool:%s' % pool_id)
-
- pool_opts = [
- cfg.ListOpt('targets', default=[]),
- cfg.ListOpt('nameservers', default=[]),
- cfg.ListOpt('also_notifies', default=[]),
- ]
-
- CONF.register_group(pool_group)
- CONF.register_opts(pool_opts, group=pool_group)
-
- # Pool Options Registration Pass Two
-
- # Find the Current Pools Target ID's
- pool_target_ids = CONF['pool:%s' % pool_id].targets
-
- # Build the [pool_target:<id>] config sections
- pool_target_opts = [
- cfg.StrOpt('type'),
- cfg.ListOpt('masters', default=[]),
- cfg.DictOpt('options', default={}, secret=True),
- ]
-
- for pool_target_id in pool_target_ids:
- pool_target_group = cfg.OptGroup('pool_target:%s' % pool_target_id)
-
- CONF.register_group(pool_target_group)
- CONF.register_opts(pool_target_opts, group=pool_target_group)
-
- # Find the Current Pools Nameserver ID's
- pool_nameserver_ids = CONF['pool:%s' % pool_id].nameservers
-
- # Build the [pool_nameserver:<id>] config sections
- pool_nameserver_opts = [
- cfg.StrOpt('host'),
- cfg.IntOpt('port'),
- ]
-
- for pool_nameserver_id in pool_nameserver_ids:
- pool_nameserver_group = cfg.OptGroup(
- 'pool_nameserver:%s' % pool_nameserver_id)
-
- CONF.register_group(pool_nameserver_group)
- CONF.register_opts(pool_nameserver_opts, group=pool_nameserver_group)
diff --git a/designate/pool_manager/cache/__init__.py b/designate/pool_manager/cache/__init__.py
deleted file mode 100644
index 07131a8a..00000000
--- a/designate/pool_manager/cache/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 oslo_log import log as logging
-
-from designate.pool_manager.cache import base
-
-LOG = logging.getLogger(__name__)
-
-
-def get_pool_manager_cache(cache_driver):
- """Return the engine class from the provided engine name"""
- cls = base.PoolManagerCache.get_driver(cache_driver)
-
- return cls()
diff --git a/designate/pool_manager/cache/base.py b/designate/pool_manager/cache/base.py
deleted file mode 100644
index 744e6206..00000000
--- a/designate/pool_manager/cache/base.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 abc
-
-import six
-
-from designate.plugin import DriverPlugin
-
-
-@six.add_metaclass(abc.ABCMeta)
-class PoolManagerCache(DriverPlugin):
-
- """Base class for cache plugins"""
- __plugin_ns__ = 'designate.pool_manager.cache'
- __plugin_type__ = 'pool_manager_cache'
-
- @abc.abstractmethod
- def clear(self, context, pool_manager_status):
- """
-
- Clear the pool manager status object from the cache.
-
- :param context: Security context information
- :param pool_manager_status: Pool manager status object to clear
- """
-
- @abc.abstractmethod
- def store(self, context, pool_manager_status):
- """
-
- Store the pool manager status object in the cache.
-
- :param context: Security context information
- :param pool_manager_status: Pool manager status object to store
- :return:
- """
-
- @abc.abstractmethod
- def retrieve(self, context, nameserver_id, zone_id, action):
- """
-
- Retrieve the pool manager status object.
-
- :param context: Security context information
- :param nameserver_id: the nameserver ID of the pool manager status
- object
- :param zone_id: the zone ID of the pool manger status object
- :param action: the action of the pool manager status object
- :return: the pool manager status object
- """
diff --git a/designate/pool_manager/cache/impl_memcache/__init__.py b/designate/pool_manager/cache/impl_memcache/__init__.py
deleted file mode 100644
index 925c20c6..00000000
--- a/designate/pool_manager/cache/impl_memcache/__init__.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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.
-
-"""
- impl_memcache.__init__
- ~~~~~~~~~~~~~~~~~~~~~~
- Memcache interface
- Docs: doc/source/memory-caching.rst
-"""""""""
-
-import six
-from oslo_config import cfg
-
-from designate import exceptions
-from designate import objects
-from designate.common import memorycache
-from designate.pool_manager.cache import base as cache_base
-
-CONF = cfg.CONF
-DEFAULT_STATUS = 'NONE'
-
-
-class MemcachePoolManagerCache(cache_base.PoolManagerCache):
- __plugin_name__ = 'memcache'
-
- def __init__(self):
- super(MemcachePoolManagerCache, self).__init__()
-
- self.cache = memorycache.get_client(
- CONF['pool_manager_cache:memcache'].memcached_servers)
- self.expiration = CONF['pool_manager_cache:memcache'].expiration
-
- def get_name(self):
- return self.name
-
- def clear(self, context, pool_manager_status):
- status_key = self._build_status_key(pool_manager_status)
- self.cache.delete(status_key)
-
- serial_number_key = self._build_serial_number_key(pool_manager_status)
- self.cache.delete(serial_number_key)
-
- def store(self, context, pool_manager_status):
- status_key = self._build_status_key(pool_manager_status)
-
- # TODO(vinod): memcache does not seem to store None as the values
- # Investigate if we can do a different default value for status
- if pool_manager_status.status:
- self.cache.set(
- status_key, pool_manager_status.status, self.expiration)
- else:
- self.cache.set(status_key, DEFAULT_STATUS, self.expiration)
-
- serial_number_key = self._build_serial_number_key(pool_manager_status)
- self.cache.set(
- serial_number_key, pool_manager_status.serial_number,
- self.expiration)
-
- def retrieve(self, context, nameserver_id, zone_id, action):
- values = {
- 'nameserver_id': nameserver_id,
- 'zone_id': zone_id,
- 'action': action,
- }
- pool_manager_status = objects.PoolManagerStatus(**values)
-
- status_key = self._build_status_key(pool_manager_status)
- status = self.cache.get(status_key)
- if status is None:
- raise exceptions.PoolManagerStatusNotFound
-
- serial_number_key = self._build_serial_number_key(pool_manager_status)
- serial_number = self.cache.get(serial_number_key)
- if serial_number is None:
- raise exceptions.PoolManagerStatusNotFound
-
- pool_manager_status.serial_number = serial_number
- if status == DEFAULT_STATUS:
- pool_manager_status.status = None
- else:
- pool_manager_status.status = status
-
- return pool_manager_status
-
- @staticmethod
- def _status_key(pool_manager_status, tail):
- key = '{nameserver}-{zone}-{action}-{tail}'.format(
- nameserver=pool_manager_status.nameserver_id,
- zone=pool_manager_status.zone_id,
- action=pool_manager_status.action,
- tail=tail
- )
- if six.PY2:
- return key.encode('utf-8')
- else:
- return key
-
- def _build_serial_number_key(self, pool_manager_status):
- return self._status_key(pool_manager_status, 'serial_number')
-
- def _build_status_key(self, pool_manager_status):
- return self._status_key(pool_manager_status, 'status')
diff --git a/designate/pool_manager/cache/impl_noop/__init__.py b/designate/pool_manager/cache/impl_noop/__init__.py
deleted file mode 100644
index f640b544..00000000
--- a/designate/pool_manager/cache/impl_noop/__init__.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 designate import exceptions
-from designate.pool_manager.cache import base as cache_base
-
-
-class NoopPoolManagerCache(cache_base.PoolManagerCache):
- __plugin_name__ = 'noop'
-
- def __init__(self):
- super(NoopPoolManagerCache, self).__init__()
-
- def get_name(self):
- return self.name
-
- def clear(self, context, pool_manager_status):
- pass
-
- def store(self, context, pool_manager_status):
- pass
-
- def retrieve(self, context, nameserver_id, zone_id, action):
- raise exceptions.PoolManagerStatusNotFound
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/__init__.py b/designate/pool_manager/cache/impl_sqlalchemy/__init__.py
deleted file mode 100644
index 349e4af7..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/__init__.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 oslo_config import cfg
-from oslo_log import log as logging
-
-from designate import exceptions
-from designate import objects
-from designate.pool_manager.cache import base as cache_base
-from designate.sqlalchemy import base as sqlalchemy_base
-from designate.pool_manager.cache.impl_sqlalchemy import tables
-
-CONF = cfg.CONF
-LOG = logging.getLogger(__name__)
-
-
-class SQLAlchemyPoolManagerCache(sqlalchemy_base.SQLAlchemy,
- cache_base.PoolManagerCache):
- __plugin_name__ = 'sqlalchemy'
-
- def __init__(self):
- super(SQLAlchemyPoolManagerCache, self).__init__()
-
- def get_name(self):
- return self.name
-
- def clear(self, context, pool_manager_status):
- # If there is no id retrieve the relevant pool manager status
- if not pool_manager_status.id:
- pool_manager_status = self.retrieve(
- context, pool_manager_status.nameserver_id,
- pool_manager_status.zone_id, pool_manager_status.action)
- self._delete(
- context, tables.pool_manager_statuses, pool_manager_status,
- exceptions.PoolManagerStatusNotFound)
-
- def store(self, context, pool_manager_status):
- if pool_manager_status.id:
- self._update(
- context, tables.pool_manager_statuses, pool_manager_status,
- exceptions.DuplicatePoolManagerStatus,
- exceptions.PoolManagerStatusNotFound)
- else:
- self._create(
- tables.pool_manager_statuses, pool_manager_status,
- exceptions.DuplicatePoolManagerStatus)
-
- def retrieve(self, context, nameserver_id, zone_id, action):
- criterion = {
- 'nameserver_id': nameserver_id,
- 'zone_id': zone_id,
- 'action': action
- }
- return self._find(
- context, tables.pool_manager_statuses, objects.PoolManagerStatus,
- objects.PoolManagerStatusList,
- exceptions.PoolManagerStatusNotFound, criterion, one=True)
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/README b/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/README
deleted file mode 100644
index 2f979fcb..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/README
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a database migration repository for the project Designate.
-
-More information at
-http://code.google.com/p/sqlalchemy-migrate/
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/__init__.py b/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/__init__.py
+++ /dev/null
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/manage.py b/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/manage.py
deleted file mode 100644
index 658a0ba1..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/manage.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright 2012 Hewlett-Packard Development Company, L.P.
-# All Rights Reserved.
-#
-# Author: Patrick Galbraith <patg@hp.com>
-#
-# 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 migrate.versioning.shell import main
-
-if __name__ == '__main__':
- main(debug='False')
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/migrate.cfg b/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/migrate.cfg
deleted file mode 100644
index 007dd3b9..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/migrate.cfg
+++ /dev/null
@@ -1,25 +0,0 @@
-[db_settings]
-# Used to identify which repository this database is versioned under.
-# You can use the name of your project.
-repository_id=DesignatePoolManager
-
-# The name of the database table used to track the schema version.
-# This name shouldn't already be used by your project.
-# If this is changed once a database is under version control, you'll need to
-# change the table name in each database too.
-version_table=migrate_version
-
-# When committing a change script, Migrate will attempt to generate the
-# sql for all supported databases; normally, if one of them fails - probably
-# because you don't have that database installed - it is ignored and the
-# commit continues, perhaps ending successfully.
-# Databases in this list MUST compile successfully during a commit, or the
-# entire commit will fail. List the databases your application will actually
-# be using to ensure your updates to that database work properly.
-# This must be a list; example: ['postgres','sqlite']
-required_dbs=[]
-
-# When creating new change scripts, Migrate will stamp the new script with
-# a version number. By default this is latest_version + 1. You can set this
-# to 'true' to tell Migrate to use the UTC timestamp instead.
-use_timestamp_numbering=False
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/001_add_pool_manager_status.py b/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/001_add_pool_manager_status.py
deleted file mode 100644
index 772a9283..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/001_add_pool_manager_status.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 sqlalchemy import Integer, DateTime, Enum, UniqueConstraint
-from sqlalchemy.schema import Table, Column, MetaData
-
-from designate.sqlalchemy.types import UUID
-
-UPDATE_STATUSES = ['SUCCESS', 'ERROR']
-UPDATE_ACTIONS = ['CREATE', 'DELETE', 'UPDATE']
-
-meta = MetaData()
-
-pool_manager_statuses = Table(
- 'pool_manager_statuses', meta,
- Column('id', UUID(), primary_key=True),
- Column('version', Integer(), nullable=False),
- Column('created_at', DateTime()),
- Column('updated_at', DateTime()),
- Column('server_id', UUID(), nullable=False),
- Column('domain_id', UUID(), nullable=False),
- Column('action', Enum(name='update_actions', *UPDATE_ACTIONS),
- nullable=False),
- Column('status', Enum(name='update_statuses', *UPDATE_STATUSES),
- nullable=True),
- Column('serial_number', Integer, nullable=False),
-
- UniqueConstraint('server_id', 'domain_id', 'action',
- name='unique_pool_manager_status'),
-
- mysql_engine='InnoDB',
- mysql_charset='utf8')
-
-
-def upgrade(migrate_engine):
- meta.bind = migrate_engine
-
- with migrate_engine.begin() as conn:
- if migrate_engine.name == "mysql":
- conn.execute("SET foreign_key_checks = 0;")
-
- elif migrate_engine.name == "postgresql":
- conn.execute("SET CONSTRAINTS ALL DEFERRED;")
-
- pool_manager_statuses.create(conn)
-
- if migrate_engine.name == "mysql":
- conn.execute("SET foreign_key_checks = 1;")
-
-
-def downgrade(migrate_engine):
- meta.bind = migrate_engine
-
- with migrate_engine.begin() as conn:
- if migrate_engine.name == "mysql":
- conn.execute("SET foreign_key_checks = 0;")
-
- elif migrate_engine.name == "postgresql":
- conn.execute("SET CONSTRAINTS ALL DEFERRED;")
-
- pool_manager_statuses.drop()
-
- if migrate_engine.name == "mysql":
- conn.execute("SET foreign_key_checks = 1;")
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/002_rename_server_to_nameserver.py b/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/002_rename_server_to_nameserver.py
deleted file mode 100644
index 3d91b965..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/002_rename_server_to_nameserver.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 sqlalchemy.schema import Table, MetaData
-
-
-meta = MetaData()
-
-
-def upgrade(migrate_engine):
- meta.bind = migrate_engine
-
- pms_table = Table('pool_manager_statuses', meta, autoload=True)
- pms_table.c.server_id.alter(name='nameserver_id')
-
-
-def downgrade(migrate_engine):
- meta.bind = migrate_engine
-
- pms_table = Table('pool_manager_statuses', meta, autoload=True)
- pms_table.c.nameserver_id.alter(name='server_id')
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/003_placeholder.py b/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/003_placeholder.py
deleted file mode 100644
index 69c0bce5..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/003_placeholder.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015 Hewlett-Packard Development Company, L.P.
-#
-# Author: Kiall Mac Innes <kiall@hpe.com>
-#
-# 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.
-#
-# This is a placeholder for Kilo backports.
-# Do not use this number for new Liberty work. New Liberty work starts after
-# all the placeholders.
-#
-# See https://blueprints.launchpad.net/nova/+spec/backportable-db-migrations
-# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
-
-
-def upgrade(migrate_engine):
- pass
-
-
-def downgrade(migration_engine):
- pass
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/004_placeholder.py b/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/004_placeholder.py
deleted file mode 100644
index 69c0bce5..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/004_placeholder.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015 Hewlett-Packard Development Company, L.P.
-#
-# Author: Kiall Mac Innes <kiall@hpe.com>
-#
-# 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.
-#
-# This is a placeholder for Kilo backports.
-# Do not use this number for new Liberty work. New Liberty work starts after
-# all the placeholders.
-#
-# See https://blueprints.launchpad.net/nova/+spec/backportable-db-migrations
-# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
-
-
-def upgrade(migrate_engine):
- pass
-
-
-def downgrade(migration_engine):
- pass
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/005_placeholder.py b/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/005_placeholder.py
deleted file mode 100644
index 69c0bce5..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/005_placeholder.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015 Hewlett-Packard Development Company, L.P.
-#
-# Author: Kiall Mac Innes <kiall@hpe.com>
-#
-# 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.
-#
-# This is a placeholder for Kilo backports.
-# Do not use this number for new Liberty work. New Liberty work starts after
-# all the placeholders.
-#
-# See https://blueprints.launchpad.net/nova/+spec/backportable-db-migrations
-# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
-
-
-def upgrade(migrate_engine):
- pass
-
-
-def downgrade(migration_engine):
- pass
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/006_placeholder.py b/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/006_placeholder.py
deleted file mode 100644
index 69c0bce5..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/006_placeholder.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015 Hewlett-Packard Development Company, L.P.
-#
-# Author: Kiall Mac Innes <kiall@hpe.com>
-#
-# 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.
-#
-# This is a placeholder for Kilo backports.
-# Do not use this number for new Liberty work. New Liberty work starts after
-# all the placeholders.
-#
-# See https://blueprints.launchpad.net/nova/+spec/backportable-db-migrations
-# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
-
-
-def upgrade(migrate_engine):
- pass
-
-
-def downgrade(migration_engine):
- pass
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/007_placeholder.py b/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/007_placeholder.py
deleted file mode 100644
index 69c0bce5..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/007_placeholder.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015 Hewlett-Packard Development Company, L.P.
-#
-# Author: Kiall Mac Innes <kiall@hpe.com>
-#
-# 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.
-#
-# This is a placeholder for Kilo backports.
-# Do not use this number for new Liberty work. New Liberty work starts after
-# all the placeholders.
-#
-# See https://blueprints.launchpad.net/nova/+spec/backportable-db-migrations
-# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
-
-
-def upgrade(migrate_engine):
- pass
-
-
-def downgrade(migration_engine):
- pass
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/008_domain_to_zone_rename.py b/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/008_domain_to_zone_rename.py
deleted file mode 100644
index 74618945..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/008_domain_to_zone_rename.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2015 Hewlett-Packard Development Company, L.P.
-#
-# Author: Kiall Mac Innes <kiall@hpe.com>
-#
-# 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.
-#
-# See https://blueprints.launchpad.net/nova/+spec/backportable-db-migrations
-# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
-from sqlalchemy.schema import Table, MetaData
-
-
-meta = MetaData()
-
-
-def upgrade(migrate_engine):
- meta.bind = migrate_engine
-
- status_table = Table('pool_manager_statuses', meta, autoload=True)
-
- status_table.c.domain_id.alter(name='zone_id')
-
-
-def downgrade(migration_engine):
- pass
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/__init__.py b/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/migrate_repo/versions/__init__.py
+++ /dev/null
diff --git a/designate/pool_manager/cache/impl_sqlalchemy/tables.py b/designate/pool_manager/cache/impl_sqlalchemy/tables.py
deleted file mode 100644
index a70f8f40..00000000
--- a/designate/pool_manager/cache/impl_sqlalchemy/tables.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron rickard <rrickard@ebaysf.com>
-#
-# 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 sqlalchemy import (Table, MetaData, Column, Integer, DateTime, Enum,
- UniqueConstraint, ForeignKeyConstraint)
-
-from oslo_utils import timeutils
-
-from designate import utils
-from designate.sqlalchemy.types import UUID
-
-UPDATE_STATUSES = ['SUCCESS', 'ERROR']
-UPDATE_ACTIONS = ['CREATE', 'DELETE', 'UPDATE']
-
-metadata = MetaData()
-
-pool_manager_statuses = Table(
- 'pool_manager_statuses', metadata,
- Column('id', UUID, default=utils.generate_uuid, primary_key=True),
- Column('version', Integer, default=1, nullable=False),
- Column('created_at', DateTime, default=lambda: timeutils.utcnow()),
- Column('updated_at', DateTime, onupdate=lambda: timeutils.utcnow()),
- Column('nameserver_id', UUID, nullable=False),
- Column('zone_id', UUID, nullable=False),
- Column('action', Enum(name='update_actions', *UPDATE_ACTIONS),
- nullable=False),
- Column('status', Enum(name='update_statuses', *UPDATE_STATUSES),
- nullable=True),
- Column('serial_number', Integer, nullable=False),
-
-
- UniqueConstraint('nameserver_id', 'zone_id', 'action',
- name='unique_pool_manager_status'),
- ForeignKeyConstraint(['zone_id'], ['zones.id']),
-
- mysql_engine='InnoDB',
- mysql_charset='utf8',
-)
diff --git a/designate/pool_manager/rpcapi.py b/designate/pool_manager/rpcapi.py
deleted file mode 100644
index dea1937e..00000000
--- a/designate/pool_manager/rpcapi.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 oslo_config import cfg
-from oslo_log import log as logging
-import oslo_messaging as messaging
-
-from designate import rpc
-from designate.loggingutils import rpc_logging
-
-LOG = logging.getLogger(__name__)
-
-MNGR_API = None
-
-
-def reset():
- global MNGR_API
- MNGR_API = None
-
-
-@rpc_logging(LOG, 'pool_manager')
-class PoolManagerAPI(object):
- """
- Client side of the Pool Manager RPC API.
-
- API version history:
-
- API version history:
-
- 1.0 - Initial version
- 2.0 - Rename domains to zones
- 2.1 - Add target_sync
- """
- RPC_API_VERSION = '2.1'
-
- def __init__(self, topic=None):
- self.topic = topic if topic else cfg.CONF['service:pool_manager'].topic
-
- target = messaging.Target(topic=self.topic,
- version=self.RPC_API_VERSION)
- self.client = rpc.get_client(target, version_cap='2.1')
-
- @classmethod
- def get_instance(cls):
- """
- The rpc.get_client() which is called upon the API object initialization
- will cause a assertion error if the designate.rpc.TRANSPORT isn't setup
- by rpc.init() before.
-
- This fixes that by creating the rpcapi when demanded.
- """
- global MNGR_API
- if not MNGR_API:
- MNGR_API = cls()
- return MNGR_API
-
- def target_sync(self, context, pool_id, target_id, timestamp):
- LOG.info(
- "target_sync: Syncing target %(target) since %(timestamp)d.",
- {
- 'target': target_id,
- 'timestamp': timestamp
- })
-
- # Modifying the topic so it is pool manager instance specific.
- topic = '%s.%s' % (self.topic, pool_id)
- cctxt = self.client.prepare(topic=topic)
- return cctxt.call(
- context, 'target_sync', pool_id=pool_id, target_id=target_id,
- timestamp=timestamp)
-
- def create_zone(self, context, zone):
- # Modifying the topic so it is pool manager instance specific.
- topic = '%s.%s' % (self.topic, zone.pool_id)
- cctxt = self.client.prepare(topic=topic)
- return cctxt.cast(
- context, 'create_zone', zone=zone)
-
- def delete_zone(self, context, zone):
- # Modifying the topic so it is pool manager instance specific.
- topic = '%s.%s' % (self.topic, zone.pool_id)
- cctxt = self.client.prepare(topic=topic)
- return cctxt.cast(
- context, 'delete_zone', zone=zone)
-
- def update_zone(self, context, zone):
- # Modifying the topic so it is pool manager instance specific.
- topic = '%s.%s' % (self.topic, zone.pool_id)
- cctxt = self.client.prepare(topic=topic)
- return cctxt.cast(
- context, 'update_zone', zone=zone)
-
- def update_status(self, context, zone, nameserver, status,
- actual_serial):
-
- # Modifying the topic so it is pool manager instance specific.
- topic = '%s.%s' % (self.topic, zone.pool_id)
- cctxt = self.client.prepare(topic=topic)
- return cctxt.cast(
- context, 'update_status', zone=zone, nameserver=nameserver,
- status=status, actual_serial=actual_serial)
diff --git a/designate/pool_manager/service.py b/designate/pool_manager/service.py
deleted file mode 100644
index da32e969..00000000
--- a/designate/pool_manager/service.py
+++ /dev/null
@@ -1,976 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 contextlib import contextmanager
-from decimal import Decimal
-import time
-from datetime import datetime
-
-from oslo_config import cfg
-import oslo_messaging as messaging
-from oslo_log import log as logging
-from oslo_concurrency import lockutils
-
-from designate import backend
-from designate import coordination
-from designate import exceptions
-from designate import objects
-from designate import utils
-from designate.central import rpcapi as central_api
-from designate.pool_manager import rpcapi as pool_manager_rpcapi
-from designate.mdns import rpcapi as mdns_api
-from designate import service
-from designate.context import DesignateContext
-from designate.pool_manager import cache
-
-
-LOG = logging.getLogger(__name__)
-CONF = cfg.CONF
-
-SUCCESS_STATUS = 'SUCCESS'
-PENDING_STATUS = 'PENDING'
-ERROR_STATUS = 'ERROR'
-NO_ZONE_STATUS = 'NO_ZONE'
-CREATE_ACTION = 'CREATE'
-DELETE_ACTION = 'DELETE'
-UPDATE_ACTION = 'UPDATE'
-MAXIMUM_THRESHOLD = 100
-
-
-@contextmanager
-def wrap_backend_call():
- """
- Wraps backend calls, ensuring any exception raised is a Backend exception.
- """
- try:
- yield
- except exceptions.Backend:
- raise
- except Exception as e:
- raise exceptions.Backend('Unknown backend failure: %r' % e)
-
-
-def _constant_retries(num_attempts, sleep_interval):
- """Generate a sequence of False terminated by a True
- Sleep `sleep_interval` between cycles but not at the end.
- """
- for cnt in range(num_attempts):
- if cnt != 0:
- LOG.debug("Executing retry n. %d", cnt)
- if cnt < num_attempts - 1:
- yield False
- time.sleep(sleep_interval)
- else:
- yield True
-
-
-class Service(service.RPCService):
- """
- Service side of the Pool Manager RPC API.
-
- API version history:
-
- 1.0 - Initial version
- 2.0 - The Big Rename
- 2.1 - Add target_sync
- """
- RPC_API_VERSION = '2.1'
-
- target = messaging.Target(version=RPC_API_VERSION)
-
- def __init__(self):
- self._scheduler = None
- self._storage = None
- self._quota = None
-
- self._pool_election = None
-
- self._central_api = None
- self._mdns_api = None
- self._pool_manager_api = None
-
- topic = '%s.%s' % (
- cfg.CONF['service:pool_manager'].topic,
- CONF['service:pool_manager'].pool_id
- )
-
- super(Service, self).__init__(
- self.service_name, topic,
- threads=cfg.CONF['service:worker'].threads,
- )
-
- self.coordination = coordination.Coordination(
- self.service_name, self.tg
- )
-
- # Get a pool manager cache connection.
- self.cache = cache.get_pool_manager_cache(
- CONF['service:pool_manager'].cache_driver)
-
- # Store some settings for quick access later
- self.threshold = CONF['service:pool_manager'].threshold_percentage
- self.timeout = CONF['service:pool_manager'].poll_timeout
- self.retry_interval = CONF['service:pool_manager'].poll_retry_interval
- self.max_retries = CONF['service:pool_manager'].poll_max_retries
- self.delay = CONF['service:pool_manager'].poll_delay
- self._periodic_sync_max_attempts = \
- CONF['service:pool_manager'].periodic_sync_max_attempts
- self._periodic_sync_retry_interval = \
- CONF['service:pool_manager'].periodic_sync_retry_interval
-
- # Compute a time (seconds) by which things should have propagated
- self.max_prop_time = utils.max_prop_time(
- self.timeout, self.max_retries, self.retry_interval, self.delay
- )
-
- def _setup_target_backends(self):
- self.target_backends = {}
-
- for target in self.pool.targets:
- # Fetch an instance of the Backend class, passing in the options
- # and masters
- self.target_backends[target.id] = backend.get_backend(target)
-
- LOG.info('%d targets setup', len(self.pool.targets))
-
- if not self.target_backends:
- raise exceptions.NoPoolTargetsConfigured()
-
- @property
- def service_name(self):
- return 'pool_manager'
-
- def start(self):
- # Build the Pool (and related) Object from Config
- context = DesignateContext.get_admin_context()
- pool_id = CONF['service:pool_manager'].pool_id
-
- has_targets = False
-
- # TODO(kiall): This block of code should be replaced with a cleaner,
- # limited version. e.g. should retry for X minutes, and
- # backoff rather than fixed retry intervals.
- while not has_targets:
- try:
- self.pool = self.central_api.get_pool(context, pool_id)
-
- if len(self.pool.targets) > 0:
- has_targets = True
- else:
- LOG.error("No targets for %s found.", self.pool)
- time.sleep(5)
-
- # Pool data may not have migrated to the DB yet
- except exceptions.PoolNotFound:
- LOG.error("Pool ID %s not found.", pool_id)
- time.sleep(5)
- # designate-central service may not have started yet
- except messaging.exceptions.MessagingTimeout:
- time.sleep(0.2)
- # designate-central failed in an unknown way, don't allow another
- # failing / not started service to cause pool-manager to crash.
- except Exception:
- LOG.exception("An unknown exception occurred while "
- "fetching pool details")
- time.sleep(5)
-
- # Create the necessary Backend instances for each target
- self._setup_target_backends()
-
- for target in self.pool.targets:
- self.target_backends[target.id].start()
-
- super(Service, self).start()
- self.coordination.start()
-
- # Setup a Leader Election, use for ensuring certain tasks are executed
- # on exactly one pool-manager instance at a time]
- self._pool_election = coordination.LeaderElection(
- self.coordination.coordinator,
- '%s:%s' % (self.service_name, self.pool.id))
- self._pool_election.start()
-
- if CONF['service:pool_manager'].enable_recovery_timer:
- interval = CONF['service:pool_manager'].periodic_recovery_interval
- LOG.info('Starting periodic recovery timer every'
- ' %(interval)s s', {'interval': interval})
- self.tg.add_timer(interval, self.periodic_recovery, interval)
-
- if CONF['service:pool_manager'].enable_sync_timer:
- interval = CONF['service:pool_manager'].periodic_sync_interval
- LOG.info('Starting periodic synchronization timer every'
- ' %(interval)s s', {'interval': interval})
- self.tg.add_timer(interval, self.periodic_sync, interval)
-
- def stop(self, graceful=True):
- self._pool_election.stop()
- # self.coordination.stop()
-
- super(Service, self).stop(graceful)
-
- for target in self.pool.targets:
- self.target_backends[target.id].stop()
-
- @property
- def central_api(self):
- if not self._central_api:
- self._central_api = central_api.CentralAPI.get_instance()
- return self._central_api
-
- @property
- def mdns_api(self):
- if not self._mdns_api:
- self._mdns_api = mdns_api.MdnsAPI.get_instance()
- return self._mdns_api
-
- @property
- def pool_manager_api(self):
- if not self._pool_manager_api:
- pool_mgr_api = pool_manager_rpcapi.PoolManagerAPI
- self._pool_manager_api = pool_mgr_api.get_instance()
- return self._pool_manager_api
-
- def _get_admin_context_all_tenants(self):
- return DesignateContext.get_admin_context(all_tenants=True)
-
- # Periodic Tasks
- def periodic_recovery(self):
- """
- Runs only on the pool leader
- :return: None
- """
- if not self._pool_election.is_leader:
- return
-
- context = self._get_admin_context_all_tenants()
- LOG.info("Starting Periodic Recovery")
-
- try:
- # Handle Deletion Failures
- zones = self._get_failed_zones(context, DELETE_ACTION)
- LOG.info("periodic_recovery:delete_zone needed on %d zones",
- len(zones))
- for zone in zones:
- self.pool_manager_api.delete_zone(context, zone)
-
- # Handle Creation Failures
- zones = self._get_failed_zones(context, CREATE_ACTION)
- LOG.info("periodic_recovery:create_zone needed on %d zones",
- len(zones))
- for zone in zones:
- self.pool_manager_api.create_zone(context, zone)
-
- # Handle Update Failures
- zones = self._get_failed_zones(context, UPDATE_ACTION)
- LOG.info("periodic_recovery:update_zone needed on %d zones",
- len(zones))
- for zone in zones:
- self.pool_manager_api.update_zone(context, zone)
-
- except Exception:
- LOG.exception('An unhandled exception in periodic '
- 'recovery occurred')
-
- def periodic_sync(self):
- """Periodically sync all the zones that are not in ERROR status
- Runs only on the pool leader
- :return: None
- """
- if not self._pool_election.is_leader:
- return
-
- LOG.info("Starting Periodic Synchronization")
- context = self._get_admin_context_all_tenants()
- zones = self._fetch_healthy_zones(context)
- zones = set(zones)
-
- # TODO(kiall): If the zone was created within the last
- # periodic_sync_seconds, attempt to recreate
- # to fill in targets which may have failed.
- retry_gen = _constant_retries(
- self._periodic_sync_max_attempts,
- self._periodic_sync_retry_interval
- )
- for is_last_cycle in retry_gen:
- zones_in_error = []
- for zone in zones:
- try:
- success = self.update_zone(context, zone)
- if not success:
- zones_in_error.append(zone)
- except Exception:
- LOG.exception('An unhandled exception in periodic '
- 'synchronization occurred.')
- zones_in_error.append(zone)
-
- if not zones_in_error:
- return
-
- zones = zones_in_error
-
- for zone in zones_in_error:
- self.central_api.update_status(context, zone.id, ERROR_STATUS,
- zone.serial)
-
- def target_sync(self, context, pool_id, target_id, timestamp):
- """
- Replay all the events that we can since a certain timestamp
- """
- context = self._get_admin_context_all_tenants()
- context.show_deleted = True
-
- target = None
- for tar in self.pool.targets:
- if tar.id == target_id:
- target = tar
- if target is None:
- raise exceptions.BadRequest('Please supply a valid target id.')
-
- LOG.info('Starting Target Sync')
-
- criterion = {
- 'pool_id': pool_id,
- 'updated_at': '>%s' % datetime.fromtimestamp(timestamp).
- isoformat(),
- }
-
- zones = self.central_api.find_zones(context, criterion=criterion,
- sort_key='updated_at', sort_dir='asc')
-
- self.tg.add_thread(self._target_sync,
- context, zones, target, timestamp)
-
- return 'Syncing %(len)s zones on %(target)s' % {'len': len(zones),
- 'target': target_id}
-
- def _target_sync(self, context, zones, target, timestamp):
- zone_ops = []
- timestamp_dt = datetime.fromtimestamp(timestamp)
-
- for zone in zones:
- if isinstance(zone.created_at, datetime):
- zone_created_at = zone.created_at
- elif isinstance(zone.created_at, str):
- zone_created_at = datetime.strptime(zone.created_at,
- "%Y-%m-%dT%H:%M:%S.%f")
- else:
- raise Exception("zone.created_at is of type %s" %
- str(type(zone.created_at)))
-
- if zone.status == 'DELETED':
- # Remove any other ops for this zone
- for zone_op in zone_ops:
- if zone.name == zone_op[0].name:
- zone_ops.remove(zone_op)
- # If the zone was created before the timestamp delete it,
- # otherwise, it will just never be created
- if (zone_created_at <= timestamp_dt):
- zone_ops.append((zone, 'DELETE'))
- elif (zone_created_at > timestamp_dt):
- # If the zone was created after the timestamp
- for zone_op in zone_ops:
- if (
- zone.name == zone_op[0].name and
- zone_op[1] == 'DELETE'
- ):
- zone_ops.remove(zone_op)
-
- zone_ops.append((zone, 'CREATE'))
- else:
- zone_ops.append((zone, 'UPDATE'))
-
- for zone, action in zone_ops:
- if action == 'CREATE':
- self._create_zone_on_target(context, target, zone)
- elif action == 'UPDATE':
- self._update_zone_on_target(context, target, zone)
- elif action == 'DELETE':
- self._delete_zone_on_target(context, target, zone)
- zone.serial = 0
- for nameserver in self.pool.nameservers:
- self.mdns_api.poll_for_serial_number(
- context, zone, nameserver, self.timeout,
- self.retry_interval, self.max_retries, self.delay)
-
- # Standard Create/Update/Delete Methods
-
- def create_zone(self, context, zone):
- """Called by Central or by periodic_recovery, instruct the backends to
- create a zone, then poll for consensus.
- On success, send NOTIFY to also_notifies and nameservers
- Finally, poll for zone serial number on nameservers.
-
- :param context: Security context information.
- :param zone: Zone to be created
- :return: None
- """
- LOG.info("Creating new zone %s", zone.name)
-
- results = []
-
- # Create the zone on each of the Pool Targets
- for target in self.pool.targets:
- results.append(
- self._create_zone_on_target(context, target, zone)
- )
-
- if self._exceed_or_meet_threshold(results.count(True)):
- LOG.debug('Consensus reached for creating zone %(zone)s '
- 'on pool targets' % {'zone': zone.name})
- # The zone status will be updated asyncronously by MiniDNS
-
- else:
-
- LOG.warning('Consensus not reached for creating zone %(zone)s '
- 'on pool targets', {'zone': zone.name})
-
- self.central_api.update_status(
- context, zone.id, ERROR_STATUS, zone.serial)
-
- return
-
- # Send a NOTIFY to each also-notifies
- for also_notify in self.pool.also_notifies:
- self._update_zone_on_also_notify(context, also_notify, zone)
-
- # Ensure the change has propagated to each nameserver
- for nameserver in self.pool.nameservers:
- create_status = self._build_status_object(
- nameserver, zone, CREATE_ACTION)
- self.cache.store(context, create_status)
-
- self.mdns_api.poll_for_serial_number(
- context, zone, nameserver, self.timeout,
- self.retry_interval, self.max_retries, self.delay)
-
- def _create_zone_on_target(self, context, target, zone):
- """Called by create_zone, run create_zone on backends
-
- :param context: Security context information.
- :param target: Target to create Zone on
- :param zone: Zone to be created
- :return: True/False
- """
- LOG.debug("Creating zone %s on target %s", zone.name, target.id)
-
- backend = self.target_backends[target.id]
- retries = 0
-
- while retries < self.max_retries:
- try:
- backend.create_zone(context, zone)
-
- return True
- except Exception:
- retries += 1
- LOG.exception(
- "Failed to create zone %(zone)s on "
- "target %(target)s on attempt %(attempt)d",
- {
- 'zone': zone.name,
- 'target': target.id,
- 'attempt': retries
- }) # noqa
- time.sleep(self.retry_interval)
-
- return False
-
- def update_zone(self, context, zone):
- """Update a zone across every pool target, check for consensus and
- for propagation.
- :param context: Security context information.
- :param zone: Zone to be updated
- :return: consensus reached (bool)
- """
- LOG.info("Updating zone %s", zone.name)
-
- # Update the zone on each of the Pool Targets
- success_count = 0
- for target in self.pool.targets:
- ok_status = self._update_zone_on_target(context, target, zone)
- if ok_status:
- success_count += 1
-
- if not self._exceed_or_meet_threshold(success_count):
- LOG.warning('Consensus not reached for updating zone %(zone)s '
- 'on pool targets', {'zone': zone.name})
- self.central_api.update_status(context, zone.id, ERROR_STATUS,
- zone.serial)
- return False
-
- LOG.debug('Consensus reached for updating zone %(zone)s '
- 'on pool targets', {'zone': zone.name})
-
- # The zone status will be updated asynchronously by MiniDNS
-
- # Send a NOTIFY to each also-notifies
- for also_notify in self.pool.also_notifies:
- self._update_zone_on_also_notify(context, also_notify, zone)
-
- # Ensure the change has propagated to each nameserver
- for nameserver in self.pool.nameservers:
- # See if there is already another update in progress
- try:
- self.cache.retrieve(context, nameserver.id, zone.id,
- UPDATE_ACTION)
- except exceptions.PoolManagerStatusNotFound:
- update_status = self._build_status_object(
- nameserver, zone, UPDATE_ACTION)
- self.cache.store(context, update_status)
-
- self.mdns_api.poll_for_serial_number(
- context, zone, nameserver, self.timeout,
- self.retry_interval, self.max_retries, self.delay)
-
- return True
-
- def _update_zone_on_target(self, context, target, zone):
- """Instruct the appropriate backend to update a zone on a target
- :param context: Security context information.
- :param target: Target to update Zone on
- :param zone: Zone to be updated
- :return: True/False
- """
- LOG.debug("Updating zone %s on target %s", zone.name, target.id)
-
- backend = self.target_backends[target.id]
-
- try:
- backend.update_zone(context, zone)
-
- return True
- except Exception:
- LOG.exception("Failed to update zone %(zone)s on target "
- "%(target)s",
- {'zone': zone.name, 'target': target.id})
- return False
-
- def _update_zone_on_also_notify(self, context, also_notify, zone):
- LOG.info('Updating zone %(zone)s on also_notify %(server)s.',
- {'zone': zone.name,
- 'server': self._get_destination(also_notify)})
-
- self.mdns_api.notify_zone_changed(
- context, zone, also_notify.host, also_notify.port, self.timeout,
- self.retry_interval, self.max_retries, 0)
-
- def delete_zone(self, context, zone):
- """
- :param context: Security context information.
- :param zone: Zone to be deleted
- :return: None
- """
- LOG.info("Deleting zone %s", zone.name)
-
- results = []
-
- # Delete the zone on each of the Pool Targets
- for target in self.pool.targets:
- results.append(
- self._delete_zone_on_target(context, target, zone))
-
- if not self._exceed_or_meet_threshold(
- results.count(True), MAXIMUM_THRESHOLD):
- LOG.warning('Consensus not reached for deleting zone %(zone)s '
- 'on pool targets', {'zone': zone.name})
- self.central_api.update_status(
- context, zone.id, ERROR_STATUS, zone.serial)
-
- zone.serial = 0
- # Ensure the change has propagated to each nameserver
- for nameserver in self.pool.nameservers:
- # See if there is already another update in progress
- try:
- self.cache.retrieve(context, nameserver.id, zone.id,
- DELETE_ACTION)
- except exceptions.PoolManagerStatusNotFound:
- update_status = self._build_status_object(
- nameserver, zone, DELETE_ACTION)
- self.cache.store(context, update_status)
-
- self.mdns_api.poll_for_serial_number(
- context, zone, nameserver, self.timeout,
- self.retry_interval, self.max_retries, self.delay)
-
- def _delete_zone_on_target(self, context, target, zone):
- """
- :param context: Security context information.
- :param target: Target to delete Zone from
- :param zone: Zone to be deleted
- :return: True/False
- """
- LOG.debug("Deleting zone %s on target %s", zone.name, target.id)
-
- backend = self.target_backends[target.id]
- retries = 0
-
- while retries < self.max_retries:
- try:
- backend.delete_zone(context, zone)
-
- return True
- except Exception:
- retries += 1
- LOG.exception(
- "Failed to delete zone %(zone)s on "
- "target %(target)s on attempt %(attempt)d",
- {
- 'zone': zone.name,
- 'target': target.id,
- 'attempt': retries
- })
- time.sleep(self.retry_interval)
-
- return False
-
- def update_status(self, context, zone, nameserver, status,
- actual_serial):
- """
- update_status is called by mdns for creates and updates.
- deletes are handled by the backend entirely and status is determined
- at the time of delete itself.
- :param context: Security context information.
- :param zone: The designate zone object.
- :param nameserver: The nameserver for which a status update is being
- sent.
- :param status: The status, 'SUCCESS' or 'ERROR'.
- :param actual_serial: The actual serial number received from the name
- server for the zone.
- :return: None
- """
- LOG.debug("Calling update_status for %s : %s : %s : %s",
- zone.name, zone.action, status, actual_serial)
- action = UPDATE_ACTION if zone.action == 'NONE' else zone.action
-
- with lockutils.lock('update-status-%s' % zone.id):
- try:
- current_status = self.cache.retrieve(
- context, nameserver.id, zone.id, action)
- except exceptions.PoolManagerStatusNotFound:
- current_status = self._build_status_object(
- nameserver, zone, action)
- self.cache.store(context, current_status)
- cache_serial = current_status.serial_number
-
- LOG.debug('For zone %s : %s on nameserver %s the cache serial '
- 'is %s and the actual serial is %s.',
- zone.name, action, self._get_destination(nameserver),
- cache_serial, actual_serial)
- if actual_serial and cache_serial <= actual_serial:
- current_status.status = status
- current_status.serial_number = actual_serial
- self.cache.store(context, current_status)
-
- LOG.debug('Attempting to get consensus serial for %s',
- zone.name)
- consensus_serial = self._get_consensus_serial(context, zone)
- LOG.debug('Consensus serial for %s is %s',
- zone.name, consensus_serial)
-
- # If there is a valid consensus serial we can still send a success
- # for that serial.
- # If there is a higher error serial we can also send an error for
- # the error serial.
- if consensus_serial != 0 and cache_serial <= consensus_serial \
- and zone.status != 'ACTIVE':
- LOG.info('For zone %(zone)s the consensus serial is '
- '%(consensus_serial)s.',
- {
- 'zone': zone.name,
- 'consensus_serial': consensus_serial
- })
- self.central_api.update_status(
- context, zone.id, SUCCESS_STATUS, consensus_serial)
-
- if status == ERROR_STATUS:
- error_serial = self._get_error_serial(
- context, zone, consensus_serial)
- if error_serial > consensus_serial or error_serial == 0:
- LOG.warning('For zone %(zone)s '
- 'the error serial is %(error_serial)s.',
- {
- 'zone': zone.name,
- 'error_serial': error_serial
- })
- self.central_api.update_status(
- context, zone.id, ERROR_STATUS, error_serial)
-
- if status == NO_ZONE_STATUS:
- if action == DELETE_ACTION:
- self.central_api.update_status(
- context, zone.id, NO_ZONE_STATUS, 0)
- else:
- LOG.warning('Zone %(zone)s is not present in some targets',
- {'zone': zone.name})
- self.central_api.update_status(
- context, zone.id, NO_ZONE_STATUS, 0)
-
- if consensus_serial == zone.serial and self._is_consensus(
- context, zone, action, SUCCESS_STATUS,
- MAXIMUM_THRESHOLD):
- self._clear_cache(context, zone, action)
-
- # Utility Methods
- def _get_failed_zones(self, context, action):
- """
- Fetch zones that are in ERROR status or have been PENDING for a long
- time. Used by periodic recovery.
- After a certain time changes either should have successfully
- propagated or gone to an ERROR state.
- However, random failures and undiscovered bugs leave zones hanging out
- in PENDING state forever. By treating those "stale" zones as failed,
- periodic recovery will attempt to restore them.
- :return: :class:`ZoneList` zones
- """
- criterion = {
- 'pool_id': CONF['service:pool_manager'].pool_id,
- 'action': action,
- 'status': ERROR_STATUS
- }
- error_zones = self.central_api.find_zones(context, criterion)
-
- # Include things that have been hanging out in PENDING
- # status for longer than they should
- # Generate the current serial, will provide a UTC Unix TS.
- current = utils.increment_serial()
- stale_criterion = {
- 'pool_id': CONF['service:pool_manager'].pool_id,
- 'action': action,
- 'status': PENDING_STATUS,
- 'serial': "<%s" % (current - self.max_prop_time)
- }
- LOG.debug('Including zones with action %(action)s and %(status)s '
- 'older than %(seconds)ds' % {'action': action,
- 'status': PENDING_STATUS,
- 'seconds': self.max_prop_time})
-
- stale_zones = self.central_api.find_zones(context, stale_criterion)
- if stale_zones:
- LOG.warning(
- 'Found %(len)d zones PENDING for more than %(sec)d seconds',
- {
- 'len': len(stale_zones),
- 'sec': self.max_prop_time
- })
- error_zones.extend(stale_zones)
-
- return error_zones
-
- def _fetch_healthy_zones(self, context):
- """Fetch all zones not in error
- :return: :class:`ZoneList` zones
- """
- criterion = {
- 'pool_id': CONF['service:pool_manager'].pool_id,
- 'status': '!%s' % ERROR_STATUS
- }
-
- periodic_sync_seconds = \
- CONF['service:pool_manager'].periodic_sync_seconds
-
- if periodic_sync_seconds is not None:
- # Generate the current serial, will provide a UTC Unix TS.
- current = utils.increment_serial()
- criterion['serial'] = ">%s" % (current - periodic_sync_seconds)
-
- zones = self.central_api.find_zones(context, criterion)
- return zones
-
- @staticmethod
- def _get_destination(nameserver):
- return '%s:%s' % (nameserver.host, nameserver.port)
-
- @staticmethod
- def _percentage(count, total_count):
- return (Decimal(count) / Decimal(total_count)) * Decimal(100)
-
- def _exceed_or_meet_threshold(self, count, threshold=None):
- """Evaluate if count / the number of pool targets >= threshold
- Used to implement consensus
- """
- threshold = threshold or self.threshold
- perc = self._percentage(count, len(self.pool.targets))
- return perc >= Decimal(threshold)
-
- @staticmethod
- def _get_sorted_serials(pool_manager_statuses, descending=False):
- serials = []
- for pool_manager_status in pool_manager_statuses:
- serials.append(pool_manager_status.serial_number)
- serials.sort(reverse=descending)
- return serials
-
- def _get_serials_ascending(self, pool_manager_statuses):
- return self._get_sorted_serials(pool_manager_statuses)
-
- def _get_serials_descending(self, pool_manager_statuses):
- return self._get_sorted_serials(pool_manager_statuses, descending=True)
-
- def _is_consensus(self, context, zone, action, status, threshold=None):
- """Fetch zone status across all nameservers through MiniDNS and compare
- it with the expected `status`
- :return: consensus reached (bool)
- """
- status_count = 0
- pool_manager_statuses = self._retrieve_statuses(
- context, zone, action)
- for pool_manager_status in pool_manager_statuses:
- if pool_manager_status.status == status:
- status_count += 1
- if threshold is None:
- threshold = self.threshold
- return self._exceed_or_meet_threshold(status_count, threshold)
-
- def _get_consensus_serial(self, context, zone):
- consensus_serial = 0
- action = UPDATE_ACTION if zone.action == 'NONE' else zone.action
-
- pm_statuses = self._retrieve_statuses(context, zone, action)
- for serial in self._get_serials_descending(pm_statuses):
- serial_count = 0
- for pm_status in pm_statuses:
- if pm_status.serial_number >= serial:
- serial_count += 1
- if self._exceed_or_meet_threshold(serial_count, self.threshold):
- consensus_serial = serial
- break
- return consensus_serial
-
- def _get_error_serial(self, context, zone, consensus_serial):
- error_serial = 0
- action = UPDATE_ACTION if zone.action == 'NONE' else zone.action
-
- if self._is_consensus(context, zone, action, ERROR_STATUS):
- pm_statuses = self._retrieve_statuses(context, zone, action)
- for serial in self._get_serials_ascending(pm_statuses):
- if serial > consensus_serial:
- error_serial = serial
- break
- return error_serial
-
- # When we hear back from the nameserver, the serial_number is set to the
- # value the nameserver
- @staticmethod
- def _build_status_object(nameserver, zone, action):
- """
- :return: :class:`objects.PoolManagerStatus`
- """
- values = {
- 'nameserver_id': nameserver.id,
- 'zone_id': zone.id,
- 'status': None,
- 'serial_number': 0,
- 'action': action
- }
- return objects.PoolManagerStatus(**values)
-
- # Methods for manipulating the cache.
- def _clear_cache(self, context, zone, action=None):
- LOG.debug('Clearing cache for zone %s with action %s.' %
- (zone.name, action))
-
- pool_manager_statuses = []
- if action:
- actions = [action]
- else:
- actions = [CREATE_ACTION, UPDATE_ACTION, DELETE_ACTION]
-
- for nameserver in self.pool.nameservers:
- for action in actions:
- pool_manager_status = self._build_status_object(
- nameserver, zone, action)
- pool_manager_statuses.append(pool_manager_status)
-
- for pool_manager_status in pool_manager_statuses:
- # Ignore any not found errors while clearing the cache
- try:
- self.cache.clear(context, pool_manager_status)
- except exceptions.PoolManagerStatusNotFound:
- pass
-
- def _retrieve_from_mdns(self, context, nameserver, zone, action):
- """Instruct MiniDNS to get a zone serial number from a nameserver
- Set error status if the zone is unexpectedly missing.
- :return: :class:`objects.PoolManagerStatus` or None
- """
- try:
- (status, actual_serial, retries) = \
- self.mdns_api.get_serial_number(
- context, zone, nameserver.host, nameserver.port,
- self.timeout, self.retry_interval, self.max_retries,
- self.delay)
- except messaging.MessagingException as msg_ex:
- LOG.debug('Could not retrieve status and serial for zone %s on '
- 'nameserver %s with action %s (%s: %s)',
- zone.name, self._get_destination(nameserver), action,
- type(msg_ex), str(msg_ex))
- return None
-
- pool_manager_status = self._build_status_object(
- nameserver, zone, action)
-
- if status == NO_ZONE_STATUS:
- if action == CREATE_ACTION:
- pool_manager_status.status = ERROR_STATUS
- elif action == DELETE_ACTION:
- pool_manager_status.status = SUCCESS_STATUS
- elif action == UPDATE_ACTION:
- pool_manager_status.action = CREATE_ACTION
- pool_manager_status.status = ERROR_STATUS
- else:
- pool_manager_status.status = status
-
- pool_manager_status.serial_number = actual_serial or 0
- LOG.debug('Retrieved status %s and serial %s for zone %s '
- 'on nameserver %s with action %s from mdns.',
- pool_manager_status.status,
- pool_manager_status.serial_number,
- zone.name, self._get_destination(nameserver), action)
- self.cache.store(context, pool_manager_status)
-
- return pool_manager_status
-
- def _retrieve_statuses(self, context, zone, action):
- """Instruct MiniDNS to get a zone serial number from all nameservers,
- unless a cached value is available.
- Set error status if the zone is unexpectedly missing.
- :return: list of :class:`objects.PoolManagerStatus`
- """
- pool_manager_statuses = []
- for nameserver in self.pool.nameservers:
- try:
- pool_manager_status = self.cache.retrieve(
- context, nameserver.id, zone.id, action)
- LOG.debug('Cache hit! Retrieved status %s and serial %s '
- 'for zone %s on nameserver %s with action %s from '
- 'the cache.',
- pool_manager_status.status,
- pool_manager_status.serial_number,
- zone.name,
- self._get_destination(nameserver), action)
- except exceptions.PoolManagerStatusNotFound:
- LOG.debug('Cache miss! Did not retrieve status and serial '
- 'for zone %s on nameserver %s with action %s from '
- 'the cache. Getting it from the server.',
- zone.name,
- self._get_destination(nameserver),
- action)
- pool_manager_status = self._retrieve_from_mdns(
- context, nameserver, zone, action)
-
- if pool_manager_status is not None:
- pool_manager_statuses.append(pool_manager_status)
-
- return pool_manager_statuses
diff --git a/designate/producer/service.py b/designate/producer/service.py
index 51af6882..2008d146 100644
--- a/designate/producer/service.py
+++ b/designate/producer/service.py
@@ -54,10 +54,7 @@ class Service(service.RPCService):
@property
def storage(self):
if not self._storage:
- # TODO(timsim): Remove this when zone_mgr goes away
- storage_driver = cfg.CONF['service:zone_manager'].storage_driver
- if cfg.CONF['service:producer'].storage_driver != storage_driver:
- storage_driver = cfg.CONF['service:producer'].storage_driver
+ storage_driver = cfg.CONF['service:producer'].storage_driver
self._storage = storage.get_storage(storage_driver)
return self._storage
@@ -88,14 +85,8 @@ class Service(service.RPCService):
self._partitioner.start()
self._partitioner.watch_partition_change(self._rebalance)
- # TODO(timsim): Remove this when zone_mgr goes away
- zmgr_enabled_tasks = CONF['service:zone_manager'].enabled_tasks
- producer_enabled_tasks = CONF['service:producer'].enabled_tasks
- enabled = zmgr_enabled_tasks
- if producer_enabled_tasks:
- enabled = producer_enabled_tasks
-
- for task in tasks.PeriodicTask.get_extensions(enabled):
+ enabled_tasks = CONF['service:producer'].enabled_tasks
+ for task in tasks.PeriodicTask.get_extensions(enabled_tasks):
LOG.debug("Registering task %s", task)
# Instantiate the task
diff --git a/designate/producer/tasks.py b/designate/producer/tasks.py
index 81dca0c3..5db0065f 100644
--- a/designate/producer/tasks.py
+++ b/designate/producer/tasks.py
@@ -20,7 +20,6 @@ from designate import plugin
from designate import rpc
from designate.central import rpcapi
from designate.worker import rpcapi as worker_rpcapi
-from designate.pool_manager import rpcapi as pool_manager_rpcapi
from oslo_config import cfg
from oslo_log import log as logging
@@ -49,15 +48,8 @@ class PeriodicTask(plugin.ExtensionPlugin):
return worker_rpcapi.WorkerAPI.get_instance()
@property
- def pool_manager_api(self):
- return pool_manager_rpcapi.PoolManagerAPI.get_instance()
-
- @property
def zone_api(self):
- # TODO(timsim): Remove this when pool_manager_api is gone
- if cfg.CONF['service:worker'].enabled:
- return self.worker_api
- return self.pool_manager_api
+ return self.worker_api
def on_partition_change(self, my_partitions, members, event):
"""Refresh partitions attribute
@@ -276,10 +268,6 @@ class WorkerPeriodicRecovery(PeriodicTask):
__plugin_name__ = 'worker_periodic_recovery'
def __call__(self):
- # TODO(timsim): Remove this when worker is always on
- if not cfg.CONF['service:worker'].enabled:
- return
-
pstart, pend = self._my_range()
LOG.info(
"Recovering zones for shards %(start)s to %(end)s",
diff --git a/designate/tests/__init__.py b/designate/tests/__init__.py
index 4df88cc5..3ed5412e 100644
--- a/designate/tests/__init__.py
+++ b/designate/tests/__init__.py
@@ -50,11 +50,6 @@ CONF.import_opt('auth_strategy', 'designate.api',
group='service:api')
CONF.import_opt('connection', 'designate.storage.impl_sqlalchemy',
group='storage:sqlalchemy')
-CONF.import_opt('cache_driver', 'designate.pool_manager',
- group='service:pool_manager')
-CONF.import_opt('connection',
- 'designate.pool_manager.cache.impl_sqlalchemy',
- group='pool_manager_cache:sqlalchemy')
CONF.import_opt('emitter_type', 'designate.service_status',
group="heartbeat_emitter")
CONF.import_opt('scheduler_filters', 'designate.scheduler',
@@ -377,8 +372,6 @@ class TestCase(base.BaseTestCase):
group='storage:sqlalchemy'
)
- self._setup_pool_manager_cache()
-
self.config(network_api='fake')
self.config(
@@ -400,31 +393,6 @@ class TestCase(base.BaseTestCase):
# Setup the Default Pool with some useful settings
self._setup_default_pool()
- def _setup_pool_manager_cache(self):
-
- self.config(
- cache_driver='sqlalchemy',
- group='service:pool_manager')
-
- repository = os.path.abspath(os.path.join(os.path.dirname(__file__),
- '..',
- 'pool_manager',
- 'cache',
- 'impl_sqlalchemy',
- 'migrate_repo'))
- db_fixture = self.useFixture(
- fixtures.DatabaseFixture.get_fixture(repository))
-
- if os.getenv('DESIGNATE_SQL_DEBUG', "False").lower() in _TRUE_VALUES:
- connection_debug = 50
- else:
- connection_debug = 0
-
- self.config(
- connection=db_fixture.url,
- connection_debug=connection_debug,
- group='pool_manager_cache:sqlalchemy')
-
def _setup_default_pool(self):
# Fetch the default pool
pool = self.storage.get_pool(self.admin_context, default_pool_id)
diff --git a/designate/tests/test_coordination.py b/designate/tests/test_coordination.py
index 67fbe149..f9285823 100644
--- a/designate/tests/test_coordination.py
+++ b/designate/tests/test_coordination.py
@@ -211,111 +211,3 @@ class TestPartitionerWithoutBackend(TestCase):
partitioner.start()
partitioner.watch_partition_change(cb)
cb.assert_called_with(partitions, None, None)
-
-
-class TestLeaderElection(TestCase):
- def setUp(self):
- super(TestLeaderElection, self).setUp()
-
- self.coord_fixture = self.useFixture(fixtures.CoordinatorFixture(
- 'zake://', b'InsertNameHere'))
-
- self.election = coordination.LeaderElection(
- self.coordinator, 'President')
-
- @property
- def coordinator(self):
- """Helper for quick access to the raw coordinator"""
- return self.coord_fixture.coordinator
-
- def test_is_leader(self):
- # We should not be leader until after we start the election.
- self.assertFalse(self.election.is_leader)
-
- # Start the election
- self.election.start()
- self.coordinator.run_watchers()
-
- # We should now be the leader.
- self.assertTrue(self.election.is_leader)
-
- # Stop the election
- self.election.stop()
-
- # We should no longer be the leader.
- self.assertFalse(self.election.is_leader)
-
- def test_callbacks(self):
- # We should not be leader until after we start the election.
- self.assertFalse(self.election.is_leader)
-
- # Create and attach a callback
- mock_callback_one = mock.Mock()
- self.election.watch_elected_as_leader(mock_callback_one)
-
- # Ensure the callback has not yet been called.
- self.assertFalse(mock_callback_one.called)
-
- # Start the election
- self.election.start()
- self.coordinator.run_watchers()
-
- # Ensure the callback has been called exactly once.
- self.assertEqual(1, mock_callback_one.call_count)
-
- # Create and attach a second callback after we start
- mock_callback_two = mock.Mock()
- self.election.watch_elected_as_leader(mock_callback_two)
-
- # Ensure the callback has been called exactly once.
- self.assertEqual(1, mock_callback_two.call_count)
-
-
-class TestLeaderElectionWithoutBackend(TestCase):
- def setUp(self):
- super(TestLeaderElectionWithoutBackend, self).setUp()
-
- # coordinator = None indicates no coordination backend has been
- # configured
- coordinator = None
- self.election = coordination.LeaderElection(coordinator, 'President')
-
- def test_is_leader(self):
- # We should not be leader until after we start the election.
- self.assertFalse(self.election.is_leader)
-
- # Start the election
- self.election.start()
-
- # We should now be the leader.
- self.assertTrue(self.election.is_leader)
-
- # Stop the election
- self.election.stop()
-
- # We should no longer be the leader.
- self.assertFalse(self.election.is_leader)
-
- def test_callbacks(self):
- # We should not be leader until after we start the election.
- self.assertFalse(self.election.is_leader)
-
- # Create and attach a callback
- mock_callback_one = mock.Mock()
- self.election.watch_elected_as_leader(mock_callback_one)
-
- # Ensure the callback has not yet been called.
- self.assertFalse(mock_callback_one.called)
-
- # Start the election
- self.election.start()
-
- # Ensure the callback has been called exactly once.
- self.assertEqual(1, mock_callback_one.call_count)
-
- # Create and attach a second callback after we start
- mock_callback_two = mock.Mock()
- self.election.watch_elected_as_leader(mock_callback_two)
-
- # Ensure the callback has been called exactly once.
- self.assertEqual(1, mock_callback_two.call_count)
diff --git a/designate/tests/test_pool_manager/__init__.py b/designate/tests/test_pool_manager/__init__.py
deleted file mode 100644
index 03f4480d..00000000
--- a/designate/tests/test_pool_manager/__init__.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 designate.tests import TestCase
-from designate.utils import DEFAULT_MDNS_PORT
-
-POOL_DICT = {
- 'id': u'794ccc2c-d751-44fe-b57f-8894c9f5c842',
- 'name': u'default',
- 'targets': [
- {
- 'id': 'f278782a-07dc-4502-9177-b5d85c5f7c7e',
- 'type': 'fake',
- 'masters': [
- {
- 'host': '127.0.0.1',
- 'port': DEFAULT_MDNS_PORT
- }
- ],
- 'options': {}
- },
- {
- 'id': 'a38703f2-b71e-4e5b-ab22-30caaed61dfd',
- 'type': 'fake',
- 'masters': [
- {
- 'host': '127.0.0.1',
- 'port': DEFAULT_MDNS_PORT
- }
- ],
- 'options': {}
- },
- ],
- 'nameservers': [
- {
- 'id': 'c5d64303-4cba-425a-9f3c-5d708584dde4',
- 'host': '127.0.0.1',
- 'port': 5355
-
- },
- {
- 'id': 'c67cdc95-9a9e-4d2a-98ed-dc78cbd85234',
- 'host': '127.0.0.1',
- 'port': 5356
- },
- ],
- 'also_notifies': [],
-}
-
-
-class PoolManagerTestCase(TestCase):
- pass
diff --git a/designate/tests/test_pool_manager/cache/__init__.py b/designate/tests/test_pool_manager/cache/__init__.py
deleted file mode 100644
index 2cf562d4..00000000
--- a/designate/tests/test_pool_manager/cache/__init__.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 testtools
-
-from designate import exceptions
-from designate import objects
-from designate.pool_manager.cache import base
-
-
-class PoolManagerCacheTestCase(object):
- def create_pool_manager_status(self):
- values = {
- 'nameserver_id': '896aa661-198c-4379-bccd-5d8de7007030',
- 'zone_id': 'bce45113-4a22-418d-a54d-c9777d056312',
- 'action': 'CREATE',
- 'status': 'SUCCESS',
- 'serial_number': 1
- }
- return objects.PoolManagerStatus.from_dict(values)
-
- def test_interface(self):
- self._ensure_interface(base.PoolManagerCache, self.cache.__class__)
-
- def test_store_and_clear_and_retrieve(self):
- expected = self.create_pool_manager_status()
- self.cache.store(self.admin_context, expected)
-
- self.cache.clear(self.admin_context, expected)
-
- with testtools.ExpectedException(exceptions.PoolManagerStatusNotFound):
- self.cache.retrieve(
- self.admin_context, expected.nameserver_id, expected.zone_id,
- expected.action)
-
- def test_retrieve(self):
- expected = self.create_pool_manager_status()
- with testtools.ExpectedException(exceptions.PoolManagerStatusNotFound):
- self.cache.retrieve(
- self.admin_context, expected.nameserver_id, expected.zone_id,
- expected.action)
diff --git a/designate/tests/test_pool_manager/cache/test_memcache.py b/designate/tests/test_pool_manager/cache/test_memcache.py
deleted file mode 100644
index e2c92c92..00000000
--- a/designate/tests/test_pool_manager/cache/test_memcache.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 mock import Mock
-
-from designate.pool_manager import cache
-from designate.tests import TestCase
-from designate.tests.test_pool_manager.cache import PoolManagerCacheTestCase
-
-
-class MemcachePoolManagerCacheTest(PoolManagerCacheTestCase, TestCase):
- def setUp(self):
- super(MemcachePoolManagerCacheTest, self).setUp()
-
- self.cache = cache.get_pool_manager_cache('memcache')
- self.mock_status = Mock(
- nameserver_id='nameserver_id',
- zone_id='zone_id',
- action='CREATE',
- )
-
- def test_store_and_retrieve(self):
- expected = self.create_pool_manager_status()
- self.cache.store(self.admin_context, expected)
-
- actual = self.cache.retrieve(
- self.admin_context, expected.nameserver_id, expected.zone_id,
- expected.action)
-
- self.assertEqual(expected.nameserver_id, actual.nameserver_id)
- self.assertEqual(expected.zone_id, actual.zone_id)
- self.assertEqual(expected.status, actual.status)
- self.assertEqual(expected.serial_number, actual.serial_number)
- self.assertEqual(expected.action, actual.action)
-
- def test_serial_number_key_is_a_string(self):
- """Memcache requires keys be strings.
-
- RabbitMQ messages are unicode by default, so any string
- interpolation requires explicit encoding.
- """
- key = self.cache._build_serial_number_key(self.mock_status)
- self.assertIsInstance(key, str)
- self.assertEqual(key, 'nameserver_id-zone_id-CREATE-serial_number')
-
- def test_status_key_is_a_string(self):
- """Memcache requires keys be strings.
-
- RabbitMQ messages are unicode by default, so any string
- interpolation requires explicit encoding.
- """
- key = self.cache._build_status_key(self.mock_status)
- self.assertIsInstance(key, str)
- self.assertEqual(key, 'nameserver_id-zone_id-CREATE-status')
diff --git a/designate/tests/test_pool_manager/cache/test_noop.py b/designate/tests/test_pool_manager/cache/test_noop.py
deleted file mode 100644
index 93313923..00000000
--- a/designate/tests/test_pool_manager/cache/test_noop.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 testtools
-
-from designate import exceptions
-from designate.pool_manager import cache
-from designate.tests import TestCase
-from designate.tests.test_pool_manager.cache import PoolManagerCacheTestCase
-
-
-class NoopPoolManagerCacheTest(PoolManagerCacheTestCase, TestCase):
- def setUp(self):
- super(NoopPoolManagerCacheTest, self).setUp()
-
- self.cache = cache.get_pool_manager_cache('noop')
-
- def test_store_and_retrieve(self):
- expected = self.create_pool_manager_status()
- self.cache.store(self.admin_context, expected)
-
- with testtools.ExpectedException(exceptions.PoolManagerStatusNotFound):
- self.cache.retrieve(
- self.admin_context, expected.nameserver_id, expected.zone_id,
- expected.action)
diff --git a/designate/tests/test_pool_manager/cache/test_sqlalchemy.py b/designate/tests/test_pool_manager/cache/test_sqlalchemy.py
deleted file mode 100644
index 751dd96a..00000000
--- a/designate/tests/test_pool_manager/cache/test_sqlalchemy.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 designate.pool_manager import cache
-from designate.tests import TestCase
-from designate.tests.test_pool_manager.cache import PoolManagerCacheTestCase
-
-
-class SqlalchemyPoolManagerCacheTest(PoolManagerCacheTestCase, TestCase):
- def setUp(self):
- super(SqlalchemyPoolManagerCacheTest, self).setUp()
-
- self.cache = cache.get_pool_manager_cache('sqlalchemy')
-
- def test_store_and_retrieve(self):
- expected = self.create_pool_manager_status()
- self.cache.store(self.admin_context, expected)
-
- actual = self.cache.retrieve(
- self.admin_context, expected.nameserver_id, expected.zone_id,
- expected.action)
-
- self.assertEqual(expected.nameserver_id, actual.nameserver_id)
- self.assertEqual(expected.zone_id, actual.zone_id)
- self.assertEqual(expected.status, actual.status)
- self.assertEqual(expected.serial_number, actual.serial_number)
- self.assertEqual(expected.action, actual.action)
diff --git a/designate/tests/test_pool_manager/test_rpcapi.py b/designate/tests/test_pool_manager/test_rpcapi.py
deleted file mode 100644
index 40143fae..00000000
--- a/designate/tests/test_pool_manager/test_rpcapi.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 mock
-from mock import patch
-import oslo_messaging as messaging
-
-from designate import objects
-from designate.pool_manager.rpcapi import PoolManagerAPI
-from designate.tests.test_pool_manager import PoolManagerTestCase
-
-
-class PoolManagerAPITest(PoolManagerTestCase):
-
- @patch.object(messaging.RPCClient, 'prepare')
- def test_create_zone(self, mock_prepare):
- inner_mock = mock.Mock()
- inner_mock.cast = mock.Mock(return_value=None)
- mock_prepare.return_value = inner_mock
-
- values = {
- 'name': 'example.org.',
- 'pool_id': '794ccc2c-d751-44fe-b57f-8894c9f5c842'
- }
- zone = objects.Zone.from_dict(values)
- PoolManagerAPI.get_instance().create_zone(self.admin_context, zone)
-
- mock_prepare.assert_called_once_with(
- topic='pool_manager.%s' % zone.pool_id)
- mock_prepare.return_value.cast.assert_called_once_with(
- self.admin_context, 'create_zone', zone=zone)
-
- @patch.object(messaging.RPCClient, 'prepare')
- def test_delete_zone(self, mock_prepare):
- inner_mock = mock.Mock()
- inner_mock.cast = mock.Mock(return_value=None)
- mock_prepare.return_value = inner_mock
-
- values = {
- 'name': 'example.org.',
- 'pool_id': '794ccc2c-d751-44fe-b57f-8894c9f5c842'
- }
- zone = objects.Zone.from_dict(values)
- PoolManagerAPI.get_instance().delete_zone(self.admin_context, zone)
-
- mock_prepare.assert_called_once_with(
- topic='pool_manager.%s' % zone.pool_id)
- mock_prepare.return_value.cast.assert_called_once_with(
- self.admin_context, 'delete_zone', zone=zone)
-
- @patch.object(messaging.RPCClient, 'prepare')
- def test_update_zone(self, mock_prepare):
- inner_mock = mock.Mock()
- inner_mock.cast = mock.Mock(return_value=None)
- mock_prepare.return_value = inner_mock
-
- values = {
- 'name': 'example.org.',
- 'pool_id': '794ccc2c-d751-44fe-b57f-8894c9f5c842'
- }
- zone = objects.Zone.from_dict(values)
- PoolManagerAPI.get_instance().update_zone(self.admin_context, zone)
-
- mock_prepare.assert_called_once_with(
- topic='pool_manager.%s' % zone.pool_id)
- mock_prepare.return_value.cast.assert_called_once_with(
- self.admin_context, 'update_zone', zone=zone)
-
- @patch.object(messaging.RPCClient, 'prepare')
- def test_update_status(self, mock_prepare):
- inner_mock = mock.Mock()
- inner_mock.cast = mock.Mock(return_value=None)
- mock_prepare.return_value = inner_mock
-
- values = {
- 'name': 'example.org.',
- 'pool_id': '794ccc2c-d751-44fe-b57f-8894c9f5c842'
- }
- zone = objects.Zone.from_dict(values)
- values = {
- 'host': '127.0.0.1',
- 'port': 53
- }
- nameserver = objects.PoolNameserver.from_dict(values)
- PoolManagerAPI.get_instance().update_status(
- self.admin_context, zone, nameserver, 'SUCCESS', 1)
-
- mock_prepare.assert_called_once_with(
- topic='pool_manager.%s' % zone.pool_id)
- mock_prepare.return_value.cast.assert_called_once_with(
- self.admin_context, 'update_status', zone=zone,
- nameserver=nameserver, status='SUCCESS', actual_serial=1)
diff --git a/designate/tests/test_pool_manager/test_service.py b/designate/tests/test_pool_manager/test_service.py
deleted file mode 100644
index 2610ebb8..00000000
--- a/designate/tests/test_pool_manager/test_service.py
+++ /dev/null
@@ -1,480 +0,0 @@
-# Copyright 2014 eBay Inc.
-#
-# Author: Ron Rickard <rrickard@ebaysf.com>
-#
-# 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 oslo_log import log
-import oslo_messaging as messaging
-from mock import call
-from mock import Mock
-from mock import patch
-
-from designate import exceptions
-from designate import objects
-from designate.utils import generate_uuid
-from designate.backend import impl_fake
-from designate.central import rpcapi as central_rpcapi
-from designate.mdns import rpcapi as mdns_rpcapi
-from designate.storage.impl_sqlalchemy import tables
-from designate.tests.test_pool_manager import PoolManagerTestCase
-from designate.tests.test_pool_manager import POOL_DICT
-import designate.pool_manager.service as pm_module
-
-LOG = log.getLogger(__name__)
-
-
-class PoolManagerServiceNoopTest(PoolManagerTestCase):
-
- def setUp(self):
- super(PoolManagerServiceNoopTest, self).setUp()
-
- self.config(
- threshold_percentage=100,
- enable_recovery_timer=False,
- enable_sync_timer=False,
- poll_retry_interval=0,
- poll_max_retries=1,
- cache_driver='noop',
- group='service:pool_manager')
-
- # TODO(kiall): Rework all this pool config etc into a fixture..
- # Configure the Pool ID
- self.config(
- pool_id='794ccc2c-d751-44fe-b57f-8894c9f5c842',
- group='service:pool_manager')
-
- # Start the Service
- with patch.object(
- central_rpcapi.CentralAPI,
- 'get_pool',
- return_value=objects.Pool.from_dict(POOL_DICT)):
- self.service = self.start_service('pool_manager')
- self.cache = self.service.cache
-
- @staticmethod
- def _build_zone(name, action, status, id=None):
- zid = id or '75ea1626-eea7-46b5-acb7-41e5897c2d40'
- values = {
- 'id': zid,
- 'name': name,
- 'pool_id': '794ccc2c-d751-44fe-b57f-8894c9f5c842',
- 'action': action,
- 'serial': 1422062497,
- 'status': status
- }
- return objects.Zone.from_dict(values)
-
- def _build_zones(self, n, action, status):
- return [
- self._build_zone("zone%02X.example." % cnt, action,
- status, id=generate_uuid())
- for cnt in range(n)
- ]
-
- @patch.object(mdns_rpcapi.MdnsAPI, 'get_serial_number',
- side_effect=messaging.MessagingException)
- @patch.object(mdns_rpcapi.MdnsAPI, 'poll_for_serial_number')
- @patch.object(mdns_rpcapi.MdnsAPI, 'notify_zone_changed')
- @patch.object(central_rpcapi.CentralAPI, 'update_status')
- def test_create_zone(
- self, mock_update_status, mock_notify_zone_changed,
- mock_poll_for_serial_number, _):
- zone = self._build_zone('example.org.', 'CREATE', 'PENDING')
-
- self.service.create_zone(self.admin_context, zone)
-
- create_statuses = self.service._retrieve_statuses(
- self.admin_context, zone, 'CREATE')
- # Even though _retrieve_statuses tries to get from mdns, mdns does
- # not return any status
- self.assertEqual(0, len(create_statuses))
-
- # Ensure poll_for_serial_number was called for each nameserver.
- self.assertEqual(2, mock_poll_for_serial_number.call_count)
- self.assertEqual(
- [call(self.admin_context, zone,
- self.service.pool.nameservers[0], 30, 0, 1, 5),
- call(self.admin_context, zone,
- self.service.pool.nameservers[1], 30, 0, 1, 5)],
- mock_poll_for_serial_number.call_args_list)
-
- # Pool manager needs to call into mdns to calculate consensus as
- # there is no cache. So update_status is never called.
- self.assertFalse(mock_update_status.called)
-
- @patch.object(mdns_rpcapi.MdnsAPI, 'get_serial_number',
- side_effect=messaging.MessagingException)
- @patch.object(impl_fake.FakeBackend, 'create_zone')
- @patch.object(mdns_rpcapi.MdnsAPI, 'poll_for_serial_number')
- @patch.object(mdns_rpcapi.MdnsAPI, 'notify_zone_changed')
- @patch.object(central_rpcapi.CentralAPI, 'update_status')
- def test_create_zone_target_both_failure(
- self, mock_update_status, mock_notify_zone_changed,
- mock_poll_for_serial_number, mock_create_zone, _):
- zone = self._build_zone('example.org.', 'CREATE', 'PENDING')
-
- mock_create_zone.side_effect = exceptions.Backend
-
- self.service.create_zone(self.admin_context, zone)
-
- create_statuses = self.service._retrieve_statuses(
- self.admin_context, zone, 'CREATE')
- self.assertEqual(0, len(create_statuses))
-
- # Since consensus is not reached this early, we immediately call
- # central's update_status.
- self.assertTrue(mock_update_status.called)
-
- @patch.object(mdns_rpcapi.MdnsAPI, 'get_serial_number',
- side_effect=messaging.MessagingException)
- @patch.object(impl_fake.FakeBackend, 'create_zone')
- @patch.object(mdns_rpcapi.MdnsAPI, 'poll_for_serial_number')
- @patch.object(mdns_rpcapi.MdnsAPI, 'notify_zone_changed')
- @patch.object(central_rpcapi.CentralAPI, 'update_status')
- def test_create_zone_target_one_failure(
- self, mock_update_status, mock_notify_zone_changed,
- mock_poll_for_serial_number, mock_create_zone, _):
-
- zone = self._build_zone('example.org.', 'CREATE', 'PENDING')
-
- mock_create_zone.side_effect = [exceptions.Backend, None]
-
- self.service.create_zone(self.admin_context, zone)
-
- create_statuses = self.service._retrieve_statuses(
- self.admin_context, zone, 'CREATE')
- self.assertEqual(0, len(create_statuses))
-
- # Since consensus is not reached this early, we immediately call
- # central's update_status.
- self.assertTrue(mock_update_status.called)
-
- @patch.object(mdns_rpcapi.MdnsAPI, 'get_serial_number',
- side_effect=messaging.MessagingException)
- @patch.object(impl_fake.FakeBackend, 'create_zone')
- @patch.object(mdns_rpcapi.MdnsAPI, 'poll_for_serial_number')
- @patch.object(mdns_rpcapi.MdnsAPI, 'notify_zone_changed')
- @patch.object(central_rpcapi.CentralAPI, 'update_status')
- def test_create_zone_target_one_failure_consensus(
- self, mock_update_status, mock_notify_zone_changed,
- mock_poll_for_serial_number, mock_create_zone, _):
-
- self.service.stop()
- self.config(
- threshold_percentage=50,
- group='service:pool_manager')
- with patch.object(
- central_rpcapi.CentralAPI,
- 'get_pool',
- return_value=objects.Pool.from_dict(POOL_DICT)):
- self.service = self.start_service('pool_manager')
-
- zone = self._build_zone('example.org.', 'CREATE', 'PENDING')
-
- mock_create_zone.side_effect = [None, exceptions.Backend]
-
- self.service.create_zone(self.admin_context, zone)
-
- create_statuses = self.service._retrieve_statuses(
- self.admin_context, zone, 'CREATE')
- self.assertEqual(0, len(create_statuses))
-
- # Ensure poll_for_serial_number was called for each nameserver.
- self.assertFalse(mock_update_status.called)
-
- @patch.object(mdns_rpcapi.MdnsAPI, 'get_serial_number',
- side_effect=messaging.MessagingException)
- @patch.object(central_rpcapi.CentralAPI, 'update_status')
- def test_update_status(self, mock_update_status, _):
-
- zone = self._build_zone('example.org.', 'UPDATE', 'PENDING')
-
- self.service.update_status(self.admin_context, zone,
- self.service.pool.nameservers[0],
- 'SUCCESS', zone.serial)
-
- update_statuses = self.service._retrieve_statuses(
- self.admin_context, zone, 'UPDATE')
- self.assertEqual(0, len(update_statuses))
-
- # Ensure update_status was not called.
- self.assertFalse(mock_update_status.called)
-
- self.service.update_status(self.admin_context, zone,
- self.service.pool.nameservers[1],
- 'SUCCESS', zone.serial)
-
- update_statuses = self.service._retrieve_statuses(
- self.admin_context, zone, 'UPDATE')
- self.assertEqual(0, len(update_statuses))
-
- # Ensure update_status was not called.
- self.assertFalse(mock_update_status.called)
-
- @patch.object(mdns_rpcapi.MdnsAPI, 'get_serial_number',
- side_effect=messaging.MessagingException)
- @patch.object(central_rpcapi.CentralAPI, 'update_status')
- def test_update_status_both_failure(self, mock_update_status, _):
- zone = self._build_zone('example.org.', 'UPDATE', 'PENDING')
-
- self.service.update_status(self.admin_context, zone,
- self.service.pool.nameservers[0],
- 'ERROR', zone.serial)
-
- update_statuses = self.service._retrieve_statuses(
- self.admin_context, zone, 'UPDATE')
- self.assertEqual(0, len(update_statuses))
-
- mock_update_status.assert_called_once_with(
- self.admin_context, zone.id, 'ERROR', 0)
-
- # Reset the mock call attributes.
- mock_update_status.reset_mock()
-
- self.service.update_status(self.admin_context, zone,
- self.service.pool.nameservers[1],
- 'ERROR', zone.serial)
-
- update_statuses = self.service._retrieve_statuses(
- self.admin_context, zone, 'UPDATE')
- self.assertEqual(0, len(update_statuses))
-
- mock_update_status.assert_called_once_with(
- self.admin_context, zone.id, 'ERROR', 0)
-
- @patch.object(mdns_rpcapi.MdnsAPI, 'get_serial_number',
- side_effect=messaging.MessagingException)
- @patch.object(central_rpcapi.CentralAPI, 'update_status')
- def test_update_status_one_failure(self, mock_update_status, _):
- zone = self._build_zone('example.org.', 'UPDATE', 'PENDING')
-
- self.service.update_status(self.admin_context, zone,
- self.service.pool.nameservers[0],
- 'SUCCESS', zone.serial)
-
- update_statuses = self.service._retrieve_statuses(
- self.admin_context, zone, 'UPDATE')
- self.assertEqual(0, len(update_statuses))
-
- # Ensure update_status was not called.
- self.assertFalse(mock_update_status.called)
-
- self.service.update_status(self.admin_context, zone,
- self.service.pool.nameservers[1],
- 'ERROR', zone.serial)
-
- update_statuses = self.service._retrieve_statuses(
- self.admin_context, zone, 'UPDATE')
- self.assertEqual(0, len(update_statuses))
-
- mock_update_status.assert_called_once_with(
- self.admin_context, zone.id, 'ERROR', 0)
-
- @patch.object(mdns_rpcapi.MdnsAPI, 'get_serial_number',
- side_effect=messaging.MessagingException)
- @patch.object(central_rpcapi.CentralAPI, 'update_status')
- def test_update_status_one_failure_consensus(self, mock_update_status, _):
-
- self.service.stop()
- self.config(
- threshold_percentage=50,
- group='service:pool_manager')
- with patch.object(
- central_rpcapi.CentralAPI,
- 'get_pool',
- return_value=objects.Pool.from_dict(POOL_DICT)):
- self.service = self.start_service('pool_manager')
-
- zone = self._build_zone('example.org.', 'UPDATE', 'PENDING')
-
- self.service.update_status(self.admin_context, zone,
- self.service.pool.nameservers[0],
- 'SUCCESS', zone.serial)
-
- update_statuses = self.service._retrieve_statuses(
- self.admin_context, zone, 'UPDATE')
- self.assertEqual(0, len(update_statuses))
-
- # Ensure update_status was not called.
- self.assertFalse(mock_update_status.called)
-
- # Reset the mock call attributes.
- mock_update_status.reset_mock()
-
- self.service.update_status(self.admin_context, zone,
- self.service.pool.nameservers[1],
- 'ERROR', zone.serial)
-
- update_statuses = self.service._retrieve_statuses(
- self.admin_context, zone, 'UPDATE')
- self.assertEqual(0, len(update_statuses))
-
- mock_update_status.assert_called_once_with(
- self.admin_context, zone.id, 'ERROR', 0)
-
- @patch.object(central_rpcapi.CentralAPI, 'find_zones')
- def test_periodic_sync_not_leader(self, mock_find_zones):
- self.service._update_zone_on_target = Mock(return_value=False)
- self.service._pool_election = Mock()
- self.service._pool_election.is_leader = False
- self.service.update_zone = Mock()
-
- self.service.periodic_sync()
- self.assertFalse(mock_find_zones.called)
-
- @patch.object(central_rpcapi.CentralAPI, 'update_status')
- def test_update_zone_no_consensus(self, mock_cent_update_status):
- zone = self._build_zone('example.org.', 'UPDATE', 'PENDING')
- self.service._update_zone_on_target = Mock(return_value=True)
- self.service._exceed_or_meet_threshold = Mock(return_value=False)
-
- ret = self.service.update_zone(self.admin_context, zone)
- self.assertFalse(ret)
-
- self.assertEqual(2, self.service._update_zone_on_target.call_count)
- self.assertEqual(1, mock_cent_update_status.call_count)
-
- @patch.object(mdns_rpcapi.MdnsAPI, 'poll_for_serial_number')
- def test_update_zone(self, mock_mdns_poll):
- zone = self._build_zone('example.org.', 'UPDATE', 'PENDING')
- self.service._update_zone_on_target = Mock(return_value=True)
- self.service._update_zone_on_also_notify = Mock()
- self.service.pool.also_notifies = objects.PoolAlsoNotifyList(
- objects=[objects.PoolAlsoNotify(host='1.0.0.0', port=1)]
- )
- self.service._exceed_or_meet_threshold = Mock(return_value=True)
-
- # cache.retrieve will throw exceptions.PoolManagerStatusNotFound
- # mdns_api.poll_for_serial_number will be called twice
- ret = self.service.update_zone(self.admin_context, zone)
- self.assertTrue(ret)
-
- self.assertEqual(2, self.service._update_zone_on_target.call_count)
- self.assertEqual(1, self.service._update_zone_on_also_notify.call_count) # noqa
- self.assertEqual(2, mock_mdns_poll.call_count)
-
- # Periodic sync
-
- @patch.object(mdns_rpcapi.MdnsAPI, 'notify_zone_changed')
- @patch.object(central_rpcapi.CentralAPI, 'update_status')
- @patch.object(central_rpcapi.CentralAPI, 'find_zones')
- def test_periodic_sync(self, mock_find_zones,
- mock_cent_update_status, *a):
- self.service.update_zone = Mock()
- mock_find_zones.return_value = self._build_zones(2, 'UPDATE',
- 'PENDING')
- self.service.periodic_sync()
-
- self.assertEqual(1, mock_find_zones.call_count)
- criterion = mock_find_zones.call_args_list[0][0][1]
- self.assertEqual('!ERROR', criterion['status'])
- self.assertEqual(2, self.service.update_zone.call_count)
- self.assertEqual(0, mock_cent_update_status.call_count)
-
- @patch.object(pm_module.time, 'sleep')
- @patch.object(mdns_rpcapi.MdnsAPI, 'notify_zone_changed')
- @patch.object(central_rpcapi.CentralAPI, 'update_status')
- @patch.object(central_rpcapi.CentralAPI, 'find_zones')
- def test_periodic_sync_with_failing_update(
- self, mock_find_zones, mock_cent_update_status, *mocks):
- self.service.update_zone = Mock(return_value=False) # fail update
- mock_find_zones.return_value = self._build_zones(3, 'UPDATE',
- 'PENDING')
- self.service.periodic_sync()
-
- self.assertEqual(1, mock_find_zones.call_count)
- criterion = mock_find_zones.call_args_list[0][0][1]
- self.assertEqual('!ERROR', criterion['status'])
-
- # 3 zones, all failing, with 3 attempts: 9 calls
- self.assertEqual(9, self.service.update_zone.call_count)
-
- # the zones have been put in ERROR status
- self.assertEqual(3, mock_cent_update_status.call_count)
-
- @patch.object(pm_module.time, 'sleep')
- @patch.object(mdns_rpcapi.MdnsAPI, 'notify_zone_changed')
- @patch.object(central_rpcapi.CentralAPI, 'update_status')
- @patch.object(central_rpcapi.CentralAPI, 'find_zones')
- def test_periodic_sync_with_failing_update_with_exception(
- self, mock_find_zones, mock_cent_update_status, *mocks):
- self.service.update_zone = Mock(side_effect=Exception)
- mock_find_zones.return_value = self._build_zones(3, 'UPDATE',
- 'PENDING')
- self.service.periodic_sync()
-
- self.assertEqual(1, mock_find_zones.call_count)
- criterion = mock_find_zones.call_args_list[0][0][1]
- self.assertEqual('!ERROR', criterion['status'])
-
- # 3 zones, all failing, with 3 attempts: 9 calls
- self.assertEqual(9, self.service.update_zone.call_count)
-
- # the zones have been put in ERROR status
- self.assertEqual(3, mock_cent_update_status.call_count)
-
-
-class PoolManagerServiceEndToEndTest(PoolManagerServiceNoopTest):
-
- def setUp(self):
- super(PoolManagerServiceEndToEndTest, self).setUp()
-
- def _fetch_all_zones(self):
- """Fetch all zones including deleted ones
- """
- query = tables.zones.select()
- return self.storage.session.execute(query).fetchall()
-
- def _log_all_zones(self, zones, msg=None):
- """Log out a summary of zones
- """
- if msg:
- LOG.debug("--- %s ---" % msg)
- cols = ('name', 'status', 'action', 'deleted', 'deleted_at',
- 'parent_zone_id')
- tpl = "%-35s | %-11s | %-11s | %-32s | %-20s | %s"
- LOG.debug(tpl % cols)
- for z in zones:
- LOG.debug(tpl % tuple(z[k] for k in cols))
-
- def _assert_count_all_zones(self, n):
- """Assert count ALL zones including deleted ones
- """
- zones = self._fetch_all_zones()
- if len(zones) == n:
- return
-
- msg = "failed: %d zones expected, %d found" % (n, len(zones))
- self._log_all_zones(zones, msg=msg)
- raise Exception("Unexpected number of zones")
-
- def _assert_num_failed_zones(self, action, n):
- zones = self.service._get_failed_zones(
- self.admin_context, action)
- if len(zones) != n:
- LOG.error("Expected %d failed zones, got %d", n, len(zones))
- self._log_all_zones(zones, msg='listing zones')
- self.assertEqual(n, len(zones))
-
- def _assert_num_healthy_zones(self, action, n):
- criterion = {
- 'action': action,
- 'pool_id': pm_module.CONF['service:pool_manager'].pool_id,
- 'status': '!%s' % pm_module.ERROR_STATUS
- }
- zones = self.service.central_api.find_zones(self.admin_context,
- criterion)
- if len(zones) != n:
- LOG.error("Expected %d healthy zones, got %d", n, len(zones))
- self._log_all_zones(zones, msg='listing zones')
- self.assertEqual(n, len(zones))
diff --git a/designate/tests/unit/backend/test_agent.py b/designate/tests/unit/backend/test_agent.py
index 2e99fc83..dcd4668c 100644
--- a/designate/tests/unit/backend/test_agent.py
+++ b/designate/tests/unit/backend/test_agent.py
@@ -28,11 +28,11 @@ from designate.tests.unit import RoObject
class AgentBackendTestCase(tests.TestCase):
def setUp(self):
super(AgentBackendTestCase, self).setUp()
- self.CONF.set_override('poll_timeout', 1, 'service:pool_manager')
+ self.CONF.set_override('poll_timeout', 1, 'service:worker')
self.CONF.set_override('poll_retry_interval', 4,
- 'service:pool_manager')
- self.CONF.set_override('poll_max_retries', 5, 'service:pool_manager')
- self.CONF.set_override('poll_delay', 6, 'service:pool_manager')
+ 'service:worker')
+ self.CONF.set_override('poll_max_retries', 5, 'service:worker')
+ self.CONF.set_override('poll_delay', 6, 'service:worker')
self.context = self.get_context()
self.zone = objects.Zone(
diff --git a/designate/tests/unit/mdns/test_notify.py b/designate/tests/unit/mdns/test_notify.py
index 6174ac08..29160449 100644
--- a/designate/tests/unit/mdns/test_notify.py
+++ b/designate/tests/unit/mdns/test_notify.py
@@ -20,7 +20,6 @@ import dns.rdataclass
import dns.rdatatype
import mock
-import designate.mdns.base as mdnsbase
import designate.mdns.notify as notify
import designate.tests
from designate.tests.unit import RoObject
@@ -42,24 +41,6 @@ class MdnsNotifyTest(designate.tests.TestCase):
1, 2, 3, 4, 5, 6, notify=True
)
- @mock.patch.object(mdnsbase.pool_mngr_api.PoolManagerAPI, 'get_instance')
- def test_poll_for_serial_number(self, mock_get_instance):
- self.notify.get_serial_number = mock.Mock(
- return_value=('status', 99, 9)
- )
- ns = RoObject(host='host', port=1234)
-
- self.notify.poll_for_serial_number(
- 'c', 'z', ns, 1, 2, 3, 4
- )
-
- self.notify.get_serial_number.assert_called_with(
- 'c', 'z', 'host', 1234, 1, 2, 3, 4
- )
- self.notify.pool_manager_api.update_status.assert_called_with(
- 'c', 'z', ns, 'status', 99
- )
-
@mock.patch('time.sleep')
def test_get_serial_number_nxdomain(self, mock_sleep):
# The zone is not found but it was supposed to be there
diff --git a/designate/tests/unit/pool_manager/__init__.py b/designate/tests/unit/pool_manager/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/designate/tests/unit/pool_manager/__init__.py
+++ /dev/null
diff --git a/designate/tests/unit/pool_manager/test_service.py b/designate/tests/unit/pool_manager/test_service.py
deleted file mode 100644
index 9ab3f808..00000000
--- a/designate/tests/unit/pool_manager/test_service.py
+++ /dev/null
@@ -1,326 +0,0 @@
-# Copyright 2015 Hewlett-Packard Development Company, L.P.
-#
-# Author: Federico Ceratto <federico.ceratto@hpe.com>
-#
-# 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 time
-from datetime import datetime
-
-import mock
-from oslo_config import cfg
-from oslo_config import fixture as cfg_fixture
-
-from designate import exceptions
-from designate import objects
-from designate import tests
-from designate.pool_manager import service
-
-CONF = cfg.CONF
-
-POOL_DICT = {
- 'also_notifies': [
- {
- 'host': u'192.0.2.4',
- 'pool_id': u'cf2e8eab-76cd-4162-bf76-8aeee3556de0',
- 'port': 53,
- }
- ],
- 'attributes': [],
- 'description': u'Default PowerDNS Pool',
- 'id': u'cf2e8eab-76cd-4162-bf76-8aeee3556de0',
- 'name': u'default',
- 'nameservers': [
- {
- 'host': u'192.0.2.2',
- 'pool_id': u'cf2e8eab-76cd-4162-bf76-8aeee3556de0',
- 'port': 53,
- },
- {
- 'host': u'192.0.2.3',
- 'pool_id': u'cf2e8eab-76cd-4162-bf76-8aeee3556de0',
- 'port': 53,
- }
- ],
- 'ns_records': [
- {
- 'hostname': u'ns1-1.example.org.',
- 'pool_id': u'cf2e8eab-76cd-4162-bf76-8aeee3556de0',
- 'priority': 1,
- },
- {
- 'hostname': u'ns1-2.example.org.',
- 'pool_id': u'cf2e8eab-76cd-4162-bf76-8aeee3556de0',
- 'priority': 2,
- }
- ],
- 'provisioner': u'UNMANAGED',
- 'targets': [
- {
- 'description': u'PowerDNS Database Cluster',
- 'masters': [],
- 'options': [],
- 'type': 'fake',
- 'pool_id': u'cf2e8eab-76cd-4162-bf76-8aeee3556de0',
- }
- ]
-}
-
-
-class PoolManagerInitTest(tests.TestCase):
- def setUp(self):
- super(PoolManagerInitTest, self).setUp()
- self.useFixture(cfg_fixture.Config(CONF))
-
- self.service = service.Service()
-
- def test_init_no_pool_targets(self):
- pool_dict = dict(POOL_DICT)
- pool_dict['targets'] = []
-
- self.service.pool = objects.Pool.from_dict(pool_dict)
- self.assertRaises(
- exceptions.NoPoolTargetsConfigured,
- self.service._setup_target_backends
- )
-
- def test_service_name(self):
- self.assertEqual('pool_manager', self.service.service_name)
-
- def test_pool_manager_rpc_topic(self):
- CONF.set_override('topic', 'test-topic', 'service:pool_manager')
-
- self.service = service.Service()
-
- self.assertEqual('test-topic.794ccc2c-d751-44fe-b57f-8894c9f5c842',
- self.service.rpc_topic)
- self.assertEqual('pool_manager', self.service.service_name)
-
- @mock.patch('designate.service.RPCService.start')
- def test_start(self, mock_rpc_start):
- self.service.tg.add_timer = mock.Mock()
- self.service._pool_election = mock.Mock()
-
- with mock.patch.object(
- self.service.central_api,
- 'get_pool',
- return_value=objects.Pool.from_dict(POOL_DICT)):
- self.service.start()
-
- call1 = self.service.tg.add_timer.call_args_list[0][0]
- self.assertEqual(120, call1[0])
- self.assertEqual(120, call1[-1])
-
- call2 = self.service.tg.add_timer.call_args_list[1][0]
- self.assertEqual(1800, call2[0])
- self.assertEqual(1800, call2[-1])
-
- @mock.patch.object(time, 'sleep')
- def test_constant_retries(self, mock_sleep):
- gen = service._constant_retries(5, 2)
- out = list(gen)
- self.assertEqual(
- [False, False, False, False, True],
- out
- )
- self.assertEqual(4, mock_sleep.call_count)
- mock_sleep.assert_called_with(2)
-
-
-class PoolManagerTest(tests.TestCase):
- def setUp(self):
- super(PoolManagerTest, self).setUp()
- self.context = self.get_context()
- self.zone = objects.Zone(
- name="example.com.",
- type="PRIMARY",
- email="hostmaster@example.com",
- serial=1,
- )
-
- self.service = service.Service()
- self.service.tg.add_timer = mock.Mock()
- self.service.pool = mock.Mock()
- setattr(self.service.pool, 'targets', ())
- setattr(self.service.pool, 'also_notifies', ())
- setattr(self.service.pool, 'nameservers', ())
- self.service._pool_election = mock.Mock()
- self.service.target_backends = {}
-
- @mock.patch.object(service.central_api.CentralAPI, 'find_zones')
- @mock.patch.object(service.utils, 'increment_serial')
- def test_get_failed_zones(self, mock_increment_serial, mock_find_zones):
- mock_increment_serial.return_value = 1453758656
-
- self.service._get_failed_zones(self.context, service.DELETE_ACTION)
-
- call_one = mock.call(
- self.context,
- {
- 'action': 'DELETE',
- 'status': 'ERROR',
- 'pool_id': '794ccc2c-d751-44fe-b57f-8894c9f5c842'
- }
- )
-
- call_two = mock.call(
- self.context,
- {
- 'action': 'DELETE',
- 'status': 'PENDING',
- 'serial': '<1453758201', # 1453758656-455
- 'pool_id': '794ccc2c-d751-44fe-b57f-8894c9f5c842'
- }
- )
-
- # any_order because Mock adds some random calls in
- mock_find_zones.assert_has_calls([call_one, call_two],
- any_order=True)
-
- def test_periodic_recover(self):
- def mock_get_failed_zones(ctx, action):
- if action == service.DELETE_ACTION:
- return [self.zone] * 3
- if action == service.CREATE_ACTION:
- return [self.zone] * 4
- if action == service.UPDATE_ACTION:
- return [self.zone] * 5
-
- self.service._get_admin_context_all_tenants = mock.Mock(
- return_value=self.context
- )
- self.service._get_failed_zones = mock_get_failed_zones
- self.service.pool_manager_api.delete_zone = mock.Mock()
- self.service.pool_manager_api.create_zone = mock.Mock()
- self.service.pool_manager_api.update_zone = mock.Mock()
-
- self.service.periodic_recovery()
-
- self.service.pool_manager_api.delete_zone.assert_called_with(
- self.context, self.zone
- )
-
- self.assertEqual(
- 3, self.service.pool_manager_api.delete_zone.call_count
- )
-
- self.service.pool_manager_api.create_zone.assert_called_with(
- self.context, self.zone
- )
- self.assertEqual(
- 4, self.service.pool_manager_api.create_zone.call_count
- )
-
- self.service.pool_manager_api.update_zone.assert_called_with(
- self.context, self.zone
- )
-
- self.assertEqual(
- 5, self.service.pool_manager_api.update_zone.call_count
- )
-
- def test_periodic_recover_exception(self):
- # Raise an exception half through the recovery
-
- def mock_get_failed_zones(ctx, action):
- if action == service.DELETE_ACTION:
- return [self.zone] * 3
- if action == service.CREATE_ACTION:
- return [self.zone] * 4
-
- self.service._get_admin_context_all_tenants = mock.Mock(
- return_value=self.context
- )
- self.service._get_failed_zones = mock_get_failed_zones
- self.service.pool_manager_api.delete_zone = mock.Mock()
- self.service.pool_manager_api.create_zone = mock.Mock(
- side_effect=Exception('oops')
- )
- self.service.pool_manager_api.update_zone = mock.Mock()
-
- self.service.periodic_recovery()
-
- self.service.pool_manager_api.delete_zone.assert_called_with(
- self.context, self.zone
- )
-
- self.assertEqual(
- 3, self.service.pool_manager_api.delete_zone.call_count
- )
-
- self.service.pool_manager_api.create_zone.assert_called_with(
- self.context, self.zone
- )
-
- self.assertEqual(
- 1, self.service.pool_manager_api.create_zone.call_count
- )
-
- self.assertEqual(
- 0, self.service.pool_manager_api.update_zone.call_count
- )
-
- def test_periodic_sync(self, ):
- self.service._fetch_healthy_zones = mock.Mock(return_value=[
- objects.Zone(name='a_zone.'),
- objects.Zone(name='b_zone.'),
- objects.Zone(name='c_zone.'),
- ])
-
- self.service.update_zone = mock.Mock()
- self.service._exceed_or_meet_threshold = mock.Mock(return_value=True)
-
- self.service.periodic_sync()
-
- self.assertEqual(3, self.service.update_zone.call_count)
-
- def test_target_sync(self):
- date = 1463154200
- older_date = datetime.fromtimestamp(1463154000)
- newer_date = datetime.fromtimestamp(1463154300)
-
- zones = [
- objects.Zone(name='a_zone.', status='ACTIVE',
- created_at=older_date),
- objects.Zone(name='b_zone.', status='ACTIVE',
- created_at=newer_date),
- objects.Zone(name='c_zone.', status='DELETED',
- created_at=older_date, serial=1),
- ]
-
- self.service._delete_zone_on_target = mock.Mock()
- self.service._create_zone_on_target = mock.Mock()
- self.service._update_zone_on_target = mock.Mock()
- self.service.mdns_api.poll_for_serial_number = mock.Mock()
-
- target = mock.Mock()
-
- self.service._target_sync(self.context, zones, target, date)
-
- self.assertEqual(1, self.service._delete_zone_on_target.call_count)
- self.assertEqual(1, self.service._create_zone_on_target.call_count)
- self.assertEqual(1, self.service._update_zone_on_target.call_count)
-
- def test_create_zone(self):
- self.service._exceed_or_meet_threshold = mock.Mock(return_value=True)
-
- self.service.create_zone(self.context, self.zone)
-
- def test_update_zone(self, ):
- self.service._exceed_or_meet_threshold = mock.Mock(return_value=True)
-
- self.service.update_zone(self.context, self.zone)
-
- def test_delete_zone(self):
- self.service._exceed_or_meet_threshold = mock.Mock(return_value=True)
-
- self.service.delete_zone(self.context, self.zone)
diff --git a/designate/tests/unit/producer/test_service.py b/designate/tests/unit/producer/test_service.py
index 1379a5ff..5e21911b 100644
--- a/designate/tests/unit/producer/test_service.py
+++ b/designate/tests/unit/producer/test_service.py
@@ -40,11 +40,6 @@ class ProducerTest(oslotest.base.BaseTestCase):
'service:producer': RoObject({
'enabled_tasks': None, # enable all tasks
}),
- # TODO(timsim): Remove this
- 'service:zone_manager': RoObject({
- 'enabled_tasks': None, # enable all tasks
- 'export_synchronous': True
- }),
'producer_task:zone_purge': '',
})
super(ProducerTest, self).setUp()
diff --git a/designate/tests/unit/test_central/test_basic.py b/designate/tests/unit/test_central/test_basic.py
index 79bea8fa..ba20121a 100644
--- a/designate/tests/unit/test_central/test_basic.py
+++ b/designate/tests/unit/test_central/test_basic.py
@@ -208,15 +208,6 @@ mdns_api = mock.PropertyMock(
])
)
-fx_pool_manager = fixtures.MockPatch(
- 'designate.central.service.pool_manager_rpcapi.Pool'
- 'ManagerAPI.get_instance',
- mock.MagicMock(spec_set=[
- 'create_zone',
- 'update_zone',
- 'delete_zone'
- ])
-)
fx_worker = fixtures.MockPatch(
'designate.central.service.worker_rpcapi.WorkerAPI.get_instance',
@@ -277,7 +268,6 @@ class CentralBasic(TestCase):
'get_storage',
])
designate.central.service.rpcapi = mock.Mock()
- designate.central.service.pool_manager_rpcapi = mock.Mock()
designate.central.service.worker_rpcapi = mock.Mock()
self.context = mock.NonCallableMock(spec_set=[
'elevated',
@@ -1013,8 +1003,7 @@ class CentralZoneTestCase(CentralBasic):
self.service.delete_zone(self.context,
CentralZoneTestCase.zone__id)
self.assertTrue(self.service.storage.delete_zone.called)
- self.assertFalse(
- self.service.pool_manager_api.delete_zone.called)
+ self.assertFalse(self.service.zone_api.delete_zone.called)
pcheck, _, _ = designate.central.service.policy.check.call_args[0]
self.assertEqual('abandon_zone', pcheck)
@@ -1141,40 +1130,22 @@ class CentralZoneTestCase(CentralBasic):
self.assertEqual(exceptions.ReportNotFound, exc.exc_info[0])
- def _test_touch_zone(self, worker_enabled=True):
- if not worker_enabled:
- self.config(
- enabled="False",
- group="service:worker"
- )
-
+ def test_touch_zone_with_worker_model(self):
self.service._touch_zone_in_storage = Mock()
self.service.storage.get_zone.return_value = RoObject(
name='example.org.',
tenant_id='2',
)
- if worker_enabled:
- with fx_worker:
- self.service.touch_zone(self.context,
- CentralZoneTestCase.zone__id)
- else:
- with fx_pool_manager:
- self.service.touch_zone(self.context,
- CentralZoneTestCase.zone__id)
-
+ with fx_worker:
+ self.service.touch_zone(self.context,
+ CentralZoneTestCase.zone__id)
self.assertTrue(designate.central.service.policy.check.called)
self.assertEqual(
'touch_zone',
designate.central.service.policy.check.call_args[0][0]
)
- def test_touch_zone_with_worker_model(self):
- self._test_touch_zone(worker_enabled=True)
-
- def test_touch_zone_with_pool_manager_model(self):
- self._test_touch_zone(worker_enabled=False)
-
def test_get_recordset_not_found(self):
self.service.storage.get_zone.return_value = RoObject(
id=CentralZoneTestCase.zone__id,
@@ -1301,12 +1272,7 @@ class CentralZoneTestCase(CentralBasic):
self.assertEqual(exceptions.BadRequest, exc.exc_info[0])
- def _test_update_recordset(self, worker_enabled=True):
- if not worker_enabled:
- self.config(
- enabled="False",
- group="service:worker"
- )
+ def test_update_recordset_worker_model(self):
self.service.storage.get_zone.return_value = RoObject(
type='foo',
name='example.org.',
@@ -1322,12 +1288,8 @@ class CentralZoneTestCase(CentralBasic):
return_value=('x', 'y')
)
- if worker_enabled:
- with fx_worker:
- self.service.update_recordset(self.context, recordset)
- else:
- with fx_pool_manager:
- self.service.update_recordset(self.context, recordset)
+ with fx_worker:
+ self.service.update_recordset(self.context, recordset)
self.assertTrue(
self.service._update_recordset_in_storage.called)
@@ -1340,12 +1302,6 @@ class CentralZoneTestCase(CentralBasic):
'recordset_id': '9c85d9b0-1e9d-4e99-aede-a06664f1af2e',
'tenant_id': '2'}, target)
- def test_update_recordset_worker_model(self):
- self._test_update_recordset(worker_enabled=True)
-
- def test_update_recordset_pool_manager_model(self):
- self._test_update_recordset(worker_enabled=False)
-
def test__update_recordset_in_storage(self):
recordset = Mock()
recordset.name = 'n'
@@ -1500,12 +1456,7 @@ class CentralZoneTestCase(CentralBasic):
self.assertEqual(exceptions.BadRequest, exc.exc_info[0])
- def _test_delete_recordset(self, worker_enabled=True):
- if not worker_enabled:
- self.config(
- enabled="False",
- group="service:worker"
- )
+ def test_delete_recordset_worker(self):
mock_zone = RoObject(
action='foo',
id=CentralZoneTestCase.zone__id_2,
@@ -1528,29 +1479,15 @@ class CentralZoneTestCase(CentralBasic):
return_value=(mock_rs, mock_zone)
)
- if worker_enabled:
- with fx_worker:
- self.service.delete_recordset(self.context,
- CentralZoneTestCase.zone__id_2,
- CentralZoneTestCase.recordset__id)
- self.assertTrue(
- self.service.zone_api.update_zone.called)
- else:
- with fx_pool_manager:
- self.service.delete_recordset(self.context,
- CentralZoneTestCase.zone__id_2,
- CentralZoneTestCase.recordset__id)
- self.assertTrue(
- self.service.zone_api.update_zone.called)
-
+ with fx_worker:
+ self.service.delete_recordset(self.context,
+ CentralZoneTestCase.zone__id_2,
+ CentralZoneTestCase.recordset__id)
self.assertTrue(
- self.service._delete_recordset_in_storage.called)
-
- def test_delete_recordset_worker(self):
- self._test_delete_recordset(worker_enabled=True)
+ self.service.zone_api.update_zone.called)
- def test_delete_recordset_pool_manager(self):
- self._test_delete_recordset(worker_enabled=False)
+ self.assertTrue(
+ self.service._delete_recordset_in_storage.called)
def test__delete_recordset_in_storage(self):
def mock_uds(c, zone, inc):
@@ -1620,9 +1557,7 @@ class CentralZoneTestCase(CentralBasic):
self.assertEqual(exceptions.BadRequest, exc.exc_info[0])
- def _test_create_record(self, worker_enabled=True):
- if not worker_enabled:
- self.config(enabled="False", group="service:worker")
+ def _test_create_record(self):
self.service._create_record_in_storage = Mock(
return_value=(None, None)
)
@@ -1637,24 +1572,14 @@ class CentralZoneTestCase(CentralBasic):
name='rs',
)
- if worker_enabled:
- with fx_worker:
- self.service.create_record(
- self.context,
- CentralZoneTestCase.zone__id,
- CentralZoneTestCase.recordset__id,
- RoObject())
- self.assertTrue(
- self.service.zone_api.update_zone.called)
- else:
- with fx_pool_manager:
- self.service.create_record(
- self.context,
- CentralZoneTestCase.zone__id,
- CentralZoneTestCase.recordset__id,
- RoObject())
- self.assertTrue(
- self.service.zone_api.update_zone.called)
+ with fx_worker:
+ self.service.create_record(
+ self.context,
+ CentralZoneTestCase.zone__id,
+ CentralZoneTestCase.recordset__id,
+ RoObject())
+ self.assertTrue(
+ self.service.zone_api.update_zone.called)
n, ctx, target = designate.central.service.policy.check.call_args[0]
self.assertEqual('create_record', n)
@@ -1667,10 +1592,7 @@ class CentralZoneTestCase(CentralBasic):
'tenant_id': '2'}, target)
def test_create_record_worker(self):
- self._test_create_record(worker_enabled=True)
-
- def test_create_record_pool_manager(self):
- self._test_create_record(worker_enabled=False)
+ self._test_create_record()
def test__create_record_in_storage(self):
self.service._enforce_record_quota = Mock()
@@ -1835,9 +1757,7 @@ class CentralZoneTestCase(CentralBasic):
self.assertEqual(exceptions.BadRequest, exc.exc_info[0])
- def _test_update_record(self, worker_enabled=True):
- if not worker_enabled:
- self.config(enabled="False", group="service:worker")
+ def test_update_record_worker(self):
self.service.storage.get_zone.return_value = RoObject(
action='a',
name='n',
@@ -1857,12 +1777,9 @@ class CentralZoneTestCase(CentralBasic):
return_value=('x', 'y')
)
- if worker_enabled:
- with fx_worker:
- self.service.update_record(self.context, record)
- else:
- with fx_pool_manager:
- self.service.update_record(self.context, record)
+ with fx_worker:
+ self.service.update_record(self.context, record)
+
self.assertTrue(self.service._update_record_in_storage.called)
n, ctx, target = designate.central.service.policy.check.call_args[0]
@@ -1876,12 +1793,6 @@ class CentralZoneTestCase(CentralBasic):
'recordset_name': 'rsn',
'tenant_id': 'tid'}, target)
- def test_update_record_worker(self):
- self._test_update_record(worker_enabled=True)
-
- def test_update_record_pool_manager(self):
- self._test_update_record(worker_enabled=False)
-
def test__update_record_in_storage(self):
self.service._update_zone_in_storage = Mock()
self.service._update_record_in_storage(
@@ -1947,9 +1858,7 @@ class CentralZoneTestCase(CentralBasic):
self.assertEqual(exceptions.RecordNotFound, exc.exc_info[0])
- def _test_delete_record(self, worker_enabled=True):
- if not worker_enabled:
- self.config(enabled="False", group="service:worker")
+ def test_delete_record_worker(self):
self.service._delete_record_in_storage = Mock(
return_value=(None, None)
)
@@ -1971,18 +1880,11 @@ class CentralZoneTestCase(CentralBasic):
managed=False,
)
- if worker_enabled:
- with fx_worker:
- self.service.delete_record(self.context,
- CentralZoneTestCase.zone__id_2,
- CentralZoneTestCase.recordset__id_2,
- CentralZoneTestCase.record__id)
- else:
- with fx_pool_manager:
- self.service.delete_record(self.context,
- CentralZoneTestCase.zone__id_2,
- CentralZoneTestCase.recordset__id_2,
- CentralZoneTestCase.record__id)
+ with fx_worker:
+ self.service.delete_record(self.context,
+ CentralZoneTestCase.zone__id_2,
+ CentralZoneTestCase.recordset__id_2,
+ CentralZoneTestCase.record__id)
t, ctx, target = designate.central.service.policy.check.call_args[0]
self.assertEqual('delete_record', t)
@@ -1995,46 +1897,6 @@ class CentralZoneTestCase(CentralBasic):
'recordset_name': 'rsn',
'tenant_id': 'tid'}, target)
- def test_delete_record_worker(self):
- self._test_delete_record(worker_enabled=True)
-
- def test_delete_record_pool_manager(self):
- self._test_delete_record(worker_enabled=False)
-
- def test_delete_record_fail_on_managed(self):
- self.service._delete_record_in_storage = Mock(
- return_value=(None, None)
- )
- self.service.storage.get_zone.return_value = RoObject(
- action='a',
- id=CentralZoneTestCase.zone__id,
- name='dn',
- tenant_id='tid',
- type='t',
- )
- self.service.storage.get_record.return_value = RoObject(
- id=CentralZoneTestCase.record__id,
- zone_id=CentralZoneTestCase.zone__id,
- recordset_id=CentralZoneTestCase.recordset__id,
- )
- self.service.storage.get_recordset.return_value = RoObject(
- name='rsn',
- id=CentralZoneTestCase.recordset__id,
- managed=True,
- )
- self.context = Mock()
- self.context.edit_managed_records = False
-
- with fx_pool_manager:
- exc = self.assertRaises(rpc_dispatcher.ExpectedException,
- self.service.delete_record,
- self.context,
- CentralZoneTestCase.zone__id_2,
- CentralZoneTestCase.recordset__id_2,
- CentralZoneTestCase.record__id_2)
-
- self.assertEqual(exceptions.BadRequest, exc.exc_info[0])
-
def test_delete_record_in_storage(self):
self.service._delete_record_in_storage(
self.context,
diff --git a/designate/tests/unit/test_pool.py b/designate/tests/unit/test_pool.py
deleted file mode 100644
index c8e6ebe2..00000000
--- a/designate/tests/unit/test_pool.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright 2015 Hewlett-Packard Development Company, L.P.
-#
-# Author: Federico Ceratto <federico.ceratto@hpe.com>
-#
-# 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 oslo_log import log as logging
-import oslotest.base
-
-from designate import objects
-
-LOG = logging.getLogger(__name__)
-
-
-def create_test_pool():
- return objects.Pool(
- name='pool1',
- description='desc',
- )
-
-
-class RoObject(dict):
- def __setitem__(self, *a):
- raise NotImplementedError
-
- def __setattr__(self, *a):
- raise NotImplementedError
-
- def __getattr__(self, k):
- return self[k]
-
-
-mock_conf = RoObject(**{
- 'host': 'foohost',
- 'pool:769ca3fc-5924-4a44-8c1f-7efbe52fbd59': RoObject(
- targets=['1588652b-50e7-46b9-b688-a9bad40a873e',
- '2588652b-50e7-46b9-b688-a9bad40a873e'],
- nameservers=['169ca3fc-5924-4a44-8c1f-7efbe52fbd59',
- '269ca3fc-5924-4a44-8c1f-7efbe52fbd59'],
- also_notifies=['1.0.0.0:1', '2.0.0.0:2']
- ),
- 'pool_nameserver:169ca3fc-5924-4a44-8c1f-7efbe52fbd59': RoObject(
- host='pool_host_1.example.',
- port=123
- ),
- 'pool_nameserver:269ca3fc-5924-4a44-8c1f-7efbe52fbd59': RoObject(
- host='pool_host_2.example.',
- port=456
- ),
- 'pool_target:1588652b-50e7-46b9-b688-a9bad40a873e': RoObject(
- type='t1',
- masters=[],
- options=dict(a='1', b='2'),
- ),
- 'pool_target:2588652b-50e7-46b9-b688-a9bad40a873e': RoObject(
- type='t2',
- masters=['1.1.1.1:11'],
- options={},
- ),
-})
-
-
-def deep_sort_lists(obj):
- """Sort lists nested in dictionaries
- """
- if isinstance(obj, dict):
- return sorted((k, deep_sort_lists(obj[k])) for k in obj)
-
- if isinstance(obj, list):
- return sorted(deep_sort_lists(v) for v in obj)
-
- return obj
-
-
-class poolTest(oslotest.base.BaseTestCase):
-
- def test_init_from_config(self):
- pool = objects.Pool.from_config(mock_conf,
- '769ca3fc-5924-4a44-8c1f-7efbe52fbd59')
- expected = [('also_notifies', [[('host', '1.0.0.0'), ('port', 1)],
- [('host', '2.0.0.0'), ('port', 2)]]),
- ('description', 'Pool built from configuration on foohost'), # noqa
- ('id', '769ca3fc-5924-4a44-8c1f-7efbe52fbd59'),
- ('nameservers', [[('host', 'pool_host_1.example.'),
- ('id', '169ca3fc-5924-4a44-8c1f-7efbe52fbd59'), # noqa
- ('port', 123)],
- [('host', 'pool_host_2.example.'),
- ('id', '269ca3fc-5924-4a44-8c1f-7efbe52fbd59'), # noqa
- ('port', 456)]]),
- ('targets', [[('id', '1588652b-50e7-46b9-b688-a9bad40a873e'), # noqa
- ('masters', []),
- ('options', [[('key', 'a'), ('value', '1')],
- [('key', 'b'), ('value', '2')]]),
- ('type', 't1')],
- [('id', '2588652b-50e7-46b9-b688-a9bad40a873e'), # noqa
- ('masters', [[('host', '1.1.1.1'),
- ('port', 11)]]),
- ('options', []),
- ('type', 't2')]])]
-
- actual = deep_sort_lists(pool.to_dict())
- self.assertEqual(actual, expected)