Add parameters field for protectable instances API
Scenario #1 User need a parameter for the region name to query resource instances from different region endpoint. Scenario #2 User uses the Protectable Instances API to query database instances from the verdor's backup software. User must provide some parameters about authentication to the restfull API of the verdor's backup software. A dict type parameter is needed for Protectable Instances API. And it is optional. blueprint instances-parameters Change-Id: I6677e86467c516433a1ba15eac42f339b953d3d9
This commit is contained in:
parent
1a8adb3014
commit
8af4ffc5f7
@ -765,6 +765,7 @@ paths:
|
|||||||
- $ref: '#/parameters/sortParam'
|
- $ref: '#/parameters/sortParam'
|
||||||
- $ref: '#/parameters/limitParam'
|
- $ref: '#/parameters/limitParam'
|
||||||
- $ref: '#/parameters/markerParam'
|
- $ref: '#/parameters/markerParam'
|
||||||
|
- $ref: '#/parameters/parametersParam'
|
||||||
tags:
|
tags:
|
||||||
- Protectable
|
- Protectable
|
||||||
- Resource
|
- Resource
|
||||||
@ -811,6 +812,7 @@ paths:
|
|||||||
- $ref: '#/parameters/projectParam'
|
- $ref: '#/parameters/projectParam'
|
||||||
- $ref: '#/parameters/protectable_typeParam'
|
- $ref: '#/parameters/protectable_typeParam'
|
||||||
- $ref: '#/parameters/resource_idParam'
|
- $ref: '#/parameters/resource_idParam'
|
||||||
|
- $ref: '#/parameters/parametersParam'
|
||||||
tags:
|
tags:
|
||||||
- Protectable
|
- Protectable
|
||||||
- Resource
|
- Resource
|
||||||
@ -1893,6 +1895,12 @@ parameters:
|
|||||||
response as the marker parameter value in a subsequent limited request.
|
response as the marker parameter value in a subsequent limited request.
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
|
parametersParam:
|
||||||
|
name: parameters
|
||||||
|
in: query
|
||||||
|
description: |
|
||||||
|
The parameters field for protectable instances query.
|
||||||
|
type: string
|
||||||
provider_idParam:
|
provider_idParam:
|
||||||
name: provider_id
|
name: provider_id
|
||||||
in: path
|
in: path
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
"""The protectables api."""
|
"""The protectables api."""
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
@ -126,6 +125,7 @@ class ProtectablesController(wsgi.Controller):
|
|||||||
"""Return data about the given protectable_type."""
|
"""Return data about the given protectable_type."""
|
||||||
context = req.environ['karbor.context']
|
context = req.environ['karbor.context']
|
||||||
protectable_type = id
|
protectable_type = id
|
||||||
|
|
||||||
LOG.info(_LI("Show the information of a given"
|
LOG.info(_LI("Show the information of a given"
|
||||||
" protectable type: %s"), protectable_type)
|
" protectable type: %s"), protectable_type)
|
||||||
|
|
||||||
@ -181,6 +181,13 @@ class ProtectablesController(wsgi.Controller):
|
|||||||
marker, limit, offset = common.get_pagination_params(params)
|
marker, limit, offset = common.get_pagination_params(params)
|
||||||
sort_keys, sort_dirs = common.get_sort_params(params)
|
sort_keys, sort_dirs = common.get_sort_params(params)
|
||||||
filters = params
|
filters = params
|
||||||
|
utils.check_filters(filters)
|
||||||
|
parameters = filters.get("parameters", None)
|
||||||
|
|
||||||
|
if parameters is not None:
|
||||||
|
if not isinstance(parameters, dict):
|
||||||
|
msg = _("The parameters must be a dict.")
|
||||||
|
raise exception.InvalidInput(reason=msg)
|
||||||
|
|
||||||
utils.remove_invalid_filter_options(
|
utils.remove_invalid_filter_options(
|
||||||
context,
|
context,
|
||||||
@ -193,11 +200,10 @@ class ProtectablesController(wsgi.Controller):
|
|||||||
msg = _("Invalid protectable type provided.")
|
msg = _("Invalid protectable type provided.")
|
||||||
raise exception.InvalidInput(reason=msg)
|
raise exception.InvalidInput(reason=msg)
|
||||||
|
|
||||||
utils.check_filters(filters)
|
|
||||||
instances = self._instances_get_all(
|
instances = self._instances_get_all(
|
||||||
context, protectable_type, marker, limit,
|
context, protectable_type, marker, limit,
|
||||||
sort_keys=sort_keys, sort_dirs=sort_dirs,
|
sort_keys=sort_keys, sort_dirs=sort_dirs,
|
||||||
filters=filters, offset=offset)
|
filters=filters, offset=offset, parameters=parameters)
|
||||||
|
|
||||||
for instance in instances:
|
for instance in instances:
|
||||||
protectable_id = instance.get("id")
|
protectable_id = instance.get("id")
|
||||||
@ -216,7 +222,7 @@ class ProtectablesController(wsgi.Controller):
|
|||||||
|
|
||||||
def _instances_get_all(self, context, protectable_type, marker=None,
|
def _instances_get_all(self, context, protectable_type, marker=None,
|
||||||
limit=None, sort_keys=None, sort_dirs=None,
|
limit=None, sort_keys=None, sort_dirs=None,
|
||||||
filters=None, offset=None):
|
filters=None, offset=None, parameters=None):
|
||||||
check_policy(context, 'get_all')
|
check_policy(context, 'get_all')
|
||||||
|
|
||||||
if filters is None:
|
if filters is None:
|
||||||
@ -240,7 +246,8 @@ class ProtectablesController(wsgi.Controller):
|
|||||||
sort_keys=sort_keys,
|
sort_keys=sort_keys,
|
||||||
sort_dirs=sort_dirs,
|
sort_dirs=sort_dirs,
|
||||||
filters=filters,
|
filters=filters,
|
||||||
offset=offset)
|
offset=offset,
|
||||||
|
parameters=parameters)
|
||||||
|
|
||||||
LOG.info(_LI("Get all instances completed successfully."))
|
LOG.info(_LI("Get all instances completed successfully."))
|
||||||
return instances
|
return instances
|
||||||
@ -253,9 +260,18 @@ class ProtectablesController(wsgi.Controller):
|
|||||||
"""Return a instance about the given protectable_type and id."""
|
"""Return a instance about the given protectable_type and id."""
|
||||||
|
|
||||||
context = req.environ['karbor.context']
|
context = req.environ['karbor.context']
|
||||||
|
params = req.params.copy()
|
||||||
|
utils.check_filters(params)
|
||||||
|
parameters = params.get("parameters", None)
|
||||||
|
|
||||||
LOG.info(_LI("Show the instance of a given protectable"
|
LOG.info(_LI("Show the instance of a given protectable"
|
||||||
" type: %s"), protectable_type)
|
" type: %s"), protectable_type)
|
||||||
|
|
||||||
|
if parameters is not None:
|
||||||
|
if not isinstance(parameters, dict):
|
||||||
|
msg = _("The parameters must be a dict.")
|
||||||
|
raise exception.InvalidInput(reason=msg)
|
||||||
|
|
||||||
protectable_types = self._get_all(context)
|
protectable_types = self._get_all(context)
|
||||||
|
|
||||||
if protectable_type not in protectable_types:
|
if protectable_type not in protectable_types:
|
||||||
@ -264,7 +280,7 @@ class ProtectablesController(wsgi.Controller):
|
|||||||
|
|
||||||
instance = self.protection_api.\
|
instance = self.protection_api.\
|
||||||
show_protectable_instance(context, protectable_type,
|
show_protectable_instance(context, protectable_type,
|
||||||
protectable_id)
|
protectable_id, parameters=parameters)
|
||||||
if instance is None:
|
if instance is None:
|
||||||
raise exception.InvalidProtectableInstance(
|
raise exception.InvalidProtectableInstance(
|
||||||
protectable_id=instance.get('id'))
|
protectable_id=instance.get('id'))
|
||||||
|
@ -61,11 +61,11 @@ class API(base.Base):
|
|||||||
|
|
||||||
def list_protectable_instances(self, context, protectable_type,
|
def list_protectable_instances(self, context, protectable_type,
|
||||||
marker, limit, sort_keys,
|
marker, limit, sort_keys,
|
||||||
sort_dirs, filters, offset):
|
sort_dirs, filters, offset, parameters):
|
||||||
return self.protection_rpcapi.\
|
return self.protection_rpcapi.\
|
||||||
list_protectable_instances(context, protectable_type,
|
list_protectable_instances(context, protectable_type,
|
||||||
marker, limit, sort_keys,
|
marker, limit, sort_keys,
|
||||||
sort_dirs, filters)
|
sort_dirs, filters, parameters)
|
||||||
|
|
||||||
def list_protectable_dependents(self, context,
|
def list_protectable_dependents(self, context,
|
||||||
protectable_id,
|
protectable_id,
|
||||||
@ -77,11 +77,13 @@ class API(base.Base):
|
|||||||
|
|
||||||
def show_protectable_instance(self, context,
|
def show_protectable_instance(self, context,
|
||||||
protectable_type,
|
protectable_type,
|
||||||
protectable_id):
|
protectable_id,
|
||||||
|
parameters=None):
|
||||||
return self.protection_rpcapi.\
|
return self.protection_rpcapi.\
|
||||||
show_protectable_instance(context,
|
show_protectable_instance(context,
|
||||||
protectable_type,
|
protectable_type,
|
||||||
protectable_id)
|
protectable_id,
|
||||||
|
parameters=parameters)
|
||||||
|
|
||||||
def show_provider(self, context, provider_id):
|
def show_provider(self, context, provider_id):
|
||||||
return self.protection_rpcapi.\
|
return self.protection_rpcapi.\
|
||||||
|
@ -284,14 +284,15 @@ class ProtectionManager(manager.Manager):
|
|||||||
limit=None,
|
limit=None,
|
||||||
sort_keys=None,
|
sort_keys=None,
|
||||||
sort_dirs=None,
|
sort_dirs=None,
|
||||||
filters=None):
|
filters=None,
|
||||||
|
parameters=None):
|
||||||
|
|
||||||
LOG.info(_LI("Start to list protectable instances of type: %s"),
|
LOG.info(_LI("Start to list protectable instances of type: %s"),
|
||||||
protectable_type)
|
protectable_type)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
resource_instances = self.protectable_registry.list_resources(
|
resource_instances = self.protectable_registry.list_resources(
|
||||||
context, protectable_type)
|
context, protectable_type, parameters)
|
||||||
except exception.ListProtectableResourceFailed as err:
|
except exception.ListProtectableResourceFailed as err:
|
||||||
LOG.error(_LE("List resources of type %(type)s failed: %(err)s"),
|
LOG.error(_LE("List resources of type %(type)s failed: %(err)s"),
|
||||||
{'type': protectable_type,
|
{'type': protectable_type,
|
||||||
@ -306,7 +307,7 @@ class ProtectionManager(manager.Manager):
|
|||||||
|
|
||||||
@messaging.expected_exceptions(exception.ListProtectableResourceFailed)
|
@messaging.expected_exceptions(exception.ListProtectableResourceFailed)
|
||||||
def show_protectable_instance(self, context, protectable_type,
|
def show_protectable_instance(self, context, protectable_type,
|
||||||
protectable_id):
|
protectable_id, parameters=None):
|
||||||
LOG.info(_LI("Start to show protectable instance of type: %s"),
|
LOG.info(_LI("Start to show protectable instance of type: %s"),
|
||||||
protectable_type)
|
protectable_type)
|
||||||
|
|
||||||
@ -314,7 +315,8 @@ class ProtectionManager(manager.Manager):
|
|||||||
resource_instance = \
|
resource_instance = \
|
||||||
self.protectable_registry.show_resource(context,
|
self.protectable_registry.show_resource(context,
|
||||||
protectable_type,
|
protectable_type,
|
||||||
protectable_id)
|
protectable_id,
|
||||||
|
parameters=parameters)
|
||||||
except exception.ListProtectableResourceFailed as err:
|
except exception.ListProtectableResourceFailed as err:
|
||||||
LOG.error(_LE("Show resources of type %(type)s id %(id)s "
|
LOG.error(_LE("Show resources of type %(type)s id %(id)s "
|
||||||
"failed: %(err)s"),
|
"failed: %(err)s"),
|
||||||
|
@ -43,7 +43,7 @@ class ProtectablePlugin(object):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def list_resources(self, context):
|
def list_resources(self, context, parameters=None):
|
||||||
"""List resource instances of type this plugin supported.
|
"""List resource instances of type this plugin supported.
|
||||||
|
|
||||||
:return: The list of resource instance.
|
:return: The list of resource instance.
|
||||||
@ -51,7 +51,7 @@ class ProtectablePlugin(object):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def show_resource(self, context, resource_id):
|
def show_resource(self, context, resource_id, parameters=None):
|
||||||
"""Show resource detail information.
|
"""Show resource detail information.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -43,7 +43,7 @@ class ImageProtectablePlugin(protectable_plugin.ProtectablePlugin):
|
|||||||
return (constants.SERVER_RESOURCE_TYPE,
|
return (constants.SERVER_RESOURCE_TYPE,
|
||||||
constants.PROJECT_RESOURCE_TYPE,)
|
constants.PROJECT_RESOURCE_TYPE,)
|
||||||
|
|
||||||
def list_resources(self, context):
|
def list_resources(self, context, parameters=None):
|
||||||
try:
|
try:
|
||||||
images = self._glance_client(context).images.list()
|
images = self._glance_client(context).images.list()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -98,7 +98,7 @@ class ImageProtectablePlugin(protectable_plugin.ProtectablePlugin):
|
|||||||
for image in images
|
for image in images
|
||||||
if image.owner == parent_resource.id]
|
if image.owner == parent_resource.id]
|
||||||
|
|
||||||
def show_resource(self, context, resource_id):
|
def show_resource(self, context, resource_id, parameters=None):
|
||||||
try:
|
try:
|
||||||
image = self._glance_client(context).images.get(resource_id)
|
image = self._glance_client(context).images.get(resource_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -28,7 +28,7 @@ class ProjectProtectablePlugin(protectable_plugin.ProtectablePlugin):
|
|||||||
def get_parent_resource_types(self):
|
def get_parent_resource_types(self):
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
def list_resources(self, context):
|
def list_resources(self, context, parameters=None):
|
||||||
# TODO(yuvalbr) handle admin context for multiple projects?
|
# TODO(yuvalbr) handle admin context for multiple projects?
|
||||||
return [resource.Resource(type=self._SUPPORT_RESOURCE_TYPE,
|
return [resource.Resource(type=self._SUPPORT_RESOURCE_TYPE,
|
||||||
id=context.project_id,
|
id=context.project_id,
|
||||||
@ -37,7 +37,7 @@ class ProjectProtectablePlugin(protectable_plugin.ProtectablePlugin):
|
|||||||
def get_dependent_resources(self, context, parent_resource):
|
def get_dependent_resources(self, context, parent_resource):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def show_resource(self, context, resource_id):
|
def show_resource(self, context, resource_id, parameters=None):
|
||||||
# TODO(yinwei) get project name through keystone client
|
# TODO(yinwei) get project name through keystone client
|
||||||
return resource.Resource(type=self._SUPPORT_RESOURCE_TYPE,
|
return resource.Resource(type=self._SUPPORT_RESOURCE_TYPE,
|
||||||
id=resource_id,
|
id=resource_id,
|
||||||
|
@ -43,7 +43,7 @@ class ServerProtectablePlugin(protectable_plugin.ProtectablePlugin):
|
|||||||
def get_parent_resource_types(self):
|
def get_parent_resource_types(self):
|
||||||
return (constants.PROJECT_RESOURCE_TYPE, )
|
return (constants.PROJECT_RESOURCE_TYPE, )
|
||||||
|
|
||||||
def list_resources(self, context):
|
def list_resources(self, context, parameters=None):
|
||||||
try:
|
try:
|
||||||
servers = self._client(context).servers.list(detailed=False)
|
servers = self._client(context).servers.list(detailed=False)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -57,7 +57,7 @@ class ServerProtectablePlugin(protectable_plugin.ProtectablePlugin):
|
|||||||
name=server.name)
|
name=server.name)
|
||||||
for server in servers]
|
for server in servers]
|
||||||
|
|
||||||
def show_resource(self, context, resource_id):
|
def show_resource(self, context, resource_id, parameters=None):
|
||||||
try:
|
try:
|
||||||
server = self._client(context).servers.get(resource_id)
|
server = self._client(context).servers.get(resource_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -44,7 +44,7 @@ class VolumeProtectablePlugin(protectable_plugin.ProtectablePlugin):
|
|||||||
return (constants.SERVER_RESOURCE_TYPE,
|
return (constants.SERVER_RESOURCE_TYPE,
|
||||||
constants.PROJECT_RESOURCE_TYPE)
|
constants.PROJECT_RESOURCE_TYPE)
|
||||||
|
|
||||||
def list_resources(self, context):
|
def list_resources(self, context, parameters=None):
|
||||||
try:
|
try:
|
||||||
volumes = self._client(context).volumes.list(detailed=False)
|
volumes = self._client(context).volumes.list(detailed=False)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -58,7 +58,7 @@ class VolumeProtectablePlugin(protectable_plugin.ProtectablePlugin):
|
|||||||
id=vol.id, name=vol.name)
|
id=vol.id, name=vol.name)
|
||||||
for vol in volumes]
|
for vol in volumes]
|
||||||
|
|
||||||
def show_resource(self, context, resource_id):
|
def show_resource(self, context, resource_id, parameters=None):
|
||||||
try:
|
try:
|
||||||
volume = self._client(context).volumes.get(resource_id)
|
volume = self._client(context).volumes.get(resource_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -70,16 +70,17 @@ class ProtectableRegistry(object):
|
|||||||
"""Get the protectable plugin with the specified type."""
|
"""Get the protectable plugin with the specified type."""
|
||||||
return self._plugin_map.get(resource_type)
|
return self._plugin_map.get(resource_type)
|
||||||
|
|
||||||
def list_resources(self, context, resource_type):
|
def list_resources(self, context, resource_type, parameters=None):
|
||||||
"""List resource instances of given type.
|
"""List resource instances of given type.
|
||||||
|
|
||||||
:param resource_type: The resource type to list instance.
|
:param resource_type: The resource type to list instance.
|
||||||
:return: The list of resource instance.
|
:return: The list of resource instance.
|
||||||
"""
|
"""
|
||||||
protectable = self._get_protectable(context, resource_type)
|
protectable = self._get_protectable(context, resource_type)
|
||||||
return protectable.list_resources(context)
|
return protectable.list_resources(context, parameters=parameters)
|
||||||
|
|
||||||
def show_resource(self, context, resource_type, resource_id):
|
def show_resource(self, context, resource_type, resource_id,
|
||||||
|
parameters=None):
|
||||||
"""List resource instances of given type.
|
"""List resource instances of given type.
|
||||||
|
|
||||||
:param resource_type: The resource type of instance.
|
:param resource_type: The resource type of instance.
|
||||||
@ -87,7 +88,8 @@ class ProtectableRegistry(object):
|
|||||||
:return: The show of resource instance.
|
:return: The show of resource instance.
|
||||||
"""
|
"""
|
||||||
protectable = self._get_protectable(context, resource_type)
|
protectable = self._get_protectable(context, resource_type)
|
||||||
return protectable.show_resource(context, resource_id)
|
return protectable.show_resource(context, resource_id,
|
||||||
|
parameters=parameters)
|
||||||
|
|
||||||
def fetch_dependent_resources(self, context, resource):
|
def fetch_dependent_resources(self, context, resource):
|
||||||
"""List dependent resources under given parent resource.
|
"""List dependent resources under given parent resource.
|
||||||
|
@ -105,7 +105,7 @@ class ProtectionAPI(object):
|
|||||||
def list_protectable_instances(
|
def list_protectable_instances(
|
||||||
self, ctxt, protectable_type=None,
|
self, ctxt, protectable_type=None,
|
||||||
marker=None, limit=None, sort_keys=None,
|
marker=None, limit=None, sort_keys=None,
|
||||||
sort_dirs=None, filters=None):
|
sort_dirs=None, filters=None, parameters=None):
|
||||||
cctxt = self.client.prepare(version='1.0')
|
cctxt = self.client.prepare(version='1.0')
|
||||||
return cctxt.call(
|
return cctxt.call(
|
||||||
ctxt,
|
ctxt,
|
||||||
@ -115,7 +115,8 @@ class ProtectionAPI(object):
|
|||||||
limit=limit,
|
limit=limit,
|
||||||
sort_keys=sort_keys,
|
sort_keys=sort_keys,
|
||||||
sort_dirs=sort_dirs,
|
sort_dirs=sort_dirs,
|
||||||
filters=filters)
|
filters=filters,
|
||||||
|
parameters=parameters)
|
||||||
|
|
||||||
def list_protectable_dependents(self,
|
def list_protectable_dependents(self,
|
||||||
ctxt, protectable_id=None,
|
ctxt, protectable_id=None,
|
||||||
@ -129,13 +130,15 @@ class ProtectionAPI(object):
|
|||||||
|
|
||||||
def show_protectable_instance(self,
|
def show_protectable_instance(self,
|
||||||
ctxt, protectable_type=None,
|
ctxt, protectable_type=None,
|
||||||
protectable_id=None):
|
protectable_id=None,
|
||||||
|
parameters=None):
|
||||||
cctxt = self.client.prepare(version='1.0')
|
cctxt = self.client.prepare(version='1.0')
|
||||||
return cctxt.call(
|
return cctxt.call(
|
||||||
ctxt,
|
ctxt,
|
||||||
'show_protectable_instance',
|
'show_protectable_instance',
|
||||||
protectable_type=protectable_type,
|
protectable_type=protectable_type,
|
||||||
protectable_id=protectable_id)
|
protectable_id=protectable_id,
|
||||||
|
parameters=parameters)
|
||||||
|
|
||||||
def show_provider(self,
|
def show_provider(self,
|
||||||
ctxt, provider_id=None):
|
ctxt, provider_id=None):
|
||||||
|
Loading…
Reference in New Issue
Block a user