Add API call to fetch tenant entities
This commit is contained in:
parent
75b72d4e34
commit
d263c9ae17
@ -16,7 +16,7 @@ from cliff.command import Command
|
||||
|
||||
|
||||
class EndpointCommand(Command):
|
||||
"""Show the Almanach Endpoint URL"""
|
||||
"""Show Almanach Endpoint URL"""
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.app.stdout.write('{}\n'.format(self.app.get_client().get_url()))
|
||||
|
46
almanachclient/commands/tenant_entities.py
Normal file
46
almanachclient/commands/tenant_entities.py
Normal file
@ -0,0 +1,46 @@
|
||||
# Copyright 2017 INAP
|
||||
#
|
||||
# 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.
|
||||
|
||||
from cliff.lister import Lister
|
||||
from dateutil import parser
|
||||
|
||||
|
||||
class TenantEntityCommand(Lister):
|
||||
"""Show all entities for a given tenant"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super().get_parser(prog_name)
|
||||
parser.add_argument('tenant_id', help='Tenant ID')
|
||||
parser.add_argument('start', help='Start Date')
|
||||
parser.add_argument('end', help='End Date')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
start = parser.parse(parsed_args.start)
|
||||
end = parser.parse(parsed_args.end)
|
||||
entities = self.app.get_client().get_tenant_entities(parsed_args.tenant_id, start, end)
|
||||
rows = []
|
||||
|
||||
for entity in entities:
|
||||
entity_type = entity.get('entity_type')
|
||||
|
||||
if entity_type == 'instance':
|
||||
properties = dict(flavor=entity.get('flavor'), image=entity.get('image_meta'))
|
||||
else:
|
||||
properties = dict(volume_type=entity.get('volume_type'), attached_to=entity.get('attached_to'))
|
||||
|
||||
rows.append((entity.get('entity_id'), entity_type, entity.get('name'),
|
||||
entity.get('start'), entity.get('end'), properties))
|
||||
|
||||
return ('Entity ID', 'Type', 'Name', 'Start', 'End', 'Properties'), rows
|
@ -16,7 +16,7 @@ from cliff.command import Command
|
||||
|
||||
|
||||
class VersionCommand(Command):
|
||||
"""Show the Almanach version number"""
|
||||
"""Show Almanach version number"""
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
info = self.app.get_client().get_info()
|
||||
|
@ -24,18 +24,25 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HttpClient(metaclass=abc.ABCMeta):
|
||||
def _get(self, url):
|
||||
|
||||
def __init__(self, url, token=None):
|
||||
self.url = url
|
||||
self.token = token
|
||||
|
||||
def _get(self, url, params=None):
|
||||
logger.debug(url)
|
||||
response = requests.get(url, headers=self._get_headers())
|
||||
response = requests.get(url, headers=self._get_headers(), params=params)
|
||||
body = response.json()
|
||||
|
||||
if response.status_code != 200:
|
||||
raise exceptions.HTTPError('HTTP Error ({})'.format(response.status_code))
|
||||
raise exceptions.HTTPError('{} ({})'.format(body.get('error') or 'HTTP Error', response.status_code))
|
||||
|
||||
return response.json()
|
||||
return body
|
||||
|
||||
def _get_headers(self):
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'User-Agent': 'python-almanachclient/{}'.format(client_version.__version__),
|
||||
'X-Auth-Token': self.token,
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ from cliff import app
|
||||
from cliff import commandmanager
|
||||
|
||||
from almanachclient.commands.endpoint import EndpointCommand
|
||||
from almanachclient.commands.tenant_entities import TenantEntityCommand
|
||||
from almanachclient.commands.version import VersionCommand
|
||||
from almanachclient.keystone_client import KeystoneClient
|
||||
from almanachclient.v1.client import Client
|
||||
@ -29,6 +30,7 @@ class AlmanachCommandManager(commandmanager.CommandManager):
|
||||
SHELL_COMMANDS = {
|
||||
'version': VersionCommand,
|
||||
'endpoint': EndpointCommand,
|
||||
'tenant entities': TenantEntityCommand,
|
||||
}
|
||||
|
||||
def load_commands(self, namespace):
|
||||
@ -66,8 +68,12 @@ class AlmanachApp(app.App):
|
||||
help='OpenStack username (Env: OS_USERNAME).')
|
||||
|
||||
parser.add_argument('--almanach-service',
|
||||
default=os.environ.get('ALMANACH_SERVICE'),
|
||||
default=os.environ.get('ALMANACH_SERVICE', 'almanach'),
|
||||
help='Almanach keystone service name (Env: ALMANACH_SERVICE).')
|
||||
|
||||
parser.add_argument('--almanach-token',
|
||||
default=os.environ.get('ALMANACH_TOKEN'),
|
||||
help='Almanach API token (Env: ALMANACH_TOKEN).')
|
||||
return parser
|
||||
|
||||
def get_client(self):
|
||||
@ -77,7 +83,7 @@ class AlmanachApp(app.App):
|
||||
service=self.options.almanach_service,
|
||||
region_name=self.options.os_region_name)
|
||||
|
||||
return Client(keystone.get_endpoint_url())
|
||||
return Client(keystone.get_endpoint_url(), token=self.options.almanach_token)
|
||||
|
||||
|
||||
def main(argv=sys.argv[1:]):
|
||||
|
@ -12,8 +12,10 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from datetime import datetime
|
||||
from unittest import mock
|
||||
|
||||
from almanachclient import exceptions
|
||||
from almanachclient.tests import base
|
||||
from almanachclient.v1.client import Client
|
||||
|
||||
@ -21,8 +23,14 @@ from almanachclient.v1.client import Client
|
||||
class TestClient(base.TestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.almanach_url = 'http://almanach_url'
|
||||
self.client = Client(self.almanach_url)
|
||||
self.url = 'http://almanach_url'
|
||||
self.token = 'token'
|
||||
self.headers = {'Content-Type': 'application/json',
|
||||
'User-Agent': 'python-almanachclient/0.0.1',
|
||||
'X-Auth-Token': self.token,
|
||||
'Accept': 'application/json'}
|
||||
|
||||
self.client = Client(self.url, self.token)
|
||||
|
||||
@mock.patch('requests.get')
|
||||
def test_get_info(self, requests):
|
||||
@ -37,3 +45,31 @@ class TestClient(base.TestCase):
|
||||
response.status_code = 200
|
||||
|
||||
self.assertEqual(expected, self.client.get_info())
|
||||
requests.assert_called_once_with('{}{}'.format(self.url, '/v1/info'), headers=self.headers, params=None)
|
||||
|
||||
@mock.patch('requests.get')
|
||||
def test_get_info_with_http_error(self, requests):
|
||||
response = mock.Mock()
|
||||
requests.return_value = response
|
||||
response.status_code = 500
|
||||
|
||||
self.assertRaises(exceptions.HTTPError, self.client.get_info)
|
||||
|
||||
@mock.patch('requests.get')
|
||||
def test_get_tenant_entities(self, requests):
|
||||
response = mock.Mock()
|
||||
expected = [mock.Mock()]
|
||||
|
||||
requests.return_value = response
|
||||
response.json.return_value = expected
|
||||
response.status_code = 200
|
||||
|
||||
start = datetime.now()
|
||||
end = datetime.now()
|
||||
params = dict(start=start.strftime(Client.DATE_FORMAT), end=end.strftime(Client.DATE_FORMAT))
|
||||
|
||||
self.assertEqual(expected, self.client.get_tenant_entities('my_tenant_id', start, end))
|
||||
|
||||
requests.assert_called_once_with('{}{}'.format(self.url, '/v1/project/my_tenant_id/entities'),
|
||||
params=params,
|
||||
headers=self.headers)
|
||||
|
@ -16,13 +16,17 @@ from almanachclient.http_client import HttpClient
|
||||
|
||||
|
||||
class Client(HttpClient):
|
||||
api_version = 'v1'
|
||||
DATE_FORMAT = '%Y-%m-%d %H:%M:%S.%f'
|
||||
|
||||
def __init__(self, url):
|
||||
self.url = url
|
||||
api_version = 'v1'
|
||||
|
||||
def get_url(self):
|
||||
return self.url
|
||||
|
||||
def get_info(self):
|
||||
return self._get('{}/{}/info'.format(self.url, self.api_version))
|
||||
|
||||
def get_tenant_entities(self, tenant_id, start, end):
|
||||
url = '{}/{}/project/{}/entities'.format(self.url, self.api_version, tenant_id)
|
||||
params = {'start': start.strftime(self.DATE_FORMAT), 'end': end.strftime(self.DATE_FORMAT)}
|
||||
return self._get(url, params)
|
||||
|
@ -1,4 +1,5 @@
|
||||
pbr>=2.0.0,!=2.1.0 # Apache-2.0
|
||||
cliff>=2.6.0 # Apache-2.0
|
||||
requests>=2.10.0,!=2.12.2,!=2.13.0 # Apache-2.0
|
||||
python-keystoneclient>=3.8.0 # Apache-2.0
|
||||
python-keystoneclient>=3.8.0 # Apache-2.0
|
||||
python-dateutil>=2.4.2 # BSD
|
Loading…
x
Reference in New Issue
Block a user