
Includes: - base functional test case class - apps tests - route tests - coverage included README updated
227 lines
7.7 KiB
Python
227 lines
7.7 KiB
Python
# All Rights Reserved.
|
|
#
|
|
# 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 aiohttp import web
|
|
|
|
from laos.api.views import app as app_view
|
|
|
|
from laos.common.base import controllers
|
|
from laos.common import config
|
|
|
|
from laos.models import app as app_model
|
|
|
|
|
|
class AppV1Controller(controllers.ServiceControllerBase):
|
|
|
|
controller_name = "apps"
|
|
version = "v1"
|
|
|
|
@controllers.api_action(method='GET', route='{project_id}/apps')
|
|
async def list(self, request, **kwargs):
|
|
"""
|
|
---
|
|
description: Listing project-scoped apps
|
|
tags:
|
|
- Apps
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: successful operation. Return "apps" JSON
|
|
"401":
|
|
description: Not authorized.
|
|
"""
|
|
c = config.Config.config_instance()
|
|
log, fnclient = c.logger, c.functions_client
|
|
project_id = request.match_info.get('project_id')
|
|
log.info("Listing apps for project: {}".format(project_id))
|
|
stored_apps = await app_model.Apps.find_by(project_id=project_id)
|
|
final = []
|
|
for app in stored_apps:
|
|
fn_app = await fnclient.apps.show(app.name, loop=c.event_loop)
|
|
final.append(app_view.AppView(app, fn_app).view())
|
|
return web.json_response(
|
|
data={
|
|
self.controller_name: final,
|
|
'message': "Successfully listed applications"
|
|
},
|
|
status=200
|
|
)
|
|
|
|
@controllers.api_action(method='POST', route='{project_id}/apps')
|
|
async def create(self, request, **kwargs):
|
|
"""
|
|
---
|
|
description: Creating project-scoped app
|
|
tags:
|
|
- Apps
|
|
produces:
|
|
- application/json
|
|
parameters:
|
|
- in: body
|
|
name: app
|
|
description: Created project-scoped app
|
|
required: true
|
|
schema:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: successful operation. Return "app" JSON
|
|
"401":
|
|
description: Not authorized.
|
|
"409":
|
|
description: App exists
|
|
"""
|
|
c = config.Config.config_instance()
|
|
log, fnclient = c.logger, c.functions_client
|
|
project_id = request.match_info.get('project_id')
|
|
data = await request.json()
|
|
log.info("Creating an app for project: {} with data {}"
|
|
.format(project_id, str(data)))
|
|
app_name = "{}-{}".format(
|
|
data["app"]["name"],
|
|
project_id)[:30]
|
|
|
|
if await app_model.Apps.exists(app_name, project_id):
|
|
return web.json_response(data={
|
|
"error": {
|
|
"message": "App {0} already exists".format(app_name)
|
|
}
|
|
}, status=409)
|
|
|
|
fn_app = await fnclient.apps.create(app_name, loop=c.event_loop)
|
|
stored_app = await app_model.Apps(
|
|
name=app_name, project_id=project_id,
|
|
description=data["app"].get(
|
|
"description",
|
|
"App for project {}".format(
|
|
project_id))).save()
|
|
|
|
return web.json_response(
|
|
data={
|
|
"app": app_view.AppView(stored_app, fn_app).view(),
|
|
"message": "App successfully created",
|
|
}, status=200
|
|
)
|
|
|
|
@controllers.api_action(method='GET', route='{project_id}/apps/{app}')
|
|
async def get(self, request, **kwargs):
|
|
"""
|
|
---
|
|
description: Pulling project-scoped app
|
|
tags:
|
|
- Apps
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: successful operation. Return "app" JSON
|
|
"401":
|
|
description: Not authorized.
|
|
"404":
|
|
description: App not found
|
|
"""
|
|
c = config.Config.config_instance()
|
|
log, fnclient = c.logger, c.functions_client
|
|
project_id = request.match_info.get('project_id')
|
|
app = request.match_info.get('app')
|
|
log.info("Requesting an app for project: {} with name {}"
|
|
.format(project_id, app))
|
|
|
|
if not (await app_model.Apps.exists(app, project_id)):
|
|
return web.json_response(data={
|
|
"error": {
|
|
"message": "App {0} not found".format(app),
|
|
}
|
|
}, status=404)
|
|
|
|
stored_app = (await app_model.Apps.find_by(
|
|
project_id=project_id, name=app)).pop()
|
|
fn_app = await fnclient.apps.show(app, loop=c.event_loop)
|
|
return web.json_response(
|
|
data={
|
|
"app": app_view.AppView(stored_app, fn_app).view(),
|
|
"message": "Successfully loaded app",
|
|
},
|
|
status=200
|
|
)
|
|
# TODO(denismakogon): disabled until iron-io/functions/pull/259
|
|
#
|
|
# @controllers.api_action(method='PUT', route='{project_id}/apps/{app}')
|
|
# async def update(self, request, **kwargs):
|
|
# log = config.Config.config_instance().logger
|
|
# project_id = request.match_info.get('project_id')
|
|
# app = request.match_info.get('app')
|
|
# data = await request.json()
|
|
# log.info("Updating an app {} for project: {} with data {}"
|
|
# .format(app, project_id, str(data)))
|
|
# return web.json_response(
|
|
# data={
|
|
# "app": {}
|
|
# },
|
|
# status=200
|
|
# )
|
|
|
|
@controllers.api_action(method='DELETE', route='{project_id}/apps/{app}')
|
|
async def delete(self, request, **kwargs):
|
|
"""
|
|
---
|
|
description: Deleting project-scoped app
|
|
tags:
|
|
- Apps
|
|
produces:
|
|
- application/json
|
|
responses:
|
|
"200":
|
|
description: successful operation. Return empty JSON
|
|
"401":
|
|
description: Not authorized.
|
|
"404":
|
|
description: App does not exist
|
|
"""
|
|
project_id = request.match_info.get('project_id')
|
|
app = request.match_info.get('app')
|
|
c = config.Config.config_instance()
|
|
fnclient = c.functions_client
|
|
if not (await app_model.Apps.exists(app, project_id)):
|
|
return web.json_response(data={
|
|
"error": {
|
|
"message": "App {0} not found".format(app),
|
|
}
|
|
}, status=404)
|
|
|
|
fn_app = await fnclient.apps.show(app, loop=c.event_loop)
|
|
fn_app_routes = await fn_app.routes.list(loop=c.event_loop)
|
|
|
|
if fn_app_routes:
|
|
return web.json_response(data={
|
|
"error": {
|
|
"message": ("App {} has routes, "
|
|
"delete them in first place")
|
|
}
|
|
}, status=403)
|
|
|
|
await app_model.Apps.delete(
|
|
project_id=project_id, name=app)
|
|
# TODO(denismakogon): enable DELETE to IronFunctions when once
|
|
# https://github.com/iron-io/functions/issues/274 implemented
|
|
# fn_app = await fnclient.apps.delete(app, loop=c.event_loop)
|
|
return web.json_response(
|
|
data={
|
|
"message": "App successfully deleted",
|
|
}, status=200)
|