Add compute usage support
Add the capability to get resources usage for a project. Change-Id: I9a6bf7edf868d6ad7d587324ec985a6e4e669f23
This commit is contained in:
parent
abbf0c8d1b
commit
633720cb94
3
releasenotes/notes/get-usage-72d249ff790d1b8f.yaml
Normal file
3
releasenotes/notes/get-usage-72d249ff790d1b8f.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
features:
|
||||
- Allow to retrieve the usage of a specific project
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
34
shade/tests/functional/test_usage.py
Normal file
34
shade/tests/functional/test_usage.py
Normal 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'))
|
33
shade/tests/unit/test_usage.py
Normal file
33
shade/tests/unit/test_usage.py
Normal 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')
|
Loading…
Reference in New Issue
Block a user