Add compute usage support

Add the capability to get resources usage
for a project.

Change-Id: I9a6bf7edf868d6ad7d587324ec985a6e4e669f23
This commit is contained in:
Arie 2016-11-04 19:20:59 +02:00
parent abbf0c8d1b
commit 633720cb94
6 changed files with 110 additions and 0 deletions

View File

@ -0,0 +1,3 @@
---
features:
- Allow to retrieve the usage of a specific project

View File

@ -662,3 +662,15 @@ class Normalizer(object):
for key, val in ret['properties'].items():
ret.setdefault(key, val)
return ret
def _normalize_usage(self, usage):
""" Normalize a usage object """
# Discard noise
usage.pop('links', None)
usage.pop('NAME_ATTR', None)
usage.pop('HUMAN_ID', None)
usage.pop('human_id', None)
usage.pop('request_ids', None)
return munch.Munch(usage)

View File

@ -891,6 +891,11 @@ class NovaQuotasDelete(task_manager.Task):
return client.nova_client.quotas.delete(**self.args)
class NovaUsageGet(task_manager.Task):
def main(self, client):
return client.nova_client.usage.get(**self.args)
class CinderQuotasSet(task_manager.Task):
def main(self, client):
return client.cinder_client.quotas.update(**self.args)

View File

@ -2022,6 +2022,29 @@ class OperatorCloud(openstackcloud.OpenStackCloud):
except nova_exceptions.BadRequest:
raise OpenStackCloudException("nova client call failed")
def get_compute_usage(self, name_or_id, start, end):
""" Get usage for a specific project
:param name_or_id: project name or id
:param start: :class:`datetime.datetime` Start date in UTC
:param end: :class:`datetime.datetime` End date in UTCs
:raises: OpenStackCloudException if it's not a valid project
:returns: Munch object with the usage
"""
proj = self.get_project(name_or_id)
if not proj:
raise OpenStackCloudException("project does not exist: {}".format(
name=proj.id))
with _utils.shade_exceptions(
"Unable to get resources usage for project: {name}".format(
name=proj.id)):
usage = self.manager.submit_task(
_tasks.NovaUsageGet(tenant_id=proj.id, start=start, end=end))
return self._normalize_usage(usage)
def set_volume_quotas(self, name_or_id, **kwargs):
""" Set a volume quota in a project

View File

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
# 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.
"""
test_usage
----------------------------------
Functional tests for `shade` usage method
"""
import datetime
from shade.tests.functional import base
class TestUsage(base.BaseFunctionalTestCase):
def test_get_usage(self):
'''Test quotas functionality'''
usage = self.operator_cloud.get_compute_usage('demo',
datetime.datetime.now(),
datetime.datetime.now())
self.assertIsNotNone(usage)
self.assertTrue(hasattr(usage, 'total_hours'))

View File

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# 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 datetime
import mock
import shade
from shade.tests.unit import base
from shade.tests import fakes
class TestUsage(base.TestCase):
@mock.patch.object(shade.OpenStackCloud, 'nova_client')
@mock.patch.object(shade.OpenStackCloud, 'keystone_client')
def test_get_usage(self, mock_keystone, mock_nova):
project = fakes.FakeProject('project_a')
start = end = datetime.datetime.now()
mock_keystone.tenants.list.return_value = [project]
self.op_cloud.get_compute_usage(project, start, end)
mock_nova.usage.get.assert_called_once_with(start=start, end=end,
tenant_id='project_a')