Add Resource Allocations API support

The Resource Allocation API was added in Stein. This adds support for
querying it with blazarclient. Only the host resource type is supported
for now.

Co-Authored-By: Matt Crees <mattc@stackhpc.com>
Co-Authored-By: Pierre Riteau <pierre@stackhpc.com>
Change-Id: I28f45320164188df73b70d4c9e04c5e53655062e
This commit is contained in:
jakecoll 2019-07-26 15:34:30 -05:00 committed by Pierre Riteau
parent 6c0ae07ee2
commit 30eab20112
8 changed files with 217 additions and 6 deletions

View File

@ -246,7 +246,7 @@ class ListCommand(BlazarCommand, lister.Lister):
return parser
def retrieve_list(self, parsed_args):
"""Retrieve a list of resources from Blazar server"""
"""Retrieve a list of resources from Blazar server."""
blazar_client = self.get_client()
body = self.args2body(parsed_args)
resource_manager = getattr(blazar_client, self.resource)

View File

@ -28,6 +28,7 @@ from oslo_utils import encodeutils
from blazarclient import client as blazar_client
from blazarclient import exception
from blazarclient.v1.shell_commands import allocations
from blazarclient.v1.shell_commands import floatingips
from blazarclient.v1.shell_commands import hosts
from blazarclient.v1.shell_commands import leases
@ -51,6 +52,8 @@ COMMANDS_V1 = {
'floatingip-show': floatingips.ShowFloatingIP,
'floatingip-create': floatingips.CreateFloatingIP,
'floatingip-delete': floatingips.DeleteFloatingIP,
'allocation-list': allocations.ListAllocations,
'allocation-show': allocations.ShowAllocations,
}
VERSION = 1

View File

@ -0,0 +1,34 @@
# Copyright (c) 2019 University of Chicago.
#
# 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 blazarclient import base
class AllocationClientManager(base.BaseClientManager):
"""Manager for the ComputeHost connected requests."""
def get(self, resource, resource_id):
"""Get allocation for resource identified by type and ID."""
resp, body = self.request_manager.get(
'/%s/%s/allocation' % (resource, resource_id))
return body['allocation']
def list(self, resource, sort_by=None):
"""List allocations for all resources of a type."""
resp, body = self.request_manager.get('/%s/allocations' % resource)
allocations = body['allocations']
if sort_by:
allocations = sorted(allocations, key=lambda l: l[sort_by])
return allocations

View File

@ -15,6 +15,7 @@
import logging
from blazarclient.v1 import allocations
from blazarclient.v1 import floatingips
from blazarclient.v1 import hosts
from blazarclient.v1 import leases
@ -62,3 +63,9 @@ class Client(object):
session=self.session,
version=self.version,
**kwargs)
self.allocation = allocations.AllocationClientManager(
blazar_url=self.blazar_url,
auth_token=self.auth_token,
session=self.session,
version=self.version,
**kwargs)

View File

@ -29,7 +29,7 @@ class ComputeHostClientManager(base.BaseClientManager):
return body['host']
def get(self, host_id):
"""Describes host specifications such as name and details."""
"""Describe host specifications such as name and details."""
resp, body = self.request_manager.get('/os-hosts/%s' % host_id)
return body['host']
@ -43,7 +43,7 @@ class ComputeHostClientManager(base.BaseClientManager):
return body['host']
def delete(self, host_id):
"""Deletes host with specified ID."""
"""Delete host with specified ID."""
resp, body = self.request_manager.delete('/os-hosts/%s' % host_id)
def list(self, sort_by=None):

View File

@ -0,0 +1,149 @@
# Copyright (c) 2019 University of Chicago.
#
# 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 logging
from blazarclient import command
from blazarclient import utils
RESOURCE_ID_PATTERN = '^[0-9]+$'
class ShowAllocations(command.ShowCommand):
"""Show allocations for resource identified by type and ID."""
resource = 'allocation'
json_indent = 4
id_pattern = RESOURCE_ID_PATTERN
name_key = 'hypervisor_hostname'
log = logging.getLogger(__name__ + '.ShowHostAllocation')
def get_parser(self, prog_name):
parser = super(ShowAllocations, self).get_parser(prog_name)
parser.add_argument(
'resource_type',
choices=['host'],
help='Show allocations for a resource type'
)
if self.allow_names:
help_str = 'ID or name of %s to look up'
else:
help_str = 'ID of %s to look up'
parser.add_argument('id', metavar="RESOURCE",
help=help_str % "resource")
parser.add_argument(
'--reservation-id',
dest='reservation_id',
default=None,
help='Show only allocations with specific reservation_id'
)
parser.add_argument(
'--lease-id',
dest='lease_id',
default=None,
help='Show only allocations with specific lease_id'
)
return parser
def get_data(self, parsed_args):
self.log.debug('get_data(%s)' % parsed_args)
blazar_client = self.get_client()
resource_manager = getattr(blazar_client, self.resource)
if self.allow_names:
res_id = utils.find_resource_id_by_name_or_id(
blazar_client,
parsed_args.resource_type,
parsed_args.id,
self.name_key,
self.id_pattern)
else:
res_id = parsed_args.id
data = resource_manager.get(
self.args2body(parsed_args)['resource'], res_id)
if parsed_args.lease_id is not None:
data['reservations'] = list(
filter(lambda d: d['lease_id'] == parsed_args.lease_id,
data['reservations']))
if parsed_args.reservation_id is not None:
data['reservations'] = list(
filter(lambda d: d['id'] == parsed_args.reservation_id,
data['reservations']))
self.format_output_data(data)
return list(zip(*sorted(data.items())))
def args2body(self, parsed_args):
params = {}
if parsed_args.resource_type == 'host':
params.update(dict(resource='os-hosts'))
return params
class ListAllocations(command.ListCommand):
"""List allocations for all resources of a type."""
resource = 'allocation'
log = logging.getLogger(__name__ + '.ListHostAllocations')
list_columns = ['resource_id', 'reservations']
def get_parser(self, prog_name):
parser = super(ListAllocations, self).get_parser(prog_name)
parser.add_argument(
'resource_type',
choices=['host'],
help='Show allocations for a resource type'
)
parser.add_argument(
'--reservation-id',
dest='reservation_id',
default=None,
help='Show only allocations with specific reservation_id'
)
parser.add_argument(
'--lease-id',
dest='lease_id',
default=None,
help='Show only allocations with specific lease_id'
)
parser.add_argument(
'--sort-by', metavar="<allocation_column>",
help='column name used to sort result',
default='resource_id'
)
return parser
def get_data(self, parsed_args):
self.log.debug('get_data(%s)' % parsed_args)
data = self.retrieve_list(parsed_args)
for resource in data:
if parsed_args.lease_id is not None:
resource['reservations'] = list(
filter(lambda d: d['lease_id'] == parsed_args.lease_id,
resource['reservations']))
if parsed_args.reservation_id is not None:
resource['reservations'] = list(
filter(lambda d: d['id'] == parsed_args.reservation_id,
resource['reservations']))
return self.setup_columns(data, parsed_args)
def args2body(self, parsed_args):
params = super(ListAllocations, self).args2body(parsed_args)
if parsed_args.resource_type == 'host':
params.update(dict(resource='os-hosts'))
return params

View File

@ -0,0 +1,16 @@
---
features:
- |
Adds support for querying the Resource Allocation API with the following
commands:
* ``blazar allocation-list``
* ``blazar allocation-show``
Only the ``host`` resource type is currently supported by the Blazar
service.
OpenStackClient commands are also available:
* ``openstack reservation allocation list``
* ``openstack reservation allocation show``

View File

@ -36,6 +36,8 @@ openstack.cli.extension =
reservation = blazarclient.osc.plugin
openstack.reservation.v1 =
reservation_allocation_list = blazarclient.v1.shell_commands.allocations:ListAllocations
reservation_allocation_show = blazarclient.v1.shell_commands.allocations:ShowAllocations
reservation_floatingip_create = blazarclient.v1.shell_commands.floatingips:CreateFloatingIP
reservation_floatingip_delete = blazarclient.v1.shell_commands.floatingips:DeleteFloatingIP
reservation_floatingip_list = blazarclient.v1.shell_commands.floatingips:ListFloatingIPs
@ -43,11 +45,11 @@ openstack.reservation.v1 =
reservation_host_create = blazarclient.v1.shell_commands.hosts:CreateHost
reservation_host_delete = blazarclient.v1.shell_commands.hosts:DeleteHost
reservation_host_list = blazarclient.v1.shell_commands.hosts:ListHosts
reservation_host_property_list = blazarclient.v1.shell_commands.hosts:ListHostProperties
reservation_host_property_set = blazarclient.v1.shell_commands.hosts:UpdateHostProperty
reservation_host_property_show = blazarclient.v1.shell_commands.hosts:ShowHostProperty
reservation_host_set = blazarclient.v1.shell_commands.hosts:UpdateHost
reservation_host_show = blazarclient.v1.shell_commands.hosts:ShowHost
reservation_host_property_list = blazarclient.v1.shell_commands.hosts:ListHostProperties
reservation_host_property_show = blazarclient.v1.shell_commands.hosts:ShowHostProperty
reservation_host_property_set = blazarclient.v1.shell_commands.hosts:UpdateHostProperty
reservation_lease_create = blazarclient.v1.shell_commands.leases:CreateLeaseBase
reservation_lease_delete = blazarclient.v1.shell_commands.leases:DeleteLease
reservation_lease_list = blazarclient.v1.shell_commands.leases:ListLeases