diff --git a/alembic/versions/1d6540fc6279_added_vendor_contact.py b/alembic/versions/1d6540fc6279_added_vendor_contact.py old mode 100644 new mode 100755 index 34a501bd..164b7c93 --- a/alembic/versions/1d6540fc6279_added_vendor_contact.py +++ b/alembic/versions/1d6540fc6279_added_vendor_contact.py @@ -16,7 +16,9 @@ import sqlalchemy as sa def upgrade(): ### commands auto generated by Alembic - please adjust! ### - op.add_column('vendor', sa.Column('contact_name', sa.String(length=120), nullable=True)) + op.add_column( + 'vendor', + sa.Column('contact_name', sa.String(length=120), nullable=True)) ### end Alembic commands ### diff --git a/alembic/versions/3790aed42558_from_scratch.py b/alembic/versions/3790aed42558_from_scratch.py old mode 100644 new mode 100755 index 08f59164..aca331c6 --- a/alembic/versions/3790aed42558_from_scratch.py +++ b/alembic/versions/3790aed42558_from_scratch.py @@ -16,63 +16,69 @@ import sqlalchemy as sa def upgrade(): ### commands auto generated by Alembic - please adjust! ### - 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=120), nullable=True), - sa.Column('test_user', sa.String(length=80), nullable=True), - sa.Column('test_key', sa.String(length=80), nullable=True), - sa.Column('admin_endpoint', sa.String(length=120), nullable=True), - sa.Column('admin_user', sa.String(length=80), nullable=True), - sa.Column('admin_key', sa.String(length=80), nullable=True), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('endpoint') + 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=120), nullable=True), + sa.Column('test_user', sa.String(length=80), nullable=True), + sa.Column('test_key', sa.String(length=80), nullable=True), + sa.Column('admin_endpoint', sa.String(length=120), nullable=True), + sa.Column('admin_user', sa.String(length=80), nullable=True), + sa.Column('admin_key', sa.String(length=80), nullable=True), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('endpoint') ) - 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.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('contact_email'), - sa.UniqueConstraint('vendor_name') + 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.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( + '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('test', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('cloud_id', sa.Integer(), nullable=True), - sa.Column('config', sa.String(length=4096), nullable=True), - sa.ForeignKeyConstraint(['cloud_id'], ['cloud.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('config', sa.String(length=4096), nullable=True), + sa.ForeignKeyConstraint(['cloud_id'], ['cloud.id'], ), + sa.PrimaryKeyConstraint('id') ) - op.create_table('test_results', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('test_id', sa.Integer(), nullable=True), - sa.Column('timestamp', sa.DateTime(), nullable=True), - sa.Column('blob', sa.Binary(), nullable=True), - sa.ForeignKeyConstraint(['test_id'], ['test.id'], ), - sa.PrimaryKeyConstraint('id') + op.create_table( + 'test_results', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('test_id', sa.Integer(), nullable=True), + sa.Column('timestamp', sa.DateTime(), nullable=True), + sa.Column('blob', sa.Binary(), nullable=True), + sa.ForeignKeyConstraint(['test_id'], ['test.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('finished', sa.Boolean(), nullable=True), - sa.Column('timestamp', sa.DateTime(), nullable=True), - sa.ForeignKeyConstraint(['test_id'], ['test.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('finished', sa.Boolean(), nullable=True), + sa.Column('timestamp', sa.DateTime(), nullable=True), + sa.ForeignKeyConstraint(['test_id'], ['test.id'], ), + sa.PrimaryKeyConstraint('id') ) ### end Alembic commands ### diff --git a/alembic/versions/4288db006e5_added_user_cloud_rel.py b/alembic/versions/4288db006e5_added_user_cloud_rel.py old mode 100644 new mode 100755 index f6d48ec7..c71c84b0 --- a/alembic/versions/4288db006e5_added_user_cloud_rel.py +++ b/alembic/versions/4288db006e5_added_user_cloud_rel.py @@ -10,9 +10,6 @@ Create Date: 2013-10-31 21:00:27.473833 revision = '4288db006e5' down_revision = '1d6540fc6279' -from alembic import op -import sqlalchemy as sa - def upgrade(): ### commands auto generated by Alembic - please adjust! ### diff --git a/alembic/versions/449461dbc725_add_apikey.py b/alembic/versions/449461dbc725_add_apikey.py old mode 100644 new mode 100755 index 9becd096..89750c88 --- a/alembic/versions/449461dbc725_add_apikey.py +++ b/alembic/versions/449461dbc725_add_apikey.py @@ -15,7 +15,8 @@ import sqlalchemy as sa def upgrade(): - op.create_table('apikey', + 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), @@ -24,7 +25,7 @@ def upgrade(): sa.Column('timestamp', sa.DateTime(), nullable=True), sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), sa.PrimaryKeyConstraint('id'), - ) + ) def downgrade(): diff --git a/alembic/versions/59e15d864941_added_subunit_output.py b/alembic/versions/59e15d864941_added_subunit_output.py old mode 100644 new mode 100755 index f393f454..a79f7336 --- a/alembic/versions/59e15d864941_added_subunit_output.py +++ b/alembic/versions/59e15d864941_added_subunit_output.py @@ -16,7 +16,10 @@ import sqlalchemy as sa def upgrade(): ### commands auto generated by Alembic - please adjust! ### - op.add_column('test_results', sa.Column('subunit', sa.String(length=8192), nullable=True)) + op.add_column( + 'test_results', + sa.Column('subunit', sa.String(length=8192), nullable=True) + ) ### end Alembic commands ### diff --git a/refstack/api.py b/refstack/api.py old mode 100644 new mode 100755 index 14e675f4..102667fc --- a/refstack/api.py +++ b/refstack/api.py @@ -1,3 +1,18 @@ +# +# 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, @@ -47,8 +62,6 @@ def _not_authorized(): status_code=401) - - def authenticate(): # If we're already authenticated, we can ignore this if flask.g.user: diff --git a/refstack/app.py b/refstack/app.py old mode 100644 new mode 100755 index b1570ae7..5f12898d --- a/refstack/app.py +++ b/refstack/app.py @@ -1,19 +1,21 @@ -# -*- coding: utf-8 -*- - -# This file based on MIT licensed code at: https://github.com/imwilsonxu/fbone - +# +# 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, request, render_template -#from flask.ext.babel import Babel - +from flask import Flask, render_template from .config import DefaultConfig -#from .user import User, user -#from .settings import settings -#from .frontend import frontend -#from .api import api -#from .admin import admin -#from .extensions import db, mail, cache, login_manager, oid from refstack import admin from refstack import api from .extensions import db @@ -55,8 +57,6 @@ def create_app(config=None, app_name=None, blueprints=None): instance_path=INSTANCE_FOLDER_PATH, instance_relative_config=True) - - configure_app(app, config) configure_hook(app) configure_blueprints(app, blueprints) @@ -85,9 +85,6 @@ def configure_app(app, config=None): if config: app.config.from_object(config) - # Use instance folder instead of env variables to make deployment easier. - #app.config.from_envvar('%s_APP_CONFIG' % DefaultConfig.PROJECT.upper(), silent=True) - def configure_extensions(app): # flask-sqlalchemy @@ -161,7 +158,8 @@ def configure_logging(app): 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 = 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 ' diff --git a/refstack/common/tempest_config.py b/refstack/common/tempest_config.py index 82eb30c1..660e3f40 100755 --- a/refstack/common/tempest_config.py +++ b/refstack/common/tempest_config.py @@ -14,7 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. from keystoneclient.v2_0 import client -from refstack.models import * +from refstack.models import db, Cloud class TempestConfig(object): @@ -24,14 +24,13 @@ class TempestConfig(object): def output(self): """outputs config in propper format""" output = '' - for k,v in self.config.items(): + for k, v in self.config.items(): output += '[%s] \n' % k - for sk,sv in v.items(): - output += '%s = %s \n' % (sk,sv) + for sk, sv in v.items(): + output += '%s = %s \n' % (sk, sv) output += '\n' return output - def build_config_from_keystone(self): """uses the keystoneclient libs to query a clouds endpoint and retrive a service catelog. that it then uses to populate the @@ -65,9 +64,11 @@ class TempestConfig(object): self._keystone.management_url = self._cloud.admin_endpoint - # make sure this keystone server can list services using has_service_catalog + # make sure this keystone server can list services + # using has_service_catalog if not self._keystone.has_service_catalog(): - # we have no service catelog all tests are fail because we can't build a config + # we have no service catelog all tests are fail + # because we can't build a config print "fail " #else: # print "has service catalog" @@ -76,13 +77,12 @@ class TempestConfig(object): # make a local dict of the service catalog for item in self._keystone.service_catalog.catalog['serviceCatalog']: - self.service_catalog[item['name']]=item['endpoints'][0]['publicURL'] - - #print "%s : %s" % (item['name'],item['endpoints'][0]['publicURL']) + self.service_catalog[item['name']] = \ + item['endpoints'][0]['publicURL'] # setup output service_available for service in self.config['service_available'].keys(): - if self.service_catalog.has_key(service): + if service in self.service_catalog: self.config['service_available'][service] = True # boto settings @@ -92,17 +92,16 @@ class TempestConfig(object): # return the actual config return self.output() - def __init__(self, cloud_id): """ sets up the default configs""" self.cloud_id = cloud_id self.config['DEFAULT'] = { - 'debug':True, - 'use_stderr':False, - 'log_file':'output', + 'debug': True, + 'use_stderr': False, + 'log_file': 'output', 'lock_path': '/tmp/'+str(cloud_id)+'/', - 'default_log_levels':"""tempest.stress=INFO,amqplib=WARN, + 'default_log_levels': """tempest.stress=INFO,amqplib=WARN, sqlalchemy=WARN,boto=WARN,suds=INFO,keystone=INFO, eventlet.wsgi.server=WARN"""} @@ -123,7 +122,6 @@ class TempestConfig(object): 'admin_tenant_name': '', 'admin_role': ''} - self.config['compute'] = { 'catalog_type': 'compute', 'allow_tenant_isolation': True, @@ -166,7 +164,7 @@ class TempestConfig(object): self.config['image'] = { 'catalog_type': 'image', 'api_version': 1, - 'http_image': 'ttp://download.cirros-cloud.net/0.3.1/cirros-0.3.1-x86_64-uec.tar.gz'} + 'http_image': ''} self.config['network'] = { 'catalog_type': 'network', @@ -175,7 +173,7 @@ class TempestConfig(object): 'tenant_network_mask_bits': 28, 'tenant_networks_reachable': False, 'public_network_id': '', - 'public_router_id': '' } + 'public_router_id': ''} self.config['volume'] = { 'catalog_type': 'volume', @@ -186,14 +184,14 @@ class TempestConfig(object): 'backend1_name': 'BACKEND_1', 'backend2_name': 'BACKEND_2', 'storage_protocol': 'iSCSI', - 'vendor_name': 'Open Source' } + 'vendor_name': 'Open Source'} self.config['object-storage'] = { 'catalog_type': 'object-store', 'container_sync_timeout': 120, 'container_sync_interval': 5, 'accounts_quotas_available': True, - 'operator_role': 'Member' } + 'operator_role': 'Member'} self.config['boto'] = { 'ssh_user': 'cirros', @@ -209,7 +207,7 @@ class TempestConfig(object): 'http_socket_timeout': 30, 'num_retries': 1, 'build_timeout': 400, - 'build_interval': 1 } + 'build_interval': 1} self.config['orchestration'] = { 'catalog_type': 'orchestration', @@ -229,12 +227,12 @@ class TempestConfig(object): 'ari_img_file': 'cirros-0.3.1-x86_64-initrd', 'aki_img_file': 'cirros-0.3.1-x86_64-vmlinuz', 'ssh_user': 'cirros', - 'large_ops_number': 0 } + 'large_ops_number': 0} self.config['cli'] = { 'enabled': True, 'cli_dir': '/usr/local/bin', - 'timeout': 15 } + 'timeout': 15} self.config['service_available'] = { 'cinder': False, @@ -243,9 +241,9 @@ class TempestConfig(object): 'swift': False, 'nova': False, 'heat': False, - 'horizon': False } + 'horizon': False} self.config['stress'] = { 'max_instances': 32, 'log_check_interval': 60, - 'default_thread_number_per_action': 4 } + 'default_thread_number_per_action': 4} diff --git a/refstack/common/tester.py b/refstack/common/tester.py index 82487a94..411fa7b7 100755 --- a/refstack/common/tester.py +++ b/refstack/common/tester.py @@ -18,7 +18,7 @@ from subprocess import call from refstack.common.tempest_config import TempestConfig import testrepository.repository.file from testrepository import ui -#from testrepository.commands import run +from testrepository.commands import run from testrepository.commands import init import gear @@ -26,17 +26,15 @@ import gear class TesterWorker(object): """gearman worker code""" - def __init__(self,app): + def __init__(self, app): self.worker = gear.Worker('run_remote_test') self.worker.addServer(app.gearman_server) self.worker.registerFunction('run_remote_test') - def run_remote_test(self): pass - def run_job(self): while True: job = self.worker.getJob() @@ -68,13 +66,11 @@ class TestRepositorySource(object): self.init_repo() - def get_subunit_stream(self): try: return self.testrepository_last_stream() except KeyError: - raise NoStreamPresent() - + pass # raise NoStreamPresent() def init_repo(self): """inits a new testrepository repo in the supplied path""" @@ -86,16 +82,14 @@ class TestRepositorySource(object): # if this happens its fine .. just means the repo is already there pass - def run(self): - here = os.getcwd() + os.getcwd() os.chdir(self.testr_directory) self._ui.c = self.testr_directory+'tempest.conf' cmd = run.run(self._ui) - res = cmd.execute() - + return cmd.execute() def testrepository_last_stream(self): factory = testrepository.repository.file.RepositoryFactory() @@ -113,8 +107,7 @@ class Tester(object): cloud_id = None _status = None - - def __init__(self,cloud_id=None,test_id=None,sha=None): + def __init__(self, cloud_id=None, test_id=None, sha=None): """ init method loads specified id or fails""" if not test_id: #create a new test id @@ -128,7 +121,6 @@ class Tester(object): self.sha = sha self.test_path = "/tmp/%s/" % cloud_id - def run_remote(self): """triggers remote run""" # install tempest in virt env @@ -144,27 +136,28 @@ class Tester(object): # write the tempest config to that folder self.write_config(self.test_path) - # setup the repo wrapper.. this creates the repo if its not already there + # setup the repo wrapper.. + # this creates the repo if its not already there tr = TestRepositorySource(self.test_path) - """TODO: So this is supposed to use the testr wrapper to trigger a run.. however.. - I am completly blocked on how to make it work the right way.. so I am moving on - for now once the congigs are setup and repo initiated it will call a subprocess - run the command .. THEN query the repo for the last set of results and store the - subunit stream. + """TODO: So this is supposed to use the testr wrapper to trigger a run. + however.. I am completly blocked on how to make it work the right way.. + so I am moving on for now once the congigs are setup and repo initiated + it will call a subprocess run the command .. THEN query the repo for + the last set of results and store the subunit stream. # run tests #tr.run() """ print "starting test" - call([self.test_path+'runtests.sh']) # replace this + call([self.test_path+'runtests.sh']) # replace this print "finished with tests" # get back the results result = tr.testrepository_last_stream() - # write results to database maybe .. or return them .. not sure which .. + # write results to database maybe .. return result.read() #return None @@ -185,7 +178,8 @@ exit $?""" % path test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-500} \ - ${PYTHON:-python} -m subunit.run discover tempest.api $LISTOPT $IDOPTION + ${PYTHON:-python} -m subunit.run discover \ + tempest.api $LISTOPT $IDOPTION test_id_option=--load-list $IDFILE test_list_option=--list group_regex=([^\.]*\.)*""" @@ -209,14 +203,16 @@ group_regex=([^\.]*\.)*""" """The status property.""" def fget(self): return self._status + def fset(self, value): self._status = value + def fdel(self): del self._status + return locals() @property def config(self): """The config property. outputs a tempest config based on settings""" return self.tempest_config.output() - diff --git a/refstack/config.py b/refstack/config.py old mode 100644 new mode 100755 index b4487eb9..0e5f1c6f --- a/refstack/config.py +++ b/refstack/config.py @@ -1,14 +1,25 @@ -# -*- coding: utf-8 -*- - -# This file based on MIT licensed code at: https://github.com/imwilsonxu/fbone - +# +# 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. @@ -34,15 +45,17 @@ class BaseConfig(object): 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' + SQLALCHEMY_DATABASE_URI = 'sqlite:///' + \ + INSTANCE_FOLDER_PATH + '/db.sqlite' # MYSQL for production. - #SQLALCHEMY_DATABASE_URI = 'mysql://username:password@server/db?charset=utf8' + #SQLALCHEMY_DATABASE_URI = \ + # 'mysql://username:password@server/db?charset=utf8' # Flask-babel: http://pythonhosted.org/Flask-Babel/ ACCEPT_LANGUAGES = ['zh'] @@ -53,13 +66,13 @@ class DefaultConfig(BaseConfig): CACHE_DEFAULT_TIMEOUT = 60 # Flask-mail: http://pythonhosted.org/flask-mail/ - # https://bitbucket.org/danjac/flask-mail/issue/3/problem-with-gmails-smtp-server 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. + # 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 diff --git a/refstack/default_settings.py b/refstack/default_settings.py old mode 100644 new mode 100755 index a02e8314..7dab22d1 --- a/refstack/default_settings.py +++ b/refstack/default_settings.py @@ -32,7 +32,7 @@ class Default(object): MAILGUN_DOMAIN = 'refstack.org' SECRET_KEY = '#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@' SQLALCHEMY_DATABASE_URI = os.environ.get( - 'DATABASE_URL', 'sqlite:///%s/refstack.db' % (db_path)) + 'DATABASE_URL', 'sqlite:///%s/refstack.db' % (db_path)) DEBUG = True SECURITY_PASSWORD_HASH = 'sha512_crypt' SECURITY_PASSWORD_SALT = SECRET_KEY diff --git a/refstack/models.py b/refstack/models.py index 4a83fe66..594ed987 100755 --- a/refstack/models.py +++ b/refstack/models.py @@ -55,12 +55,11 @@ class ApiKey(db.Model): backref=db.backref('apikeys', lazy='dynamic')) -""" -Note: The vendor list will be pre-populated from the sponsoring company database. -TODO: better define the vendor object and its relationship with user -it needs the ability to facilitate a login. -""" class Vendor(db.Model): + """Note: The vendor list will be pre-populated from the + sponsoring company database. + TODO: better define the vendor object and its relationship with user + it needs the ability to facilitate a login.""" __tablename__ = 'vendor' id = db.Column(db.Integer, primary_key=True) vendor_name = db.Column(db.String(80), unique=True) @@ -87,7 +86,7 @@ class Cloud(db.Model): user_id = db.Column(db.Integer, db.ForeignKey('user.id')) user = db.relationship('User', - backref=db.backref('clouds',lazy='dynamic')) + backref=db.backref('clouds', lazy='dynamic')) class Test(db.Model): @@ -95,10 +94,9 @@ class Test(db.Model): id = db.Column(db.Integer, primary_key=True) cloud_id = db.Column(db.Integer, db.ForeignKey('cloud.id')) cloud = db.relationship('Cloud', - backref=db.backref('tests',lazy='dynamic')) + backref=db.backref('tests', lazy='dynamic')) config = db.Column(db.String(4096)) - def __init__(self, cloud_id): self.cloud_id = cloud_id @@ -108,13 +106,12 @@ class TestStatus(db.Model): id = db.Column(db.Integer, primary_key=True) test_id = db.Column(db.Integer, db.ForeignKey('test.id')) test = db.relationship('Test', - backref=db.backref('status',lazy='dynamic')) + backref=db.backref('status', lazy='dynamic')) message = db.Column(db.String(1024)) finished = db.Column(db.Boolean, default=False) timestamp = db.Column(db.DateTime, default=datetime.now) - - def __init__(self,test_id, message, finished=False): + def __init__(self, test_id, message, finished=False): self.test_id = test_id self.message = message self.finished = finished @@ -125,9 +122,7 @@ class TestResults(db.Model): id = db.Column(db.Integer, primary_key=True) test_id = db.Column(db.Integer, db.ForeignKey('test.id')) test = db.relationship('Test', - backref=db.backref('results',lazy='dynamic')) + backref=db.backref('results', lazy='dynamic')) timestamp = db.Column(db.DateTime, default=datetime.now) subunit = db.Column(db.String(8192)) blob = db.Column(db.Binary) - - diff --git a/refstack/utils.py b/refstack/utils.py old mode 100644 new mode 100755 index 45be994d..24413736 --- a/refstack/utils.py +++ b/refstack/utils.py @@ -1,13 +1,23 @@ -# -*- coding: utf-8 -*- - -# This file based on MIT licensed code at: https://github.com/imwilsonxu/fbone - +# +# 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. """ Utils has nothing to do with models and views. """ from datetime import datetime -import logging import os import pprint import random @@ -92,7 +102,8 @@ def pretty_date(dt, default=None): def allowed_file(filename): - return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_AVATAR_EXTENSIONS + return '.' in filename and \ + filename.rsplit('.', 1)[1] in ALLOWED_AVATAR_EXTENSIONS def id_generator(size=10, chars=string.ascii_letters + string.digits): diff --git a/refstack/web.py b/refstack/web.py index a7ae49c1..2984da41 100755 --- a/refstack/web.py +++ b/refstack/web.py @@ -1,6 +1,5 @@ # -# Copyright (c) 2013 Piston Cloud Computing, Inc. -# All Rights Reserved. +# 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 @@ -13,30 +12,26 @@ # 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 -import logging - -import flask -from flask import Flask, abort, flash, request, redirect, url_for, \ - render_template, g, session -from flask_openid import OpenID -from flask.ext.admin import Admin, BaseView, expose, AdminIndexView -from flask.ext.admin.contrib.sqlamodel import ModelView -from flask.ext.security import Security, SQLAlchemyUserDatastore, \ - UserMixin, RoleMixin, login_required -from wtforms import Form, BooleanField, TextField, \ - PasswordField, validators +# +from flask import abort, flash, request, redirect, url_for, \ + render_template, g, session, flask +#from flask_openid import OpenID +#from flask.ext.admin import Admin, BaseView, expose, AdminIndexView +#from flask.ext.admin.contrib.sqlamodel import ModelView +#from flask.ext.security import Security, \ +# UserMixin, login_required +#from wtforms import TextField from flask_mail import Mail from refstack import app as base_app from refstack.extensions import db from refstack.extensions import oid -from refstack import api -from refstack.models import ApiKey -from refstack.models import Cloud -from refstack.models import Test -from refstack.models import TestResults -from refstack.models import TestStatus +#from refstack import api +#from refstack.models import ApiKey +#from refstack.models import Cloud +#from refstack.models import Test +#from refstack.models import TestResults +#from refstack.models import TestStatus from refstack.models import User from refstack.models import Vendor @@ -62,7 +57,7 @@ def index(): """Index view.""" if g.user is not None: # something else - clouds = Cloud.query.filter_by(user_id=g.user.id).all() + clouds = db.Cloud.query.filter_by(user_id=g.user.id).all() return render_template('home.html', clouds=clouds) else: vendors = Vendor.query.all() @@ -79,8 +74,9 @@ def login(): # 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']) + return oid.try_login( + "https://login.launchpad.net/", + ask_for=['email', 'nickname']) @oid.after_login @@ -127,7 +123,7 @@ def create_profile(): @app.route('/delete-cloud/', methods=['GET', 'POST']) def delete_cloud(cloud_id): """Delete function for clouds.""" - c = Cloud.query.filter_by(id=cloud_id).first() + c = db.Cloud.query.filter_by(id=cloud_id).first() if not c: flash(u'Not a valid Cloud ID!') @@ -142,7 +138,7 @@ def delete_cloud(cloud_id): @app.route('/edit-cloud/', methods=['GET', 'POST']) def edit_cloud(cloud_id): - c = Cloud.query.filter_by(id=cloud_id).first() + c = db.Cloud.query.filter_by(id=cloud_id).first() if not c: flash(u'Not a valid Cloud ID!') @@ -188,9 +184,7 @@ def edit_cloud(cloud_id): admin_user=c.admin_user, admin_key=c.admin_key) - - - return render_template('edit_cloud.html',form=form) + return render_template('edit_cloud.html', form=form) @app.route('/create-cloud', methods=['GET', 'POST']) @@ -215,7 +209,7 @@ def create_cloud(): elif not request.form['admin_key']: flash(u'Error: All fields are required') else: - c = Cloud() + c = db.Cloud() c.user_id = g.user.id c.label = request.form['label'] c.endpoint = request.form['endpoint'] diff --git a/scripts/import_vendors.py b/scripts/import_vendors.py index e79d56e1..ea11abfc 100755 --- a/scripts/import_vendors.py +++ b/scripts/import_vendors.py @@ -14,9 +14,9 @@ # License for the specific language governing permissions and limitations # under the License. # -"""Simple script for importing the vendor +"""Simple script for importing the vendor list csv file provided by the foundation""" -from refstack.models import * +from refstack.models import db, Vendor import csv _file = 'members_sponsors_20131030.csv'