diff --git a/README.rst b/README.rst index 2a18bbe7..d2fc0624 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,6 @@ RefStack/TCUP and Driver Test This project support collection and publication of Community Test results for OpenStack. There are multiple components of this effort: * `RefStack `_: Community-facing API for registration of interop-compliance endpoints for on-demand testing. -* `TCUP `_: Portable, Containerized Tempest for Community running and reporting results to RefStack * Driver Test Participate @@ -31,10 +30,3 @@ Collecting the Results > Running RefStack RefStack is a Web UI and API used to collect and display test results. This information is used by the DefCore committee to help select must-pass capabilities. `RefStack docs `_ - -Test your Cloud and Share! > Running TCUP ------------------------------------------ - -TCUP (Tempest in a Container to Upload from Probe) is a portable way for community members to quickly and consistently run Tempest against private and public clouds. - -`TCUP docs `_ diff --git a/alembic/versions/121ee191d348_added_alt_user.py b/alembic/versions/121ee191d348_added_alt_user.py deleted file mode 100755 index 063e76bb..00000000 --- a/alembic/versions/121ee191d348_added_alt_user.py +++ /dev/null @@ -1,24 +0,0 @@ -"""added_alt_user - -Revision ID: 121ee191d348 -Revises: 2d1f3e3cd357 -Create Date: 2014-04-07 11:43:51.800255 - -""" - -# revision identifiers, used by Alembic. -revision = '121ee191d348' -down_revision = '2d1f3e3cd357' - -from alembic import op -import sqlalchemy as sa - - -def upgrade(): - op.add_column( - 'cloud', - sa.Column('alt_user', sa.String(length=80), nullable=True)) - - -def downgrade(): - op.drop_column('cloud', 'alt_user') diff --git a/alembic/versions/2d1f3e3cd357_added_architecture_t.py b/alembic/versions/2d1f3e3cd357_added_architecture_t.py deleted file mode 100755 index a0a4ad5a..00000000 --- a/alembic/versions/2d1f3e3cd357_added_architecture_t.py +++ /dev/null @@ -1,28 +0,0 @@ -"""added architecture to cloud - -Revision ID: 2d1f3e3cd357 -Revises: 4a425a7aff50 -Create Date: 2014-03-07 12:11:20.403933 - -""" - -# revision identifiers, used by Alembic. -revision = '2d1f3e3cd357' -down_revision = '4a425a7aff50' - -from alembic import op -import sqlalchemy as sa - - -def upgrade(): - ### commands auto generated by Alembic - please adjust! ### - op.add_column( - 'cloud', - sa.Column('architecture', sa.String(length=40), nullable=True)) - ### end Alembic commands ### - - -def downgrade(): - ### commands auto generated by Alembic - please adjust! ### - op.drop_column('cloud', 'architecture') - ### end Alembic commands ### diff --git a/alembic/versions/4a425a7aff50_major_restructure.py b/alembic/versions/4a425a7aff50_major_restructure.py deleted file mode 100755 index 752e501f..00000000 --- a/alembic/versions/4a425a7aff50_major_restructure.py +++ /dev/null @@ -1,100 +0,0 @@ -"""major restructure - -Revision ID: 4a425a7aff50 -Revises: None -Create Date: 2014-03-07 11:20:58.899889 - -""" - -# revision identifiers, used by Alembic. -revision = '4a425a7aff50' -down_revision = None - -from alembic import op -import sqlalchemy as sa - - -def upgrade(): - ### commands auto generated by Alembic - please adjust! ### - op.create_table( - 'vendor', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('vendor_name', sa.String(length=80), nullable=True), - sa.Column('contact_email', sa.String(length=120), nullable=True), - sa.Column('contact_name', sa.String(length=120), nullable=True), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('contact_email'), - sa.UniqueConstraint('vendor_name') - ) - op.create_table( - 'user', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('vendor_id', sa.Integer(), nullable=True), - sa.Column('name', sa.String(length=60), nullable=True), - sa.Column('email', sa.String(length=200), nullable=True), - sa.Column('email_verified', sa.Boolean(), nullable=True), - sa.Column('openid', sa.String(length=200), nullable=True), - sa.Column('authorized', sa.Boolean(), nullable=True), - sa.Column('su', sa.Boolean(), nullable=True), - sa.ForeignKeyConstraint(['vendor_id'], ['vendor.id'], ), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('email'), - sa.UniqueConstraint('openid') - ) - op.create_table( - 'apikey', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('name', sa.String(length=60), nullable=True), - sa.Column('key', sa.String(length=200), nullable=True), - sa.Column('openid', sa.String(length=200), nullable=True), - sa.Column('timestamp', sa.DateTime(), nullable=True), - sa.Column('user_id', sa.Integer(), nullable=True), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table( - 'cloud', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('label', sa.String(length=60), nullable=True), - sa.Column('endpoint', sa.String(length=512), nullable=True), - sa.Column('endpoint_v3', sa.String(length=512), nullable=True), - sa.Column('admin_endpoint', sa.String(length=512), nullable=True), - sa.Column('test_user', sa.String(length=80), nullable=True), - sa.Column('admin_user', sa.String(length=80), nullable=True), - sa.Column('version', sa.String(length=80), nullable=True), - sa.Column('tempest_sha', sa.String(length=128), nullable=True), - sa.Column('user_id', sa.Integer(), nullable=True), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table( - 'test', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('cloud_id', sa.Integer(), nullable=True), - sa.Column('finished', sa.Boolean(), nullable=True), - sa.Column('subunit', sa.String(length=4096), nullable=True), - sa.Column('parsed', sa.String(length=4096), nullable=True), - sa.ForeignKeyConstraint(['cloud_id'], ['cloud.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table( - 'test_status', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('test_id', sa.Integer(), nullable=True), - sa.Column('message', sa.String(length=1024), nullable=True), - sa.Column('timestamp', sa.DateTime(), nullable=True), - sa.ForeignKeyConstraint(['test_id'], ['test.id'], ), - sa.PrimaryKeyConstraint('id') - ) - ### end Alembic commands ### - - -def downgrade(): - ### commands auto generated by Alembic - please adjust! ### - op.drop_table('test_status') - op.drop_table('test') - op.drop_table('cloud') - op.drop_table('apikey') - op.drop_table('user') - op.drop_table('vendor') - ### end Alembic commands ### diff --git a/doc/run_tempest_manually.md b/doc/run_tempest_manually.md deleted file mode 100644 index 5d906a38..00000000 --- a/doc/run_tempest_manually.md +++ /dev/null @@ -1,32 +0,0 @@ -Below Instructions guide you to run tempest manually from tcup container : - -Pre-requisites : set up docker container by following instructions in the tcup.md document -Once you are in TCUP container, make sure you can able to ping $OS_AUTH_URL - -Instructions : - -1)cd tempest/etc - -2)copy tempest.conf.sample tempest.conf - -3)update the tempest.conf file with the target cloud values(AUTH_URL,User name,Password,Tenent name,Tenent Id,IMAGE_ID,IMAGE_ID_ALT) - - -4)update below attributes in tempest.conf with the OS_VALUES then save the tempest.conf file - -**Tempest.conf** ** Replace with **** -uri = OS_AUTH_URL -username = OS_USERNAME -password = OS_PASSWORD -tenant name = OS_TENANT_NAME -image_ref = {$IMAGE_ID}(run glance image-list command on target cloud, - copy image id then replace here) -image_ref_alt = {$IMAGE_ID_ALT}(run glance image-list command on target - cloud,copy image id then replace here) -5)cd tempest - -6)nosetests -v tempest ( to run full tempest suits) - -If you want to stop the tempest execution at the first failure,use below command - -7)nosetests -vx tempest diff --git a/doc/tcup.md b/doc/tcup.md deleted file mode 100644 index 85677e74..00000000 --- a/doc/tcup.md +++ /dev/null @@ -1,70 +0,0 @@ -TCUP Configuration -=========================== - -The following instructions are designs run Refstack/Tempest in a container with minimal setup on your system. - -> These steps are do not install Refstack for contributions or development, they are intended for a user who wants to just run and report test results. - -1. Make sure you have python and wget installed for your operating system. - -1. Install Docker using [[https://www.docker.io/gettingstarted/#h_installation]] - 1. Note: if you are in an environment with a proxy, make sure you configure `/etc/default/docker` to leverage the proxy too! - 1. You may want to prep-the environment using `sudo docker pull ubuntu:13.10` - -1. Setup Docker to run without sudo - 1. permanently (recommended): - 1. `sudo usermod -a -G docker ` - 1. you will need to reboot after this change - 1. short term: `sudo chmod 666 /var/run/docker.sock` - -1. Get the code: `wget https://raw.githubusercontent.com/stackforge/refstack/master/scripts/tcup.py` - 1. note: you can also get the code by cloning the Refstack and running the code in `/scripts/tcup.py` - -1. Set your environment variables to access the test target cloud - 1. generally, you will `source openrc.sh` to load the cloud credentials and URLs - -Note : once you have loaded openrc.sh, type this command : ‘env | grep OS_’ then make sure values are assigned to each of the below: - -*OS_TENANT_ID -*OS_PASSWORD -*OS_AUTH_URL -*OS_USERNAME -*OS_TENANT_NAME - -If values are missing for any of the above, you could manually export for missing env variable (ex:‘export OS_PASSWORD=’) - -1. Run TCUP: `python tcup.py` - 1. if you want to work on the code from Refstack, use `scripts/tcup.py' - - -## Troubleshooting TCUP - -Before troubleshooting TCUP, make sure that you have network connectivity to our target cloud from the host system (the one you run TCUP on). -1. ping the IP or FQDN from `echo $OS_AUTH_URL` -1. get a "HTTP/1.1 200 OK" response from `curl -I $OS_AUTH_URL` - -There are several ways to trouble shoot, TCUP. - -1. Run TCUP using the debug flag: `tcup.py --debug` -1. Attach to the container as instructed at the end of the TCUP script -1. Inside the container: - 1. check your environment variables include the OS_* values using `export | grep OS_` - 1. ping the IP or FQDN from `echo $OS_AUTH_URL` - 1. get "200 OK" from Keystone using `curl -I $OS_AUTH_URL` - 1. confirm your credentials are working using `keystone catalog` - -## Docker Tips - -1. You can inspect which containers are running! - 1. `docker ps` shows the running containers - 1. `docker attach` allows you to connect to a container (may have to press enter) - 1. exit from inside the container with `Ctrl-p` + `Ctrl-q` -1. Orphaned Containers: Over time, you may end up with [orphaned contaniers](http://jimhoskins.com/2013/07/27/remove-untagged-docker-images.html), use the following to clean them up - 1. `docker rm $(docker ps -a -q)` - 1. `docker rmi $(docker images | grep "^" | awk "{print $3}")` - -## For Developers - -If you run TCUP in debug mode (`export DEBUG=true` or using `--debug` parameter) then TCUP will automatically mount your PWD as /dev. -If you run TCUP from your Refstack clone, then you can work directly in Refstack code from inside -a TCUP container from the /dev directory. diff --git a/refstack/admin.py b/refstack/admin.py deleted file mode 100644 index c576ff73..00000000 --- a/refstack/admin.py +++ /dev/null @@ -1,28 +0,0 @@ - -import flask -from flask.ext.admin.contrib import sqla - -import models - -# Global admin object -from refstack.extensions import admin -from refstack.extensions import db - - -class SecureView(sqla.ModelView): - def is_accessible(self): - # let us look at the admin if we're in debug mode - if flask.current_app.debug: - return True - return flask.g.user.su is not False - - -def init_app(app): - admin.init_app(app) - - -def configure_admin(app): - admin.add_view(SecureView(models.ApiKey, db.session)) - admin.add_view(SecureView(models.Cloud, db.session)) - admin.add_view(SecureView(models.User, db.session)) - admin.add_view(SecureView(models.Vendor, db.session)) diff --git a/refstack/api.py b/refstack/api.py deleted file mode 100755 index 047528f6..00000000 --- a/refstack/api.py +++ /dev/null @@ -1,81 +0,0 @@ -# -# Copyright (c) 2013 Piston Cloud Computing, Inc. 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. -# -"""Basic API code. - -This is using Flask-Restless at the moment because it is super simple, -but probably should be moved to a more versatile framework like -Flask-Restful later on. -""" - -import flask -from flask.ext import restless - -import models -from refstack.extensions import api - - -def init_app(app, *args, **kw): - api.init_app(app, *args, **kw) - - -def access_control(**kw): - if not flask.g.user: - raise _not_authorized() - - if not flask.g.user.su: - return _not_authorized() - - # That's it, we're defaulting to superuser only access - # until we flesh this out further - - -ALL_METHODS = {'GET_SINGLE': [access_control], - 'GET_MANY': [access_control], - 'PUT_SINGLE': [access_control], - 'PUT_MANY': [access_control], - 'POST': [access_control], - 'DELETE': [access_control]} - - -def configure_api(app): - cloud_api = api.create_api_blueprint(models.Cloud, - preprocessors=ALL_METHODS) - cloud_api.before_request(authenticate) - app.register_blueprint(cloud_api) - - -def _not_authorized(): - return restless.ProcessingException(message='Not Authorized', - status_code=401) - - -def authenticate(): - # If we're already authenticated, we can ignore this - if flask.g.user: - return - - # Otherwise check headers - openid = flask.request.headers.get('X-AUTH-OPENID') - if openid: - # In debug mode accept anything - if flask.current_app.debug and False: - flask.g.user = models.User.query.filter_by(openid=openid).first() - return - - apikey = flask.request.headers.get('X-AUTH-APIKEY') - apikey_ref = models.ApiKey.query.filter_by(key=apikey) - if apikey_ref['openid'] == openid: - flask.g.user = apikey_ref.user diff --git a/refstack/app.py b/refstack/app.py deleted file mode 100755 index f063ab5a..00000000 --- a/refstack/app.py +++ /dev/null @@ -1,207 +0,0 @@ -# -# Copyright (c) 2013 Piston Cloud Computing, Inc. 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. -# -import os -from flask import Flask, render_template -from refstack.config import DefaultConfig -import admin -import api -from refstack.extensions import db -from refstack.extensions import oid - - -from refstack import utils - - -INSTANCE_FOLDER_PATH = utils.INSTANCE_FOLDER_PATH - - -# For import * -__all__ = ['create_app'] - -DEFAULT_BLUEPRINTS = tuple() -# frontend, -# user, -# settings, -# api, -# admin, -#) - - -def create_app(config=None, app_name=None, blueprints=None): - """Create a Flask app.""" - - if app_name is None: - app_name = DefaultConfig.PROJECT - if blueprints is None: - blueprints = DEFAULT_BLUEPRINTS - - # NOTE(termie): Flask has this new instance_path stuff that allows - # you to keep config and such in different places, but I don't really - # see how that is going to be very helpful, so we're going to stick - # to using config relative to the root unless we explicitly set such - # a path in the INSTANCE_FOLDER_PATH environment variable. - app = Flask(app_name, - instance_path=INSTANCE_FOLDER_PATH, - instance_relative_config=True) - - configure_app(app, config) - configure_hook(app) - configure_blueprints(app, blueprints) - configure_extensions(app) - configure_logging(app) - configure_template_filters(app) - configure_error_handlers(app) - - if app.debug: - print(utils.dump_config(app)) - - return app - - -def configure_app(app, config=None): - """Different ways of configurations.""" - - # http://flask.pocoo.org/docs/api/#configuration - app.config.from_object(DefaultConfig) - - # If we've set the INSTANCE_FOLDER_PATH environment var, this may be - # loaded from an instance folder, otherwise relative to flask.root_path. - # http://flask.pocoo.org/docs/config/#instance-folders - app.config.from_pyfile('refstack.cfg', silent=True) - - if config: - app.config.from_object(config) - - -def configure_extensions(app): - # flask-sqlalchemy - db.init_app(app) - - # flask-admin - admin.init_app(app) - admin.configure_admin(app) - - # flask-restless - api.init_app(app, flask_sqlalchemy_db=db) - api.configure_api(app) - - ## flask-mail - #mail.init_app(app) - - ## flask-cache - #cache.init_app(app) - - ## flask-babel - #babel = Babel(app) - - #@babel.localeselector - #def get_locale(): - # accept_languages = app.config.get('ACCEPT_LANGUAGES') - # return request.accept_languages.best_match(accept_languages) - - ## flask-login - #login_manager.login_view = 'frontend.login' - #login_manager.refresh_view = 'frontend.reauth' - - #@login_manager.user_loader - #def load_user(id): - # return User.query.get(id) - #login_manager.setup_app(app) - - # flask-openid - oid.init_app(app) - - -def configure_blueprints(app, blueprints): - """Configure blueprints in views.""" - - for blueprint in blueprints: - app.register_blueprint(blueprint) - - -def configure_template_filters(app): - - @app.template_filter() - def pretty_date(value): - return pretty_date(value) - - @app.template_filter() - def format_date(value, format='%Y-%m-%d'): - return value.strftime(format) - - -def configure_logging(app): - """Configure file(info) and email(error) logging.""" - - if app.debug or app.testing: - # Skip debug and test mode. Just check standard output. - return - - import logging - from logging.handlers import SMTPHandler - - # Set info level on logger, which might be overwritten by handlers. - # Suppress DEBUG messages. - app.logger.setLevel(logging.INFO) - - info_log = os.path.join(app.config['LOG_FOLDER'], 'info.log') - info_file_handler = logging.handlers.RotatingFileHandler( - info_log, maxBytes=100000, backupCount=10) - info_file_handler.setLevel(logging.INFO) - info_file_handler.setFormatter(logging.Formatter( - '%(asctime)s %(levelname)s: %(message)s ' - '[in %(pathname)s:%(lineno)d]') - ) - app.logger.addHandler(info_file_handler) - - # Testing - #app.logger.info("testing info.") - #app.logger.warn("testing warn.") - #app.logger.error("testing error.") - - mail_handler = SMTPHandler(app.config['MAIL_SERVER'], - app.config['MAIL_USERNAME'], - app.config['ADMINS'], - 'O_ops... %s failed!' % app.config['PROJECT'], - (app.config['MAIL_USERNAME'], - app.config['MAIL_PASSWORD'])) - mail_handler.setLevel(logging.ERROR) - mail_handler.setFormatter(logging.Formatter( - '%(asctime)s %(levelname)s: %(message)s ' - '[in %(pathname)s:%(lineno)d]') - ) - app.logger.addHandler(mail_handler) - - -def configure_hook(app): - @app.before_request - def before_request(): - pass - - -def configure_error_handlers(app): - - @app.errorhandler(403) - def forbidden_page(error): - return render_template("errors/forbidden_page.html"), 403 - - @app.errorhandler(404) - def page_not_found(error): - return render_template("errors/page_not_found.html"), 404 - - @app.errorhandler(500) - def server_error_page(error): - return render_template("errors/server_error.html"), 500 diff --git a/refstack/client/client.py b/refstack/client/client.py deleted file mode 100644 index e69de29b..00000000 diff --git a/refstack/client/requirements.txt b/refstack/client/requirements.txt deleted file mode 100644 index 439faee1..00000000 --- a/refstack/client/requirements.txt +++ /dev/null @@ -1,10 +0,0 @@ -lockfile -subunit -python-daemon -extras -statsd>=1.0.0,<3.0 -sqlalchemy>=0.8.2,<0.9.0 -pyzmq>=13.1.0,<14.0.0 -git+https://github.com/openstack/tempest.git -SQLAlchemy==0.8.1 -requests==1.2.3 diff --git a/refstack/client/runtests.sh b/refstack/client/runtests.sh deleted file mode 100644 index e69de29b..00000000 diff --git a/refstack/client/test-requirements.txt b/refstack/client/test-requirements.txt deleted file mode 100644 index bb3d39d2..00000000 --- a/refstack/client/test-requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -python-subunit -docutils==0.9.1 diff --git a/refstack/client/tox.ini b/refstack/client/tox.ini deleted file mode 100755 index 3d7a9537..00000000 --- a/refstack/client/tox.ini +++ /dev/null @@ -1,19 +0,0 @@ -# content of: tox.ini , put in same dir as setup.py -[tox] -envlist = py27 - - -[testenv] -# Set STATSD env variables so that statsd code paths are tested. -setenv = STATSD_HOST=localhost - STATSD_PORT=8125 - - VIRTUAL_ENV=/tmp/1/env -changedir=/tmp/1 -commands= - client.py {posargs:--config} - - -deps = -r{toxinidir}/requirements.txt - -r{toxinidir}/test-requirements.txt - diff --git a/refstack/config.py b/refstack/config.py deleted file mode 100755 index 0e5f1c6f..00000000 --- a/refstack/config.py +++ /dev/null @@ -1,90 +0,0 @@ -# -# Copyright (c) 2013 Piston Cloud Computing, Inc. 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. -# -import os - -from utils import make_dir, INSTANCE_FOLDER_PATH, PROJECT_ROOT - - -class BaseConfig(object): - """base config object""" - PROJECT = "refstack" - - # The app root path, also can use flask.root_path. - PROJECT_ROOT = PROJECT_ROOT - - DEBUG = False - TESTING = False - - ADMINS = ['youremail@yourdomain.com'] - - # http://flask.pocoo.org/docs/quickstart/#sessions - SECRET_KEY = 'secret key' - - LOG_FOLDER = os.path.join(INSTANCE_FOLDER_PATH, 'logs') - make_dir(LOG_FOLDER) - - # Fild upload, should override in production. - # Limited the maximum allowed payload to 16 megabytes. - # http://flask.pocoo.org/docs/patterns/fileuploads/#improving-uploads - MAX_CONTENT_LENGTH = 16 * 1024 * 1024 - UPLOAD_FOLDER = os.path.join(INSTANCE_FOLDER_PATH, 'uploads') - make_dir(UPLOAD_FOLDER) - - -class DefaultConfig(BaseConfig): - """default config thing""" - DEBUG = True - - # Flask-Sqlalchemy: http://packages.python.org/Flask-SQLAlchemy/config.html - SQLALCHEMY_ECHO = True - # SQLITE for prototyping. - SQLALCHEMY_DATABASE_URI = 'sqlite:///' + \ - INSTANCE_FOLDER_PATH + '/db.sqlite' - # MYSQL for production. - #SQLALCHEMY_DATABASE_URI = \ - # 'mysql://username:password@server/db?charset=utf8' - - # Flask-babel: http://pythonhosted.org/Flask-Babel/ - ACCEPT_LANGUAGES = ['zh'] - BABEL_DEFAULT_LOCALE = 'en' - - # Flask-cache: http://pythonhosted.org/Flask-Cache/ - CACHE_TYPE = 'simple' - CACHE_DEFAULT_TIMEOUT = 60 - - # Flask-mail: http://pythonhosted.org/flask-mail/ - MAIL_DEBUG = DEBUG - MAIL_SERVER = 'smtp.gmail.com' - MAIL_PORT = 587 - MAIL_USE_TLS = True - MAIL_USE_SSL = False - # Should put MAIL_USERNAME and MAIL_PASSWORD - # in production under instance folder. - MAIL_USERNAME = 'yourmail@gmail.com' - MAIL_PASSWORD = 'yourpass' - MAIL_DEFAULT_SENDER = MAIL_USERNAME - - # Flask-openid: http://pythonhosted.org/Flask-OpenID/ - OPENID_FS_STORE_PATH = os.path.join(INSTANCE_FOLDER_PATH, 'openid') - make_dir(OPENID_FS_STORE_PATH) - - -class TestConfig(BaseConfig): - TESTING = True - WTF_CSRF_ENABLED = False - - SQLALCHEMY_ECHO = False - SQLALCHEMY_DATABASE_URI = 'sqlite://' diff --git a/refstack/decorators.py b/refstack/decorators.py deleted file mode 100644 index 2e0539f8..00000000 --- a/refstack/decorators.py +++ /dev/null @@ -1,17 +0,0 @@ -#-*- coding: utf-8 -*- - -# This file based on MIT licensed code at: https://github.com/imwilsonxu/fbone - -from functools import wraps - -from flask import abort -from flask.ext.login import current_user - - -def admin_required(f): - @wraps(f) - def decorated_function(*args, **kwargs): - if not current_user.is_admin(): - abort(403) - return f(*args, **kwargs) - return decorated_function diff --git a/refstack/extensions.py b/refstack/extensions.py deleted file mode 100755 index ccf6bcbe..00000000 --- a/refstack/extensions.py +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (c) 2013 Piston Cloud Computing, Inc. -# 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 flask.ext.admin import Admin -admin = Admin() - -from flask.ext.restless import APIManager -api = APIManager() - -from flask.ext.sqlalchemy import SQLAlchemy -db = SQLAlchemy() - -from flask.ext.mail import Mail -mail = Mail() - -# TODO(termie): not used yet -#from flask.ext.cache import Cache -#cache = Cache() - -from flask.ext.login import LoginManager -login_manager = LoginManager() - -from flask.ext.openid import OpenID -oid = OpenID() diff --git a/refstack/templates/admin/master_legacy.html b/refstack/templates/admin/master_legacy.html deleted file mode 100644 index f217bdf3..00000000 --- a/refstack/templates/admin/master_legacy.html +++ /dev/null @@ -1,11 +0,0 @@ -{% extends "layout.html" %} -{% import 'admin/layout.html' as layout with context -%} -{% block head_css %} - - - -{% endblock %} -{% block body %}{% endblock %} -{% block tail_js %} - -{% endblock %} \ No newline at end of file diff --git a/refstack/templates/create_profile.html b/refstack/templates/create_profile.html deleted file mode 100644 index 00030fb0..00000000 --- a/refstack/templates/create_profile.html +++ /dev/null @@ -1,22 +0,0 @@ -{% extends "layout.html" %} -{% block title %}Create Profile{% endblock %} -{% block body %} -

Create Profile

-

- Hey! This is the first time you signed in on this website. In - order to proceed we need some extra information from you: -

-
-
Name: -
-
E-Mail: -
-
-

- - -

-

- If you don't want to proceed, you can sign out again. -{% endblock %} diff --git a/refstack/templates/edit_profile.html b/refstack/templates/edit_profile.html deleted file mode 100644 index a9b6b877..00000000 --- a/refstack/templates/edit_profile.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends "layout.html" %} -{% block title %}Edit Profile{% endblock %} -{% block body %} -

Edit Profile

-
-
-
Name: -
-
E-Mail -
-
-

- - -

-{% endblock %} diff --git a/refstack/templates/errors/page_not_found.html b/refstack/templates/errors/page_not_found.html deleted file mode 100644 index 32616182..00000000 --- a/refstack/templates/errors/page_not_found.html +++ /dev/null @@ -1 +0,0 @@ -page not found diff --git a/refstack/templates/home.html b/refstack/templates/home.html deleted file mode 100644 index 8377d188..00000000 --- a/refstack/templates/home.html +++ /dev/null @@ -1,131 +0,0 @@ -{% extends "layout.html" %} -{% block title %}Welcome{% endblock %} -{% block body %} -
-
- Clouds - -
- - {% for cloud in clouds %} - - - - - {% endfor %} -
- {{ cloud.label }} - -
- - - -
-
-
- -
-
- Tests -
- - {% for cloud in clouds %} - {% for test in cloud.tests %} - - - - - {% endfor %} - {% endfor %} -
- {{ cloud.label }} (Test ID: {{ test.id }} ) - -
- {% if test.finished %} - - - {% else %} - - {% endif %} - -
-
-
- - -{% endblock %} diff --git a/refstack/templates/index.html b/refstack/templates/index.html deleted file mode 100644 index 4ad9e700..00000000 --- a/refstack/templates/index.html +++ /dev/null @@ -1,41 +0,0 @@ -{% extends "layout.html" %} -{% block title %}Welcome{% endblock %} -{% block body %} -
-

What is Refstack?

-
-
- -

An existence proof of the certified openstack APIs.

-
-
- -

A reference OpenStack environment for tools developers.

-
-
- -

A certification process for OpenStack service and product vendors.

-
-
-
- Vendors that are registered with RefStack:

-
    - {% for vendor in vendors %} -
  • {{ vendor.vendor_name }}
  • - {% endfor %} -
-
-
-

Get involved!

- We welcome collaboration.
- To join the conversation jump into #refstack on freenode. -

- For a living blueprint see our etherpad! -
-
-

Refstack CLI

- The refstack command line interface allows you to pre-test your cloud.
-
- Documentation coming soon! -
-{% endblock %} \ No newline at end of file diff --git a/refstack/templates/layout.html b/refstack/templates/layout.html deleted file mode 100644 index c4fe3f0c..00000000 --- a/refstack/templates/layout.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - {% block title %}Welcome{% endblock %} | RefStack - - - - - - - - - - - - {% block head_css %}{% endblock %} - - -
-
- - -
- -
- {% for message in get_flashed_messages() %} -

{{ message }}

- {% endfor %} -
- {% block body %}{% endblock %} -
-
-
- {% block tail_js %}{% endblock %} - - - diff --git a/refstack/templates/login.html b/refstack/templates/login.html deleted file mode 100644 index f319b31e..00000000 --- a/refstack/templates/login.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "layout.html" %} -{% block title %}Sign in{% endblock %} -{% block body %} -

Sign in

-
- {% if error %}

Error: {{ error }}

{% endif %} -

- OpenID: - - - -

-{% endblock %} diff --git a/refstack/templates/scorecard.html b/refstack/templates/scorecard.html deleted file mode 100644 index 3e9c5cbf..00000000 --- a/refstack/templates/scorecard.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - {% block title %}Welcome{% endblock %} | RefStack - - - - - - - - - - - - {% block head_css %}{% endblock %} - - -
- -
- -
-
- Forced Results -
-
    -
  • compute
  • -
  • aggregates
  • -
  • availability zone
  • -
  • fixed ips
  • -
  • flavors access
  • -
  • flavors extra specs
  • -
  • flavors
  • -
  • hosts
  • -
  • hypervisor
  • -
  • quotas
  • -
  • servers
  • -
  • services
  • -
  • simple tenant usage
  • -
  • flavors
  • -
  • floating ips
  • -
  • floating ips actions
  • -
  • list floating ips
  • -
  • images
  • -
  • image metadata
  • -
  • images oneserver
  • -
  • images
  • -
  • list image filters
  • -
  • list images
  • -
  • keypairs
  • -
  • keypairs
  • -
  • limits
  • -
  • absolute limits
  • -
  • security groups
  • -
  • security group rules
  • -
  • security groups
  • -
  • servers
  • -
  • attach interfaces
  • -
  • create server
  • -
  • disk config
  • -
  • instance actions
  • -
  • list server filters
  • -
  • list servers negative
  • -
  • multiple create
  • -
  • server actions
  • -
  • server addresses
  • -
  • server metadata
  • -
  • server personality
  • -
  • server rescue
  • -
  • servers negative
  • -
  • servers
  • -
  • virtual interfaces
  • -
  • authorization
  • -
  • auth token
  • -
  • extensions
  • -
  • live block migration
  • -
  • quotas
  • -
  • volumes
  • -
  • attach volume
  • -
  • volumes get
  • -
  • volumes list
  • -
  • volumes negative
  • -
  • identity
  • -
  • admin
  • -
  • roles
  • -
  • services
  • -
  • tenants
  • -
  • users
  • -
  • image
  • -
  • v1
  • -
  • image members
  • -
  • images
  • -
  • v2
  • -
  • images
  • -
  • network
  • -
  • floating ips
  • -
  • load balancer
  • -
  • networks
  • -
  • quotas
  • -
  • routers
  • -
  • security groups
  • -
  • object storage
  • -
  • account quotas
  • -
  • account services
  • -
  • container acl
  • -
  • container services
  • -
  • container staticweb
  • -
  • container sync
  • -
  • object expiry
  • -
  • object services
  • -
  • object version
  • -
  • orchestration
  • -
  • neutron resources
  • -
  • non empty stack
  • -
  • server cfn init
  • -
  • stacks
  • -
  • templates
  • -
  • volume
  • -
  • multi backend
  • -
  • volume types extra specs negative
  • -
  • volume types extra specs
  • -
  • volume types negative
  • -
  • volume types
  • -
  • volumes actions
  • -
  • volumes get
  • -
  • volumes list
  • -
  • volumes negative
  • -
  • volumes snapshots
  • -
- {% block body %}{% endblock %} -
-
-
- - - \ No newline at end of file diff --git a/refstack/templates/view_profile.html b/refstack/templates/view_profile.html deleted file mode 100644 index b82cb6ad..00000000 --- a/refstack/templates/view_profile.html +++ /dev/null @@ -1,45 +0,0 @@ -{% extends "layout.html" %} -{% block title %}View Profile{% endblock %} -{% block body %} - -
-
- {{ user.name }}'s profile - - - - - -
- - - - - - - - - - -
- E-Mail: - - {{ user.email }} - {% if user.email_verified %} - - {% else %} - - {% endif %} -
- Vendor: - - {{ user.vendor.vendor_name }} - {% if user.authorized %} - - {% else %} - - {% endif %} -
-
- -{% endblock %} diff --git a/refstack/tests/unit/tests.py b/refstack/tests/unit/tests.py index f3e13add..bb8d3ead 100755 --- a/refstack/tests/unit/tests.py +++ b/refstack/tests/unit/tests.py @@ -13,15 +13,11 @@ # License for the specific language governing permissions and limitations # under the License. # -from refstack import app as base_app import unittest class TestSequenceFunctions(unittest.TestCase): - def setUp(self): - self.app = base_app.create_app().test_client() - def test_nothing(self): # make sure the shuffled sequence does not lose any elements pass diff --git a/refstack/utils.py b/refstack/utils.py index c94b7eb0..3fef52b1 100755 --- a/refstack/utils.py +++ b/refstack/utils.py @@ -19,7 +19,6 @@ from datetime import datetime import os -import pprint import random import string @@ -120,8 +119,3 @@ def make_dir(dir_path): ### Begin Non-Fbone stuff - - -def dump_config(app): - """Useful to dump app config for debug purposes.""" - return pprint.pformat(dict(app.config.items())) diff --git a/refstack/web.py b/refstack/web.py deleted file mode 100755 index b393e201..00000000 --- a/refstack/web.py +++ /dev/null @@ -1,184 +0,0 @@ -# -# Copyright (c) 2013 Piston Cloud Computing, Inc. 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. -# - -import flask -from flask import abort, flash, request, redirect, url_for, \ - render_template, g, session -from flask_mail import Mail -from refstack import app as base_app -from refstack.extensions import db -from refstack.extensions import oid -from refstack.models import Cloud -from refstack.models import Test -from refstack.models import User -from refstack.models import Vendor - -app = base_app.create_app() -mail = Mail(app) -public_routes = ['/post-result', '/get-miniconf'] - - -@app.before_request -def before_request(): - """Runs before the request itself.""" - if request.path not in public_routes: - g.user = None - if 'openid' in session: - flask.g.user = User.query.\ - filter_by(openid=session['openid']).first() - - -@app.route('/', methods=['POST', 'GET']) -def index(): - """Index view.""" - if g.user is not None: - # something else - clouds = Cloud.query.filter_by(user_id=g.user.id).all() - return render_template('home.html', clouds=clouds) - else: - vendors = Vendor.query.all() - return render_template('index.html', vendors=vendors) - - -@app.route('/login', methods=['GET', 'POST']) -@oid.loginhandler -def login(): - """Does the login via OpenID. - - Has to call into `oid.try_login` to start the OpenID machinery. - """ - # if we are already logged in, go back to were we came from - if g.user is not None: - return redirect(oid.get_next_url()) - return oid.try_login( - "https://login.launchpad.net/", - ask_for=['email', 'nickname']) - - -@oid.after_login -def create_or_login(resp): - """This is called when login with OpenID succeeded and it's not - necessary to figure out if this is the users's first login or not. - This function has to redirect otherwise the user will be presented - with a terrible URL which we certainly don't want. - """ - session['openid'] = resp.identity_url - user = User.query.filter_by(openid=resp.identity_url).first() - if user is not None: - flash(u'Successfully signed in') - g.user = user - return redirect(oid.get_next_url()) - return redirect(url_for('create_profile', next=oid.get_next_url(), - name=resp.fullname or resp.nickname, - email=resp.email)) - - -@app.route('/create-profile', methods=['GET', 'POST']) -def create_profile(): - """If this is the user's first login, the create_or_login function - will redirect here so that the user can set up his profile. - """ - if g.user is not None or 'openid' not in session: - return redirect(url_for('index')) - if request.method == 'POST': - name = request.form['name'] - email = request.form['email'] - if not name: - flash(u'Error: you have to provide a name') - elif '@' not in email: - flash(u'Error: you have to enter a valid email address') - else: - flash(u'Profile successfully created') - db.session.add(User(name, email, session['openid'])) - db.session.commit() - return redirect(oid.get_next_url()) - return render_template( - 'create_profile.html', next_url=oid.get_next_url()) - - -@app.route('/profile/edit', methods=['GET', 'POST']) -def edit_profile(): - """Updates a profile.""" - if g.user is None: - abort(401) - form = dict(name=g.user.name, email=g.user.email) - if request.method == 'POST': - if 'delete' in request.form: - db.session.delete(g.user) - db.session.commit() - session['openid'] = None - flash(u'Profile deleted') - return redirect(url_for('index')) - form['name'] = request.form['name'] - form['email'] = request.form['email'] - if not form['name']: - flash(u'Error: you have to provide a name') - elif '@' not in form['email']: - flash(u'Error: you have to enter a valid email address') - else: - flash(u'Profile successfully created') - g.user.name = form['name'] - g.user.email = form['email'] - db.session.commit() - return redirect(url_for('edit_profile')) - return render_template('edit_profile.html', form=form) - - -@app.route('/profile', methods=['GET', 'POST']) -def view_profile(): - """Updates a profile.""" - if g.user is None: - abort(401) - - return render_template('view_profile.html', user=g.user) - - -@app.route('/logout') -def logout(): - """Log out.""" - session.pop('openid', None) - flash(u'You have been signed out') - return redirect(oid.get_next_url()) - - -@app.route('/post-result', methods=['POST']) -def post_result(): - """Receive tempest test result from a remote test runner.""" - # todo: come up with some form of authentication - # Im sure we can come with something more elegant than this - # but it should work for now. - #print request.files - f = request.files['file'] - if not f: - return 'only valid with file post', 400 - else: - if request.args.get('test_id', ''): - # this data is for a specific test triggered by the gui and we - # want to relate it - new_test = Test.query.\ - filter_by(id=request.args.get('test_id', '')).first() - new_test.subunit = f.read() - new_test.finished = True - - else: - # anonymous data .. we still want to capture it - new_test = Test() - new_test.subunit = f.read() - new_test.finished = True - db.session.add(new_test) - - db.session.commit() - return 'thank you', 201 diff --git a/requirements.txt b/requirements.txt index ce49e3cf..c2a74cc7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,21 +1,6 @@ -Flask==0.10.1 -Flask-Admin==1.0.7 -Flask-Login==0.2.11 -Flask-Mail==0.9.0 -Flask-OpenID==1.2.1 -Flask-Principal==0.3.5 -Flask-SQLAlchemy==1.0 -Flask-Security==1.6.3 -Flask-WTF==0.8.3 -Flask-Restless==0.13.1 SQLAlchemy==0.8.3 -WTForms==1.0.4 -Werkzeug==0.9.6 alembic==0.5.0 gunicorn==0.17.4 pyOpenSSL==0.13 pycrypto==2.6 -python-openid==2.2.5 requests==1.2.3 -python-keystoneclient -Jinja2==2.7.1