small refactoring - service and storage (dao) layers has been created
Change-Id: Ia3c106bfbe87a7e9c08659fd61308164b9afb2dc
This commit is contained in:
parent
097f7c44a2
commit
c67850ac63
@ -18,7 +18,7 @@ from flask import Flask
|
|||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
from savanna.openstack.common import log
|
from savanna.openstack.common import log
|
||||||
from savanna.storage.defaults import setup_defaults
|
from savanna.storage.defaults import setup_defaults
|
||||||
from savanna.storage.storage import setup_storage, DB
|
from savanna.storage.db import setup_storage, DB
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
@ -24,7 +24,7 @@ from savanna.api import v02 as api_v02
|
|||||||
from savanna.middleware.auth_valid import filter_factory as auth_valid
|
from savanna.middleware.auth_valid import filter_factory as auth_valid
|
||||||
from savanna.utils.scheduler import setup_scheduler
|
from savanna.utils.scheduler import setup_scheduler
|
||||||
from savanna.utils.api import render
|
from savanna.utils.api import render
|
||||||
from savanna.storage.storage import setup_storage
|
from savanna.storage.db import setup_storage
|
||||||
|
|
||||||
from savanna.openstack.common import log
|
from savanna.openstack.common import log
|
||||||
|
|
||||||
|
@ -17,12 +17,10 @@ import eventlet
|
|||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
from savanna.storage.models import NodeTemplate, NodeType, NodeProcess, \
|
|
||||||
NodeTemplateConfig, Cluster, ClusterNodeCount
|
|
||||||
from savanna.storage.storage import DB
|
|
||||||
from savanna.utils.api import abort_and_log
|
from savanna.utils.api import abort_and_log
|
||||||
from savanna.service import cluster_ops
|
from savanna.service import cluster_ops
|
||||||
from savanna.openstack.common import log as logging
|
from savanna.openstack.common import log as logging
|
||||||
|
import savanna.storage.storage as storage
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -30,6 +28,105 @@ CONF = cfg.CONF
|
|||||||
CONF.import_opt('allow_cluster_ops', 'savanna.config')
|
CONF.import_opt('allow_cluster_ops', 'savanna.config')
|
||||||
|
|
||||||
|
|
||||||
|
## Node Template ops:
|
||||||
|
|
||||||
|
def get_node_template(**args):
|
||||||
|
return _node_template(storage.get_node_template(**args))
|
||||||
|
|
||||||
|
|
||||||
|
def get_node_templates(**args):
|
||||||
|
return [_node_template(tmpl) for tmpl
|
||||||
|
in storage.get_node_templates(**args)]
|
||||||
|
|
||||||
|
|
||||||
|
def create_node_template(values):
|
||||||
|
"""
|
||||||
|
Creates new node template from values dict
|
||||||
|
:param values: dict
|
||||||
|
:return: created node template resource
|
||||||
|
"""
|
||||||
|
values = values.pop('node_template')
|
||||||
|
|
||||||
|
name = values.pop('name')
|
||||||
|
node_type_id = storage.get_node_type(name=values.pop('node_type')).id
|
||||||
|
# todo(slukjanov): take tenant_id from headers
|
||||||
|
tenant_id = "tenant-01"
|
||||||
|
flavor_id = values.pop('flavor_id')
|
||||||
|
|
||||||
|
nt = storage.create_node_template(name, node_type_id, tenant_id,
|
||||||
|
flavor_id, values)
|
||||||
|
|
||||||
|
return get_node_template(id=nt.id)
|
||||||
|
|
||||||
|
|
||||||
|
def terminate_node_template(**args):
|
||||||
|
return storage.terminate_node_template(**args)
|
||||||
|
|
||||||
|
|
||||||
|
## Cluster ops:
|
||||||
|
|
||||||
|
def get_cluster(**args):
|
||||||
|
return _cluster(storage.get_cluster(**args))
|
||||||
|
|
||||||
|
|
||||||
|
def get_clusters(**args):
|
||||||
|
return [_cluster(cluster) for cluster in
|
||||||
|
storage.get_clusters(**args)]
|
||||||
|
|
||||||
|
|
||||||
|
def create_cluster(values):
|
||||||
|
values = values.pop('cluster')
|
||||||
|
|
||||||
|
name = values.pop('name')
|
||||||
|
base_image_id = values.pop('base_image_id')
|
||||||
|
# todo(slukjanov): take tenant_id from headers
|
||||||
|
tenant_id = "tenant-01"
|
||||||
|
templates = values.pop('node_templates')
|
||||||
|
|
||||||
|
# todo(slukjanov): check that we can create objects in the specified tenant
|
||||||
|
|
||||||
|
cluster = storage.create_cluster(name, base_image_id, tenant_id, templates)
|
||||||
|
|
||||||
|
eventlet.spawn(_cluster_creation_job, request.headers, cluster.id)
|
||||||
|
|
||||||
|
return get_cluster(id=cluster.id)
|
||||||
|
|
||||||
|
|
||||||
|
def _cluster_creation_job(headers, cluster_id):
|
||||||
|
cluster = storage.get_cluster(id=cluster_id)
|
||||||
|
LOG.debug("Starting cluster '%s' creation: %s", cluster_id,
|
||||||
|
_cluster(cluster).dict)
|
||||||
|
|
||||||
|
if CONF.allow_cluster_ops:
|
||||||
|
cluster_ops.launch_cluster(headers, cluster)
|
||||||
|
else:
|
||||||
|
LOG.info("Cluster ops are disabled, use --allow-cluster-ops flag")
|
||||||
|
|
||||||
|
# update cluster status
|
||||||
|
storage.update_cluster_status('Active', id=cluster.id)
|
||||||
|
|
||||||
|
|
||||||
|
def terminate_cluster(**args):
|
||||||
|
cluster = storage.update_cluster_status('Stoping', **args)
|
||||||
|
|
||||||
|
eventlet.spawn(_cluster_termination_job, request.headers, cluster.id)
|
||||||
|
|
||||||
|
|
||||||
|
def _cluster_termination_job(headers, cluster_id):
|
||||||
|
cluster = storage.get_cluster(id=cluster_id)
|
||||||
|
LOG.debug("Stoping cluster '%s' creation: %s", cluster_id,
|
||||||
|
_cluster(cluster).dict)
|
||||||
|
|
||||||
|
if CONF.allow_cluster_ops:
|
||||||
|
cluster_ops.stop_cluster(headers, cluster)
|
||||||
|
else:
|
||||||
|
LOG.info("Cluster ops are disabled, use --allow-cluster-ops flag")
|
||||||
|
|
||||||
|
storage.terminate_cluster(id=cluster.id)
|
||||||
|
|
||||||
|
|
||||||
|
## Utils and DB object to Resource converters
|
||||||
|
|
||||||
def _clean_nones(obj):
|
def _clean_nones(obj):
|
||||||
d_type = type(obj)
|
d_type = type(obj)
|
||||||
if d_type is not dict or d_type is not list:
|
if d_type is not dict or d_type is not list:
|
||||||
@ -99,56 +196,6 @@ def _node_template(nt):
|
|||||||
return Resource('node_template', d)
|
return Resource('node_template', d)
|
||||||
|
|
||||||
|
|
||||||
def _template_id_by_name(template):
|
|
||||||
return NodeTemplate.query.filter_by(name=template).first().id
|
|
||||||
|
|
||||||
|
|
||||||
def _type_id_by_name(_type):
|
|
||||||
return NodeType.query.filter_by(name=_type).first().id
|
|
||||||
|
|
||||||
|
|
||||||
def get_node_template(**args):
|
|
||||||
return _node_template(NodeTemplate.query.filter_by(**args).first())
|
|
||||||
|
|
||||||
|
|
||||||
def get_node_templates(**args):
|
|
||||||
return [_node_template(tmpl) for tmpl
|
|
||||||
in NodeTemplate.query.filter_by(**args).all()]
|
|
||||||
|
|
||||||
|
|
||||||
def create_node_template(values):
|
|
||||||
"""
|
|
||||||
Creates new node template from values dict
|
|
||||||
:param values: dict
|
|
||||||
:return: created node template resource
|
|
||||||
"""
|
|
||||||
values = values.pop('node_template')
|
|
||||||
|
|
||||||
name = values.pop('name')
|
|
||||||
node_type_id = _type_id_by_name(values.pop('node_type'))
|
|
||||||
# todo(slukjanov): take tenant_id from headers
|
|
||||||
tenant_id = "tenant-01"
|
|
||||||
flavor_id = values.pop('flavor_id')
|
|
||||||
|
|
||||||
nt = NodeTemplate(name, node_type_id, tenant_id, flavor_id)
|
|
||||||
DB.session.add(nt)
|
|
||||||
for process_name in values:
|
|
||||||
process = NodeProcess.query.filter_by(name=process_name).first()
|
|
||||||
conf = values.get(process_name)
|
|
||||||
for prop in process.node_process_properties:
|
|
||||||
val = conf.get(prop.name, None)
|
|
||||||
if not val and prop.required:
|
|
||||||
if not prop.default:
|
|
||||||
raise RuntimeError('Template \'%s\', value missed '
|
|
||||||
'for required param: %s %s'
|
|
||||||
% (name, process.name, prop.name))
|
|
||||||
val = prop.default
|
|
||||||
DB.session.add(NodeTemplateConfig(nt.id, prop.id, val))
|
|
||||||
DB.session.commit()
|
|
||||||
|
|
||||||
return get_node_template(id=nt.id)
|
|
||||||
|
|
||||||
|
|
||||||
def _cluster(cluster):
|
def _cluster(cluster):
|
||||||
if not cluster:
|
if not cluster:
|
||||||
abort_and_log(404, 'Cluster not found')
|
abort_and_log(404, 'Cluster not found')
|
||||||
@ -173,94 +220,3 @@ def _cluster(cluster):
|
|||||||
d['service_urls'][service.name] = service.url
|
d['service_urls'][service.name] = service.url
|
||||||
|
|
||||||
return Resource('cluster', d)
|
return Resource('cluster', d)
|
||||||
|
|
||||||
|
|
||||||
def get_cluster(**args):
|
|
||||||
return _cluster(Cluster.query.filter_by(**args).first())
|
|
||||||
|
|
||||||
|
|
||||||
def get_clusters(**args):
|
|
||||||
return [_cluster(cluster) for cluster in
|
|
||||||
Cluster.query.filter_by(**args).all()]
|
|
||||||
|
|
||||||
|
|
||||||
def create_cluster(values):
|
|
||||||
values = values.pop('cluster')
|
|
||||||
|
|
||||||
name = values.pop('name')
|
|
||||||
base_image_id = values.pop('base_image_id')
|
|
||||||
# todo(slukjanov): take tenant_id from headers
|
|
||||||
tenant_id = "tenant-01"
|
|
||||||
templates = values.pop('node_templates')
|
|
||||||
|
|
||||||
# todo(slukjanov): check that we can create objects in the specified tenant
|
|
||||||
|
|
||||||
cluster = Cluster(name, base_image_id, tenant_id)
|
|
||||||
DB.session.add(cluster)
|
|
||||||
for template in templates:
|
|
||||||
count = templates.get(template)
|
|
||||||
template_id = _template_id_by_name(template)
|
|
||||||
cnc = ClusterNodeCount(cluster.id, template_id, int(count))
|
|
||||||
DB.session.add(cnc)
|
|
||||||
DB.session.commit()
|
|
||||||
|
|
||||||
eventlet.spawn(_cluster_creation_job, request.headers, cluster.id)
|
|
||||||
|
|
||||||
return get_cluster(id=cluster.id)
|
|
||||||
|
|
||||||
|
|
||||||
def _cluster_creation_job(headers, cluster_id):
|
|
||||||
cluster = Cluster.query.filter_by(id=cluster_id).first()
|
|
||||||
LOG.debug("Starting cluster '%s' creation: %s", cluster_id,
|
|
||||||
_cluster(cluster).dict)
|
|
||||||
|
|
||||||
if CONF.allow_cluster_ops:
|
|
||||||
cluster_ops.launch_cluster(headers, cluster)
|
|
||||||
else:
|
|
||||||
LOG.info("Cluster ops are disabled, use --allow-cluster-ops flag")
|
|
||||||
|
|
||||||
# update cluster status
|
|
||||||
cluster = Cluster.query.filter_by(id=cluster.id).first()
|
|
||||||
cluster.status = 'Active'
|
|
||||||
DB.session.add(cluster)
|
|
||||||
DB.session.commit()
|
|
||||||
|
|
||||||
|
|
||||||
def terminate_cluster(**args):
|
|
||||||
# update cluster status
|
|
||||||
cluster = Cluster.query.filter_by(**args).first()
|
|
||||||
cluster.status = 'Stoping'
|
|
||||||
DB.session.add(cluster)
|
|
||||||
DB.session.commit()
|
|
||||||
|
|
||||||
eventlet.spawn(_cluster_termination_job, request.headers, cluster.id)
|
|
||||||
|
|
||||||
|
|
||||||
def _cluster_termination_job(headers, cluster_id):
|
|
||||||
cluster = Cluster.query.filter_by(id=cluster_id).first()
|
|
||||||
LOG.debug("Stoping cluster '%s' creation: %s", cluster_id,
|
|
||||||
_cluster(cluster).dict)
|
|
||||||
|
|
||||||
if CONF.allow_cluster_ops:
|
|
||||||
cluster_ops.stop_cluster(headers, cluster)
|
|
||||||
else:
|
|
||||||
LOG.info("Cluster ops are disabled, use --allow-cluster-ops flag")
|
|
||||||
|
|
||||||
DB.session.delete(cluster)
|
|
||||||
DB.session.commit()
|
|
||||||
|
|
||||||
|
|
||||||
def terminate_node_template(**args):
|
|
||||||
template = NodeTemplate.query.filter_by(**args).first()
|
|
||||||
if template:
|
|
||||||
if len(template.nodes):
|
|
||||||
abort_and_log(500, "There are active nodes created using "
|
|
||||||
"template '%s' you trying to terminate"
|
|
||||||
% args)
|
|
||||||
else:
|
|
||||||
DB.session.delete(template)
|
|
||||||
DB.session.commit()
|
|
||||||
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
@ -20,7 +20,7 @@ from jinja2 import PackageLoader
|
|||||||
from paramiko import SSHClient, AutoAddPolicy
|
from paramiko import SSHClient, AutoAddPolicy
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
from savanna.storage.models import Node, ServiceUrl
|
from savanna.storage.models import Node, ServiceUrl
|
||||||
from savanna.storage.storage import DB
|
from savanna.storage.db import DB
|
||||||
from savanna.utils.openstack.nova import novaclient
|
from savanna.utils.openstack.nova import novaclient
|
||||||
from savanna.openstack.common import log as logging
|
from savanna.openstack.common import log as logging
|
||||||
|
|
||||||
|
40
savanna/storage/db.py
Normal file
40
savanna/storage/db.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Copyright (c) 2013 Mirantis Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
# implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from flask.ext.sqlalchemy import SQLAlchemy
|
||||||
|
from oslo.config import cfg
|
||||||
|
|
||||||
|
DB = SQLAlchemy()
|
||||||
|
|
||||||
|
opts = [
|
||||||
|
cfg.StrOpt('database_uri',
|
||||||
|
default='sqlite:////tmp/savanna.db',
|
||||||
|
help='URL for sqlalchemy database'),
|
||||||
|
cfg.BoolOpt('echo',
|
||||||
|
default=False,
|
||||||
|
help='Sqlalchemy echo')
|
||||||
|
]
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
CONF.register_opts(opts, group='sqlalchemy')
|
||||||
|
|
||||||
|
|
||||||
|
def setup_storage(app):
|
||||||
|
app.config['SQLALCHEMY_DATABASE_URI'] = CONF.sqlalchemy.database_uri
|
||||||
|
app.config['SQLALCHEMY_ECHO'] = CONF.sqlalchemy.echo
|
||||||
|
|
||||||
|
DB.app = app
|
||||||
|
DB.init_app(app)
|
||||||
|
DB.create_all()
|
@ -13,96 +13,13 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from savanna.storage.models import NodeProcess, NodeProcessProperty, \
|
from savanna.storage.storage import create_node_type, \
|
||||||
NodeType, NodeTemplate, NodeTemplateConfig, Cluster, ClusterNodeCount
|
create_node_template, create_node_process
|
||||||
from savanna.storage.storage import DB
|
|
||||||
from savanna.openstack.common import log as logging
|
from savanna.openstack.common import log as logging
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def create_node_process(name, properties):
|
|
||||||
"""
|
|
||||||
Creates new node process and node process properties
|
|
||||||
:param name: process name
|
|
||||||
:param properties: array of triples (name, required, default)
|
|
||||||
:return: created node process
|
|
||||||
"""
|
|
||||||
process = NodeProcess(name)
|
|
||||||
DB.session.add(process)
|
|
||||||
DB.session.commit()
|
|
||||||
for p in properties:
|
|
||||||
prop = NodeProcessProperty(process.id, p[0], p[1], p[2])
|
|
||||||
DB.session.add(prop)
|
|
||||||
DB.session.commit()
|
|
||||||
return process
|
|
||||||
|
|
||||||
|
|
||||||
def create_node_type(name, processes):
|
|
||||||
"""
|
|
||||||
Creates new node type using specified list of processes
|
|
||||||
:param name:
|
|
||||||
:param processes:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
node_type = NodeType(name)
|
|
||||||
node_type.processes = processes
|
|
||||||
DB.session.add(node_type)
|
|
||||||
DB.session.commit()
|
|
||||||
return node_type
|
|
||||||
|
|
||||||
|
|
||||||
def create_node_template(name, node_type_id, tenant_id, flavor_id, configs):
|
|
||||||
"""
|
|
||||||
Creates new node templates
|
|
||||||
:param name: template name
|
|
||||||
:param node_type_id: node type
|
|
||||||
:param tenant_id: tenant
|
|
||||||
:param flavor_id: flavor
|
|
||||||
:param configs: dict of process->property->value
|
|
||||||
:return: created node template
|
|
||||||
"""
|
|
||||||
node_template = NodeTemplate(name, node_type_id, tenant_id, flavor_id)
|
|
||||||
DB.session.add(node_template)
|
|
||||||
for process_name in configs:
|
|
||||||
process = NodeProcess.query.filter_by(name=process_name).first()
|
|
||||||
conf = configs.get(process_name)
|
|
||||||
for prop in process.node_process_properties:
|
|
||||||
val = conf.get(prop.name, None)
|
|
||||||
if not val and prop.required:
|
|
||||||
if not prop.default:
|
|
||||||
raise RuntimeError('Template \'%s\', value missed '
|
|
||||||
'for required param: %s %s'
|
|
||||||
% (name, process.name, prop.name))
|
|
||||||
val = prop.default
|
|
||||||
DB.session.add(NodeTemplateConfig(node_template.id, prop.id, val))
|
|
||||||
DB.session.commit()
|
|
||||||
|
|
||||||
return node_template
|
|
||||||
|
|
||||||
|
|
||||||
def create_cluster(name, base_image_id, tenant_id, templates):
|
|
||||||
"""
|
|
||||||
Creates new cluster
|
|
||||||
:param name: cluster name
|
|
||||||
:param base_image_id: base image
|
|
||||||
:param tenant_id: tenant
|
|
||||||
:param templates: dict of template->count
|
|
||||||
:return: created cluster
|
|
||||||
"""
|
|
||||||
cluster = Cluster(name, base_image_id, tenant_id)
|
|
||||||
DB.session.add(cluster)
|
|
||||||
for template in templates:
|
|
||||||
count = templates.get(template)
|
|
||||||
cnc = ClusterNodeCount(cluster.id,
|
|
||||||
NodeTemplate.query.filter_by(name=template)
|
|
||||||
.first().id, int(count))
|
|
||||||
DB.session.add(cnc)
|
|
||||||
DB.session.commit()
|
|
||||||
|
|
||||||
return cluster
|
|
||||||
|
|
||||||
|
|
||||||
def setup_defaults(reset_db=False, gen_templates=False):
|
def setup_defaults(reset_db=False, gen_templates=False):
|
||||||
nt_jt_nn = None
|
nt_jt_nn = None
|
||||||
nt_jt = None
|
nt_jt = None
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from savanna.storage.storage import DB
|
from savanna.storage.db import DB
|
||||||
|
|
||||||
|
|
||||||
class NodeTemplate(DB.Model):
|
class NodeTemplate(DB.Model):
|
||||||
|
@ -13,28 +13,150 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from flask.ext.sqlalchemy import SQLAlchemy
|
from savanna.storage.db import DB
|
||||||
from oslo.config import cfg
|
|
||||||
|
|
||||||
DB = SQLAlchemy()
|
from savanna.storage.models import NodeTemplate, NodeProcess, Cluster, \
|
||||||
|
ClusterNodeCount, NodeTemplateConfig, NodeType, NodeProcessProperty
|
||||||
opts = [
|
from savanna.utils.api import abort_and_log
|
||||||
cfg.StrOpt('database_uri',
|
|
||||||
default='sqlite:////tmp/savanna.db',
|
|
||||||
help='URL for sqlalchemy database'),
|
|
||||||
cfg.BoolOpt('echo',
|
|
||||||
default=False,
|
|
||||||
help='Sqlalchemy echo')
|
|
||||||
]
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
|
||||||
CONF.register_opts(opts, group='sqlalchemy')
|
|
||||||
|
|
||||||
|
|
||||||
def setup_storage(app):
|
## Node Template ops:
|
||||||
app.config['SQLALCHEMY_DATABASE_URI'] = CONF.sqlalchemy.database_uri
|
|
||||||
app.config['SQLALCHEMY_ECHO'] = CONF.sqlalchemy.echo
|
|
||||||
|
|
||||||
DB.app = app
|
def get_node_template(**args):
|
||||||
DB.init_app(app)
|
return NodeTemplate.query.filter_by(**args).first()
|
||||||
DB.create_all()
|
|
||||||
|
|
||||||
|
def get_node_templates(**args):
|
||||||
|
return NodeTemplate.query.filter_by(**args).all()
|
||||||
|
|
||||||
|
|
||||||
|
def create_node_template(name, node_type_id, tenant_id, flavor_id, configs):
|
||||||
|
"""
|
||||||
|
Creates new node templates
|
||||||
|
:param name: template name
|
||||||
|
:param node_type_id: node type
|
||||||
|
:param tenant_id: tenant
|
||||||
|
:param flavor_id: flavor
|
||||||
|
:param configs: dict of process->property->value
|
||||||
|
:return: created node template
|
||||||
|
"""
|
||||||
|
node_template = NodeTemplate(name, node_type_id, tenant_id, flavor_id)
|
||||||
|
DB.session.add(node_template)
|
||||||
|
for process_name in configs:
|
||||||
|
process = NodeProcess.query.filter_by(name=process_name).first()
|
||||||
|
conf = configs.get(process_name)
|
||||||
|
for prop in process.node_process_properties:
|
||||||
|
val = conf.get(prop.name, None)
|
||||||
|
if not val and prop.required:
|
||||||
|
if not prop.default:
|
||||||
|
raise RuntimeError('Template \'%s\', value missed '
|
||||||
|
'for required param: %s %s'
|
||||||
|
% (name, process.name, prop.name))
|
||||||
|
val = prop.default
|
||||||
|
DB.session.add(NodeTemplateConfig(node_template.id, prop.id, val))
|
||||||
|
DB.session.commit()
|
||||||
|
|
||||||
|
return node_template
|
||||||
|
|
||||||
|
|
||||||
|
def terminate_node_template(**args):
|
||||||
|
template = NodeTemplate.query.filter_by(**args).first()
|
||||||
|
if template:
|
||||||
|
if len(template.nodes):
|
||||||
|
abort_and_log(500, "There are active nodes created using "
|
||||||
|
"template '%s' you trying to terminate"
|
||||||
|
% args)
|
||||||
|
else:
|
||||||
|
DB.session.delete(template)
|
||||||
|
DB.session.commit()
|
||||||
|
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
## Cluster ops:
|
||||||
|
|
||||||
|
def get_cluster(**args):
|
||||||
|
return Cluster.query.filter_by(**args).first()
|
||||||
|
|
||||||
|
|
||||||
|
def get_clusters(**args):
|
||||||
|
return Cluster.query.filter_by(**args).all()
|
||||||
|
|
||||||
|
|
||||||
|
def create_cluster(name, base_image_id, tenant_id, templates):
|
||||||
|
"""
|
||||||
|
Creates new cluster
|
||||||
|
:param name: cluster name
|
||||||
|
:param base_image_id: base image
|
||||||
|
:param tenant_id: tenant
|
||||||
|
:param templates: dict of template->count
|
||||||
|
:return: created cluster
|
||||||
|
"""
|
||||||
|
cluster = Cluster(name, base_image_id, tenant_id)
|
||||||
|
DB.session.add(cluster)
|
||||||
|
for template in templates:
|
||||||
|
count = templates.get(template)
|
||||||
|
template_id = get_node_template(name=template).id
|
||||||
|
cnc = ClusterNodeCount(cluster.id, template_id, int(count))
|
||||||
|
DB.session.add(cnc)
|
||||||
|
DB.session.commit()
|
||||||
|
|
||||||
|
return cluster
|
||||||
|
|
||||||
|
|
||||||
|
def terminate_cluster(**args):
|
||||||
|
cluster = get_cluster(**args)
|
||||||
|
DB.session.delete(cluster)
|
||||||
|
DB.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def update_cluster_status(new_status, **args):
|
||||||
|
cluster = Cluster.query.filter_by(**args).first()
|
||||||
|
cluster.status = new_status
|
||||||
|
DB.session.add(cluster)
|
||||||
|
DB.session.commit()
|
||||||
|
|
||||||
|
return cluster
|
||||||
|
|
||||||
|
|
||||||
|
## Node Process ops:
|
||||||
|
|
||||||
|
def create_node_process(name, properties):
|
||||||
|
"""
|
||||||
|
Creates new node process and node process properties
|
||||||
|
:param name: process name
|
||||||
|
:param properties: array of triples (name, required, default)
|
||||||
|
:return: created node process
|
||||||
|
"""
|
||||||
|
process = NodeProcess(name)
|
||||||
|
DB.session.add(process)
|
||||||
|
DB.session.commit()
|
||||||
|
for p in properties:
|
||||||
|
prop = NodeProcessProperty(process.id, p[0], p[1], p[2])
|
||||||
|
DB.session.add(prop)
|
||||||
|
DB.session.commit()
|
||||||
|
|
||||||
|
return process
|
||||||
|
|
||||||
|
|
||||||
|
## Node Type ops:
|
||||||
|
|
||||||
|
def get_node_type(**args):
|
||||||
|
return NodeType.query.filter_by(**args).first()
|
||||||
|
|
||||||
|
|
||||||
|
def create_node_type(name, processes):
|
||||||
|
"""
|
||||||
|
Creates new node type using specified list of processes
|
||||||
|
:param name:
|
||||||
|
:param processes:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
node_type = NodeType(name)
|
||||||
|
node_type.processes = processes
|
||||||
|
DB.session.add(node_type)
|
||||||
|
DB.session.commit()
|
||||||
|
|
||||||
|
return node_type
|
||||||
|
@ -26,7 +26,7 @@ from savanna.main import make_app
|
|||||||
from savanna.service import api
|
from savanna.service import api
|
||||||
from savanna.storage.defaults import setup_defaults
|
from savanna.storage.defaults import setup_defaults
|
||||||
from savanna.storage.models import Node, NodeTemplate
|
from savanna.storage.models import Node, NodeTemplate
|
||||||
from savanna.storage.storage import DB
|
from savanna.storage.db import DB
|
||||||
import savanna.main
|
import savanna.main
|
||||||
from savanna.utils import scheduler
|
from savanna.utils import scheduler
|
||||||
from savanna.openstack.common import log as logging
|
from savanna.openstack.common import log as logging
|
||||||
@ -85,8 +85,8 @@ def _stub_auth_valid(*args, **kwargs):
|
|||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
CONF.import_opt('debug', 'savanna.openstack.common.log')
|
CONF.import_opt('debug', 'savanna.openstack.common.log')
|
||||||
CONF.import_opt('allow_cluster_ops', 'savanna.config')
|
CONF.import_opt('allow_cluster_ops', 'savanna.config')
|
||||||
CONF.import_opt('database_uri', 'savanna.storage.storage', group='sqlalchemy')
|
CONF.import_opt('database_uri', 'savanna.storage.db', group='sqlalchemy')
|
||||||
CONF.import_opt('echo', 'savanna.storage.storage', group='sqlalchemy')
|
CONF.import_opt('echo', 'savanna.storage.db', group='sqlalchemy')
|
||||||
|
|
||||||
|
|
||||||
class TestApi(unittest.TestCase):
|
class TestApi(unittest.TestCase):
|
||||||
|
Loading…
Reference in New Issue
Block a user