Initial commit to use Pecan for RestAPI service
Change-Id: Ie1fd9dbec8a5163a2959846c6ca845572ce23b12
This commit is contained in:
parent
ae03ef1d35
commit
6d2152767a
@ -13,6 +13,7 @@ lxml>=3.4.0
|
||||
oslo.log>=1.0.0
|
||||
oslo.utils>=1.2.0
|
||||
paramiko>=1.14.0
|
||||
pecan>=0.9.0
|
||||
pycrypto>=2.6.1
|
||||
pymongo>=2.7.2
|
||||
python-glanceclient>=0.15.0
|
||||
|
142
scale/kb_config.py
Normal file
142
scale/kb_config.py
Normal file
@ -0,0 +1,142 @@
|
||||
# Copyright 2015 Cisco Systems, 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
|
||||
import sys
|
||||
|
||||
import configure
|
||||
import log as logging
|
||||
from oslo_config import cfg
|
||||
|
||||
import credentials
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
# Some hardcoded client side options we do not want users to change
|
||||
hardcoded_client_cfg = {
|
||||
# Number of tenants to be created on the cloud
|
||||
'number_tenants': 1,
|
||||
|
||||
# Number of Users to be created inside the tenant
|
||||
'users_per_tenant': 1,
|
||||
|
||||
# Number of routers to be created within the context of each User
|
||||
# For now support only 1 router per user
|
||||
'routers_per_user': 1,
|
||||
|
||||
# Number of networks to be created within the context of each Router
|
||||
# Assumes 1 subnet per network
|
||||
'networks_per_router': 1,
|
||||
|
||||
# Number of VM instances to be created within the context of each Network
|
||||
'vms_per_network': 1,
|
||||
|
||||
# Number of security groups per network
|
||||
'secgroups_per_network': 1
|
||||
}
|
||||
|
||||
def get_absolute_path_for_file(file_name):
|
||||
'''
|
||||
Return the filename in absolute path for any file
|
||||
passed as relateive path.
|
||||
'''
|
||||
if os.path.isabs(__file__):
|
||||
abs_file_path = os.path.join(__file__.split("kb_config.py")[0],
|
||||
file_name)
|
||||
else:
|
||||
abs_file = os.path.abspath(__file__)
|
||||
abs_file_path = os.path.join(abs_file.split("kb_config.py")[0],
|
||||
file_name)
|
||||
|
||||
return abs_file_path
|
||||
|
||||
class KBConfig(object):
|
||||
|
||||
def __init__(self):
|
||||
# The default configuration file for KloudBuster
|
||||
default_cfg_file = get_absolute_path_for_file("cfg.scale.yaml")
|
||||
# Read the configuration file
|
||||
self.config_scale = configure.Configuration.from_file(default_cfg_file).configure()
|
||||
self.cred_tested = None
|
||||
self.cred_testing = None
|
||||
self.server_cfg = None
|
||||
self.client_cfg = None
|
||||
self.topo_cfg = None
|
||||
|
||||
def init_with_cli(self):
|
||||
self.get_credentials()
|
||||
self.get_configs()
|
||||
self.get_topo_cfg()
|
||||
|
||||
def init_with_rest_api(self, **kwargs):
|
||||
self.cred_tested = kwargs['cred_tested']
|
||||
self.cred_testing = kwargs['cred_testing']
|
||||
self.server_cfg = kwargs['server_cfg']
|
||||
self.client_cfg = kwargs['client_cfg']
|
||||
self.topo_cfg = kwargs['topo_cfg']
|
||||
|
||||
def get_total_vm_count(self, config):
|
||||
return (config['number_tenants'] * config['users_per_tenant'] *
|
||||
config['routers_per_user'] * config['networks_per_router'] *
|
||||
config['vms_per_network'])
|
||||
|
||||
def get_credentials(self):
|
||||
# Retrieve the credentials
|
||||
self.cred_tested = credentials.Credentials(CONF.tested_rc, CONF.passwd_tested, CONF.no_env)
|
||||
if CONF.testing_rc and CONF.testing_rc != CONF.tested_rc:
|
||||
self.cred_testing = credentials.Credentials(CONF.testing_rc,
|
||||
CONF.passwd_testing,
|
||||
CONF.no_env)
|
||||
else:
|
||||
# Use the same openrc file for both cases
|
||||
self.cred_testing = self.cred_tested
|
||||
|
||||
def get_configs(self):
|
||||
if CONF.config:
|
||||
alt_config = configure.Configuration.from_file(CONF.config).configure()
|
||||
self.config_scale = self.config_scale.merge(alt_config)
|
||||
|
||||
# Initialize the key pair name
|
||||
if self.config_scale['public_key_file']:
|
||||
# verify the public key file exists
|
||||
if not os.path.exists(self.config_scale['public_key_file']):
|
||||
LOG.error('Error: Invalid public key file: ' + self.config_scale['public_key_file'])
|
||||
sys.exit(1)
|
||||
else:
|
||||
# pick the user's public key if there is one
|
||||
pub_key = os.path.expanduser('~/.ssh/id_rsa.pub')
|
||||
if os.path.isfile(pub_key):
|
||||
self.config_scale['public_key_file'] = pub_key
|
||||
LOG.info('Using %s as public key for all VMs' % (pub_key))
|
||||
|
||||
# A bit of config dict surgery, extract out the client and server side
|
||||
# and transplant the remaining (common part) into the client and server dict
|
||||
self.server_cfg = self.config_scale.pop('server')
|
||||
self.client_cfg = self.config_scale.pop('client')
|
||||
self.server_cfg.update(self.config_scale)
|
||||
self.client_cfg.update(self.config_scale)
|
||||
|
||||
# Hardcode a few client side options
|
||||
self.client_cfg.update(hardcoded_client_cfg)
|
||||
|
||||
# Adjust the VMs per network on the client side to match the total
|
||||
# VMs on the server side (1:1)
|
||||
# There is an additional VM in client kloud as a proxy node
|
||||
self.client_cfg['vms_per_network'] =\
|
||||
self.get_total_vm_count(self.server_cfg) + 1
|
||||
|
||||
def get_topo_cfg(self):
|
||||
if CONF.topology:
|
||||
self.topo_cfg = configure.Configuration.from_file(CONF.topology).configure()
|
1
scale/kb_server/MANIFEST.in
Normal file
1
scale/kb_server/MANIFEST.in
Normal file
@ -0,0 +1 @@
|
||||
recursive-include public *
|
68
scale/kb_server/config.py
Normal file
68
scale/kb_server/config.py
Normal file
@ -0,0 +1,68 @@
|
||||
# Copyright 2015 Cisco Systems, 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.
|
||||
|
||||
# Server Specific Configurations
|
||||
server = {
|
||||
'port': '8080',
|
||||
'host': '0.0.0.0'
|
||||
}
|
||||
|
||||
# Pecan Application Configurations
|
||||
app = {
|
||||
'root': 'kb_server.controllers.root.RootController',
|
||||
'modules': ['kb_server'],
|
||||
'static_root': '%(confdir)s/public',
|
||||
'template_path': '%(confdir)s/kb_server/templates',
|
||||
'debug': True,
|
||||
'errors': {
|
||||
404: '/error/404',
|
||||
'__force_dict__': True
|
||||
}
|
||||
}
|
||||
|
||||
logging = {
|
||||
'root': {'level': 'INFO', 'handlers': ['console']},
|
||||
'loggers': {
|
||||
'kb_server': {'level': 'DEBUG', 'handlers': ['console']},
|
||||
'pecan': {'level': 'DEBUG', 'handlers': ['console']},
|
||||
'py.warnings': {'handlers': ['console']},
|
||||
'__force_dict__': True
|
||||
},
|
||||
'handlers': {
|
||||
'console': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.StreamHandler',
|
||||
'formatter': 'color'
|
||||
}
|
||||
},
|
||||
'formatters': {
|
||||
'simple': {
|
||||
'format': ('%(asctime)s %(levelname)-5.5s [%(name)s]'
|
||||
'[%(threadName)s] %(message)s')
|
||||
},
|
||||
'color': {
|
||||
'()': 'pecan.log.ColorFormatter',
|
||||
'format': ('%(asctime)s [%(padded_color_levelname)s] [%(name)s]'
|
||||
'[%(threadName)s] %(message)s'),
|
||||
'__force_dict__': True
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Custom Configurations must be in Python dictionary format::
|
||||
#
|
||||
# foo = {'bar':'baz'}
|
||||
#
|
||||
# All configurations are accessible at::
|
||||
# pecan.conf
|
0
scale/kb_server/kb_server/__init__.py
Normal file
0
scale/kb_server/kb_server/__init__.py
Normal file
27
scale/kb_server/kb_server/app.py
Normal file
27
scale/kb_server/kb_server/app.py
Normal file
@ -0,0 +1,27 @@
|
||||
# Copyright 2015 Cisco Systems, 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 kb_server import model
|
||||
from pecan import make_app
|
||||
|
||||
def setup_app(config):
|
||||
|
||||
model.init_model()
|
||||
app_conf = dict(config.app)
|
||||
|
||||
return make_app(
|
||||
app_conf.pop('root'),
|
||||
logging=getattr(config, 'logging', {}),
|
||||
**app_conf
|
||||
)
|
0
scale/kb_server/kb_server/controllers/__init__.py
Normal file
0
scale/kb_server/kb_server/controllers/__init__.py
Normal file
46
scale/kb_server/kb_server/controllers/config.py
Normal file
46
scale/kb_server/kb_server/controllers/config.py
Normal file
@ -0,0 +1,46 @@
|
||||
# Copyright 2015 Cisco Systems, 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
|
||||
import sys
|
||||
kb_main_path = os.path.split(os.path.abspath(__file__))[0] + "/../../.."
|
||||
sys.path.append(kb_main_path)
|
||||
|
||||
from kb_config import KBConfig
|
||||
from pecan import expose
|
||||
|
||||
class ConfigController(object):
|
||||
|
||||
def __init__(self):
|
||||
self.kb_config = KBConfig()
|
||||
self.cur_config = None
|
||||
|
||||
@expose(generic=True)
|
||||
def default_config(self):
|
||||
def_config = self.kb_config.config_scale
|
||||
return str(def_config)
|
||||
|
||||
@expose(generic=True)
|
||||
def current_config(self):
|
||||
return str(self.cur_config)
|
||||
|
||||
@expose(generic=True)
|
||||
def status(self):
|
||||
return "RETURN CURRENT STATUS HERE"
|
||||
|
||||
@status.when(method='PUT')
|
||||
def status_PUT(self, **kw):
|
||||
# @TODO(recursively update the config dictionary with the information
|
||||
# provided by application (client))
|
||||
return str(kw)
|
33
scale/kb_server/kb_server/controllers/root.py
Normal file
33
scale/kb_server/kb_server/controllers/root.py
Normal file
@ -0,0 +1,33 @@
|
||||
# Copyright 2015 Cisco Systems, 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 config import ConfigController
|
||||
from pecan import abort
|
||||
from pecan import expose
|
||||
|
||||
class APIController(object):
|
||||
@expose()
|
||||
def _lookup(self, primary_key, *remainder):
|
||||
if primary_key == "config":
|
||||
return ConfigController(), remainder
|
||||
else:
|
||||
abort(404)
|
||||
|
||||
class RootController(object):
|
||||
@expose()
|
||||
def _lookup(self, primary_key, *remainder):
|
||||
if primary_key == "api":
|
||||
return APIController(), remainder
|
||||
else:
|
||||
abort(404)
|
29
scale/kb_server/kb_server/model/__init__.py
Normal file
29
scale/kb_server/kb_server/model/__init__.py
Normal file
@ -0,0 +1,29 @@
|
||||
# Copyright 2015 Cisco Systems, 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 pecan import conf # noqa
|
||||
|
||||
|
||||
def init_model():
|
||||
"""
|
||||
This is a stub method which is called at application startup time.
|
||||
|
||||
If you need to bind to a parsed database configuration, set up tables or
|
||||
ORM classes, or perform any database initialization, this is the
|
||||
recommended place to do it.
|
||||
|
||||
For more information working with databases, and some common recipes,
|
||||
see http://pecan.readthedocs.org/en/latest/databases.html
|
||||
"""
|
||||
pass
|
6
scale/kb_server/setup.cfg
Normal file
6
scale/kb_server/setup.cfg
Normal file
@ -0,0 +1,6 @@
|
||||
[nosetests]
|
||||
match=^test
|
||||
where=kb_server
|
||||
nocapture=1
|
||||
cover-package=kb_server
|
||||
cover-erase=1
|
38
scale/kb_server/setup.py
Normal file
38
scale/kb_server/setup.py
Normal file
@ -0,0 +1,38 @@
|
||||
# Copyright 2015 Cisco Systems, 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.
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
try:
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
except ImportError:
|
||||
from ez_setup import use_setuptools
|
||||
use_setuptools()
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
name='kb_server',
|
||||
version='0.1',
|
||||
description='',
|
||||
author='',
|
||||
author_email='',
|
||||
install_requires=[
|
||||
"pecan",
|
||||
],
|
||||
test_suite='kb_server',
|
||||
zip_safe=False,
|
||||
include_package_data=True,
|
||||
packages=find_packages(exclude=['ez_setup'])
|
||||
)
|
@ -21,8 +21,8 @@ import traceback
|
||||
|
||||
import base_compute
|
||||
import base_network
|
||||
import configure
|
||||
from glanceclient.v2 import client as glanceclient
|
||||
from kb_config import KBConfig
|
||||
from kb_runner import KBRunner
|
||||
from kb_scheduler import KBScheduler
|
||||
from keystoneclient.v2_0 import client as keystoneclient
|
||||
@ -32,28 +32,12 @@ from oslo_config import cfg
|
||||
from tabulate import tabulate
|
||||
import tenant
|
||||
|
||||
import credentials
|
||||
import sshutils
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_absolute_path_for_file(file_name):
|
||||
'''
|
||||
Return the filename in absolute path for any file
|
||||
passed as relateive path.
|
||||
'''
|
||||
if os.path.isabs(__file__):
|
||||
abs_file_path = os.path.join(__file__.split("kloudbuster.py")[0],
|
||||
file_name)
|
||||
else:
|
||||
abs_file = os.path.abspath(__file__)
|
||||
abs_file_path = os.path.join(abs_file.split("kloudbuster.py")[0],
|
||||
file_name)
|
||||
|
||||
return abs_file_path
|
||||
|
||||
def create_keystone_client(admin_creds):
|
||||
"""
|
||||
Return the keystone client and auth URL given a credential
|
||||
@ -404,8 +388,6 @@ hardcoded_client_cfg = {
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# The default configuration file for KloudBuster
|
||||
default_cfg_file = get_absolute_path_for_file("cfg.scale.yaml")
|
||||
|
||||
cli_opts = [
|
||||
cfg.StrOpt("config",
|
||||
@ -441,64 +423,23 @@ if __name__ == '__main__':
|
||||
|
||||
logging.setup("kloudbuster")
|
||||
|
||||
# Read the configuration file
|
||||
config_scale = configure.Configuration.from_file(default_cfg_file).configure()
|
||||
if CONF.config:
|
||||
alt_config = configure.Configuration.from_file(CONF.config).configure()
|
||||
config_scale = config_scale.merge(alt_config)
|
||||
kb_config = KBConfig()
|
||||
kb_config.init_with_cli()
|
||||
|
||||
if CONF.topology:
|
||||
topology = configure.Configuration.from_file(CONF.topology).configure()
|
||||
else:
|
||||
topology = None
|
||||
|
||||
# Retrieve the credentials
|
||||
cred = credentials.Credentials(CONF.tested_rc, CONF.passwd_tested, CONF.no_env)
|
||||
if CONF.testing_rc and CONF.testing_rc != CONF.tested_rc:
|
||||
cred_testing = credentials.Credentials(CONF.testing_rc,
|
||||
CONF.passwd_testing,
|
||||
CONF.no_env)
|
||||
else:
|
||||
# Use the same openrc file for both cases
|
||||
cred_testing = cred
|
||||
|
||||
# Initialize the key pair name
|
||||
if config_scale['public_key_file']:
|
||||
# verify the public key file exists
|
||||
if not os.path.exists(config_scale['public_key_file']):
|
||||
LOG.error('Error: Invalid public key file: ' + config_scale['public_key_file'])
|
||||
sys.exit(1)
|
||||
else:
|
||||
# pick the user's public key if there is one
|
||||
pub_key = os.path.expanduser('~/.ssh/id_rsa.pub')
|
||||
if os.path.isfile(pub_key):
|
||||
config_scale['public_key_file'] = pub_key
|
||||
LOG.info('Using %s as public key for all VMs' % (pub_key))
|
||||
|
||||
# A bit of config dict surgery, extract out the client and server side
|
||||
# and transplant the remaining (common part) into the client and server dict
|
||||
server_side_cfg = config_scale.pop('server')
|
||||
client_side_cfg = config_scale.pop('client')
|
||||
server_side_cfg.update(config_scale)
|
||||
client_side_cfg.update(config_scale)
|
||||
|
||||
# Hardcode a few client side options
|
||||
client_side_cfg.update(hardcoded_client_cfg)
|
||||
|
||||
# Adjust the VMs per network on the client side to match the total
|
||||
# VMs on the server side (1:1)
|
||||
# There is an additional VM in client kloud as a proxy node
|
||||
client_side_cfg['vms_per_network'] = get_total_vm_count(server_side_cfg) + 1
|
||||
|
||||
image_check = check_and_upload_images(cred, cred_testing, server_side_cfg.image_name,
|
||||
client_side_cfg.image_name)
|
||||
image_check = check_and_upload_images(
|
||||
kb_config.cred_tested,
|
||||
kb_config.cred_testing,
|
||||
kb_config.server_cfg.image_name,
|
||||
kb_config.client_cfg.image_name)
|
||||
if not image_check:
|
||||
sys.exit(1)
|
||||
|
||||
# The KloudBuster class is just a wrapper class
|
||||
# levarages tenant and user class for resource creations and
|
||||
# deletion
|
||||
kloudbuster = KloudBuster(cred, cred_testing, server_side_cfg, client_side_cfg, topology)
|
||||
# levarages tenant and user class for resource creations and deletion
|
||||
kloudbuster = KloudBuster(
|
||||
kb_config.cred_tested, kb_config.cred_testing,
|
||||
kb_config.server_cfg, kb_config.client_cfg,
|
||||
kb_config.topo_cfg)
|
||||
kloudbuster.run()
|
||||
|
||||
if CONF.json:
|
||||
|
Loading…
x
Reference in New Issue
Block a user