Allow package_get by name
If package lookup by id fails, filter by fully_qualified_name and choose the first (and what will be only) result. Also allows delete and update to use FQN as well as ID. This may need revisiting to allow non-unique FQNs. Change-Id: I84fb8e155b5aa4bc036f8b598101b6b969962325 Implements: blueprint id-fqn-equivalence
This commit is contained in:
parent
84bff3be68
commit
da7fda4832
|
@ -25,7 +25,7 @@ Methods for application package management
|
|||
|
||||
**Package Properties**
|
||||
|
||||
- ``id``: guid corresponds to database record
|
||||
- ``id``: guid of a package (``fully_qualified_name`` can also be used for some API functions)
|
||||
- ``fully_qualified_name``: fully qualified domain name - domain name that specifies exact application location
|
||||
- ``name``: user-friendly name
|
||||
- ``type``: package type, "library" or "application"
|
||||
|
@ -181,9 +181,11 @@ Get package details
|
|||
"""""""""""""""""""
|
||||
`/v1/catalog/packages/{id} [GET]`
|
||||
|
||||
Display details for a package.
|
||||
|
||||
**Parameters**
|
||||
|
||||
``id`` (required) Numeric `id` of the package to perform action with
|
||||
``id`` (required) Hexadecimal `id` (or fully qualified name) of the package
|
||||
|
||||
**Response 200 (application/json)**
|
||||
|
||||
|
@ -226,6 +228,10 @@ Update a Package
|
|||
Allows to edit mutable fields (categories, tags, name, description, is_public, enabled).
|
||||
See the full specification `here <http://tools.ietf.org/html/rfc6902>`_.
|
||||
|
||||
**Parameters**
|
||||
|
||||
``id`` (required) Hexadecimal `id` (or fully qualified name) of the package
|
||||
|
||||
Allowed operations:
|
||||
|
||||
::
|
||||
|
@ -288,19 +294,23 @@ Note, that replacing categories with empty list is not allowed as well as the re
|
|||
|
||||
**Response 400**
|
||||
|
||||
* In attempt to replace categories with empty list or remove last category
|
||||
* An attempt to replace categories with empty list or remove last category
|
||||
|
||||
**Response 404**
|
||||
|
||||
* In attempt to update package that doesn't exist
|
||||
* An attempt to update package that doesn't exist
|
||||
|
||||
Delete application definition from the catalog
|
||||
""""""""""""""""""""""""""""""""""""""""""""""
|
||||
`/v1/catalog/packages/{id} [DELETE]`
|
||||
|
||||
**Parameters**
|
||||
|
||||
``id`` (required) Hexadecimal `id` (or fully qualified name) of the package to delete
|
||||
|
||||
**Response 404**
|
||||
|
||||
* In attempt to delete package that doesn't exist
|
||||
* An attempt to delete package that doesn't exist
|
||||
|
||||
Download application data
|
||||
-------------------------
|
||||
|
@ -313,7 +323,7 @@ Get application definition package
|
|||
|
||||
**Parameters**
|
||||
|
||||
* id (required) Numeric `id` of the package to perform action with
|
||||
* id (required) Hexadecimal `id` (or fully qualified name) of the package
|
||||
|
||||
**Response 200 (application/octetstream)**
|
||||
|
||||
|
@ -331,7 +341,7 @@ Retrieve UI definition for a application which described in a package with provi
|
|||
|
||||
**Parameters**
|
||||
|
||||
* id (required) Numeric `id` of the package to perform action with
|
||||
* id (required) Hexadecimal `id` (or fully qualified name) of the package
|
||||
|
||||
**Response 200 (application/octet-stream)**
|
||||
|
||||
|
@ -357,8 +367,7 @@ Retrieve application logo which described in a package with provided id
|
|||
|
||||
**Parameters**
|
||||
|
||||
id (required) Numeric `id` of the package to perform action with
|
||||
|
||||
id (required) Hexadecimal `id` (or fully qualified name) of the package
|
||||
|
||||
**Response 200 (application/octet-stream)**
|
||||
|
||||
|
|
|
@ -33,10 +33,25 @@ SEARCH_MAPPING = {'fqn': 'fully_qualified_name',
|
|||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _package_get(package_id, session):
|
||||
package = session.query(models.Package).get(package_id)
|
||||
def _package_get(package_id_or_name, session):
|
||||
# TODO (sjmc7): update openstack/common and pull in
|
||||
# uuidutils, check that package_id_or_name resembles a
|
||||
# UUID before trying to treat it as one
|
||||
package = session.query(models.Package).get(package_id_or_name)
|
||||
if not package:
|
||||
msg = _("Package id '{0}' is not found").format(package_id)
|
||||
# Try using the FQN name instead. Since FQNs right now are unique,
|
||||
# don't need to do any logic to figure out if we have the right one.
|
||||
# # TODO (sjmc7): Revisit for precedence rules.
|
||||
# Heat does this in nicer way, giving each stack an unambiguous ID of
|
||||
# stack_name/id and redirecting to it in the API. We need to do some
|
||||
# reworking for precedence rules later, so maybe take a look at this
|
||||
package = session.query(models.Package).filter_by(
|
||||
fully_qualified_name=package_id_or_name
|
||||
).first()
|
||||
|
||||
if not package:
|
||||
msg = _("Package id or name '{0}' not found").\
|
||||
format(package_id_or_name)
|
||||
LOG.error(msg)
|
||||
raise exc.HTTPNotFound(msg)
|
||||
|
||||
|
@ -60,14 +75,14 @@ def _authorize_package(package, context, allow_public=False):
|
|||
raise exc.HTTPForbidden(msg)
|
||||
|
||||
|
||||
def package_get(package_id, context):
|
||||
def package_get(package_id_or_name, context):
|
||||
"""
|
||||
Return package details
|
||||
:param package_id: ID of a package, string
|
||||
:param package_id: ID or name of a package, string
|
||||
:returns: detailed information about package, dict
|
||||
"""
|
||||
session = db_session.get_session()
|
||||
package = _package_get(package_id, session)
|
||||
package = _package_get(package_id_or_name, session)
|
||||
_authorize_package(package, context, allow_public=True)
|
||||
return package
|
||||
|
||||
|
@ -191,7 +206,7 @@ def _do_remove(package, change):
|
|||
return package
|
||||
|
||||
|
||||
def package_update(pkg_id, changes, context):
|
||||
def package_update(pkg_id_or_name, changes, context):
|
||||
"""
|
||||
Update package information
|
||||
:param changes: parameters to update
|
||||
|
@ -203,7 +218,7 @@ def package_update(pkg_id, changes, context):
|
|||
'remove': _do_remove}
|
||||
session = db_session.get_session()
|
||||
with session.begin():
|
||||
pkg = _package_get(pkg_id, session)
|
||||
pkg = _package_get(pkg_id_or_name, session)
|
||||
_authorize_package(pkg, context)
|
||||
|
||||
for change in changes:
|
||||
|
@ -338,15 +353,12 @@ def package_upload(values, tenant_id):
|
|||
return package
|
||||
|
||||
|
||||
def package_delete(package_id, context):
|
||||
"""
|
||||
Delete package information from the system ID of a package, string
|
||||
parameters to update
|
||||
"""
|
||||
def package_delete(package_id_or_name, context):
|
||||
"""Delete a package by name or by ID"""
|
||||
session = db_session.get_session()
|
||||
|
||||
with session.begin():
|
||||
package = _package_get(package_id, session)
|
||||
package = _package_get(package_id_or_name, session)
|
||||
_authorize_package(package, context)
|
||||
session.delete(package)
|
||||
|
||||
|
|
Loading…
Reference in New Issue