cli cloud stuff
add, remove and list cloud cli commands complete as well as db models tweaked to high hell..
This commit is contained in:
parent
0379f00772
commit
f90cac1452
@ -42,7 +42,7 @@ fileConfig(config.config_file_name)
|
|||||||
# from myapp import mymodel
|
# from myapp import mymodel
|
||||||
# target_metadata = mymodel.Base.metadata
|
# target_metadata = mymodel.Base.metadata
|
||||||
# target_metadata = None
|
# target_metadata = None
|
||||||
from refstack.web import db
|
from refstack.models import db
|
||||||
target_metadata = db.metadata
|
target_metadata = db.metadata
|
||||||
|
|
||||||
|
|
||||||
|
25
alembic/versions/23f82f78731b_fixing_unique.py
Executable file
25
alembic/versions/23f82f78731b_fixing_unique.py
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
"""Adding Cloud and User models
|
||||||
|
|
||||||
|
Revision ID: 23f82f78731b
|
||||||
|
Revises: 40d4c6d389ec
|
||||||
|
Create Date: 2013-07-02 15:02:46.951119
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '23f82f78731b'
|
||||||
|
down_revision = '40d4c6d389ec'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
### commands auto generated by Alembic - please adjust! ###
|
||||||
|
pass
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
### commands auto generated by Alembic - please adjust! ###
|
||||||
|
pass
|
||||||
|
|
||||||
|
### end Alembic commands ###
|
22
alembic/versions/2bf99fa45ded_remove_unique_restra.py
Executable file
22
alembic/versions/2bf99fa45ded_remove_unique_restra.py
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
"""remove unique restraints from cloud add one to users
|
||||||
|
|
||||||
|
Revision ID: 2bf99fa45ded
|
||||||
|
Revises: 23f82f78731b
|
||||||
|
Create Date: 2013-09-20 06:14:43.246339
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '2bf99fa45ded'
|
||||||
|
down_revision = '23f82f78731b'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
pass
|
@ -30,4 +30,4 @@ def upgrade():
|
|||||||
def downgrade():
|
def downgrade():
|
||||||
### commands auto generated by Alembic - please adjust! ###
|
### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_table('vendor')
|
op.drop_table('vendor')
|
||||||
### end Alembic commands ###
|
### end Alembic commands ###
|
@ -35,12 +35,7 @@ def upgrade():
|
|||||||
sa.Column('admin_key', sa.String(length=80), nullable=True),
|
sa.Column('admin_key', sa.String(length=80), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['vendor_id'], ['vendor.id'], ),
|
sa.ForeignKeyConstraint(['vendor_id'], ['vendor.id'], ),
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.PrimaryKeyConstraint('id'),
|
||||||
sa.UniqueConstraint('admin_endpoint'),
|
sa.UniqueConstraint('endpoint')
|
||||||
sa.UniqueConstraint('admin_key'),
|
|
||||||
sa.UniqueConstraint('admin_user'),
|
|
||||||
sa.UniqueConstraint('endpoint'),
|
|
||||||
sa.UniqueConstraint('test_key'),
|
|
||||||
sa.UniqueConstraint('test_user')
|
|
||||||
)
|
)
|
||||||
### end Alembic commands ###
|
### end Alembic commands ###
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
import os
|
import os
|
||||||
from flask import Flask, session
|
from flask import Flask, session
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
db_path = os.path.abspath(
|
db_path = os.path.abspath(
|
||||||
os.path.join(os.path.basename(__file__), "../"))
|
os.path.join(os.path.basename(__file__), "../"))
|
||||||
|
|
||||||
|
@ -14,92 +14,187 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
import os.path
|
"""
|
||||||
import sys
|
"""
|
||||||
import subprocess
|
|
||||||
import argparse
|
import argparse
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
from refstack.common.test import Test
|
from sqlalchemy.exc import IntegrityError
|
||||||
|
from refstack.localmodels import *
|
||||||
basedir = os.path.dirname(__file__)
|
|
||||||
|
|
||||||
def call(*args, **kwargs):
|
|
||||||
"""subprocess.call with error checking."""
|
|
||||||
assert not subprocess.call(*args, **kwargs)
|
|
||||||
|
|
||||||
class actions(argparse.Action):
|
|
||||||
""" david please comment this """
|
|
||||||
test_id = None
|
|
||||||
params = {}
|
|
||||||
|
|
||||||
def __call__(self, parser, params, values, option_string=None, **kwargs):
|
|
||||||
"""Triggered by -c command line argument """
|
|
||||||
self.params = params
|
|
||||||
setattr(self.params, self.dest, values)
|
|
||||||
|
|
||||||
self._print(self.params, verbose=True)
|
|
||||||
|
|
||||||
# action function mapping
|
|
||||||
actions = { 'run' : self.run,
|
|
||||||
'status' : self.status,
|
|
||||||
'cancel' : self.cancel,
|
|
||||||
'result' : self.result,
|
|
||||||
'export' : self.export,
|
|
||||||
'list' : self.list }
|
|
||||||
|
|
||||||
if len(self.params.command) > 1:
|
|
||||||
print "Please only use one command at a time!\n\n"
|
|
||||||
parser.print_help()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
for command in self.params.command:
|
|
||||||
if command in actions:
|
|
||||||
actions[command]()
|
|
||||||
|
|
||||||
|
|
||||||
def _print(self, output, verbose=False):
|
def add(args):
|
||||||
""" print wrapper so -v and -s can be respected """
|
"""add cloud
|
||||||
if not self.params.silent:
|
|
||||||
if verbose is False:
|
refstack add --endpoint='http://127.0.0.1:5000/v3/' --test-user='demo'
|
||||||
print(output)
|
--test-key='pass' --admin-endpoint='http://127.0.0.1:5000/v3/'
|
||||||
elif verbose is True and self.params.verbose > 0:
|
--admin-user='admin' --admin-key='pass'
|
||||||
print(output)
|
|
||||||
|
outputs confirmation along with the id of the cloud that was just added.
|
||||||
|
endpoint is a unique key so you only get to add one record per end point"""
|
||||||
|
try:
|
||||||
|
cloud = Cloud(args.endpoint,
|
||||||
|
args.test_user,
|
||||||
|
args.test_key,
|
||||||
|
args.admin_endpoint,
|
||||||
|
args.admin_user,
|
||||||
|
args.admin_key)
|
||||||
|
|
||||||
|
db.add(cloud)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
print 'New cloud added with id: %s ' % (cloud.id)
|
||||||
|
|
||||||
|
except IntegrityError:
|
||||||
|
print 'A Cloud with %s as its endpoint has already been added. ' % args.endpoint
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
""" run test command"""
|
def remove(args):
|
||||||
self._print('run command called',True)
|
"""remove cloud
|
||||||
tester = Test()
|
refstack remove {cloud_id}
|
||||||
self._print(tester.config)
|
|
||||||
|
confirms that cloud-id 123 has been removed from the database as well as
|
||||||
|
all tests assosiateed with it."""
|
||||||
|
cloud = db.query(Cloud).get(args.cloud_id)
|
||||||
|
|
||||||
|
if cloud is None:
|
||||||
|
print 'No cloud with id: %s ' % args.cloud_id
|
||||||
|
|
||||||
|
else:
|
||||||
|
db.delete(cloud)
|
||||||
|
db.commit()
|
||||||
|
print 'cloud %s has been deleted.' % args.cloud_id
|
||||||
|
|
||||||
|
|
||||||
def status(self):
|
def clouds(args):
|
||||||
""" get the status of a running test"""
|
"""returns either a list of cached tests"""
|
||||||
self._print('status command called',True)
|
print 'Your clouds:\n'
|
||||||
|
print 'id | endpoint | test-user | admin-user '
|
||||||
|
print '---------------------------------------'
|
||||||
|
for row in db.query(Cloud).all():
|
||||||
|
print "%s | %s | %s | %s " % (row.id, row.endpoint, row.test_user, row.admin_user)
|
||||||
|
print ''
|
||||||
|
|
||||||
|
|
||||||
def cancel(self):
|
def run(args):
|
||||||
""" cancels a running test"""
|
"""run test command
|
||||||
self._print('cancel command called',True)
|
|
||||||
|
refstack run --cloud_id {123} --sha {sha}
|
||||||
|
|
||||||
|
triggers local run of tempest with specified cloud_id returns a
|
||||||
|
test_id so that the user can check status or cancel the test"""
|
||||||
|
print 'run triggered'
|
||||||
|
|
||||||
|
|
||||||
def result(self):
|
def status(args):
|
||||||
""" outputs the results of a test"""
|
"""get the status of a running test
|
||||||
self._print('result command called',True)
|
|
||||||
|
refstack status --test-id {123}
|
||||||
|
"""
|
||||||
|
print 'status triggered'
|
||||||
|
|
||||||
|
|
||||||
def export(self):
|
def cancel(args):
|
||||||
""" export something forgot why I adddedd this"""
|
"""cancels a running test
|
||||||
self._print('export command called',True)
|
|
||||||
|
refstack cancel --test-id {test_id}
|
||||||
|
|
||||||
|
stops the running test if it is running and displays output to user"""
|
||||||
|
print 'cancel triggered'
|
||||||
|
|
||||||
|
|
||||||
def list(self):
|
def result(args):
|
||||||
""" returns a list of cached test results"""
|
"""outputs the results of a test
|
||||||
self._print('list command called',True)
|
|
||||||
|
refstack results --test_id --format {screen|subunit}
|
||||||
|
|
||||||
|
if the test isn't finished it will say in progress otherwise will return
|
||||||
|
subunit|screen output"""
|
||||||
|
print 'result triggered'
|
||||||
|
|
||||||
|
|
||||||
|
def tests(args):
|
||||||
|
"""returns either a list of clouds"""
|
||||||
|
print 'tests triggered'
|
||||||
|
|
||||||
|
|
||||||
|
def clouds(args):
|
||||||
|
"""returns either a list of cached tests"""
|
||||||
|
print 'Your clouds:\n'
|
||||||
|
print 'id | endpoint | test-user | admin-user '
|
||||||
|
print '---------------------------------------'
|
||||||
|
for row in db.query(Cloud).all():
|
||||||
|
print "%s | %s | %s | %s " % (row.id, row.endpoint, row.test_user, row.admin_user)
|
||||||
|
print ''
|
||||||
|
|
||||||
|
def subcommands(subparsers):
|
||||||
|
"""argparse subparsers with """
|
||||||
|
add_cloud_parser = subparsers.add_parser('add', help='Add a new Cloud')
|
||||||
|
|
||||||
|
add_cloud_parser.add_argument('--endpoint',
|
||||||
|
required=True,
|
||||||
|
action='store',
|
||||||
|
dest='endpoint',
|
||||||
|
help='Non-admin keystone endpoint')
|
||||||
|
|
||||||
|
add_cloud_parser.add_argument('--test-user',
|
||||||
|
required=True,
|
||||||
|
action='store',
|
||||||
|
dest='test_user',
|
||||||
|
help='Non-admin keystone user')
|
||||||
|
|
||||||
|
add_cloud_parser.add_argument('--test-key',
|
||||||
|
required=True,
|
||||||
|
action='store',
|
||||||
|
dest='test_key',
|
||||||
|
help='Non-admin keystone password or key')
|
||||||
|
|
||||||
|
add_cloud_parser.add_argument('--admin-endpoint',
|
||||||
|
required=True,
|
||||||
|
action='store',
|
||||||
|
dest='admin_endpoint',
|
||||||
|
help='Admin keystone endpoint')
|
||||||
|
|
||||||
|
add_cloud_parser.add_argument('--admin-user',
|
||||||
|
required=True,
|
||||||
|
action='store',
|
||||||
|
dest='admin_user',
|
||||||
|
help='Admin keystone user')
|
||||||
|
|
||||||
|
add_cloud_parser.add_argument('--admin-key',
|
||||||
|
required=True,
|
||||||
|
action='store',
|
||||||
|
dest='admin_key',
|
||||||
|
help='Admin keystone key or password')
|
||||||
|
|
||||||
|
"""argparse options for the remove command """
|
||||||
|
remove_parser = subparsers.add_parser('remove', help='remove a Cloud')
|
||||||
|
|
||||||
|
remove_parser.add_argument(action='store',
|
||||||
|
dest='cloud_id',
|
||||||
|
help='The id of the cloud you want to remove')
|
||||||
|
|
||||||
|
"""argparse options for the run command """
|
||||||
|
run_parser = subparsers.add_parser('run', help='run tests on cloud')
|
||||||
|
|
||||||
|
"""argparse options for the status command """
|
||||||
|
status_parser = subparsers.add_parser('status', help='status of test')
|
||||||
|
|
||||||
|
"""argparse options for the cancel command """
|
||||||
|
cancel_parser = subparsers.add_parser('cancel', help='cancel a test')
|
||||||
|
|
||||||
|
"""argparse options for the result command """
|
||||||
|
result_parser = subparsers.add_parser('result', help='provides results')
|
||||||
|
|
||||||
|
"""argparse options for the tests command """
|
||||||
|
tests_parser = subparsers.add_parser('tests', help='list tests')
|
||||||
|
|
||||||
|
"""argparse options for the clouds command """
|
||||||
|
clouds_parser = subparsers.add_parser('clouds', help='list clouds')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
""" command line hook """
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
description=dedent("""\
|
description=dedent("""\
|
||||||
@ -112,32 +207,33 @@ def main():
|
|||||||
Refstack CLI:
|
Refstack CLI:
|
||||||
\n\n\n """))
|
\n\n\n """))
|
||||||
|
|
||||||
|
|
||||||
# output options
|
# output options
|
||||||
parser.add_argument('--verbose', '-v', action='count')
|
parser.add_argument('--verbose', '-v', action='count')
|
||||||
parser.add_argument('--silent', '-s', action='store_true')
|
parser.add_argument('--silent', '-s', action='store_true')
|
||||||
|
|
||||||
|
subparsers = parser.add_subparsers(help='Sub commands', dest='command')
|
||||||
# all paramaters can be overridden
|
|
||||||
parser.add_argument('--test-id', nargs='?', type=int,
|
|
||||||
default=None,
|
|
||||||
help="""id of the test you want to interact with.. if you are starting
|
|
||||||
a new test you can leave this blank and it will
|
|
||||||
return a new test_id""")
|
|
||||||
|
|
||||||
parser.add_argument('command', nargs='+', action=actions,
|
subcommands(subparsers)
|
||||||
help="Command to execute. ",
|
|
||||||
choices=['run','status','cancel','result','export','list'] )
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
# validate input
|
|
||||||
#option_given = not (args.c == None)
|
|
||||||
|
|
||||||
#if not option_given:
|
# action function mapping
|
||||||
# parser.print_help()
|
actions = { 'add': add,
|
||||||
# sys.exit(1)
|
'remove': remove,
|
||||||
|
'run': run,
|
||||||
|
'status': status,
|
||||||
|
'cancel': cancel,
|
||||||
|
'result': result,
|
||||||
|
'tests': tests,
|
||||||
|
'clouds': clouds}
|
||||||
|
|
||||||
|
if args.command in actions:
|
||||||
|
actions[args.command](args)
|
||||||
|
else:
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
222
refstack/cli/refstack_old
Executable file
222
refstack/cli/refstack_old
Executable file
@ -0,0 +1,222 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# 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.path
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import argparse
|
||||||
|
from textwrap import dedent
|
||||||
|
from refstack.common.test import Test
|
||||||
|
from refstack.common.cloud import Cloud
|
||||||
|
|
||||||
|
basedir = os.path.dirname(__file__)
|
||||||
|
|
||||||
|
def call(*args, **kwargs):
|
||||||
|
"""subprocess.call with error checking."""
|
||||||
|
assert not subprocess.call(*args, **kwargs)
|
||||||
|
|
||||||
|
class actions(argparse.Action):
|
||||||
|
""" david please comment this """
|
||||||
|
test_id = None
|
||||||
|
params = {}
|
||||||
|
|
||||||
|
def __call__(self, parser, params, values, option_string=None, **kwargs):
|
||||||
|
"""Triggered by -c command line argument """
|
||||||
|
self.params = params
|
||||||
|
setattr(self.params, self.dest, values)
|
||||||
|
|
||||||
|
self._print(self.params, verbose=False)
|
||||||
|
|
||||||
|
# action function mapping
|
||||||
|
actions = { 'add' : self.add,
|
||||||
|
'remove' : self.remove,
|
||||||
|
'run' : self.run,
|
||||||
|
'status' : self.status,
|
||||||
|
'cancel' : self.cancel,
|
||||||
|
'result' : self.result,
|
||||||
|
'list-tests' : self.list_tests,
|
||||||
|
'list-clouds' : self.list_clouds }
|
||||||
|
|
||||||
|
if len(self.params.command) > 1:
|
||||||
|
print "Please only use one command at a time!\n\n"
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
for command in self.params.command:
|
||||||
|
if command in actions:
|
||||||
|
actions[command]()
|
||||||
|
|
||||||
|
|
||||||
|
def _print(self, output, verbose=False):
|
||||||
|
"""print wrapper so -v and -s can be respected"""
|
||||||
|
if not self.params.silent:
|
||||||
|
if verbose is False:
|
||||||
|
print(output)
|
||||||
|
elif verbose is True and self.params.verbose > 0:
|
||||||
|
print(output)
|
||||||
|
|
||||||
|
def add(self):
|
||||||
|
""" add new cloud
|
||||||
|
needs endpoint,test_user,test_key, admin_endpoint,admin_user,admin_key
|
||||||
|
|
||||||
|
refstack add --endpoint='http://127.0.0.1:5000/v3/' --test_user='demo'
|
||||||
|
--test_key='pass' --admin_endpoint='http://127.0.0.1:5000/v3/'
|
||||||
|
--admin_user='admin' --admin_key='pass'
|
||||||
|
|
||||||
|
outputs confirmation along with the cloud_id that was just created."""
|
||||||
|
self._print('add command called')
|
||||||
|
#self._print(self.params.endpoint)
|
||||||
|
#for k,v in self.params.:
|
||||||
|
# self._print(k + ': ' + v)
|
||||||
|
c = Cloud()
|
||||||
|
|
||||||
|
c.add(self.params.endpoint,self.params.test_user,self.params.test_key,
|
||||||
|
self.params.admin_endpoint,self.params.admin_user,self.params.admin_key)
|
||||||
|
|
||||||
|
self._print('cloud added ')
|
||||||
|
|
||||||
|
|
||||||
|
def remove(self):
|
||||||
|
""" add new cloud
|
||||||
|
refstack remove --cloud_id 123
|
||||||
|
|
||||||
|
confirms that cloud-id 123 has been removed from the database as well as
|
||||||
|
all tests assosiateed with it."""
|
||||||
|
self._print('remove command called',True)
|
||||||
|
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
""" run test command
|
||||||
|
|
||||||
|
refstack run --cloud_id {123} --sha {sha}
|
||||||
|
|
||||||
|
triggers local run of tempest with specified cloud_id returns a
|
||||||
|
test_id so that the user can check status or cancel the test"""
|
||||||
|
self._print('run command called',True)
|
||||||
|
|
||||||
|
|
||||||
|
def status(self):
|
||||||
|
""" get the status of a running test
|
||||||
|
|
||||||
|
refstack status --test-id {123}
|
||||||
|
"""
|
||||||
|
self._print('status command called',True)
|
||||||
|
|
||||||
|
|
||||||
|
def cancel(self):
|
||||||
|
""" cancels a running test
|
||||||
|
|
||||||
|
refstack cancel --test-id {test_id}
|
||||||
|
|
||||||
|
stops the running test if it is running and displays output to user"""
|
||||||
|
self._print('cancel command called',True)
|
||||||
|
|
||||||
|
|
||||||
|
def result(self):
|
||||||
|
""" outputs the results of a test
|
||||||
|
|
||||||
|
refstack results --test_id --format {screen|subunit}
|
||||||
|
|
||||||
|
if the test isn't finished it will say in progress otherwise will return
|
||||||
|
subunit|screen output"""
|
||||||
|
self._print('result command called',True)
|
||||||
|
|
||||||
|
|
||||||
|
def list_tests(self):
|
||||||
|
""" returns either a list of cached test results or a list of clouds
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
self._print('list command called',True)
|
||||||
|
|
||||||
|
|
||||||
|
def list_clouds(self):
|
||||||
|
""" returns either a list of cached test results or a list of clouds
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
self._print('list command called',True)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
""" command line hook """
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
description=dedent("""\
|
||||||
|
This is a CLI utility for refstack
|
||||||
|
|
||||||
|
"""),
|
||||||
|
epilog=dedent("""\
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
Refstack CLI:
|
||||||
|
\n\n\n """))
|
||||||
|
|
||||||
|
# output options
|
||||||
|
parser.add_argument('--verbose', '-v', action='count')
|
||||||
|
parser.add_argument('--silent', '-s', action='store_true')
|
||||||
|
|
||||||
|
|
||||||
|
# params for add endpoint,test_user,test_key, admin_endpoint,admin_user,admin_key
|
||||||
|
parser.add_argument('--endpoint', nargs='?', type=str,
|
||||||
|
default=None,
|
||||||
|
help="""""")
|
||||||
|
|
||||||
|
parser.add_argument('--test_user', nargs='?', type=str,
|
||||||
|
default=None,
|
||||||
|
help="""""")
|
||||||
|
|
||||||
|
parser.add_argument('--test_key', nargs='?', type=str,
|
||||||
|
default=None,
|
||||||
|
help="""""")
|
||||||
|
|
||||||
|
parser.add_argument('--admin_endpoint', nargs='?', type=str,
|
||||||
|
default=None,
|
||||||
|
help="""""")
|
||||||
|
|
||||||
|
parser.add_argument('--admin_user', nargs='?', type=str,
|
||||||
|
default=None,
|
||||||
|
help="""""")
|
||||||
|
|
||||||
|
parser.add_argument('--admin_key', nargs='?', type=str,
|
||||||
|
default=None,
|
||||||
|
help="""""")
|
||||||
|
|
||||||
|
|
||||||
|
parser.add_argument('--test-id', nargs='?', type=int,
|
||||||
|
default=None,
|
||||||
|
help="""id of the test you want to interact with.. if you are starting
|
||||||
|
a new test you can leave this blank and it will
|
||||||
|
return a new test_id""")
|
||||||
|
|
||||||
|
parser.add_argument('command', nargs='+', action=actions,
|
||||||
|
help="Command to execute. ",
|
||||||
|
choices=[ 'run','add','remove',
|
||||||
|
'status','cancel','result',
|
||||||
|
'list_clouds','list_tests'])
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
# validate input
|
||||||
|
#option_given = not (args.c == None)
|
||||||
|
|
||||||
|
#if not option_given:
|
||||||
|
# parser.print_help()
|
||||||
|
# sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -13,32 +13,55 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
from keystoneclient.v2_0 import client
|
||||||
from refstack.common import *
|
from refstack.common import *
|
||||||
|
import refstack.models
|
||||||
|
|
||||||
|
class Cloud(object):
|
||||||
|
""" Cloud functions"""
|
||||||
|
cloud_id = None
|
||||||
|
|
||||||
class Cloud:
|
def __init__(self, cloud_id = None):
|
||||||
""" Vendor functions"""
|
|
||||||
id = None
|
|
||||||
|
|
||||||
def __init__(self, id):
|
|
||||||
""" init method loads specified id or fails"""
|
""" init method loads specified id or fails"""
|
||||||
self.id = id
|
self.cloud_id = cloud_id
|
||||||
|
|
||||||
@def end_point():
|
if not cloud_id:
|
||||||
doc = "The end_point property."
|
# we have a new cloud.
|
||||||
def fget(self):
|
# do nothing because now we'll call the add method
|
||||||
return self._end_point
|
return None
|
||||||
def fset(self, value):
|
else:
|
||||||
self._end_point = value
|
# load an existing cloud
|
||||||
def fdel(self):
|
self._cloud = models.Cloud.query.filter_by(id=self.cloud_id).first()
|
||||||
del self._end_point
|
|
||||||
return locals()
|
|
||||||
|
|
||||||
foo = property(**foo())
|
if not self._cloud:
|
||||||
|
# cloud not found.. invalid id
|
||||||
|
# maybe I should do someting about this ..
|
||||||
|
return None
|
||||||
|
|
||||||
def tests(self, cloud_
|
self._keystone = client.Client(username=self._cloud.admin_user,
|
||||||
id = None):
|
password=self._cloud.admin_key,
|
||||||
""" returns object populated with test objects that belong to
|
auth_url=self._cloud.admin_endpoint )
|
||||||
this user and filter
|
|
||||||
ed by cloud_id if specified """
|
self._end_point = None
|
||||||
|
|
||||||
|
def add(self,endpoint,test_user,test_key,
|
||||||
|
admin_endpoint,admin_user,admin_key,vendor_id=None):
|
||||||
|
#adds a new cloud to the db
|
||||||
|
models.db.session.add(Cloud(endpoint,test_user,test_key,
|
||||||
|
admin_endpoint,admin_user,admin_key,vendor_id))
|
||||||
|
models.db.session.commit()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def end_point(self):
|
||||||
|
"""end_point property"""
|
||||||
|
return self._end_point
|
||||||
|
|
||||||
|
@end_point.setter
|
||||||
|
def end_point(self, value):
|
||||||
|
self._end_point = value
|
||||||
|
|
||||||
|
def get_config(self):
|
||||||
|
"""uses end_point and creditials from the specified cloud_id to
|
||||||
|
get a list of services and enpoints from keystone then outputs a
|
||||||
|
usable tempest config"""
|
||||||
|
|
||||||
|
@ -13,11 +13,13 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
from refstack.common.cloud import Cloud
|
||||||
|
|
||||||
class TempestConfig(object):
|
class TempestConfig(object):
|
||||||
"""temptest config options. gets converted to a tempest config file"""
|
"""temptest config options. gets converted to a tempest config file"""
|
||||||
config = {}
|
config = {}
|
||||||
|
|
||||||
|
|
||||||
def output(self):
|
def output(self):
|
||||||
"""outputs config in propper format"""
|
"""outputs config in propper format"""
|
||||||
output = ''
|
output = ''
|
||||||
|
53
refstack/localmodels.py
Executable file
53
refstack/localmodels.py
Executable file
@ -0,0 +1,53 @@
|
|||||||
|
#
|
||||||
|
# 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 sqlalchemy import create_engine
|
||||||
|
from sqlalchemy.orm import scoped_session, sessionmaker,relationship, backref
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
from sqlalchemy import Column, Integer, String, ForeignKey
|
||||||
|
|
||||||
|
engine = create_engine('sqlite:////tmp/refstack.db', convert_unicode=True)
|
||||||
|
db = scoped_session(sessionmaker(autocommit=False,
|
||||||
|
autoflush=False,
|
||||||
|
bind=engine))
|
||||||
|
|
||||||
|
Base = declarative_base()
|
||||||
|
Base.query = db.query_property()
|
||||||
|
|
||||||
|
|
||||||
|
class Cloud(Base):
|
||||||
|
__tablename__ = 'cloud'
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
endpoint = Column(String(120), unique=True)
|
||||||
|
test_user = Column(String(80), unique=False)
|
||||||
|
test_key = Column(String(80), unique=False)
|
||||||
|
admin_endpoint = Column(String(120), unique=False)
|
||||||
|
admin_user = Column(String(80), unique=False)
|
||||||
|
admin_key = Column(String(80), unique=False)
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
endpoint,
|
||||||
|
test_user,
|
||||||
|
test_key,
|
||||||
|
admin_endpoint,
|
||||||
|
admin_user,
|
||||||
|
admin_key):
|
||||||
|
self.endpoint = endpoint
|
||||||
|
self.test_user = test_user
|
||||||
|
self.test_key = test_key
|
||||||
|
self.admin_endpoint = admin_endpoint
|
||||||
|
self.admin_user = admin_user
|
||||||
|
self.admin_key = admin_key
|
||||||
|
|
@ -1,4 +1,3 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013 Piston Cloud Computing, Inc.
|
# Copyright (c) 2013 Piston Cloud Computing, Inc.
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
@ -36,12 +35,12 @@ class Cloud(db.Model):
|
|||||||
vendor = db.relationship('Vendor',
|
vendor = db.relationship('Vendor',
|
||||||
backref=db.backref('clouds',
|
backref=db.backref('clouds',
|
||||||
lazy='dynamic'))
|
lazy='dynamic'))
|
||||||
endpoint = db.Column(db.String(120), unique=True)
|
endpoint = db.Column(db.String(120), unique=False)
|
||||||
test_user = db.Column(db.String(80), unique=True)
|
test_user = db.Column(db.String(80), unique=False)
|
||||||
test_key = db.Column(db.String(80), unique=True)
|
test_key = db.Column(db.String(80), unique=False)
|
||||||
admin_endpoint = db.Column(db.String(120), unique=True)
|
admin_endpoint = db.Column(db.String(120), unique=False)
|
||||||
admin_user = db.Column(db.String(80), unique=True)
|
admin_user = db.Column(db.String(80), unique=False)
|
||||||
admin_key = db.Column(db.String(80), unique=True)
|
admin_key = db.Column(db.String(80), unique=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.endpoint
|
return self.endpoint
|
||||||
@ -50,7 +49,7 @@ class Cloud(db.Model):
|
|||||||
class User(db.Model):
|
class User(db.Model):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
name = db.Column(db.String(60))
|
name = db.Column(db.String(60))
|
||||||
email = db.Column(db.String(200))
|
email = db.Column(db.String(200), unique=True)
|
||||||
openid = db.Column(db.String(200), unique=True)
|
openid = db.Column(db.String(200), unique=True)
|
||||||
|
|
||||||
def __init__(self, name, email, openid):
|
def __init__(self, name, email, openid):
|
||||||
@ -59,4 +58,4 @@ class User(db.Model):
|
|||||||
self.openid = openid
|
self.openid = openid
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
156
refstack/templates/tempest.conf
Executable file
156
refstack/templates/tempest.conf
Executable file
@ -0,0 +1,156 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
debug = True
|
||||||
|
#log_config = ${log_config}
|
||||||
|
use_stderr = False
|
||||||
|
log_file = ${log_file}
|
||||||
|
lock_path=${lock_path}
|
||||||
|
default_log_levels=tempest.stress=INFO,amqplib=WARN,sqlalchemy=WARN,boto=WARN,suds=INFO,keystone=INFO,eventlet.wsgi.server=WARN
|
||||||
|
|
||||||
|
[identity]
|
||||||
|
catalog_type = identity
|
||||||
|
disable_ssl_certificate_validation = False
|
||||||
|
uri = ${uri}
|
||||||
|
uri_v3 = ${uri_v3}
|
||||||
|
region = RegionOne
|
||||||
|
username = ${username}
|
||||||
|
password = ${pass}
|
||||||
|
tenant_name = ${tenant_name}
|
||||||
|
alt_username = alt_demo
|
||||||
|
alt_password = pass
|
||||||
|
alt_tenant_name = alt_demo
|
||||||
|
admin_username = admin
|
||||||
|
admin_password = pass
|
||||||
|
admin_tenant_name = admin
|
||||||
|
admin_role = admin
|
||||||
|
|
||||||
|
[compute]
|
||||||
|
allow_tenant_isolation = True
|
||||||
|
allow_tenant_reuse = true
|
||||||
|
image_ref = ${image_ref}
|
||||||
|
image_ref_alt = ${image_ref_alt}
|
||||||
|
flavor_ref = ${flavor_ref}
|
||||||
|
flavor_ref_alt = ${flavor_ref_alt}
|
||||||
|
image_ssh_user = ${image_ssh_user}
|
||||||
|
image_ssh_password = ${image_ssh_password}
|
||||||
|
image_alt_ssh_user = ${image_alt_ssh_user}
|
||||||
|
image_alt_ssh_password = ${image_alt_ssh_password}
|
||||||
|
build_interval = 1
|
||||||
|
build_timeout = 400
|
||||||
|
run_ssh = false
|
||||||
|
ssh_user = ${ssh_user}
|
||||||
|
fixed_network_name = ${fixed_network_name}
|
||||||
|
network_for_ssh = ${fixed_network_name}
|
||||||
|
ip_version_for_ssh = 4
|
||||||
|
ping_timeout = 60
|
||||||
|
ssh_timeout = 400
|
||||||
|
ready_wait = 0
|
||||||
|
ssh_channel_timeout = 60
|
||||||
|
use_floatingip_for_ssh = True
|
||||||
|
catalog_type = compute
|
||||||
|
#region = RegionOne
|
||||||
|
create_image_enabled = true
|
||||||
|
resize_available = true
|
||||||
|
change_password_available=False
|
||||||
|
live_migration_available = ${live_migration_availablea}
|
||||||
|
use_block_migration_for_live_migration = False
|
||||||
|
block_migrate_supports_cinder_iscsi = false
|
||||||
|
disk_config_enabled = true
|
||||||
|
flavor_extra_enabled = true
|
||||||
|
volume_device_name = ${volume_device_name}
|
||||||
|
|
||||||
|
[compute-admin]
|
||||||
|
username =
|
||||||
|
password =
|
||||||
|
tenant_name =
|
||||||
|
|
||||||
|
[image]
|
||||||
|
catalog_type = image
|
||||||
|
#region = RegionOne
|
||||||
|
api_version = 1
|
||||||
|
http_image = http://download.cirros-cloud.net/0.3.1/cirros-0.3.1-x86_64-uec.tar.gz
|
||||||
|
|
||||||
|
[network]
|
||||||
|
api_version = 2.0
|
||||||
|
catalog_type = network
|
||||||
|
#region = RegionOne
|
||||||
|
tenant_network_cidr = 10.100.0.0/16
|
||||||
|
tenant_network_mask_bits = 28
|
||||||
|
tenant_networks_reachable = false
|
||||||
|
public_network_id =
|
||||||
|
public_router_id =
|
||||||
|
|
||||||
|
|
||||||
|
[volume]
|
||||||
|
catalog_type = volume
|
||||||
|
disk_format = raw
|
||||||
|
build_interval = 1
|
||||||
|
build_timeout = 400
|
||||||
|
multi_backend_enabled = false
|
||||||
|
backend1_name = BACKEND_1
|
||||||
|
backend2_name = BACKEND_2
|
||||||
|
storage_protocol = iSCSI
|
||||||
|
vendor_name = Open Source
|
||||||
|
|
||||||
|
[object-storage]
|
||||||
|
catalog_type = object-store
|
||||||
|
#region = RegionOne
|
||||||
|
container_sync_timeout = 120
|
||||||
|
container_sync_interval = 5
|
||||||
|
accounts_quotas_available = True
|
||||||
|
operator_role = Member
|
||||||
|
|
||||||
|
[boto]
|
||||||
|
ssh_user = cirros
|
||||||
|
ec2_url = http://172.16.200.130:8773/services/Cloud
|
||||||
|
s3_url = http://172.16.200.130:3333
|
||||||
|
aws_access =
|
||||||
|
aws_secret =
|
||||||
|
s3_materials_path = /home/stack/devstack/files/images/s3-materials/cirros-0.3.1
|
||||||
|
ari_manifest = cirros-0.3.1-x86_64-initrd.manifest.xml
|
||||||
|
ami_manifest = cirros-0.3.1-x86_64-blank.img.manifest.xml
|
||||||
|
aki_manifest = cirros-0.3.1-x86_64-vmlinuz.manifest.xml
|
||||||
|
instance_type = m1.nano
|
||||||
|
http_socket_timeout = 30
|
||||||
|
num_retries = 1
|
||||||
|
build_timeout = 400
|
||||||
|
build_interval = 1
|
||||||
|
|
||||||
|
[orchestration]
|
||||||
|
catalog_type = orchestration
|
||||||
|
#region = RegionOne
|
||||||
|
build_interval = 1
|
||||||
|
build_timeout = 300
|
||||||
|
instance_type = m1.micro
|
||||||
|
#image_ref = ubuntu-vm-heat-cfntools
|
||||||
|
#keypair_name = heat_key
|
||||||
|
|
||||||
|
[dashboard]
|
||||||
|
dashboard_url = http://172.16.200.130/
|
||||||
|
login_url = http://172.16.200.130/auth/login/
|
||||||
|
|
||||||
|
[scenario]
|
||||||
|
img_dir = /home/stack/devstack/files/images/cirros-0.3.1-x86_64-uec
|
||||||
|
ami_img_file = cirros-0.3.1-x86_64-blank.img
|
||||||
|
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
|
||||||
|
|
||||||
|
[cli]
|
||||||
|
enabled = True
|
||||||
|
cli_dir = /usr/local/bin
|
||||||
|
timeout = 15
|
||||||
|
|
||||||
|
[service_available]
|
||||||
|
cinder = True
|
||||||
|
neutron = False
|
||||||
|
glance = True
|
||||||
|
swift = False
|
||||||
|
nova = True
|
||||||
|
heat = False
|
||||||
|
horizon = True
|
||||||
|
|
||||||
|
[stress]
|
||||||
|
max_instances = 32
|
||||||
|
log_check_interval = 60
|
||||||
|
default_thread_number_per_action=4
|
@ -16,4 +16,5 @@ psycopg2==2.5
|
|||||||
pyOpenSSL==0.13
|
pyOpenSSL==0.13
|
||||||
pycrypto==2.6
|
pycrypto==2.6
|
||||||
python-openid==2.2.5
|
python-openid==2.2.5
|
||||||
requests==1.2.3
|
requests==1.2.3
|
||||||
|
python-keystoneclient
|
Loading…
x
Reference in New Issue
Block a user