storyboard/storyboard/api/v1/project_groups.py

261 lines
8.9 KiB
Python

# Copyright (c) 2013 Mirantis Inc.
#
# 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 oslo_config import cfg
from pecan import abort
from pecan import response
from pecan import rest
from pecan.secure import secure
import wsme.types as wtypes
import wsmeext.pecan as wsme_pecan
from storyboard._i18n import _
import storyboard.api.auth.authorization_checks as checks
from storyboard.api.v1 import validations
from storyboard.api.v1 import wmodels
from storyboard.common import decorators
import storyboard.common.exception as exc
from storyboard.db.api import project_groups
from storyboard.db.api import projects
CONF = cfg.CONF
class ProjectsSubcontroller(rest.RestController):
"""This controller should be used to list, add or remove projects from a
Project Group.
"""
@decorators.db_exceptions
@secure(checks.guest)
@wsme_pecan.wsexpose([wmodels.Project], int)
def get(self, project_group_id):
"""Get projects inside a project group.
Example::
curl https://my.example.org/api/v1/project_groups/55/projects
:param project_group_id: An ID of the project group.
"""
project_group = project_groups.project_group_get(project_group_id)
if not project_group:
raise exc.NotFound(_("Project Group %s not found")
% project_group_id)
return [wmodels.Project.from_db_model(project)
for project in project_group.projects]
@decorators.db_exceptions
@secure(checks.superuser)
@wsme_pecan.wsexpose(wmodels.Project, int, int)
def put(self, project_group_id, project_id):
"""Add a project to a project_group.
This command is only available to Admin users.
Example::
curl https://my.example.org/api/v1/project_groups/17/projects/17 \\
-X PUT -H 'Authorization: Bearer MY_ACCESS_TOKEN' \\
-H 'Content-Type: application/json;charset=UTF-8' \\
--data-binary '{}'
:param project_group_id: An ID of the project group.
:param project_id: An ID of project in this project group.
"""
project_groups.project_group_add_project(project_group_id, project_id)
return wmodels.Project.from_db_model(projects.project_get(project_id))
@decorators.db_exceptions
@secure(checks.superuser)
@wsme_pecan.wsexpose(None, int, int, status_code=204)
def delete(self, project_group_id, project_id):
"""Delete a project from a project_group.
This command is only available to Admin users.
Example::
curl https://my.example.org/api/v1/project_groups/17/projects/1 \\
-X DELETE -H 'Authorization: Bearer MY_ACCESS_TOKEN'
:param project_group_id: An ID of the project group.
:param project_id: An ID of project in this project group.
"""
project_groups.project_group_delete_project(project_group_id,
project_id)
class ProjectGroupsController(rest.RestController):
"""REST controller for Project Groups.
NOTE: PUT requests should be used to update only top-level fields.
The nested fields (projects) should be updated using requests to a
projects subcontroller.
"""
validation_post_schema = validations.PROJECT_GROUPS_POST_SCHEMA
validation_put_schema = validations.PROJECT_GROUPS_PUT_SCHEMA
@decorators.db_exceptions
@secure(checks.guest)
@wsme_pecan.wsexpose(wmodels.ProjectGroup, int)
def get_one(self, project_group_id):
"""Retrieve information about the given project group.
Example::
curl https://my.example.org/api/v1/project_groups/55
:param project_group_id: Project group id.
"""
group = project_groups.project_group_get(project_group_id)
if not group:
raise exc.NotFound(_("Project Group %s not found")
% project_group_id)
return wmodels.ProjectGroup.from_db_model(group)
@decorators.db_exceptions
@secure(checks.guest)
@wsme_pecan.wsexpose([wmodels.ProjectGroup], int, int, int, wtypes.text,
wtypes.text, int, wtypes.text, wtypes.text)
def get(self, marker=None, offset=None, limit=None, name=None, title=None,
subscriber_id=None, sort_field='id', sort_dir='asc'):
"""Retrieve a list of projects groups.
Example::
curl https://my.example.org/api/v1/project_groups
:param marker: The resource id where the page should begin.
:param offset: The offset to start the page at.
:param limit: The number of project groups to retrieve.
:param name: A string to filter the name by.
:param title: A string to filter the title by.
:param subscriber_id: The ID of a subscriber to filter by.
:param sort_field: The name of the field to sort on.
:param sort_dir: Sort direction for results (asc, desc).
"""
if limit is not None:
limit = max(0, limit)
# Resolve the marker record.
marker_group = None
if marker is not None:
marker_group = project_groups.project_group_get(marker)
groups = project_groups.project_group_get_all(
marker=marker_group,
offset=offset,
limit=limit,
name=name,
title=title,
subscriber_id=subscriber_id,
sort_field=sort_field,
sort_dir=sort_dir)
group_count = project_groups.project_group_get_count(
name=name, title=title, subscriber_id=subscriber_id)
# Apply the query response headers.
if limit:
response.headers['X-Limit'] = str(limit)
response.headers['X-Total'] = str(group_count)
if marker_group:
response.headers['X-Marker'] = str(marker_group.id)
if offset is not None:
response.headers['X-Offset'] = str(offset)
return [wmodels.ProjectGroup.from_db_model(group) for group in groups]
@decorators.db_exceptions
@secure(checks.superuser)
@wsme_pecan.wsexpose(wmodels.ProjectGroup, body=wmodels.ProjectGroup)
def post(self, project_group):
"""Create a new project group.
This command is only available to Admin users.
Example::
curl https://my.example.org/api/v1/project_groups \\
-H 'Authorization: Bearer MY_ACCESS_TOKEN' \\
-H 'Content-Type: application/json;charset=UTF-8' \\
--data-binary '{"title":"test-group","name":"test-group"}'
:param project_group: A project group within the request body.
"""
created_group = project_groups.project_group_create(
project_group.as_dict())
return wmodels.ProjectGroup.from_db_model(created_group)
@decorators.db_exceptions
@secure(checks.superuser)
@wsme_pecan.wsexpose(wmodels.ProjectGroup, int, body=wmodels.ProjectGroup)
def put(self, project_group_id, project_group):
"""Modify this project group.
This command is only available to Admin users.
Example::
curl https://my.example.org/api/v1/project_groups/17 -X PUT \\
-H 'Authorization: Bearer MY_ACCESS_TOKEN' \\
-H 'Content-Type: application/json;charset=UTF-8' \\
--data-binary '{"id":17,"name":"test-group",\\
"title":"test-group-that-is-changed"}'
:param project_group_id: An ID of the project group.
:param project_group: A project group within the request body.
"""
updated_group = project_groups.project_group_update(
project_group_id,
project_group.as_dict(omit_unset=True))
return wmodels.ProjectGroup.from_db_model(updated_group)
@decorators.db_exceptions
@secure(checks.superuser)
@wsme_pecan.wsexpose(None, int, status_code=204)
def delete(self, project_group_id):
"""Delete this project group.
This command is only available to Admin users.
Example::
curl https://my.example.org/api/v1/project_groups/17 -X DELETE \\
-H 'Authorization: Bearer MY_ACCESS_TOKEN'
:param project_group_id: An ID of the project group.
"""
try:
project_groups.project_group_delete(project_group_id)
except exc.NotFound as not_found_exc:
abort(404, not_found_exc.message)
except exc.NotEmpty as not_empty_exc:
abort(400, not_empty_exc.message)
projects = ProjectsSubcontroller()