Extend reports API extension with more information

Change-Id: Id8ebd69e32f520e8aa56a9df1f34b2532b899e35
This commit is contained in:
Kiall Mac Innes 2013-04-29 21:44:06 +01:00
parent 8c4b88d7ff
commit 4a1b325e89
8 changed files with 142 additions and 28 deletions

View File

@ -17,6 +17,8 @@
"update_tsigkey": "rule:admin",
"delete_tsigkey": "rule:admin",
"get_tenants": "rule:admin",
"get_tenant": "rule:admin",
"count_tenants": "rule:admin",
"create_domain": "rule:admin_or_owner",

View File

@ -22,6 +22,24 @@ central_api = central_rpcapi.CentralAPI()
blueprint = flask.Blueprint('reports', __name__)
@blueprint.route('/reports/tenants', methods=['GET'])
def reports_tenants():
context = flask.request.environ.get('context')
tenants = central_api.get_tenants(context)
return flask.jsonify(tenants=tenants)
@blueprint.route('/reports/tenants/<tenant_id>', methods=['GET'])
def reports_tenant(tenant_id):
context = flask.request.environ.get('context')
tenant = central_api.get_tenant(context, tenant_id)
return flask.jsonify(tenant)
@blueprint.route('/reports/counts', methods=['GET'])
def reports_counts():
context = flask.request.environ.get('context')

View File

@ -28,6 +28,7 @@ class CentralAPI(rpc_proxy.RpcProxy):
1.0 - Initial version
1.1 - Add new finder methods
1.2 - Add get_tenant and get_tenants
"""
def __init__(self, topic=None):
topic = topic if topic else cfg.CONF.central_topic
@ -88,6 +89,16 @@ class CentralAPI(rpc_proxy.RpcProxy):
return self.call(context, msg)
# Tenant Methods
def get_tenants(self, context):
msg = self.make_msg('get_tenants')
return self.call(context, msg, version='1.2')
def get_tenant(self, context, tenant_id):
msg = self.make_msg('get_tenant', tenant_id=tenant_id)
return self.call(context, msg, version='1.2')
def count_tenants(self, context):
msg = self.make_msg('count_tenants')

View File

@ -27,7 +27,7 @@ LOG = logging.getLogger(__name__)
class Service(rpc_service.Service):
RPC_API_VERSION = '1.1'
RPC_API_VERSION = '1.2'
def __init__(self, *args, **kwargs):
backend_driver = cfg.CONF['service:central'].backend_driver
@ -323,6 +323,19 @@ class Service(rpc_service.Service):
return self.storage.delete_tsigkey(context, tsigkey_id)
# Tenant Methods
def get_tenants(self, context):
policy.check('get_tenants', context)
return self.storage.get_tenants(context)
def get_tenant(self, context, tenant_id):
target = {
'tenant_id': tenant_id
}
policy.check('get_tenant', context, target)
return self.storage.get_tenant(context, tenant_id)
def count_tenants(self, context):
policy.check('count_tenants', context)
return self.storage.count_tenants(context)

View File

@ -114,6 +114,23 @@ class Storage(Plugin):
:param tsigkey_id: Delete a TSIG Key via ID
"""
@abc.abstractmethod
def get_tenants(self, context):
"""
Get all Tenants.
:param context: RPC Context.
"""
@abc.abstractmethod
def get_tenant(self, context, tenant_id):
"""
Get all Tenants.
:param context: RPC Context.
:param tenant_id: ID of the Tenant.
"""
@abc.abstractmethod
def count_tenants(self, context, values):
"""

View File

@ -15,7 +15,7 @@
# under the License.
import time
from sqlalchemy.orm import exc
from sqlalchemy import distinct
from sqlalchemy import distinct, func
from moniker.openstack.common import cfg
from moniker.openstack.common import log as logging
from moniker import exceptions
@ -177,6 +177,25 @@ class SQLAlchemyStorage(base.Storage):
tsigkey.delete(self.session)
# Tenant Methods
def get_tenants(self, context):
query = self.session.query(models.Domain.tenant_id,
func.count(models.Domain.id))
query = query.group_by(models.Domain.tenant_id)
return [{'id': t[0], 'domain_count': t[1]} for t in query.all()]
def get_tenant(self, context, tenant_id):
query = self.session.query(models.Domain.name)
query = query.filter(models.Domain.tenant_id == tenant_id)
result = query.all()
return {
'id': tenant_id,
'domain_count': len(result),
'domains': [r[0] for r in result]
}
def count_tenants(self, context):
# tenants are the owner of domains, count the number of unique tenants
# select count(distinct tenant_id) from domains

View File

@ -65,6 +65,9 @@ class TestCase(unittest2.TestCase):
}, {
'name': 'example.net.',
'email': 'example@example.net',
}, {
'name': 'example.org.',
'email': 'example@example.org',
}]
record_fixtures = [

View File

@ -291,6 +291,49 @@ class StorageTestCase(TestCase):
uuid = 'caf771fc-6b05-4891-bee1-c2a48621f57b'
self.storage.delete_tsigkey(self.admin_context, uuid)
# Tenant Tests
def test_get_tenants(self):
# create 3 domains in 2 tenants
self.create_domain(fixture=0, values={'tenant_id': 'One'})
self.create_domain(fixture=1, values={'tenant_id': 'One'})
self.create_domain(fixture=2, values={'tenant_id': 'Two'})
result = self.storage.get_tenants(self.admin_context)
expected = [{
'id': 'One',
'domain_count': 2
}, {
'id': 'Two',
'domain_count': 1
}]
self.assertEquals(result, expected)
def test_get_tenant(self):
# create 2 domains in a tenant
_, domain_1 = self.create_domain(fixture=0, values={'tenant_id': 1})
_, domain_2 = self.create_domain(fixture=1, values={'tenant_id': 1})
result = self.storage.get_tenant(self.admin_context, 1)
self.assertEquals(result['id'], 1)
self.assertEquals(result['domain_count'], 2)
self.assertItemsEqual(result['domains'],
[domain_1['name'], domain_2['name']])
def test_count_tenants(self):
# in the beginning, there should be nothing
tenants = self.storage.count_tenants(self.admin_context)
self.assertEqual(tenants, 0)
# create 2 domains with 2 tenants
self.create_domain(fixture=0, values={'tenant_id': 1})
self.create_domain(fixture=1, values={'tenant_id': 2})
tenants = self.storage.count_tenants(self.admin_context)
self.assertEqual(tenants, 2)
# Domain Tests
def test_create_domain(self):
values = {
@ -441,6 +484,20 @@ class StorageTestCase(TestCase):
uuid = 'caf771fc-6b05-4891-bee1-c2a48621f57b'
self.storage.delete_domain(self.admin_context, uuid)
def test_count_domains(self):
# in the beginning, there should be nothing
domains = self.storage.count_domains(self.admin_context)
self.assertEqual(domains, 0)
# Create a single domain
self.create_domain()
# count 'em up
domains = self.storage.count_domains(self.admin_context)
# well, did we get 1?
self.assertEqual(domains, 1)
def test_create_record(self):
domain_fixture, domain = self.create_domain()
@ -606,20 +663,6 @@ class StorageTestCase(TestCase):
self.assertEqual(pong['status'], True)
self.assertIsNotNone(pong['rtt'])
def test_count_domains(self):
# in the beginning, there should be nothing
domains = self.storage.count_domains(self.admin_context)
self.assertEqual(domains, 0)
# Create a single domain
self.create_domain()
# count 'em up
domains = self.storage.count_domains(self.admin_context)
# well, did we get 1?
self.assertEqual(domains, 1)
def test_count_records(self):
# in the beginning, there should be nothing
records = self.storage.count_records(self.admin_context)
@ -632,15 +675,3 @@ class StorageTestCase(TestCase):
# we should have 1 record now
records = self.storage.count_domains(self.admin_context)
self.assertEqual(records, 1)
def test_count_tenants(self):
# in the beginning, there should be nothing
tenants = self.storage.count_tenants(self.admin_context)
self.assertEqual(tenants, 0)
# create 2 domains with 2 tenants
self.create_domain(fixture=0, values={'tenant_id': 1})
self.create_domain(fixture=1, values={'tenant_id': 2})
tenants = self.storage.count_tenants(self.admin_context)
self.assertEqual(tenants, 2)