add usage API
Change-Id: Id6a688192277f9a58b13ca45d2596d375c5c187d
This commit is contained in:
parent
d5f060ad09
commit
84bc653862
@ -7,6 +7,9 @@
|
||||
- context: .
|
||||
repository: vexxhost/atmosphere-ingress
|
||||
target: atmosphere-ingress
|
||||
- context: .
|
||||
repository: vexxhost/atmosphere-usage
|
||||
target: atmosphere-usage
|
||||
|
||||
- job:
|
||||
name: atmosphere:image:upload
|
||||
|
@ -27,3 +27,6 @@ ENV FLASK_APP=atmosphere.app \
|
||||
|
||||
FROM atmosphere AS atmosphere-ingress
|
||||
ENV UWSGI_WSGI_FILE=/usr/local/bin/atmosphere-ingress-wsgi
|
||||
|
||||
FROM atmosphere AS atmosphere-usage
|
||||
ENV UWSGI_WSGI_FILE=/usr/local/bin/atmosphere-usage-wsgi
|
62
atmosphere/api/usage.py
Normal file
62
atmosphere/api/usage.py
Normal file
@ -0,0 +1,62 @@
|
||||
# Copyright 2020 VEXXHOST, 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.
|
||||
|
||||
"""Usage API."""
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from flask import abort
|
||||
from flask import Blueprint
|
||||
from flask import request
|
||||
from flask import jsonify
|
||||
from keystonemiddleware import auth_token
|
||||
from oslo_config import cfg
|
||||
|
||||
from atmosphere.app import create_app
|
||||
from atmosphere import models
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
blueprint = Blueprint('usage', __name__)
|
||||
|
||||
|
||||
def init_application(config=None):
|
||||
"""Create usage API application."""
|
||||
app = create_app(config)
|
||||
app.register_blueprint(blueprint)
|
||||
|
||||
cfg.CONF([])
|
||||
authtoken_config = dict(CONF.keystone_authtoken)
|
||||
authtoken_config['log_name'] = app.name
|
||||
|
||||
app.wsgi_app = auth_token.AuthProtocol(app.wsgi_app, authtoken_config)
|
||||
return app
|
||||
|
||||
|
||||
@blueprint.route('/v1/resources')
|
||||
def list_resources():
|
||||
"""List all resources for a specific project."""
|
||||
# Project ID from request (or allow override if admin)
|
||||
project_id = request.headers['X-Project-Id']
|
||||
if 'admin' in request.headers['X-Roles'] and 'project_id' in request.args:
|
||||
project_id = request.args['project_id']
|
||||
|
||||
try:
|
||||
start = datetime.fromisoformat(request.args['start'])
|
||||
end = datetime.fromisoformat(request.args['end'])
|
||||
except (KeyError, ValueError):
|
||||
abort(400)
|
||||
|
||||
resources = models.Resource.get_all_by_time_range(start, end, project_id)
|
||||
return jsonify(resources)
|
@ -15,8 +15,25 @@
|
||||
from dateutil.relativedelta import relativedelta
|
||||
import pytest
|
||||
|
||||
from atmosphere.api import ingress
|
||||
from atmosphere.tests.unit import fake
|
||||
from atmosphere import models
|
||||
from atmosphere.models import db
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app():
|
||||
app = ingress.init_application()
|
||||
app.config['TESTING'] = True
|
||||
app.config['SQLALCHEMY_ECHO'] = True
|
||||
return app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def _db(app):
|
||||
db.init_app(app)
|
||||
db.create_all()
|
||||
return db
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("client", "db_session")
|
||||
|
37
atmosphere/tests/unit/api/test_usage.py
Normal file
37
atmosphere/tests/unit/api/test_usage.py
Normal file
@ -0,0 +1,37 @@
|
||||
# Copyright 2020 VEXXHOST, 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 dateutil.relativedelta import relativedelta
|
||||
import pytest
|
||||
|
||||
from atmosphere.api import usage
|
||||
from atmosphere.tests.unit import fake
|
||||
from atmosphere import models
|
||||
from atmosphere.models import db
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app():
|
||||
app = usage.init_application()
|
||||
app.config['TESTING'] = True
|
||||
app.config['SQLALCHEMY_ECHO'] = True
|
||||
return app
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("client")
|
||||
class TestResourceNoAuth:
|
||||
def test_get_resources(self, client):
|
||||
response = client.get('/v1/resources')
|
||||
|
||||
assert response.status_code == 401
|
@ -18,7 +18,6 @@ from flask_sqlalchemy import SQLAlchemy
|
||||
|
||||
from atmosphere.app import create_app
|
||||
from atmosphere.api import ingress
|
||||
from atmosphere.models import db
|
||||
|
||||
|
||||
@pytest.fixture(params=[
|
||||
@ -36,19 +35,3 @@ from atmosphere.models import db
|
||||
])
|
||||
def ignored_event(request):
|
||||
yield request.param
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app():
|
||||
app = create_app()
|
||||
app.config['TESTING'] = True
|
||||
app.config['SQLALCHEMY_ECHO'] = True
|
||||
app.register_blueprint(ingress.blueprint)
|
||||
return app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def _db(app):
|
||||
db.init_app(app)
|
||||
db.create_all()
|
||||
return db
|
||||
|
@ -22,11 +22,28 @@ from dateutil.relativedelta import relativedelta
|
||||
from freezegun import freeze_time
|
||||
import before_after
|
||||
|
||||
from atmosphere.api import ingress
|
||||
from atmosphere import models
|
||||
from atmosphere.models import db
|
||||
from atmosphere import exceptions
|
||||
from atmosphere.tests.unit import fake
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app():
|
||||
app = ingress.init_application()
|
||||
app.config['TESTING'] = True
|
||||
app.config['SQLALCHEMY_ECHO'] = True
|
||||
return app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def _db(app):
|
||||
db.init_app(app)
|
||||
db.create_all()
|
||||
return db
|
||||
|
||||
|
||||
class GetOrCreateTestMixin:
|
||||
def test_with_existing_object(self):
|
||||
event = fake.get_normalized_event()
|
||||
|
@ -2,5 +2,6 @@ ceilometer
|
||||
Flask
|
||||
Flask-Migrate
|
||||
Flask-SQLAlchemy
|
||||
keystonemiddleware
|
||||
python-dateutil
|
||||
PyMySQL
|
||||
|
@ -8,6 +8,7 @@ packages =
|
||||
[entry_points]
|
||||
wsgi_scripts =
|
||||
atmosphere-ingress-wsgi = atmosphere.api.ingress:init_application
|
||||
atmosphere-usage-wsgi = atmosphere.api.usage:init_application
|
||||
|
||||
[tool:pytest]
|
||||
mocked-sessions=atmosphere.models.db.session
|
||||
|
Loading…
Reference in New Issue
Block a user