diff --git a/designate/api/admin/controllers/extensions/export.py b/designate/api/admin/controllers/extensions/export.py index ee4de7c08..b468ca746 100644 --- a/designate/api/admin/controllers/extensions/export.py +++ b/designate/api/admin/controllers/extensions/export.py @@ -28,34 +28,8 @@ class ExportController(rest.RestController): @utils.validate_uuid('zone_id') def get_one(self, zone_id): context = pecan.request.environ['context'] - policy.check('zone_export', context) - servers = self.central_api.get_domain_servers(context, zone_id) - domain = self.central_api.get_domain(context, zone_id) + zones = self.central_api.export_zone(context, zone_id) - criterion = {'domain_id': zone_id} - recordsets = self.central_api.find_recordsets(context, criterion) - - records = [] - - for recordset in recordsets: - criterion = { - 'domain_id': domain['id'], - 'recordset_id': recordset['id'] - } - - raw_records = self.central_api.find_records(context, criterion) - - for record in raw_records: - records.append({ - 'name': recordset['name'], - 'type': recordset['type'], - 'ttl': recordset['ttl'], - 'data': record['data'], - }) - - return utils.render_template('bind9-zone.jinja2', - servers=servers, - domain=domain, - records=records) + return zones diff --git a/designate/central/rpcapi.py b/designate/central/rpcapi.py index 2f619df9b..738e43217 100644 --- a/designate/central/rpcapi.py +++ b/designate/central/rpcapi.py @@ -49,14 +49,15 @@ class CentralAPI(object): 5.0 - Remove dead server code 5.1 - Add xfr_domain 5.2 - Add Zone Import methods + 5.3 - Add Zone Export method """ - RPC_API_VERSION = '5.2' + RPC_API_VERSION = '5.3' def __init__(self, topic=None): topic = topic if topic else cfg.CONF.central_topic target = messaging.Target(topic=topic, version=self.RPC_API_VERSION) - self.client = rpc.get_client(target, version_cap='5.2') + self.client = rpc.get_client(target, version_cap='5.3') @classmethod def get_instance(cls): @@ -230,6 +231,10 @@ class CentralAPI(object): LOG.info(_LI("find_recordset: Calling central's find_recordset.")) return self.client.call(context, 'find_recordset', criterion=criterion) + def export_zone(self, context, zone_id): + LOG.info(_LI("export_zone: Calling central's export_zone.")) + return self.client.call(context, 'export_zone', zone_id=zone_id) + def update_recordset(self, context, recordset, increment_serial=True): LOG.info(_LI("update_recordset: Calling central's update_recordset.")) return self.client.call(context, 'update_recordset', @@ -495,7 +500,7 @@ class CentralAPI(object): def xfr_domain(self, context, domain_id): LOG.info(_LI("xfr_domain: Calling central's xfr_domain")) - cctxt = self.client.prepare(version='5.2') + cctxt = self.client.prepare(version='5.3') return cctxt.call(context, 'xfr_domain', domain_id=domain_id) # Zone Import Methods diff --git a/designate/central/service.py b/designate/central/service.py index f26306311..eed28e873 100644 --- a/designate/central/service.py +++ b/designate/central/service.py @@ -259,7 +259,7 @@ def notification(notification_type): class Service(service.RPCService, service.Service): - RPC_API_VERSION = '5.2' + RPC_API_VERSION = '5.3' target = messaging.Target(version=RPC_API_VERSION) @@ -1222,6 +1222,16 @@ class Service(service.RPCService, service.Service): return recordset + def export_zone(self, context, zone_id): + domain = self.get_domain(context, zone_id) + + criterion = {'domain_id': zone_id} + recordsets = self.storage.find_recordsets_export(context, criterion) + + return utils.render_template('export-zone.jinja2', + domain=domain, + recordsets=recordsets) + @notification('dns.recordset.update') @synchronized_domain() def update_recordset(self, context, recordset, increment_serial=True): diff --git a/designate/resources/templates/export-zone.jinja2 b/designate/resources/templates/export-zone.jinja2 new file mode 100644 index 000000000..027fd6307 --- /dev/null +++ b/designate/resources/templates/export-zone.jinja2 @@ -0,0 +1,7 @@ +$ORIGIN {{ domain.name }} +$TTL {{ domain.ttl }} + +{% for recordset in recordsets -%} +{{recordset[0]}} {{recordset[1] or ''}} IN {{recordset[2]}} {{recordset[3]}} +{% endfor %} + diff --git a/designate/storage/impl_sqlalchemy/__init__.py b/designate/storage/impl_sqlalchemy/__init__.py index ff56323b0..3d324cfb2 100644 --- a/designate/storage/impl_sqlalchemy/__init__.py +++ b/designate/storage/impl_sqlalchemy/__init__.py @@ -523,6 +523,24 @@ class SQLAlchemyStorage(sqlalchemy_base.SQLAlchemy, storage_base.Storage): return recordset + def find_recordsets_export(self, context, criterion=None): + query = None + + rjoin = tables.records.join( + tables.recordsets, + tables.records.c.recordset_id == tables.recordsets.c.id) + + query = select([tables.recordsets.c.name, tables.recordsets.c.ttl, + tables.recordsets.c.type, tables.records.c.data]).\ + select_from(rjoin) + + query = query.order_by(tables.recordsets.c.created_at) + + raw_rows = self._select_raw( + context, tables.recordsets, criterion, query) + + return raw_rows + def get_recordset(self, context, recordset_id): return self._find_recordsets(context, {'id': recordset_id}, one=True)