Add commands for resource property API

This adds commands for interacting with the resource property API
that is specified in blueprint resource-properties-discovery-api.

Change-Id: Ibe024dc9b2d02d4061ab7eb68a4607d1356a6318
This commit is contained in:
Mark Powers 2021-09-21 20:01:46 +00:00 committed by Pierre Riteau
parent 2091bd933a
commit cf2de7cb63
8 changed files with 202 additions and 0 deletions

View File

@ -67,6 +67,14 @@ class RequestManager(object):
""" """
return self.request(url, 'PUT', body=body) return self.request(url, 'PUT', body=body)
def patch(self, url, body):
"""Sends patch request to Blazar.
:param url: URL to the wanted Blazar resource.
:type url: str
"""
return self.request(url, 'PATCH', body=body)
def request(self, url, method, **kwargs): def request(self, url, method, **kwargs):
"""Base request method. """Base request method.

View File

@ -307,3 +307,69 @@ class ShowCommand(BlazarCommand, show.ShowOne):
data = resource_manager.get(res_id) data = resource_manager.get(res_id)
self.format_output_data(data) self.format_output_data(data)
return list(zip(*sorted(data.items()))) return list(zip(*sorted(data.items())))
class ShowPropertyCommand(BlazarCommand, show.ShowOne):
"""Show information of a given resource property."""
api = 'reservation'
resource = None
log = None
def get_parser(self, prog_name):
parser = super(ShowPropertyCommand, self).get_parser(prog_name)
parser.add_argument('property_name', metavar='PROPERTY_NAME',
help='Name of property.')
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)
data = resource_manager.get_property(parsed_args.property_name)
if parsed_args.formatter == 'table':
self.format_output_data(data)
return list(zip(*sorted(data.items())))
class UpdatePropertyCommand(BlazarCommand):
api = 'reservation'
resource = None
log = None
def run(self, parsed_args):
self.log.debug('run(%s)' % parsed_args)
blazar_client = self.get_client()
body = self.args2body(parsed_args)
resource_manager = getattr(blazar_client, self.resource)
resource_manager.set_property(**body)
print(
'Updated %s property: %s' % (
self.resource, parsed_args.property_name),
file=self.app.stdout)
return
def get_parser(self, prog_name):
parser = super(UpdatePropertyCommand, self).get_parser(prog_name)
parser.add_argument(
'property_name', metavar='PROPERTY_NAME',
help='Name of property to patch.'
)
parser.add_argument(
'--private',
action='store_true',
default=False,
help='Set property to private.'
)
parser.add_argument(
'--public',
action='store_true',
default=False,
help='Set property to public.'
)
return parser
def args2body(self, parsed_args):
return dict(
property_name=parsed_args.property_name,
private=(parsed_args.private is True))

View File

@ -90,3 +90,9 @@ class InsufficientAuthInformation(BlazarClientException):
"for the authentication. The instance of " "for the authentication. The instance of "
"keystoneauth1.session.Session class is required.") "keystoneauth1.session.Session class is required.")
code = 400 code = 400
class ResourcePropertyNotFound(BlazarClientException):
"""Occurs if the resource property specified does not exist"""
message = _("The resource property does not exist.")
code = 404

View File

@ -44,6 +44,9 @@ COMMANDS_V1 = {
'host-create': hosts.CreateHost, 'host-create': hosts.CreateHost,
'host-update': hosts.UpdateHost, 'host-update': hosts.UpdateHost,
'host-delete': hosts.DeleteHost, 'host-delete': hosts.DeleteHost,
'host-property-list': hosts.ListHostProperties,
'host-property-show': hosts.ShowHostProperty,
'host-property-set': hosts.UpdateHostProperty,
'floatingip-list': floatingips.ListFloatingIPs, 'floatingip-list': floatingips.ListFloatingIPs,
'floatingip-show': floatingips.ShowFloatingIP, 'floatingip-show': floatingips.ShowFloatingIP,
'floatingip-create': floatingips.CreateFloatingIP, 'floatingip-create': floatingips.CreateFloatingIP,

View File

@ -14,6 +14,7 @@
# limitations under the License. # limitations under the License.
from blazarclient import base from blazarclient import base
from blazarclient import exception
from blazarclient.i18n import _ from blazarclient.i18n import _
@ -52,3 +53,43 @@ class ComputeHostClientManager(base.BaseClientManager):
if sort_by: if sort_by:
hosts = sorted(hosts, key=lambda l: l[sort_by]) hosts = sorted(hosts, key=lambda l: l[sort_by])
return hosts return hosts
def list_properties(self, detail=False, all=False, sort_by=None):
url = '/os-hosts/properties'
query_parts = []
if detail:
query_parts.append("detail=True")
if all:
query_parts.append("all=True")
if query_parts:
url += "?" + "&".join(query_parts)
resp, body = self.request_manager.get(url)
resource_properties = body['resource_properties']
# Values is a reserved word in cliff so need to rename values column.
if detail:
for p in resource_properties:
p['property_values'] = p['values']
del p['values']
if sort_by:
resource_properties = sorted(resource_properties,
key=lambda l: l[sort_by])
return resource_properties
def get_property(self, property_name):
resource_property = [
x for x in self.list_properties(detail=True)
if x['property'] == property_name]
if not resource_property:
raise exception.ResourcePropertyNotFound()
return resource_property[0]
def set_property(self, property_name, private):
data = {'private': private}
resp, body = self.request_manager.patch(
'/os-hosts/properties/%s' % property_name, body=data)
return body['resource_property']

View File

@ -16,6 +16,7 @@
import logging import logging
from blazarclient import command from blazarclient import command
from blazarclient import exception
HOST_ID_PATTERN = '^[0-9]+$' HOST_ID_PATTERN = '^[0-9]+$'
@ -120,3 +121,68 @@ class DeleteHost(command.DeleteCommand):
log = logging.getLogger(__name__ + '.DeleteHost') log = logging.getLogger(__name__ + '.DeleteHost')
name_key = 'hypervisor_hostname' name_key = 'hypervisor_hostname'
id_pattern = HOST_ID_PATTERN id_pattern = HOST_ID_PATTERN
class ShowHostProperty(command.ShowPropertyCommand):
"""Show host property."""
resource = 'host'
json_indent = 4
log = logging.getLogger(__name__ + '.ShowHostProperty')
class ListHostProperties(command.ListCommand):
"""List host properties."""
resource = 'host'
log = logging.getLogger(__name__ + '.ListHostProperties')
list_columns = ['property', 'private', 'property_values']
def args2body(self, parsed_args):
params = {
'detail': parsed_args.detail,
'all': parsed_args.all,
}
if parsed_args.sort_by:
if parsed_args.sort_by in self.list_columns:
params['sort_by'] = parsed_args.sort_by
else:
msg = 'Invalid sort option %s' % parsed_args.sort_by
raise exception.BlazarClientException(msg)
return params
def retrieve_list(self, parsed_args):
"""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)
data = resource_manager.list_properties(**body)
return data
def get_parser(self, prog_name):
parser = super(ListHostProperties, self).get_parser(prog_name)
parser.add_argument(
'--detail',
action='store_true',
help='Return properties with values and attributes.',
default=False
)
parser.add_argument(
'--sort-by', metavar="<property_column>",
help='column name used to sort result',
default='property'
)
parser.add_argument(
'--all',
action='store_true',
help='Return all properties, public and private.',
default=False
)
return parser
class UpdateHostProperty(command.UpdatePropertyCommand):
"""Update attributes of a host property."""
resource = 'host'
json_indent = 4
log = logging.getLogger(__name__ + '.UpdateHostProperty')
name_key = 'property_name'

View File

@ -0,0 +1,9 @@
---
features:
- |
Added support for managing host resource properties using the following new
commands:
* ``host-property-list``
* ``host-property-show``
* ``host-property-set``

View File

@ -44,6 +44,9 @@ openstack.reservation.v1 =
reservation_host_list = blazarclient.v1.shell_commands.hosts:ListHosts reservation_host_list = blazarclient.v1.shell_commands.hosts:ListHosts
reservation_host_set = blazarclient.v1.shell_commands.hosts:UpdateHost reservation_host_set = blazarclient.v1.shell_commands.hosts:UpdateHost
reservation_host_show = blazarclient.v1.shell_commands.hosts:ShowHost 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_create = blazarclient.v1.shell_commands.leases:CreateLeaseBase
reservation_lease_delete = blazarclient.v1.shell_commands.leases:DeleteLease reservation_lease_delete = blazarclient.v1.shell_commands.leases:DeleteLease
reservation_lease_list = blazarclient.v1.shell_commands.leases:ListLeases reservation_lease_list = blazarclient.v1.shell_commands.leases:ListLeases