pep8 cleanup

This commit is contained in:
David Lenwell 2014-02-21 16:08:12 -08:00
parent 14b0810030
commit 0bd1399735
15 changed files with 221 additions and 194 deletions

4
alembic/versions/1d6540fc6279_added_vendor_contact.py Normal file → Executable file
View File

@ -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 ###

18
alembic/versions/3790aed42558_from_scratch.py Normal file → Executable file
View File

@ -16,7 +16,8 @@ import sqlalchemy as sa
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_table('cloud',
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),
@ -28,7 +29,8 @@ def upgrade():
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('endpoint')
)
op.create_table('vendor',
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),
@ -36,7 +38,8 @@ def upgrade():
sa.UniqueConstraint('contact_email'),
sa.UniqueConstraint('vendor_name')
)
op.create_table('user',
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),
@ -50,14 +53,16 @@ def upgrade():
sa.UniqueConstraint('email'),
sa.UniqueConstraint('openid')
)
op.create_table('test',
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',
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),
@ -65,7 +70,8 @@ def upgrade():
sa.ForeignKeyConstraint(['test_id'], ['test.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('test_status',
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),

3
alembic/versions/4288db006e5_added_user_cloud_rel.py Normal file → Executable file
View File

@ -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! ###

3
alembic/versions/449461dbc725_add_apikey.py Normal file → Executable file
View File

@ -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),

5
alembic/versions/59e15d864941_added_subunit_output.py Normal file → Executable file
View File

@ -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 ###

17
refstack/api.py Normal file → Executable file
View File

@ -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:

38
refstack/app.py Normal file → Executable file
View File

@ -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 '

View File

@ -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}

View File

@ -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,14 +136,15 @@ 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()
@ -164,7 +157,7 @@ class Tester(object):
# 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()

33
refstack/config.py Normal file → Executable file
View File

@ -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

0
refstack/default_settings.py Normal file → Executable file
View File

View File

@ -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)

23
refstack/utils.py Normal file → Executable file
View File

@ -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):

View File

@ -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,7 +74,8 @@ 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/",
return oid.try_login(
"https://login.launchpad.net/",
ask_for=['email', 'nickname'])
@ -127,7 +123,7 @@ def create_profile():
@app.route('/delete-cloud/<int:cloud_id>', 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/<int:cloud_id>', 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']

View File

@ -16,7 +16,7 @@
#
"""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'