diff --git a/designate/api/v2/controllers/zones/tasks/transfer_accepts.py b/designate/api/v2/controllers/zones/tasks/transfer_accepts.py index f430ea2a6..8c883cda2 100644 --- a/designate/api/v2/controllers/zones/tasks/transfer_accepts.py +++ b/designate/api/v2/controllers/zones/tasks/transfer_accepts.py @@ -47,6 +47,31 @@ class TransferAcceptsController(rest.RestController): return DesignateAdapter.render( 'API_v2', transfer_accepts, request=request) + @pecan.expose(template='json:', content_type='application/json') + def get_all(self, **params): + """List ZoneTransferAccepts""" + request = pecan.request + context = request.environ['context'] + + # Extract the pagination params + marker, limit, sort_key, sort_dir = utils.get_paging_params( + params, self.SORT_KEYS) + + # Extract any filter params. + criterion = self._apply_filter_params(params, ('status',), {}) + + zone_transfer_accepts = self.central_api.find_zone_transfer_accepts( + context, criterion, marker, limit, sort_key, sort_dir) + + LOG.info(_LI("Retrieved %(zone_transfer_accepts)s"), + {'zone_transfer_accepts': zone_transfer_accepts}) + + return DesignateAdapter.render( + 'API_v2', + zone_transfer_accepts, + request=request, + context=context) + @pecan.expose(template='json:', content_type='application/json') def post_all(self): """Create ZoneTransferAccept""" diff --git a/designate/storage/impl_sqlalchemy/__init__.py b/designate/storage/impl_sqlalchemy/__init__.py index e4c072c9b..61f4e243c 100644 --- a/designate/storage/impl_sqlalchemy/__init__.py +++ b/designate/storage/impl_sqlalchemy/__init__.py @@ -1571,16 +1571,37 @@ class SQLAlchemyStorage(sqlalchemy_base.SQLAlchemy, storage_base.Storage): zone_transfer_request, exceptions.ZoneTransferRequestNotFound) + def count_zone_transfer_accept(self, context, criterion=None): + query = select([func.count(tables.zone_transfer_accepts.c.id)]) + query = self._apply_criterion(tables.zone_transfer_accepts, + query, criterion) + query = self._apply_deleted_criteria(context, + tables.zone_transfer_accepts, query) + + resultproxy = self.session.execute(query) + result = resultproxy.fetchone() + + if result is None: + return 0 + + return result[0] + def _find_zone_transfer_accept(self, context, criterion, one=False, marker=None, limit=None, sort_key=None, sort_dir=None): - return self._find( - context, tables.zone_transfer_accepts, - objects.ZoneTransferAccept, - objects.ZoneTransferAcceptList, - exceptions.ZoneTransferAcceptNotFound, criterion, - one, marker, limit, sort_key, sort_dir) + zone_transfer_accept = self._find( + context, tables.zone_transfer_accepts, + objects.ZoneTransferAccept, + objects.ZoneTransferAcceptList, + exceptions.ZoneTransferAcceptNotFound, criterion, + one, marker, limit, sort_key, sort_dir) + + if not one: + zone_transfer_accept.total_count = self.count_zone_transfer_accept( + context, criterion) + + return zone_transfer_accept def create_zone_transfer_accept(self, context, zone_transfer_accept): diff --git a/designate/tests/test_api/test_v2/test_zone_transfers.py b/designate/tests/test_api/test_v2/test_zone_transfers.py index c4c2d3447..c9a7609d4 100644 --- a/designate/tests/test_api/test_v2/test_zone_transfers.py +++ b/designate/tests/test_api/test_v2/test_zone_transfers.py @@ -23,6 +23,7 @@ class ApiV2ZoneTransfersTest(ApiV2TestCase): self.zone = self.create_zone() self.tenant_1_context = self.get_context(tenant=1) self.tenant_2_context = self.get_context(tenant=2) + self.policy({'admin': '@'}) def test_create_zone_transfer_request(self): response = self.client.post_json( @@ -97,6 +98,31 @@ class ApiV2ZoneTransfersTest(ApiV2TestCase): response.json['zone_id']) self.assertIn('updated_at', response.json) + def test_get_zone_transfer_requests(self): + response = self.client.get( + '/zones/tasks/transfer_requests') + + # Check the headers are what we expect + self.assertEqual(200, response.status_int) + self.assertEqual('application/json', response.content_type) + + # Check the body structure is what we expect + self.assertIn('transfer_requests', response.json) + self.assertIn('links', response.json) + self.assertIn('self', response.json['links']) + + # We should start with 0 transfer accepts + self.assertEqual(0, len(response.json['transfer_requests'])) + + self.client.post_json( + '/zones/%s/tasks/transfer_requests' % (self.zone.id), + {}) + + data = self.client.get( + '/zones/tasks/transfer_requests') + + self.assertEqual(1, len(data.json['transfer_requests'])) + def test_update_zone_transfer_request(self): initial = self.client.post_json( '/zones/%s/tasks/transfer_requests' % (self.zone.id), @@ -174,6 +200,39 @@ class ApiV2ZoneTransfersTest(ApiV2TestCase): 'COMPLETE', new_ztr.json['status']) + def test_get_zone_transfer_accepts(self): + response = self.client.get( + '/zones/tasks/transfer_accepts') + + # Check the headers are what we expect + self.assertEqual(200, response.status_int) + self.assertEqual('application/json', response.content_type) + + # Check the body structure is what we expect + self.assertIn('transfer_accepts', response.json) + self.assertIn('links', response.json) + self.assertIn('self', response.json['links']) + self.assertIn('metadata', response.json) + + # We should start with 0 transfer accepts + self.assertEqual(0, len(response.json['transfer_accepts'])) + + initial = self.client.post_json( + '/zones/%s/tasks/transfer_requests' % (self.zone.id), + {}) + + self.client.post_json( + '/zones/tasks/transfer_accepts', + { + 'zone_transfer_request_id': + initial.json['id'], + 'key': initial.json['key'] + }) + + data = self.client.get( + '/zones/tasks/transfer_accepts') + self.assertEqual(1, len(data.json['transfer_accepts'])) + def test_create_zone_transfer_request_deleting_zone(self): url = '/zones/%s/tasks/transfer_requests' % (self.zone.id) body = {} @@ -187,3 +246,43 @@ class ApiV2ZoneTransfersTest(ApiV2TestCase): self.client.delete('/zones/%s' % self.zone['id'], status=202) self._assert_exception('bad_request', 400, self.client.post_json, url, body) + + # Metadata tests + def test_metadata_exists_zone_transfer_accepts(self): + initial = self.client.post_json( + '/zones/%s/tasks/transfer_requests' % (self.zone.id), + {}) + + self.client.post_json( + '/zones/tasks/transfer_accepts', + { + 'zone_transfer_request_id': + initial.json['id'], + 'key': initial.json['key'] + }) + + result = self.client.get( + '/zones/tasks/transfer_accepts') + + # Make sure the fields exist + self.assertIn('metadata', result.json) + self.assertIn('total_count', result.json['metadata']) + + def test_total_count_zone_transfer_accepts(self): + initial = self.client.post_json( + '/zones/%s/tasks/transfer_requests' % (self.zone.id), + {}) + + self.client.post_json( + '/zones/tasks/transfer_accepts', + { + 'zone_transfer_request_id': + initial.json['id'], + 'key': initial.json['key'] + }) + + result = self.client.get( + '/zones/tasks/transfer_accepts') + + # Make sure total_count picked it up + self.assertEqual(1, result.json['metadata']['total_count'])