database layer
Change-Id: I6ff5e8773e8eb158e61f5eead8b1c76f7e4df834
This commit is contained in:
parent
40b32e8273
commit
363a76281d
|
@ -1,8 +1,6 @@
|
|||
===============================
|
||||
namos
|
||||
===============================
|
||||
|
||||
OpenStack Service, Device manager
|
||||
=========================
|
||||
namos - OpenStack manager
|
||||
=========================
|
||||
|
||||
* Free software: Apache license
|
||||
* Documentation: http://docs.openstack.org/developer/namos
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
[database]
|
||||
connection = mysql+pymysql://root:password@172.241.0.101/namos?charset=utf8
|
|
@ -0,0 +1,110 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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 sys
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from namos.common import config
|
||||
from namos.db import sample
|
||||
from namos.db.sqlalchemy import migration
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
MANAGE_COMMAND_NAME = 'namos-manage'
|
||||
|
||||
|
||||
class DBCommand(object):
|
||||
|
||||
def upgrade(self):
|
||||
migration.upgrade(CONF.command.revision)
|
||||
|
||||
def downgrade(self):
|
||||
migration.downgrade(CONF.command.revision)
|
||||
|
||||
def revision(self):
|
||||
migration.revision(CONF.command.message, CONF.command.autogenerate)
|
||||
|
||||
def stamp(self):
|
||||
migration.stamp(CONF.command.revision)
|
||||
|
||||
def version(self):
|
||||
print(migration.version())
|
||||
|
||||
def create_schema(self):
|
||||
migration.create_schema()
|
||||
|
||||
def history(self):
|
||||
migration.history()
|
||||
|
||||
def demo_data(self):
|
||||
if CONF.command.purge:
|
||||
sample.purge_demo_data()
|
||||
else:
|
||||
sample.populate_demo_data()
|
||||
|
||||
|
||||
def add_command_parsers(subparsers):
|
||||
command_object = DBCommand()
|
||||
|
||||
parser = subparsers.add_parser('upgrade')
|
||||
parser.set_defaults(func=command_object.upgrade)
|
||||
parser.add_argument('--revision', nargs='?')
|
||||
|
||||
parser = subparsers.add_parser('downgrade')
|
||||
parser.set_defaults(func=command_object.downgrade)
|
||||
parser.add_argument('--revision', nargs='?')
|
||||
|
||||
parser = subparsers.add_parser('stamp')
|
||||
parser.add_argument('--revision', nargs='?')
|
||||
parser.set_defaults(func=command_object.stamp)
|
||||
|
||||
parser = subparsers.add_parser('revision')
|
||||
parser.add_argument('-m', '--message')
|
||||
parser.add_argument('--autogenerate', action='store_true')
|
||||
parser.set_defaults(func=command_object.revision)
|
||||
|
||||
parser = subparsers.add_parser('version')
|
||||
parser.set_defaults(func=command_object.version)
|
||||
|
||||
parser = subparsers.add_parser('history')
|
||||
parser.set_defaults(func=command_object.history)
|
||||
|
||||
parser = subparsers.add_parser('create_schema')
|
||||
parser.set_defaults(func=command_object.create_schema)
|
||||
|
||||
parser = subparsers.add_parser('demo_data')
|
||||
parser.add_argument('-p', '--purge', action='store_true')
|
||||
parser.set_defaults(func=command_object.demo_data)
|
||||
|
||||
|
||||
command_opt = cfg.SubCommandOpt('command',
|
||||
title='Command',
|
||||
help='Available commands',
|
||||
handler=add_command_parsers)
|
||||
|
||||
CONF.register_cli_opt(command_opt)
|
||||
# olso mandates to initialize the config after cli opt registration
|
||||
config.init_conf(prog=MANAGE_COMMAND_NAME)
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
CONF.command.func()
|
||||
except Exception as e:
|
||||
sys.exit("ERROR: %s" % e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,36 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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 oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
import namos
|
||||
|
||||
PROJECT_NAME = 'namos'
|
||||
VERSION = namos.__version__
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
def init_conf(prog):
|
||||
CONF(project=PROJECT_NAME,
|
||||
version=VERSION,
|
||||
prog=prog)
|
||||
|
||||
|
||||
def setup_log(prog=PROJECT_NAME):
|
||||
logging.register_options(cfg.CONF)
|
||||
logging.setup(cfg.CONF,
|
||||
prog,
|
||||
version=VERSION)
|
|
@ -0,0 +1,121 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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 json
|
||||
import logging
|
||||
import six
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NamosException(Exception):
|
||||
msg_fmt = ("An unknown exception occurred.")
|
||||
message = None
|
||||
error_code = None
|
||||
http_status_code = None
|
||||
data = {}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.kwargs = kwargs
|
||||
|
||||
try:
|
||||
if kwargs.get('message') is not None:
|
||||
self.message = kwargs['message']
|
||||
else:
|
||||
self.message = json.dumps(
|
||||
{'error_code': self.error_code,
|
||||
'message': self.msg_fmt % kwargs,
|
||||
'http_code': self.http_status_code,
|
||||
'data': kwargs})
|
||||
if kwargs.get('data') is not None:
|
||||
self.data = kwargs['data']
|
||||
except KeyError:
|
||||
self.message = self.msg_fmt
|
||||
LOG.exception(('Exception in string format operation'))
|
||||
for name, value in six.iteritems(kwargs):
|
||||
LOG.error("%s: %s" % (name, value)) # noqa
|
||||
|
||||
def __str__(self):
|
||||
return unicode(self.message).encode('UTF-8')
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.message)
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
return self.__class__(**self.kwargs)
|
||||
|
||||
|
||||
class NotFound(NamosException):
|
||||
msg_fmt = ("Not Found")
|
||||
error_code = -1
|
||||
http_status_code = 404
|
||||
|
||||
|
||||
class RegionNotFound(NotFound):
|
||||
msg_fmt = ("Region %(region_id)s does not found")
|
||||
error_code = 0x01001
|
||||
|
||||
|
||||
class RegionAlreadyExist(NamosException):
|
||||
msg_fmt = ("Region %(region_id)s already exists")
|
||||
error_code = 0x01002
|
||||
http_status_code = 403
|
||||
|
||||
|
||||
class DeviceNotFound(NotFound):
|
||||
msg_fmt = ("Device %(device_id)s does not found")
|
||||
error_code = 0x02001
|
||||
|
||||
|
||||
class DeviceEndpointNotFound(NotFound):
|
||||
msg_fmt = ("Device Endpoint %(device_endpoint_id)s does not found")
|
||||
error_code = 0x03001
|
||||
|
||||
|
||||
class DeviceDriverNotFound(NotFound):
|
||||
msg_fmt = ("Device Driver %(device_driver_id)s does not found")
|
||||
error_code = 0x04001
|
||||
|
||||
|
||||
class DeviceDriverClassNotFound(NotFound):
|
||||
msg_fmt = ("Device Driver Class %(device_driver_class_id)s "
|
||||
"does not found")
|
||||
error_code = 0x05001
|
||||
|
||||
|
||||
class ServiceNotFound(NotFound):
|
||||
msg_fmt = ("Service %(service_id)s does not found")
|
||||
error_code = 0x06001
|
||||
|
||||
|
||||
class ServiceNodeNotFound(NotFound):
|
||||
msg_fmt = ("Service Node %(service_node_id)s does not found")
|
||||
error_code = 0x07001
|
||||
|
||||
|
||||
class ServiceComponentNotFound(NotFound):
|
||||
msg_fmt = ("Service Component %(service_component_id)s does not found")
|
||||
error_code = 0x08001
|
||||
|
||||
|
||||
class ServiceWorkerNotFound(NotFound):
|
||||
msg_fmt = ("Service Worker %(service_worker_id)s "
|
||||
"does not found")
|
||||
error_code = 0x09001
|
||||
|
||||
|
||||
class ConfigNotFound(NotFound):
|
||||
msg_fmt = ("Config %(config_id)s does not found")
|
||||
error_code = 0x0a001
|
|
@ -0,0 +1,367 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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 oslo_config import cfg
|
||||
from oslo_db import api
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
_BACKEND_MAPPING = {'sqlalchemy': 'namos.db.sqlalchemy.api'}
|
||||
|
||||
IMPL = api.DBAPI.from_config(CONF, backend_mapping=_BACKEND_MAPPING)
|
||||
|
||||
|
||||
def get_engine():
|
||||
return IMPL.get_engine()
|
||||
|
||||
|
||||
def get_session():
|
||||
return IMPL.get_session()
|
||||
|
||||
|
||||
# TODO(kanagaraj-manickam): Add db wrapper function to capture the db
|
||||
# exception in each of the below methods and log it
|
||||
|
||||
# Region
|
||||
|
||||
def region_create(context, values):
|
||||
return IMPL.region_create(context, values)
|
||||
|
||||
|
||||
def region_update(context, _id, values):
|
||||
return IMPL.region_update(context, _id, values)
|
||||
|
||||
|
||||
def region_get(context, _id):
|
||||
return IMPL.region_get(context, _id)
|
||||
|
||||
|
||||
def region_get_by_name(context, name):
|
||||
return IMPL.region_get_by_name(context, name)
|
||||
|
||||
|
||||
def region_get_all(context):
|
||||
return IMPL.region_get_all(context)
|
||||
|
||||
|
||||
def region_delete(context, _id):
|
||||
return IMPL.region_delete(context, _id)
|
||||
|
||||
|
||||
# Device
|
||||
|
||||
def device_create(context, values):
|
||||
return IMPL.device_create(context, values)
|
||||
|
||||
|
||||
def device_update(context, _id, values):
|
||||
return IMPL.device_update(context, _id, values)
|
||||
|
||||
|
||||
def device_get(context, _id):
|
||||
return IMPL.device_get(context, _id)
|
||||
|
||||
|
||||
def device_get_by_name(context, name):
|
||||
return IMPL.device_get_by_name(context, name)
|
||||
|
||||
|
||||
def device_get_all(context):
|
||||
return IMPL.device_get_all(context)
|
||||
|
||||
|
||||
def device_delete(context, _id):
|
||||
return IMPL.device_delete(context, _id)
|
||||
|
||||
|
||||
# Device Endpoint
|
||||
|
||||
def device_endpoint_create(context, values):
|
||||
return IMPL.device_endpoint_create(context, values)
|
||||
|
||||
|
||||
def device_endpoint_update(context, _id, values):
|
||||
return IMPL.device_endpoint_update(context, _id, values)
|
||||
|
||||
|
||||
def device_endpoint_get(context, _id):
|
||||
return IMPL.device_endpoint_get(context, _id)
|
||||
|
||||
|
||||
def device_endpoint_get_by_name(context, name):
|
||||
return IMPL.device_endpoint_get_by_name(context, name)
|
||||
|
||||
|
||||
def device_endpoint_get_by_device_type(context,
|
||||
device_id,
|
||||
type=None,
|
||||
name=None):
|
||||
return IMPL.device_endpoint_get_by_device_type(context, device_id,
|
||||
type, name)
|
||||
|
||||
|
||||
def device_endpoint_get_all(context):
|
||||
return IMPL.device_endpoint_get_all(context)
|
||||
|
||||
|
||||
def device_endpoint_delete(context, _id):
|
||||
return IMPL.device_endpoint_delete(context, _id)
|
||||
|
||||
|
||||
# Device Driver
|
||||
|
||||
def device_driver_create(context, values):
|
||||
return IMPL.device_driver_create(context, values)
|
||||
|
||||
|
||||
def device_driver_update(context, _id, values):
|
||||
return IMPL.device_driver_update(context, _id, values)
|
||||
|
||||
|
||||
def device_driver_get(context, _id):
|
||||
return IMPL.device_driver_get(context, _id)
|
||||
|
||||
|
||||
def device_driver_get_by_name(context, name):
|
||||
return IMPL.device_driver_get_by_name(context, name)
|
||||
|
||||
|
||||
def device_driver_get_by_device_endpoint_service_worker(
|
||||
context,
|
||||
device_id=None,
|
||||
endpoint_id=None,
|
||||
device_driver_class_id=None,
|
||||
service_worker_id=None):
|
||||
return IMPL.device_driver_get_by_device_endpoint_service_worker(
|
||||
context,
|
||||
device_id,
|
||||
endpoint_id,
|
||||
device_driver_class_id,
|
||||
service_worker_id)
|
||||
|
||||
|
||||
def device_driver_get_all(context):
|
||||
return IMPL.device_driver_get_all(context)
|
||||
|
||||
|
||||
def device_driver_delete(context, _id):
|
||||
return IMPL.device_driver_delete(context, _id)
|
||||
|
||||
|
||||
# Device Driver Class
|
||||
|
||||
def device_driver_class_create(context, values):
|
||||
return IMPL.device_driver_class_create(context, values)
|
||||
|
||||
|
||||
def device_driver_class_update(context, _id, values):
|
||||
return IMPL.device_driver_class_update(context, _id, values)
|
||||
|
||||
|
||||
def device_driver_class_get(context, _id):
|
||||
return IMPL.device_driver_class_get(context, _id)
|
||||
|
||||
|
||||
def device_driver_class_get_by_name(context, name):
|
||||
return IMPL.device_driver_class_get_by_name(context, name)
|
||||
|
||||
|
||||
def device_driver_class_get_all(context):
|
||||
return IMPL.device_driver_class_get_all(context)
|
||||
|
||||
|
||||
def device_driver_class_delete(context, _id):
|
||||
return IMPL.device_driver_class_delete(context, _id)
|
||||
|
||||
|
||||
# Service
|
||||
|
||||
def service_create(context, values):
|
||||
return IMPL.service_create(context, values)
|
||||
|
||||
|
||||
def service_update(context, _id, values):
|
||||
return IMPL.service_update(context, _id, values)
|
||||
|
||||
|
||||
def service_get(context, _id):
|
||||
return IMPL.service_get(context, _id)
|
||||
|
||||
|
||||
def service_get_by_name(context, name):
|
||||
return IMPL.service_get_by_name(context, name)
|
||||
|
||||
|
||||
def service_get_all(context):
|
||||
return IMPL.service_get_all(context)
|
||||
|
||||
|
||||
def service_delete(context, _id):
|
||||
return IMPL.service_delete(context, _id)
|
||||
|
||||
|
||||
# Service Node
|
||||
|
||||
def service_node_create(context, values):
|
||||
return IMPL.service_node_create(context, values)
|
||||
|
||||
|
||||
def service_node_update(context, _id, values):
|
||||
return IMPL.service_node_update(context, _id, values)
|
||||
|
||||
|
||||
def service_node_get(context, _id):
|
||||
return IMPL.service_node_get(context, _id)
|
||||
|
||||
|
||||
def service_node_get_by_name(context, name):
|
||||
return IMPL.service_node_get_by_name(context, name)
|
||||
|
||||
|
||||
def service_node_get_all(context):
|
||||
return IMPL.service_node_get_all(context)
|
||||
|
||||
|
||||
def service_node_delete(context, _id):
|
||||
return IMPL.service_node_delete(context, _id)
|
||||
|
||||
|
||||
# Service Component
|
||||
|
||||
def service_component_create(context, values):
|
||||
return IMPL.service_component_create(context, values)
|
||||
|
||||
|
||||
def service_component_update(context, _id, values):
|
||||
return IMPL.service_component_update(context, _id, values)
|
||||
|
||||
|
||||
def service_component_get(context, _id):
|
||||
return IMPL.service_component_get(context, _id)
|
||||
|
||||
|
||||
def service_component_get_by_name(context, name):
|
||||
return IMPL.service_component_get_by_name(context, name)
|
||||
|
||||
|
||||
def service_component_get_all_by_node_for_service(context,
|
||||
node_id,
|
||||
service_id=None,
|
||||
name=None):
|
||||
return IMPL.service_component_get_all_by_node_for_service(context,
|
||||
node_id,
|
||||
service_id,
|
||||
name)
|
||||
|
||||
|
||||
def service_component_get_all(context):
|
||||
return IMPL.service_component_get_all(context)
|
||||
|
||||
|
||||
def service_component_delete(context, _id):
|
||||
return IMPL.service_component_delete(context, _id)
|
||||
|
||||
|
||||
# Service Worker
|
||||
def service_worker_create(context, values):
|
||||
return IMPL.service_worker_create(context, values)
|
||||
|
||||
|
||||
def service_worker_update(context, _id, values):
|
||||
return IMPL.service_worker_update(context, _id, values)
|
||||
|
||||
|
||||
def service_worker_get(context, _id):
|
||||
return IMPL.service_worker_get(context, _id)
|
||||
|
||||
|
||||
def service_worker_get_by_name(context, name):
|
||||
return IMPL.service_worker_get_by_name(context, name)
|
||||
|
||||
|
||||
def service_worker_get_by_host_for_service_component(context,
|
||||
service_component_id,
|
||||
host=None):
|
||||
return IMPL.service_worker_get_by_host_for_service_component(
|
||||
context,
|
||||
service_component_id,
|
||||
host)
|
||||
|
||||
|
||||
def service_worker_get_all(context):
|
||||
return IMPL.service_worker_get_all(context)
|
||||
|
||||
|
||||
def service_worker_delete(context, _id):
|
||||
return IMPL.service_worker_delete(context, _id)
|
||||
|
||||
|
||||
# Config
|
||||
|
||||
def config_create(context, values):
|
||||
return IMPL.config_create(context, values)
|
||||
|
||||
|
||||
def config_update(context, _id, values):
|
||||
return IMPL.config_update(context, _id, values)
|
||||
|
||||
|
||||
def config_get(context, _id):
|
||||
return IMPL.config_get(context, _id)
|
||||
|
||||
|
||||
def config_get_by_name(context, name):
|
||||
return IMPL.config_get_by_name(context, name)
|
||||
|
||||
|
||||
def config_get_by_name_for_service_worker(context,
|
||||
service_worker_id,
|
||||
name=None):
|
||||
return IMPL.config_get_by_name_for_service_worker(context,
|
||||
service_worker_id,
|
||||
name)
|
||||
|
||||
|
||||
def config_get_all(context):
|
||||
return IMPL.config_get_all(context)
|
||||
|
||||
|
||||
def config_delete(context, _id):
|
||||
return IMPL.config_delete(context, _id)
|
||||
|
||||
|
||||
def service_perspective_get(context, service_id,
|
||||
include_details=False):
|
||||
return IMPL.service_perspective_get(context,
|
||||
service_id,
|
||||
include_details)
|
||||
|
||||
|
||||
def device_perspective_get(context, device_id,
|
||||
include_details=False):
|
||||
return IMPL.device_perspective_get(context,
|
||||
device_id,
|
||||
include_details)
|
||||
|
||||
|
||||
def region_perspective_get(context, region_id,
|
||||
include_details=False):
|
||||
return IMPL.region_perspective_get(context,
|
||||
region_id,
|
||||
include_details)
|
||||
|
||||
|
||||
def infra_perspective_get(context):
|
||||
return IMPL.infra_perspective_get(context)
|
|
@ -0,0 +1,18 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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.
|
||||
|
||||
"""Database setup and migration commands."""
|
||||
|
||||
# TODO(kanagaraj-manickam) Introduce the abstraction here and consume it
|
||||
# in db_sync to make the db backend as portable
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,444 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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 namos.db import api
|
||||
|
||||
REGION_LIST = [
|
||||
{'f7dcd175-27ef-46b5-997f-e6e572f320af':
|
||||
{'name': 'RegionOne',
|
||||
'keystone_region_id': 'region_one',
|
||||
'extra': {'location': 'bangalore'}}
|
||||
},
|
||||
{'f7dcd175-27ef-46b5-997f-e6e572f320b0':
|
||||
{'name': 'RegionTwo',
|
||||
'keystone_region_id': 'region_two',
|
||||
'extra': {'location': 'chennai'}}
|
||||
}
|
||||
]
|
||||
|
||||
DEVICE_LIST = [
|
||||
# vCenter
|
||||
{'91007d3c-9c95-40c5-8f94-c7b071f9b577':
|
||||
{
|
||||
'name': 'Vmware_vCenter_1',
|
||||
'display_name': 'VMWare vCenter 1',
|
||||
'description': 'vCenter 5.0',
|
||||
'status': 'active',
|
||||
'extra': {'owner': 'mkr1481@namos.com'},
|
||||
'region_id': 'f7dcd175-27ef-46b5-997f-e6e572f320af'}
|
||||
},
|
||||
# Clusters
|
||||
{'d468ea2e-74f6-4a55-a7f4-a56d18e91c66':
|
||||
{
|
||||
'name': 'vmware_vc_Cluster_1',
|
||||
'display_name': 'VMWare vCenter 1 Cluster 1',
|
||||
'description': 'Cluster 1 having 3 hosts',
|
||||
'status': 'active',
|
||||
'extra': {'owner': 'mkr1481@namos.com',
|
||||
'vcpus': 1000,
|
||||
'ram_in_gb': 1024},
|
||||
'parent_id': '91007d3c-9c95-40c5-8f94-c7b071f9b577',
|
||||
'region_id': 'f7dcd175-27ef-46b5-997f-e6e572f320af'}
|
||||
},
|
||||
{'6c97f476-8e27-4e21-8528-a5ec236306f3':
|
||||
{'name': 'vmware_vc_Cluster_2',
|
||||
'display_name': 'VMWare vCenter 1 Cluster 2',
|
||||
'description': 'Cluster 2 having 5 hosts',
|
||||
'status': 'active',
|
||||
'extra': {'owner': 'mkr1481@namos.com'},
|
||||
'parent_id': '91007d3c-9c95-40c5-8f94-c7b071f9b577',
|
||||
'region_id': 'f7dcd175-27ef-46b5-997f-e6e572f320af'}
|
||||
},
|
||||
# Datastores
|
||||
{'fdab6c51-38fb-4fb1-a76f-9c243a8b8296':
|
||||
{'name': 'Vmware_vCenter_1_datastore_1',
|
||||
'display_name': 'VMWare vCenter 1 datastore 1',
|
||||
'description': 'vCenter 5.0 Datastore created from FC',
|
||||
'status': 'active',
|
||||
'extra': {'owner': 'mkr1481@namos.com',
|
||||
'size_in_gb': '102400'},
|
||||
'parent_id': '91007d3c-9c95-40c5-8f94-c7b071f9b577',
|
||||
'region_id': 'f7dcd175-27ef-46b5-997f-e6e572f320af'}
|
||||
},
|
||||
{'05b935b3-942c-439c-a6a4-9c3c73285430':
|
||||
{'name': 'Vmware_vCenter_1_datastore_2',
|
||||
'display_name': 'VMWare vCenter 1 datastore 2',
|
||||
'description': 'vCenter 5.0 Datastore created from FC',
|
||||
'status': 'active',
|
||||
'extra': {'owner': 'mkr1481@namos.com',
|
||||
'size_in_gb': '10240'},
|
||||
'parent_id': '91007d3c-9c95-40c5-8f94-c7b071f9b577',
|
||||
'region_id': 'f7dcd175-27ef-46b5-997f-e6e572f320af'}
|
||||
},
|
||||
# Switch
|
||||
{'f062556b-45c4-417d-80fa-4283b9c58da3':
|
||||
{'name': 'Vmware_vCenter_1_switch_1',
|
||||
'display_name': 'VMWare vCenter 1 Dist. vSwitch 1',
|
||||
'description': 'vCenter 5.0 distributed virtual switch',
|
||||
'status': 'active',
|
||||
'extra': {'owner': 'mkr1481@namos.com'},
|
||||
'parent_id': '91007d3c-9c95-40c5-8f94-c7b071f9b577',
|
||||
'region_id': 'f7dcd175-27ef-46b5-997f-e6e572f320af'}
|
||||
}
|
||||
]
|
||||
|
||||
ENDPOINT_LIST = [
|
||||
{'7403bf80-9376-4081-89ee-d2501661ca84':{
|
||||
'name': 'vcenter1_connection',
|
||||
'connection': {'host_ip': '10.1.1.3',
|
||||
'host_port': 443,
|
||||
'host_username': 'adminstrator',
|
||||
'host_password': 'password'},
|
||||
'device_id': '91007d3c-9c95-40c5-8f94-c7b071f9b577'
|
||||
}}
|
||||
]
|
||||
|
||||
|
||||
DEVICE_DRIVER_CLASS_LIST = [
|
||||
{'0664e8c0-ff02-427e-8fa3-8788c017ad84': {
|
||||
'python_class': 'nova...vcdriver',
|
||||
'type': 'compute',
|
||||
'vendor': 'vmware-community'
|
||||
}},
|
||||
{'11caf99c-f820-4266-a461-5a15437a8144': {
|
||||
'python_class': 'cinder...vmdkdriver',
|
||||
'type': 'volume',
|
||||
'vendor': 'vmware-community'
|
||||
}},
|
||||
{'bb99ea96-fe6b-49e6-a761-faea92b79f75': {
|
||||
'python_class': 'neutron...nsxdriver',
|
||||
'type': 'network',
|
||||
'vendor': 'vmware-community'
|
||||
}}
|
||||
]
|
||||
|
||||
DEVICE_DRIVER_LIST = [
|
||||
# nova
|
||||
{'3c089cdb-e1d5-4182-9a8e-cef9899fd7e5':{
|
||||
'endpoint_id': '7403bf80-9376-4081-89ee-d2501661ca84',
|
||||
'device_driver_class_id':'0664e8c0-ff02-427e-8fa3-8788c017ad84',
|
||||
'device_id': 'd468ea2e-74f6-4a55-a7f4-a56d18e91c66'
|
||||
}},
|
||||
# nova
|
||||
{'4e0360ae-0728-4bfd-a557-3ad867231787':{
|
||||
'endpoint_id': '7403bf80-9376-4081-89ee-d2501661ca84',
|
||||
'device_driver_class_id':'0664e8c0-ff02-427e-8fa3-8788c017ad84',
|
||||
'device_id': '6c97f476-8e27-4e21-8528-a5ec236306f3'
|
||||
}},
|
||||
# cinder
|
||||
{'92d5e2c1-511b-4837-a57d-5e6ee723060c':{
|
||||
'endpoint_id': '7403bf80-9376-4081-89ee-d2501661ca84',
|
||||
'device_driver_class_id':'11caf99c-f820-4266-a461-5a15437a8144',
|
||||
'device_id': 'fdab6c51-38fb-4fb1-a76f-9c243a8b8296'
|
||||
}},
|
||||
# cinder
|
||||
{'f3d807a0-eff0-4473-8ae5-594967136e05':{
|
||||
'endpoint_id': '7403bf80-9376-4081-89ee-d2501661ca84',
|
||||
'python_class_id':'11caf99c-f820-4266-a461-5a15437a8144',
|
||||
'device_id': '05b935b3-942c-439c-a6a4-9c3c73285430'
|
||||
}},
|
||||
# neutron
|
||||
{'f27eb548-929c-45e2-a2a7-dc123e2a1bc7':{
|
||||
'endpoint_id': '7403bf80-9376-4081-89ee-d2501661ca84',
|
||||
'python_class_id':'bb99ea96-fe6b-49e6-a761-faea92b79f75',
|
||||
'device_id': 'f062556b-45c4-417d-80fa-4283b9c58da3'
|
||||
}}
|
||||
]
|
||||
|
||||
|
||||
SERVICE_LIST =[
|
||||
{'11367a37-976f-468a-b8dd-77b28ee63cf4': {
|
||||
'name': 'nova_service',
|
||||
'keystone_service_id': 'b9c2549f-f685-4bc2-92e9-ba8af9c18599'
|
||||
}},
|
||||
{'809e04c1-2f3b-43af-9677-3428a0154216': {
|
||||
'name': 'cinder_service',
|
||||
'keystone_service_id': '9cc4c374-abb5-4bdc-9129-f0fa4bba0e0b'
|
||||
}},
|
||||
{'3495fa07-39d9-4d87-9f97-0a582a3e25c3': {
|
||||
'name': 'neutron_service',
|
||||
'keystone_service_id': 'b24e2884-75bc-4876-81d1-5b4fb6e92afc'
|
||||
}}
|
||||
]
|
||||
|
||||
SERVICE_NODE_LIST = [
|
||||
{
|
||||
'a5073d58-2dbb-4146-b47c-4e5f7dc11fbe': {
|
||||
'name': 'd_network_node_1',
|
||||
'fqdn': 'network_node_1.devstack1.abc.com',
|
||||
'region_id': 'f7dcd175-27ef-46b5-997f-e6e572f320af'
|
||||
}
|
||||
},
|
||||
{
|
||||
'4e99a641-dbe9-416e-8c0a-78015dc55a2a': {
|
||||
'name': 'd_compute_node_1',
|
||||
'fqdn': 'compute_node_1.devstack.abc.com',
|
||||
'region_id': 'f7dcd175-27ef-46b5-997f-e6e572f320af'
|
||||
}
|
||||
},
|
||||
{
|
||||
'b92f4811-7970-421b-a611-d51c62972388': {
|
||||
'name': 'd_cloud-controller-1',
|
||||
'fqdn': 'cloud_controller_1.devstack1.abc.com',
|
||||
'region_id': 'f7dcd175-27ef-46b5-997f-e6e572f320af'
|
||||
}
|
||||
},
|
||||
{
|
||||
'e5913cd3-a416-40e1-889f-1a1b1c53001c': {
|
||||
'name': 'd_storage_node_1',
|
||||
'fqdn': 'storage_node_1.devstack.abc.com',
|
||||
'region_id': 'f7dcd175-27ef-46b5-997f-e6e572f320af'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
SERVICE_COMPONENT_LIST = [
|
||||
# nova
|
||||
{
|
||||
'7259a9ff-2e6f-4e8d-b2fb-a529188825dd': {
|
||||
'name': 'd_nova-compute',
|
||||
'node_id': '4e99a641-dbe9-416e-8c0a-78015dc55a2a',
|
||||
'service_id': '11367a37-976f-468a-b8dd-77b28ee63cf4'
|
||||
}
|
||||
},
|
||||
{
|
||||
'e5e366ea-9029-4ba0-8bbc-f658e642aa54': {
|
||||
'name': 'd_nova-scheduler',
|
||||
'node_id': 'b92f4811-7970-421b-a611-d51c62972388',
|
||||
'service_id': '11367a37-976f-468a-b8dd-77b28ee63cf4'
|
||||
}
|
||||
},
|
||||
{
|
||||
'f7813622-85ee-4588-871d-42c3128fa14f': {
|
||||
'name': 'd_nova-api',
|
||||
'node_id': 'b92f4811-7970-421b-a611-d51c62972388',
|
||||
'service_id': '11367a37-976f-468a-b8dd-77b28ee63cf4'
|
||||
}
|
||||
},
|
||||
# cinder
|
||||
{
|
||||
'b0e9ac3f-5600-406c-95e4-f698b1eecfc6': {
|
||||
'name': 'd_cinder-volume',
|
||||
'node_id': 'e5913cd3-a416-40e1-889f-1a1b1c53001c',
|
||||
'service_id': '809e04c1-2f3b-43af-9677-3428a0154216'
|
||||
}
|
||||
},
|
||||
# neutron
|
||||
{
|
||||
'54f608bd-fb01-4614-9653-acbb803aeaf7':{
|
||||
'name': 'd_neutron-agent',
|
||||
'node_id': 'a5073d58-2dbb-4146-b47c-4e5f7dc11fbe',
|
||||
'service_id': '3495fa07-39d9-4d87-9f97-0a582a3e25c3'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
SERVICE_WORKER_LIST = [
|
||||
# cluster-1
|
||||
{
|
||||
'65dbd695-fa92-4950-b8b4-d46aa0408f6a': {
|
||||
'name': 'd_nova-compute-esx-cluster1',
|
||||
'pid': '1233454343',
|
||||
'host': 'd_nova-compute-esx-cluster1',
|
||||
'service_component_id': '7259a9ff-2e6f-4e8d-b2fb-a529188825dd',
|
||||
'device_driver_id': '3c089cdb-e1d5-4182-9a8e-cef9899fd7e5'
|
||||
}
|
||||
},
|
||||
# cluster-2
|
||||
{
|
||||
'50d2c0c6-741d-4108-a3a2-2090eaa0be37': {
|
||||
'name': 'd_nova-compute-esx-cluster2',
|
||||
'pid': '1233454344',
|
||||
'host': 'd_nova-compute-esx-cluster2',
|
||||
'service_component_id': '7259a9ff-2e6f-4e8d-b2fb-a529188825dd',
|
||||
'device_driver_id': '4e0360ae-0728-4bfd-a557-3ad867231787'
|
||||
}
|
||||
},
|
||||
# datastore-1
|
||||
{
|
||||
'77e3ee16-fa2b-4e12-ad1c-226971d1a482': {
|
||||
'name': 'd_cinder-volume-vmdk-1',
|
||||
'pid': '09878654',
|
||||
'host': 'd_cinder-volume-vmdk-1',
|
||||
'service_component_id': 'b0e9ac3f-5600-406c-95e4-f698b1eecfc6',
|
||||
'device_driver_id': '92d5e2c1-511b-4837-a57d-5e6ee723060c'
|
||||
}
|
||||
},
|
||||
# datastore-2
|
||||
{
|
||||
'8633ce68-2b02-4efd-983c-49a460f6d7ef': {
|
||||
'name': 'd_cinder-volume-vmdk-2',
|
||||
'pid': '4353453',
|
||||
'host': 'd_cinder-volume-vmdk-2',
|
||||
'service_component_id': 'b0e9ac3f-5600-406c-95e4-f698b1eecfc6',
|
||||
'device_driver_id': 'f3d807a0-eff0-4473-8ae5-594967136e05'
|
||||
}
|
||||
},
|
||||
# vswitch
|
||||
{
|
||||
'5a3ac5b9-9186-45d8-928c-9e702368dfb4': {
|
||||
'name': 'd_neutron-agent',
|
||||
'pid': '2359234',
|
||||
'host': 'd_neutron-agent',
|
||||
'service_component_id': '54f608bd-fb01-4614-9653-acbb803aeaf7',
|
||||
'device_driver_id': 'f27eb548-929c-45e2-a2a7-dc123e2a1bc7'
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
CONFIG_LIST = [
|
||||
{
|
||||
'dc6aa02f-ba70-4410-a59c-5e113e629fe5': {
|
||||
'name':'vmware.host_ip',
|
||||
'value':'10.1.0.1',
|
||||
'help': 'VMWare vcenter IP address',
|
||||
'default':'',
|
||||
'type':'String',
|
||||
'required':True,
|
||||
'secret': False,
|
||||
'config_file':'/etc/nova/nova.conf',
|
||||
'service_worker_id': '65dbd695-fa92-4950-b8b4-d46aa0408f6a'
|
||||
}
|
||||
},
|
||||
{
|
||||
'dc6aa02f-ba70-4410-a59c-5e113e629f10': {
|
||||
'name':'vmware.host_username',
|
||||
'value':'Administraotr',
|
||||
'help': 'VMWare vcenter Username',
|
||||
'default':'Administrator',
|
||||
'type':'String',
|
||||
'required':True,
|
||||
'secret': False,
|
||||
'file':'/etc/nova/nova.conf',
|
||||
'service_worker_id': '65dbd695-fa92-4950-b8b4-d46aa0408f6a'
|
||||
}
|
||||
},
|
||||
{
|
||||
'dc6aa02f-ba70-4410-a59c-5e113e629f11': {
|
||||
'name':'vmware.host_password',
|
||||
'value':'password',
|
||||
'help': 'VMWare vcenter password',
|
||||
'default':'',
|
||||
'type':'String',
|
||||
'required':True,
|
||||
'secret': True,
|
||||
'file':'/etc/nova/nova.conf',
|
||||
'service_worker_id': '65dbd695-fa92-4950-b8b4-d46aa0408f6a'
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def inject_id(value):
|
||||
if isinstance(value, dict):
|
||||
_id = value.keys()[0]
|
||||
value1 = value[_id].copy()
|
||||
value1['id'] = _id
|
||||
|
||||
return value1
|
||||
return value
|
||||
|
||||
|
||||
def _device_populate_demo_data():
|
||||
for region in REGION_LIST:
|
||||
region = inject_id(region)
|
||||
api.region_create(None, region)
|
||||
|
||||
for device in DEVICE_LIST:
|
||||
device = inject_id(device)
|
||||
api.device_create(None, device)
|
||||
|
||||
for device_endpoint in ENDPOINT_LIST:
|
||||
device_endpoint = inject_id(device_endpoint)
|
||||
api.device_endpoint_create(None, device_endpoint)
|
||||
|
||||
# TODO(kanagaraj-manickam) Move this to alembic upgrade
|
||||
for device_driver_class in DEVICE_DRIVER_CLASS_LIST:
|
||||
device_driver_class = inject_id(device_driver_class)
|
||||
api.device_driver_class_create(None, device_driver_class)
|
||||
|
||||
for device_driver in DEVICE_DRIVER_LIST:
|
||||
device_driver = inject_id(device_driver)
|
||||
api.device_driver_create(None, device_driver)
|
||||
|
||||
|
||||
def _service_populate_demo_data():
|
||||
for service in SERVICE_LIST:
|
||||
service = inject_id(service)
|
||||
api.service_create(None, service)
|
||||
|
||||
for service_node in SERVICE_NODE_LIST:
|
||||
service_node = inject_id(service_node)
|
||||
api.service_node_create(None, service_node)
|
||||
|
||||
for service_component in SERVICE_COMPONENT_LIST:
|
||||
service_component = inject_id(service_component)
|
||||
api.service_component_create(None, service_component)
|
||||
|
||||
for service_worker in SERVICE_WORKER_LIST:
|
||||
service_worker = inject_id(service_worker)
|
||||
api.service_worker_create(None, service_worker)
|
||||
|
||||
for config in CONFIG_LIST:
|
||||
config = inject_id(config)
|
||||
api.config_create(None, config)
|
||||
|
||||
|
||||
def populate_demo_data():
|
||||
_device_populate_demo_data()
|
||||
_service_populate_demo_data()
|
||||
|
||||
|
||||
def _device_purge_demo_data():
|
||||
for device_driver in DEVICE_DRIVER_LIST:
|
||||
api.device_driver_delete(None, device_driver.keys()[0])
|
||||
|
||||
for device_endpoint in ENDPOINT_LIST:
|
||||
api.device_endpoint_delete(None, device_endpoint.keys()[0])
|
||||
|
||||
# Reverse the order of delete from child to parent device
|
||||
for device in DEVICE_LIST[::-1]:
|
||||
api.device_delete(None, device.keys()[0])
|
||||
|
||||
# TODO(kanagaraj-manickam) Move this to alembic downgrade
|
||||
for device_driver_class in DEVICE_DRIVER_CLASS_LIST:
|
||||
api.device_driver_class_delete(None, device_driver_class.keys()[0])
|
||||
|
||||
|
||||
def _service_purge_demo_data():
|
||||
for config in CONFIG_LIST:
|
||||
api.config_delete(None, config.keys()[0])
|
||||
for service_worker in SERVICE_WORKER_LIST:
|
||||
api.service_worker_delete(None, service_worker.keys()[0])
|
||||
|
||||
for service_component in SERVICE_COMPONENT_LIST:
|
||||
api.service_component_delete(None, service_component.keys()[0])
|
||||
|
||||
for service_node in SERVICE_NODE_LIST:
|
||||
api.service_node_delete(None, service_node.keys()[0])
|
||||
|
||||
for service in SERVICE_LIST:
|
||||
api.service_delete(None, service.keys()[0])
|
||||
|
||||
|
||||
def _region_purge_demo_data():
|
||||
for region in REGION_LIST:
|
||||
api.region_delete(None, region.keys()[0])
|
||||
|
||||
|
||||
def purge_demo_data():
|
||||
_service_purge_demo_data()
|
||||
_device_purge_demo_data()
|
||||
_region_purge_demo_data()
|
|
@ -0,0 +1,59 @@
|
|||
# A generic, single database configuration.
|
||||
|
||||
[alembic]
|
||||
# path to migration scripts
|
||||
script_location = %(here)s/alembic
|
||||
|
||||
# template used to generate migration files
|
||||
# file_template = %%(rev)s_%%(slug)s
|
||||
|
||||
# max length of characters to apply to the
|
||||
# "slug" field
|
||||
#truncate_slug_length = 40
|
||||
|
||||
# set to 'true' to run the environment during
|
||||
# the 'revision' command, regardless of autogenerate
|
||||
# revision_environment = false
|
||||
|
||||
# set to 'true' to allow .pyc and .pyo files without
|
||||
# a source .py file to be detected as revisions in the
|
||||
# versions/ directory
|
||||
# sourceless = false
|
||||
|
||||
#sqlalchemy.url = driver://user:pass@localhost/dbname
|
||||
#sqlalchemy.url = mysql+mysqldb://root:password@localhost/namos
|
||||
|
||||
# Logging configuration
|
||||
[loggers]
|
||||
keys = root,sqlalchemy,alembic
|
||||
|
||||
[handlers]
|
||||
keys = console
|
||||
|
||||
[formatters]
|
||||
keys = generic
|
||||
|
||||
[logger_root]
|
||||
level = WARN
|
||||
handlers = console
|
||||
qualname =
|
||||
|
||||
[logger_sqlalchemy]
|
||||
level = WARN
|
||||
handlers =
|
||||
qualname = sqlalchemy.engine
|
||||
|
||||
[logger_alembic]
|
||||
level = INFO
|
||||
handlers =
|
||||
qualname = alembic
|
||||
|
||||
[handler_console]
|
||||
class = StreamHandler
|
||||
args = (sys.stderr,)
|
||||
level = NOTSET
|
||||
formatter = generic
|
||||
|
||||
[formatter_generic]
|
||||
format = %(levelname)-5.5s [%(name)s] %(message)s
|
||||
datefmt = %H:%M:%S
|
|
@ -0,0 +1,89 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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 __future__ import with_statement
|
||||
from alembic import context
|
||||
from sqlalchemy import engine_from_config, pool
|
||||
from logging.config import fileConfig
|
||||
|
||||
# this is the Alembic Config object, which provides
|
||||
# access to the values within the .ini file in use.
|
||||
config = context.config
|
||||
|
||||
# Interpret the config file for Python logging.
|
||||
# This line sets up loggers basically.
|
||||
fileConfig(config.config_file_name)
|
||||
|
||||
# add your model's MetaData object here
|
||||
# for 'autogenerate' support
|
||||
# from myapp import mymodel
|
||||
# target_metadata = mymodel.Base.metadata
|
||||
|
||||
from namos.db.sqlalchemy.models import BASE
|
||||
target_metadata = BASE.metadata
|
||||
|
||||
# other values from the config, defined by the needs of env.py,
|
||||
# can be acquired:
|
||||
# my_important_option = config.get_main_option("my_important_option")
|
||||
# ... etc.
|
||||
|
||||
|
||||
def run_migrations_offline():
|
||||
"""Run migrations in 'offline' mode.
|
||||
|
||||
This configures the context with just a URL
|
||||
and not an Engine, though an Engine is acceptable
|
||||
here as well. By skipping the Engine creation
|
||||
we don't even need a DBAPI to be available.
|
||||
|
||||
Calls to context.execute() here emit the given string to the
|
||||
script output.
|
||||
|
||||
"""
|
||||
url = config.get_main_option("sqlalchemy.url")
|
||||
context.configure(url=url, target_metadata=target_metadata)
|
||||
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
|
||||
|
||||
def run_migrations_online():
|
||||
"""Run migrations in 'online' mode.
|
||||
|
||||
In this scenario we need to create an Engine
|
||||
and associate a connection with the context.
|
||||
|
||||
"""
|
||||
engine = engine_from_config(
|
||||
config.get_section(config.config_ini_section),
|
||||
prefix='sqlalchemy.',
|
||||
poolclass=pool.NullPool)
|
||||
|
||||
connection = engine.connect()
|
||||
context.configure(
|
||||
connection=connection,
|
||||
target_metadata=target_metadata
|
||||
)
|
||||
|
||||
try:
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
|
||||
if context.is_offline_mode():
|
||||
run_migrations_offline()
|
||||
else:
|
||||
run_migrations_online()
|
|
@ -0,0 +1,22 @@
|
|||
"""${message}
|
||||
|
||||
Revision ID: ${up_revision}
|
||||
Revises: ${down_revision}
|
||||
Create Date: ${create_date}
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = ${repr(up_revision)}
|
||||
down_revision = ${repr(down_revision)}
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
${imports if imports else ""}
|
||||
|
||||
def upgrade():
|
||||
${upgrades if upgrades else "pass"}
|
||||
|
||||
|
||||
def downgrade():
|
||||
${downgrades if downgrades else "pass"}
|
|
@ -0,0 +1,188 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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.
|
||||
|
||||
"""Initial version
|
||||
|
||||
Revision ID: 48ebec3cd6f6
|
||||
Revises: None
|
||||
Create Date: 2014-10-31 10:57:41.695077
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '48ebec3cd6f6'
|
||||
down_revision = None
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.create_table(
|
||||
'service',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Uuid(length=36), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=False),
|
||||
sa.Column('deleted_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('extra', sa.Json(), nullable=True),
|
||||
sa.Column('keystone_service_id', sa.Uuid(length=36), nullable=False),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
mysql_engine='InnoDB'
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'device_driver_class',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Uuid(length=36), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=False),
|
||||
sa.Column('deleted_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('extra', sa.Json(), nullable=True),
|
||||
sa.Column('python_class', sa.String(length=64), nullable=False),
|
||||
sa.Column('version', sa.String(length=64), nullable=True),
|
||||
sa.Column('type', sa.String(length=64), nullable=False),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
mysql_engine='InnoDB'
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'region',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Uuid(length=36), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=False),
|
||||
sa.Column('deleted_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('extra', sa.Json(), nullable=True),
|
||||
sa.Column('keystone_region_id', sa.String(length=255), nullable=False),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
mysql_engine='InnoDB'
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'device',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Uuid(length=36), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=False),
|
||||
sa.Column('deleted_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('status', sa.String(length=64), nullable=False),
|
||||
sa.Column('description', sa.Text(), nullable=True),
|
||||
sa.Column('extra', sa.Json(), nullable=True),
|
||||
sa.Column('display_name', sa.String(length=255), nullable=True),
|
||||
sa.Column('parent_id', sa.Uuid(length=36), nullable=True),
|
||||
sa.Column('region_id', sa.Uuid(length=36), nullable=False),
|
||||
sa.ForeignKeyConstraint(['parent_id'], ['device.id'], ),
|
||||
sa.ForeignKeyConstraint(['region_id'], ['region.id'], ),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
mysql_engine='InnoDB'
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'service_node',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Uuid(length=36), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=False),
|
||||
sa.Column('deleted_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('description', sa.Text(), nullable=True),
|
||||
sa.Column('extra', sa.Json(), nullable=True),
|
||||
sa.Column('fqdn', sa.String(length=128), nullable=False),
|
||||
sa.Column('region_id', sa.Uuid(length=36), nullable=True),
|
||||
sa.ForeignKeyConstraint(['region_id'], ['region.id'], ),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
mysql_engine='InnoDB'
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'device_endpoint',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Uuid(length=36), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=False),
|
||||
sa.Column('extra', sa.Json(), nullable=True),
|
||||
sa.Column('device_id', sa.Uuid(length=36), nullable=True),
|
||||
sa.Column('connection', sa.Json(), nullable=False),
|
||||
sa.ForeignKeyConstraint(['device_id'], ['device.id'], ),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
mysql_engine='InnoDB'
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'service_component',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Uuid(length=36), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=False),
|
||||
sa.Column('deleted_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('description', sa.Text(), nullable=True),
|
||||
sa.Column('extra', sa.Json(), nullable=True),
|
||||
sa.Column('node_id', sa.Uuid(length=36), nullable=False),
|
||||
sa.Column('service_id', sa.Uuid(length=36), nullable=False),
|
||||
sa.ForeignKeyConstraint(['node_id'], ['service_node.id'], ),
|
||||
sa.ForeignKeyConstraint(['service_id'], ['service.id'], ),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
mysql_engine='InnoDB'
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'device_driver',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Uuid(length=36), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=False),
|
||||
sa.Column('deleted_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('extra', sa.Json(), nullable=True),
|
||||
sa.Column('endpoint_id', sa.Uuid(length=36), nullable=True),
|
||||
sa.Column('device_id', sa.Uuid(length=36), nullable=True),
|
||||
sa.Column('python_class_id', sa.Uuid(length=36), nullable=True),
|
||||
sa.ForeignKeyConstraint(['device_id'], ['device.id'], ),
|
||||
sa.ForeignKeyConstraint(['endpoint_id'], ['device_endpoint.id'], ),
|
||||
sa.ForeignKeyConstraint(['python_class_id'],
|
||||
['device_driver_class.id'], ),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
mysql_engine='InnoDB'
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'service_worker',
|
||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Uuid(length=36), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=False),
|
||||
sa.Column('deleted_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('extra', sa.Json(), nullable=True),
|
||||
sa.Column('pid', sa.String(length=32), nullable=False),
|
||||
sa.Column('host', sa.String(length=248), nullable=False),
|
||||
sa.Column('service_component_id', sa.Uuid(length=36), nullable=False),
|
||||
sa.Column('device_driver_id', sa.Uuid(length=36), nullable=False),
|
||||
sa.ForeignKeyConstraint(['device_driver_id'], ['device_driver.id'], ),
|
||||
sa.ForeignKeyConstraint(['service_component_id'],
|
||||
['service_component.id'], ),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
mysql_engine='InnoDB'
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.drop_table('oslo_config')
|
||||
op.drop_table('device_driver')
|
||||
op.drop_table('service_worker')
|
||||
op.drop_table('service_component')
|
||||
op.drop_table('device_endpoint')
|
||||
op.drop_table('service_node')
|
||||
op.drop_table('device')
|
||||
op.drop_table('region')
|
||||
op.drop_table('device_driver_class')
|
||||
op.drop_table('service')
|
|
@ -0,0 +1,794 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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 sys
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_db.sqlalchemy import session as db_session
|
||||
|
||||
from namos.common import exception
|
||||
from namos.db.sqlalchemy import models
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
_facade = None
|
||||
|
||||
|
||||
def get_facade():
|
||||
global _facade
|
||||
|
||||
if not _facade:
|
||||
_facade = db_session.EngineFacade.from_config(CONF)
|
||||
return _facade
|
||||
|
||||
|
||||
get_engine = lambda: get_facade().get_engine()
|
||||
get_session = lambda: get_facade().get_session()
|
||||
|
||||
|
||||
def get_backend():
|
||||
"""The backend is this module itself."""
|
||||
return sys.modules[__name__]
|
||||
|
||||
|
||||
def _model_query(context, *args):
|
||||
session = _session(context)
|
||||
query = session.query(*args)
|
||||
return query
|
||||
|
||||
|
||||
def _session(context):
|
||||
return (context and hasattr(context, 'session') and context.session) \
|
||||
or get_session()
|
||||
|
||||
|
||||
def _create(context, resource_ref, values):
|
||||
resource_ref.update(values)
|
||||
resource_ref.save(_session(context))
|
||||
return resource_ref
|
||||
|
||||
|
||||
def _update(context, cls, _id, values):
|
||||
resource_ref = _get(context, cls, _id)
|
||||
resource_ref.update_and_save(values, _session(context))
|
||||
return resource_ref
|
||||
|
||||
|
||||
def _get(context, cls, _id):
|
||||
result = _model_query(context, cls).get(_id)
|
||||
return result
|
||||
|
||||
|
||||
def _get_by_name(context, cls, name):
|
||||
result = _model_query(context, cls). \
|
||||
filter_by(name=name).first()
|
||||
return result
|
||||
|
||||
|
||||
# TODO(kanagaraj-manickam): Add pagination
|
||||
def _get_all(context, cls):
|
||||
results = _model_query(context, cls).all()
|
||||
|
||||
if results is None:
|
||||
results = []
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def _get_all_by(context, cls, **kwargs):
|
||||
results = _model_query(context, cls).filter_by(**kwargs).all()
|
||||
return results
|
||||
|
||||
|
||||
def _delete(context, cls, _id):
|
||||
result = _get(context, cls, _id)
|
||||
if result is not None:
|
||||
result.delete(_session(context))
|
||||
|
||||
|
||||
# Region
|
||||
|
||||
def region_create(context, values):
|
||||
return _create(context, models.Region(), values)
|
||||
|
||||
|
||||
def region_update(context, _id, values):
|
||||
return _update(context, models.Region, _id, values)
|
||||
|
||||
|
||||
def region_get(context, _id):
|
||||
region = _get(context, models.Region, _id)
|
||||
if region is None:
|
||||
raise exception.RegionNotFound(region_id=_id)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def region_get_by_name(context, name):
|
||||
region = _get_by_name(context, models.Region, name)
|
||||
if region is None:
|
||||
raise exception.RegionNotFound(region_id=name)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def region_get_all(context):
|
||||
return _get_all(context, models.Region)
|
||||
|
||||
|
||||
def region_delete(context, _id):
|
||||
return _delete(context, models.Region, _id)
|
||||
|
||||
|
||||
# Device
|
||||
|
||||
def device_create(context, values):
|
||||
return _create(context, models.Device(), values)
|
||||
|
||||
|
||||
def device_update(context, _id, values):
|
||||
return _update(context, models.Device, _id, values)
|
||||
|
||||
|
||||
def device_get(context, _id):
|
||||
region = _get(context, models.Device, _id)
|
||||
if region is None:
|
||||
raise exception.DeviceNotFound(device_id=_id)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def device_get_by_name(context, name):
|
||||
region = _get_by_name(context, models.Device, name)
|
||||
if region is None:
|
||||
raise exception.DeviceNotFound(device_id=name)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def device_get_all(context):
|
||||
return _get_all(context, models.Device)
|
||||
|
||||
|
||||
def _device_get_all_by(context, **kwargs):
|
||||
return _get_all_by(context, models.Device, **kwargs)
|
||||
|
||||
|
||||
def device_delete(context, _id):
|
||||
return _delete(context, models.Device, _id)
|
||||
|
||||
|
||||
# Device Endpoint
|
||||
|
||||
def device_endpoint_create(context, values):
|
||||
return _create(context, models.DeviceEndpoint(), values)
|
||||
|
||||
|
||||
def device_endpoint_update(context, _id, values):
|
||||
return _update(context, models.DeviceEndpoint, _id, values)
|
||||
|
||||
|
||||
def device_endpoint_get(context, _id):
|
||||
region = _get(context, models.DeviceEndpoint, _id)
|
||||
if region is None:
|
||||
raise exception.DeviceEndpointNotFound(device_endpoint_id=_id)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def device_endpoint_get_by_name(context, name):
|
||||
region = _get_by_name(context, models.DeviceEndpoint, name)
|
||||
if region is None:
|
||||
raise exception.DeviceEndpointNotFound(device_endpoint_id=name)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def device_endpoint_get_by_device_type(context,
|
||||
device_id,
|
||||
type=None,
|
||||
name=None):
|
||||
query = _model_query(context, models.DeviceEndpoint)
|
||||
if device_id is not None:
|
||||
query = query.filter_by(device_id=device_id)
|
||||
if type is not None:
|
||||
query = query.filter_by(type=type)
|
||||
if name is not None:
|
||||
query = query.filter_by(name=name)
|
||||
return query.all()
|
||||
|
||||
|
||||
def device_endpoint_get_all(context):
|
||||
return _get_all(context, models.DeviceEndpoint)
|
||||
|
||||
|
||||
def _device_endpoint_get_all_by(context, **kwargs):
|
||||
return _get_all_by(context, models.DeviceEndpoint, **kwargs)
|
||||
|
||||
|
||||
def device_endpoint_delete(context, _id):
|
||||
return _delete(context, models.DeviceEndpoint, _id)
|
||||
|
||||
|
||||
# Device Driver
|
||||
def device_driver_create(context, values):
|
||||
return _create(context, models.DeviceDriver(), values)
|
||||
|
||||
|
||||
def device_driver_update(context, _id, values):
|
||||
return _update(context, models.DeviceDriver, _id, values)
|
||||
|
||||
|
||||
def device_driver_get(context, _id):
|
||||
region = _get(context, models.DeviceDriver, _id)
|
||||
if region is None:
|
||||
raise exception.DeviceDriverNotFound(device_driver_id=_id)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def device_driver_get_by_name(context, name):
|
||||
region = _get_by_name(context, models.DeviceDriver, name)
|
||||
if region is None:
|
||||
raise exception.DeviceDriverNotFound(device_driver_id=name)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def device_driver_get_by_device_endpoint_service_worker(
|
||||
context,
|
||||
device_id=None,
|
||||
endpoint_id=None,
|
||||
device_driver_class_id=None,
|
||||
service_worker_id=None):
|
||||
query = _model_query(context, models.DeviceDriver)
|
||||
if device_id is not None:
|
||||
query = query.filter_by(device_id=device_id)
|
||||
if endpoint_id is not None:
|
||||
query = query.filter_by(endpoint_id=endpoint_id)
|
||||
if device_driver_class_id is not None:
|
||||
query = query.filter_by(device_driver_class_id=device_driver_class_id)
|
||||
if service_worker_id is not None:
|
||||
query = query.filter_by(service_worker_id=service_worker_id)
|
||||
return query.all()
|
||||
|
||||
|
||||
def device_driver_get_all(context):
|
||||
return _get_all(context, models.DeviceDriver)
|
||||
|
||||
|
||||
def _device_driver_get_all_by(context, **kwargs):
|
||||
return _get_all_by(context, models.DeviceDriver, **kwargs)
|
||||
|
||||
|
||||
def device_driver_delete(context, _id):
|
||||
return _delete(context, models.DeviceDriver, _id)
|
||||
|
||||
|
||||
# Device Driver Class
|
||||
|
||||
def device_driver_class_create(context, values):
|
||||
return _create(context, models.DeviceDriverClass(), values)
|
||||
|
||||
|
||||
def device_driver_class_update(context, _id, values):
|
||||
return _update(context, models.DeviceDriverClass, _id, values)
|
||||
|
||||
|
||||
def device_driver_class_get(context, _id):
|
||||
region = _get(context, models.DeviceDriverClass, _id)
|
||||
if region is None:
|
||||
raise exception.DeviceDriverClassNotFound(device_driver_id=_id)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def device_driver_class_get_by_name(context, name):
|
||||
region = _get_by_name(context, models.DeviceDriverClass, name)
|
||||
if region is None:
|
||||
raise exception.DeviceDriverClassNotFound(device_driver_class_id=name)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def device_driver_class_get_all(context):
|
||||
return _get_all(context, models.DeviceDriverClass)
|
||||
|
||||
|
||||
def _device_driver_classget_all_by(context, **kwargs):
|
||||
return _get_all_by(context, models.DeviceDriverClass, **kwargs)
|
||||
|
||||
|
||||
def device_driver_class_delete(context, _id):
|
||||
return _delete(context, models.DeviceDriverClass, _id)
|
||||
|
||||
|
||||
# Service
|
||||
|
||||
def service_create(context, values):
|
||||
return _create(context, models.Service(), values)
|
||||
|
||||
|
||||
def service_update(context, _id, values):
|
||||
return _update(context, models.Service, _id, values)
|
||||
|
||||
|
||||
def service_get(context, _id):
|
||||
region = _get(context, models.Service, _id)
|
||||
if region is None:
|
||||
raise exception.ServiceNotFound(service_id=_id)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def service_get_by_name(context, name):
|
||||
region = _get_by_name(context, models.Service, name)
|
||||
if region is None:
|
||||
raise exception.ServiceNotFound(service_id=name)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def service_get_all(context):
|
||||
return _get_all(context, models.Service)
|
||||
|
||||
|
||||
def _service_get_all_by(context, **kwargs):
|
||||
return _get_all_by(context, models.Service, **kwargs)
|
||||
|
||||
|
||||
def service_delete(context, _id):
|
||||
return _delete(context, models.Service, _id)
|
||||
|
||||
|
||||
# ServiceNode
|
||||
|
||||
def service_node_create(context, values):
|
||||
return _create(context, models.ServiceNode(), values)
|
||||
|
||||
|
||||
def service_node_update(context, _id, values):
|
||||
return _update(context, models.ServiceNode, _id, values)
|
||||
|
||||
|
||||
def service_node_get(context, _id):
|
||||
region = _get(context, models.ServiceNode, _id)
|
||||
if region is None:
|
||||
raise exception.ServiceNodeNotFound(service_node_id=_id)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def service_node_get_by_name(context, name):
|
||||
region = _get_by_name(context, models.ServiceNode, name)
|
||||
if region is None:
|
||||
raise exception.ServiceNodeNotFound(service_node_id=name)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def service_node_get_all(context):
|
||||
return _get_all(context, models.ServiceNode)
|
||||
|
||||
|
||||
def _service_node_get_all_by(context, **kwargs):
|
||||
return _get_all_by(context, models.ServiceNode, **kwargs)
|
||||
|
||||
|
||||
def service_node_delete(context, _id):
|
||||
return _delete(context, models.ServiceNode, _id)
|
||||
|
||||
|
||||
# ServiceComponent
|
||||
|
||||
def service_component_create(context, values):
|
||||
return _create(context, models.ServiceComponent(), values)
|
||||
|
||||
|
||||
def service_component_update(context, _id, values):
|
||||
return _update(context, models.ServiceComponent, _id, values)
|
||||
|
||||
|
||||
def service_component_get(context, _id):
|
||||
region = _get(context, models.ServiceComponent, _id)
|
||||
if region is None:
|
||||
raise exception.ServiceComponentNotFound(service_component_id=_id)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def service_component_get_by_name(context, name):
|
||||
region = _get_by_name(context, models.ServiceComponent, name)
|
||||
if region is None:
|
||||
raise exception.ServiceComponentNotFound(service_component_id=name)
|
||||
|
||||
return region
|
||||
|
||||
|
||||
def service_component_get_all_by_node_for_service(context,
|
||||
node_id,
|
||||
service_id=None,
|
||||
name=None):
|
||||
query = _model_query(context, models.ServiceComponent). \
|
||||
filter_by(node_id=node_id)
|
||||
if service_id is not None:
|
||||
query = query.filter_by(service_id=service_id)
|
||||
if name is not None:
|
||||
query = query.filter_by(name=name)
|
||||
return query.all()
|
||||
|
||||
|
||||
def service_component_get_all(context):
|
||||
return _get_all(context, models.ServiceComponent)
|
||||
|
||||
|
||||
def _service_component_get_all_by(context, **kwargs):
|
||||
return _get_all_by(context, models.ServiceComponent, **kwargs)
|
||||
|
||||
|
||||
def service_component_delete(context, _id):
|
||||
return _delete(context, models.ServiceComponent, _id)
|
||||
|
||||
|
||||
# ServiceWorker
|
||||
|
||||
def service_worker_create(context, values):
|
||||
return _create(context, models.ServiceWorker(), values)
|
||||
|
||||
|
||||
def service_worker_update(context, _id, values):
|
||||
return _update(context, models.ServiceWorker, _id, values)
|
||||
|
||||
|
||||
def service_worker_get(context, _id):
|
||||
service_worker = _get(context, models.ServiceWorker, _id)
|
||||
if service_worker is None:
|
||||
raise exception.ServiceWorkerNotFound(service_worker_id=_id)
|
||||
|
||||
return service_worker
|
||||
|
||||
|
||||
def service_worker_get_by_name(context, name):
|
||||
service_worker = _get_by_name(context, models.ServiceWorker, name)
|
||||
if service_worker is None:
|
||||
raise exception.ServiceWorkerNotFound(service_worker_id=name)
|
||||
|
||||
return service_worker
|
||||
|
||||
|
||||
def service_worker_get_by_host_for_service_component(context,
|
||||
service_component_id,
|
||||
host=None):
|
||||
query = _model_query(context, models.ServiceWorker). \
|
||||
filter_by(service_component_id=service_component_id)
|
||||
if host is not None:
|
||||
query = query.filter_by(host=host)
|
||||
return query.all()
|
||||
|
||||
|
||||
def service_worker_get_all(context):
|
||||
return _get_all(context, models.ServiceWorker)
|
||||
|
||||
|
||||
def _service_worker_get_all_by(context, **kwargs):
|
||||
return _get_all_by(context, models.ServiceWorker, **kwargs)
|
||||
|
||||
|
||||
def service_worker_delete(context, _id):
|
||||
return _delete(context, models.ServiceWorker, _id)
|
||||
|
||||
|
||||
# Config
|
||||
|
||||
def config_create(context, values):
|
||||
return _create(context, models.OsloConfig(), values)
|
||||
|
||||
|
||||
def config_update(context, _id, values):
|
||||
return _update(context, models.OsloConfig, _id, values)
|
||||
|
||||
|
||||
def config_get(context, _id):
|
||||
config = _get(context, models.OsloConfig, _id)
|
||||
if config is None:
|
||||
raise exception.ConfigNotFound(config_id=_id)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def config_get_by_name(context, name):
|
||||
config = _get_by_name(context, models.OsloConfig, name)
|
||||
if config is None:
|
||||
raise exception.ConfigNotFound(config_id=name)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def config_get_by_name_for_service_worker(context,
|
||||
service_worker_id,
|
||||
name=None):
|
||||
query = _model_query(context, models.OsloConfig). \
|
||||
filter_by(service_worker_id=service_worker_id)
|
||||
if name is not None:
|
||||
query = query.filter_by(name=name)
|
||||
return query.all()
|
||||
|
||||
|
||||
def config_get_all(context):
|
||||
return _get_all(context, models.OsloConfig)
|
||||
|
||||
|
||||
def _config_get_all_by(context, **kwargs):
|
||||
return _get_all_by(context, models.OsloConfig, **kwargs)
|
||||
|
||||
|
||||
def config_delete(context, _id):
|
||||
return _delete(context, models.OsloConfig, _id)
|
||||
|
||||
|
||||
# REST-API
|
||||
def service_perspective_get(context, service_id, include_details=False):
|
||||
# 1. itr over Service Components and find name vs set of components
|
||||
# (for example, nova-compute vs set of nova-compute deployment)
|
||||
# Mention the service_node
|
||||
# 2. For each components, itr over Service Workers
|
||||
# 3. For each workers, itr over device_drivers
|
||||
# 4. For each device_driver, Mention
|
||||
# device_driver_class
|
||||
# device_endpoint<->device
|
||||
|
||||
# on include_details, for each of the entity, include complete details
|
||||
service_perspective = dict()
|
||||
service_perspective['service'] = service_get(context, service_id).to_dict()
|
||||
service_components = _service_component_get_all_by(context,
|
||||
service_id=service_id)
|
||||
service_perspective['service_components'] = dict()
|
||||
# service_perspective['service_components']['size'] =
|
||||
# len(service_components)
|
||||
|
||||
for sc in service_components:
|
||||
service_perspective['service_components'][sc.id] = dict()
|
||||
service_perspective['service_components'][sc.id]['service_component']\
|
||||
= sc.to_dict()
|
||||
service_perspective['service_components'][sc.id]['service_node']\
|
||||
= service_node_get(context, sc.node_id).to_dict()
|
||||
service_workers = _service_worker_get_all_by(
|
||||
context,
|
||||
service_component_id=sc.id)
|
||||
service_perspective['service_components'][sc.id]['service_workers'] \
|
||||
= dict()
|
||||
# service_perspective['service_components'][sc.id]\
|
||||
# ['service_workers']['size'] = len(service_workers)
|
||||
|
||||
for sw in service_workers:
|
||||
service_perspective['service_components'][
|
||||
sc.id]['service_workers'][sw.id] = dict()
|
||||
service_perspective['service_components'][
|
||||
sc.id]['service_workers'][sw.id][
|
||||
'service_worker'] = sw.to_dict()
|
||||
|
||||
device_drivers = _device_driver_get_all_by(
|
||||
context,
|
||||
service_worker_id=sw.id)
|
||||
service_perspective['service_components'][
|
||||
sc.id]['service_workers'][sw.id]['device_drivers'] = dict()
|
||||
|
||||
# service_perspective['service_components'][sc.id]\
|
||||
# ['service_workers'][sw.id]['device_drivers']['size'] \
|
||||
# = len(device_drivers)
|
||||
for driver in device_drivers:
|
||||
service_perspective['service_components'][
|
||||
sc.id]['service_workers'][sw.id]['device_drivers'][
|
||||
driver.id] = dict()
|
||||
service_perspective['service_components'][
|
||||
sc.id]['service_workers'][sw.id]['device_drivers'][
|
||||
driver.id]['driver'] = driver.to_dict()
|
||||
service_perspective['service_components'][
|
||||
sc.id]['service_workers'][sw.id]['device_drivers'][
|
||||
driver.id]['device_endpoint'] = device_endpoint_get(
|
||||
context,
|
||||
driver.endpoint_id).to_dict()
|
||||
service_perspective['service_components'][
|
||||
sc.id]['service_workers'][sw.id]['device_drivers'][
|
||||
driver.id]['device'] = device_get(
|
||||
context,
|
||||
driver.device_id).to_dict()
|
||||
service_perspective['service_components'][
|
||||
sc.id]['service_workers'][sw.id]['device_drivers'][
|
||||
driver.id][
|
||||
'device_driver_class'] = device_driver_class_get(
|
||||
context,
|
||||
driver.device_driver_class_id
|
||||
).to_dict()
|
||||
|
||||
return service_perspective
|
||||
|
||||
|
||||
# REST-API
|
||||
def device_perspective_get(context, device_id, include_details=False):
|
||||
# 1. list endpoints
|
||||
# 2. For each endpoint, itr over device_drivers and
|
||||
# find device_driver_class vs set of device_driver (for example,
|
||||
# nova-compute-vc-driver vs set of nova-compute's device-driver deployment)
|
||||
# 3. For each drivers, mention service_worker,
|
||||
# service_component<->service_node<->service
|
||||
|
||||
# on include_details, for each of the entity, include complete details
|
||||
device_perspective = dict()
|
||||
device_perspective['device'] = device_get(context, device_id).to_dict()
|
||||
endpoints = _device_endpoint_get_all_by(context,
|
||||
device_id=device_id)
|
||||
device_perspective['device_endpoints'] = dict()
|
||||
# device_perspective['device_endpoints']['size'] = len(endpoints)
|
||||
|
||||
for ep in endpoints:
|
||||
device_perspective['device_endpoints'][ep.id] = dict()
|
||||
device_perspective['device_endpoints'][
|
||||
ep.id]['device_endpoint'] = ep.to_dict()
|
||||
|
||||
device_drivers = _device_driver_get_all_by(context,
|
||||
endpoint_id=ep.id)
|
||||
device_perspective['device_endpoints'][
|
||||
ep.id]['device_drivers'] = dict()
|
||||
# device_perspective['device_endpoints'][ep.id] \
|
||||
# ['device_drivers']['size'] = len(device_drivers)
|
||||
|
||||
for driver in device_drivers:
|
||||
device_perspective['device_endpoints'][
|
||||
ep.id]['device_drivers'][driver.id] = dict()
|
||||
device_perspective['device_endpoints'][
|
||||
ep.id]['device_drivers'][driver.id][
|
||||
'device_driver'] = driver.to_dict()
|
||||
|
||||
service_worker = service_worker_get(
|
||||
context,
|
||||
driver.service_worker_id)
|
||||
service_component = service_component_get(
|
||||
context,
|
||||
service_worker.service_component_id)
|
||||
device_perspective['device_endpoints'][
|
||||
ep.id]['device_drivers'][
|
||||
driver.id]['service_worker'] = service_worker.to_dict()
|
||||
service = service_get(context, service_component.service_id)
|
||||
|
||||
device_perspective['device_endpoints'][
|
||||
ep.id]['device_drivers'][
|
||||
driver.id]['service_component'] = service_component.to_dict()
|
||||
|
||||
device_perspective['device_endpoints'][
|
||||
ep.id]['device_drivers'][
|
||||
driver.id]['service'] = service.to_dict()
|
||||
device_perspective['device_endpoints'][
|
||||
ep.id]['device_drivers'][driver.id][
|
||||
'device_driver_class'] = device_driver_class_get(
|
||||
context,
|
||||
driver.device_driver_class_id
|
||||
).to_dict()
|
||||
|
||||
return device_perspective
|
||||
|
||||
|
||||
# REST-API
|
||||
def region_perspective_get(context, region_id, include_details=False):
|
||||
# itr over service_nodes
|
||||
# For each service_nodes, itr over service_id
|
||||
# itr over devices.
|
||||
|
||||
# on include_details, for each of the entity, include complete details
|
||||
|
||||
region_perspective = dict()
|
||||
region_perspective['region'] = region_get(context, region_id).to_dict()
|
||||
s_nodes = _service_node_get_all_by(context,
|
||||
region_id=region_id)
|
||||
# region_perspective['service_nodes'] = dict()
|
||||
# region_perspective['service_nodes']['size'] = len(s_nodes)
|
||||
# for s_node in s_nodes:
|
||||
# region_perspective['service_nodes'][s_node.id] = dict()
|
||||
# region_perspective['service_nodes'][s_node.id]['service_node']\
|
||||
# = s_node
|
||||
# s_components = _service_component_get_all_by(context,
|
||||
# node_id=s_node.id)
|
||||
# srvs = list()
|
||||
# for s_component in s_components:
|
||||
# srvs.append(s_component.service_id)
|
||||
# srvs = set(srvs)
|
||||
#
|
||||
# region_perspective['service_nodes'][s_node.id]['services'] = dict()
|
||||
# region_perspective['service_nodes'][s_node.id]['services']['size']\
|
||||
# = len(srvs)
|
||||
# for s_id in srvs:
|
||||
# s = service_get(context, s_id)
|
||||
# region_perspective['service_nodes'][s_node.id]['services'][s_id]\
|
||||
# = s
|
||||
|
||||
region_perspective['services'] = dict()
|
||||
for s_node in s_nodes:
|
||||
s_components = _service_component_get_all_by(
|
||||
context,
|
||||
node_id=s_node.id)
|
||||
srvs = list()
|
||||
for s_component in s_components:
|
||||
srvs.append(s_component.service_id)
|
||||
srvs = set(srvs)
|
||||
|
||||
# region_perspective['services']['size']\
|
||||
# = len(srvs)
|
||||
for s_id in srvs:
|
||||
s = service_get(context, s_id)
|
||||
region_perspective['services'][s_id] = s.to_dict()
|
||||
|
||||
devices = _device_get_all_by(context, region_id=region_id)
|
||||
region_perspective['devices'] = dict()
|
||||
# region_perspective['devices']['size'] = len(devices)
|
||||
for d in devices:
|
||||
region_perspective['devices'][d.id] = d.to_dict()
|
||||
|
||||
return region_perspective
|
||||
|
||||
|
||||
def infra_perspective_get(context):
|
||||
infra_perspective = dict()
|
||||
|
||||
regions = region_get_all(context)
|
||||
infra_perspective['regions'] = dict()
|
||||
# infra_perspective['regions']['size'] = len(regions)
|
||||
|
||||
for region in regions:
|
||||
infra_perspective['regions'][region.id] = dict()
|
||||
infra_perspective['regions'][region.id]['region'] = region.to_dict()
|
||||
region_perspective = region_perspective_get(context,
|
||||
region.id)
|
||||
|
||||
infra_perspective['regions'][region.id]['services'] = dict()
|
||||
for s_id in region_perspective['services']:
|
||||
infra_perspective['regions'][
|
||||
region.id]['services'][s_id] = service_perspective_get(
|
||||
context,
|
||||
s_id)
|
||||
|
||||
infra_perspective['regions'][region.id]['devices'] = dict()
|
||||
for d_id in region_perspective['devices']:
|
||||
infra_perspective['regions'][region.id]['devices'][
|
||||
d_id] = device_perspective_get(
|
||||
context,
|
||||
d_id)
|
||||
|
||||
return infra_perspective
|
||||
|
||||
if __name__ == '__main__':
|
||||
from namos.common import config
|
||||
|
||||
config.init_conf(prog='test-run')
|
||||
# print config_get_by_name_for_service_worker(
|
||||
# None,
|
||||
# 'f46983a4-6b42-48b0-8b66-66175fa07bc8',
|
||||
# 'database.use_db_reconnect'
|
||||
# )
|
||||
|
||||
# print region_perspective_get(None,
|
||||
# region_id='f7dcd175-27ef-46b5-997f-e6e572f320b0')
|
||||
#
|
||||
# print service_perspective_get(None,
|
||||
# service_id='11367a37-976f-468a-b8dd-77b28ee63cf4')
|
||||
#
|
||||
# print device_perspective_get(
|
||||
# None,
|
||||
# device_id='05b935b3-942c-439c-a6a4-9c3c73285430')
|
||||
|
||||
# persp = infra_perspective_get(None)
|
||||
# import json
|
||||
# perp_json = json.dumps(persp, indent=4)
|
||||
# print perp_json
|
|
@ -0,0 +1,123 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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 alembic
|
||||
from alembic import config as alembic_config
|
||||
import alembic.migration as alembic_migration
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_db import exception as db_exc
|
||||
|
||||
from namos.db.sqlalchemy import api as sqla_api
|
||||
from namos.db.sqlalchemy import models
|
||||
|
||||
|
||||
# Following commands are based on sqlalchemy
|
||||
def version(config=None, engine=None):
|
||||
"""Current database version.
|
||||
|
||||
:returns: Database version
|
||||
:rtype: string
|
||||
"""
|
||||
if engine is None:
|
||||
engine = sqla_api.get_engine()
|
||||
with engine.connect() as conn:
|
||||
context = alembic_migration.MigrationContext.configure(conn)
|
||||
return context.get_current_revision()
|
||||
|
||||
|
||||
def create_schema(config=None, engine=None):
|
||||
"""Create database schema from models description.
|
||||
|
||||
Can be used for initial installation instead of upgrade('head').
|
||||
"""
|
||||
if engine is None:
|
||||
engine = sqla_api.get_engine()
|
||||
|
||||
if version(engine=engine) is not None:
|
||||
raise db_exc.DbMigrationError("DB schema is already under version"
|
||||
" control. Use upgrade instead")
|
||||
|
||||
models.BASE.metadata.create_all(engine)
|
||||
stamp('head', config=config)
|
||||
|
||||
|
||||
# Following commands are alembic commands
|
||||
|
||||
def _alembic_config():
|
||||
# TODO(kanagaraj-manickam): It is an hack to use database.connection
|
||||
# for all alembic related commands
|
||||
|
||||
path = os.path.join(os.path.dirname(__file__), 'alembic.ini')
|
||||
config = alembic_config.Config(path)
|
||||
config.set_main_option('sqlalchemy.url', cfg.CONF.database.connection)
|
||||
return config
|
||||
|
||||
|
||||
def upgrade(revision, config=None):
|
||||
"""Used for upgrading database.
|
||||
|
||||
:param version: Desired database version
|
||||
:type version: string
|
||||
"""
|
||||
revision = revision or 'head'
|
||||
config = config or _alembic_config()
|
||||
|
||||
alembic.command.upgrade(config, revision)
|
||||
|
||||
|
||||
def downgrade(revision, config=None):
|
||||
"""Used for downgrading database.
|
||||
|
||||
:param version: Desired database version
|
||||
:type version: string
|
||||
"""
|
||||
revision = revision or 'base'
|
||||
config = config or _alembic_config()
|
||||
return alembic.command.downgrade(config, revision)
|
||||
|
||||
|
||||
def stamp(revision, config=None):
|
||||
"""Stamps database with provided revision.
|
||||
|
||||
Don't run any migrations.
|
||||
|
||||
:param revision: Should match one from repository or head - to stamp
|
||||
database with most recent revision
|
||||
:type revision: string
|
||||
"""
|
||||
config = config or _alembic_config()
|
||||
return alembic.command.stamp(config, revision=revision)
|
||||
|
||||
|
||||
def revision(message=None, autogenerate=False, config=None):
|
||||
"""Creates template for migration.
|
||||
|
||||
:param message: Text that will be used for migration title
|
||||
:type message: string
|
||||
:param autogenerate: If True - generates diff based on current database
|
||||
state
|
||||
:type autogenerate: bool
|
||||
"""
|
||||
config = config or _alembic_config()
|
||||
return alembic.command.revision(config, message=message,
|
||||
autogenerate=autogenerate)
|
||||
|
||||
|
||||
def history(config=None):
|
||||
"""List the available versions."""
|
||||
config = config or _alembic_config()
|
||||
return alembic.command.history(config)
|
|
@ -0,0 +1,294 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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.
|
||||
|
||||
"""
|
||||
SQLAlchemy models for namos database
|
||||
"""
|
||||
|
||||
import sqlalchemy
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
import uuid
|
||||
|
||||
from namos.db.sqlalchemy.types import Json
|
||||
from namos.db.sqlalchemy.types import Uuid
|
||||
from oslo_db.sqlalchemy import models
|
||||
from oslo_utils import timeutils
|
||||
|
||||
|
||||
BASE = declarative_base()
|
||||
|
||||
|
||||
class NamosBase(models.ModelBase,
|
||||
models.TimestampMixin):
|
||||
# TODO(kanagaraj-manickam) Make this as db independent
|
||||
__table_args__ = {'mysql_engine': 'InnoDB'}
|
||||
|
||||
id = sqlalchemy.Column(Uuid, primary_key=True,
|
||||
default=lambda: str(uuid.uuid4()))
|
||||
name = sqlalchemy.Column(sqlalchemy.String(255),
|
||||
# unique=True,
|
||||
nullable=False,
|
||||
default=lambda: str(uuid.uuid4()))
|
||||
|
||||
def expire(self, session, attrs=None):
|
||||
session.expire(self, attrs)
|
||||
|
||||
def refresh(self, session, attrs=None):
|
||||
session.refresh(self, attrs)
|
||||
|
||||
def delete(self, session):
|
||||
session.delete(self)
|
||||
session.flush()
|
||||
|
||||
def update_and_save(self, values, session):
|
||||
self.update(values)
|
||||
self.save(session)
|
||||
|
||||
def __str__(self):
|
||||
return "{id:%s, name:%s}" % (self.id, self.name)
|
||||
|
||||
def __repr__(self):
|
||||
return str(self.to_dict())
|
||||
|
||||
def to_dict(self):
|
||||
result = dict()
|
||||
for k, v in self.iteritems():
|
||||
if not str(k).endswith('_at'):
|
||||
result[k] = v
|
||||
return result
|
||||
|
||||
|
||||
class SoftDelete(object):
|
||||
deleted_at = sqlalchemy.Column(sqlalchemy.DateTime)
|
||||
|
||||
def soft_delete(self, session):
|
||||
self.update_and_save({'deleted_at': timeutils.utcnow()},
|
||||
session=session)
|
||||
|
||||
|
||||
class StateAware(object):
|
||||
status = sqlalchemy.Column(
|
||||
'status',
|
||||
sqlalchemy.String(64),
|
||||
nullable=False)
|
||||
|
||||
|
||||
class Description(object):
|
||||
description = sqlalchemy.Column(sqlalchemy.Text)
|
||||
|
||||
|
||||
class Extra(object):
|
||||
extra = sqlalchemy.Column(Json)
|
||||
|
||||
|
||||
class Region(BASE,
|
||||
NamosBase,
|
||||
SoftDelete,
|
||||
Extra):
|
||||
__tablename__ = 'region'
|
||||
|
||||
# Its of type String to match with keystone region id
|
||||
keystone_region_id = sqlalchemy.Column(
|
||||
sqlalchemy.String(255),
|
||||
nullable=False)
|
||||
|
||||
|
||||
class Device(BASE,
|
||||
NamosBase,
|
||||
SoftDelete,
|
||||
StateAware,
|
||||
Description,
|
||||
Extra):
|
||||
__tablename__ = 'device'
|
||||
|
||||
display_name = sqlalchemy.Column(sqlalchemy.String(255))
|
||||
parent_id = sqlalchemy.Column(
|
||||
Uuid,
|
||||
sqlalchemy.ForeignKey('device.id'))
|
||||
region_id = sqlalchemy.Column(
|
||||
Uuid,
|
||||
sqlalchemy.ForeignKey('region.id'),
|
||||
nullable=False)
|
||||
# TODO(kanagaraj-manickam) owner with keystone user id as one field??
|
||||
|
||||
|
||||
class DeviceEndpoint(BASE,
|
||||
NamosBase,
|
||||
Extra):
|
||||
__tablename__ = 'device_endpoint'
|
||||
|
||||
device_id = sqlalchemy.Column(
|
||||
Uuid,
|
||||
sqlalchemy.ForeignKey('device.id'),
|
||||
nullable=False)
|
||||
type = sqlalchemy.Column(
|
||||
sqlalchemy.String(32)
|
||||
)
|
||||
connection = sqlalchemy.Column(
|
||||
Json,
|
||||
nullable=False)
|
||||
|
||||
|
||||
class DeviceDriver(BASE,
|
||||
NamosBase,
|
||||
SoftDelete,
|
||||
Extra):
|
||||
__tablename__ = 'device_driver'
|
||||
|
||||
endpoint_id = sqlalchemy.Column(
|
||||
Uuid,
|
||||
sqlalchemy.ForeignKey('device_endpoint.id')
|
||||
)
|
||||
|
||||
device_id = sqlalchemy.Column(
|
||||
Uuid,
|
||||
sqlalchemy.ForeignKey('device.id'))
|
||||
|
||||
device_driver_class_id = sqlalchemy.Column(
|
||||
Uuid,
|
||||
sqlalchemy.ForeignKey('device_driver_class.id')
|
||||
)
|
||||
service_worker_id = sqlalchemy.Column(
|
||||
Uuid,
|
||||
sqlalchemy.ForeignKey('service_worker.id')
|
||||
)
|
||||
|
||||
# List of supported drivers in a given openstack release. so when
|
||||
# openstack is released, migration script could be updated to pre-populate
|
||||
# drivers in this table, which helps to track the drivers being released
|
||||
# in the given openstack version.
|
||||
|
||||
|
||||
class DeviceDriverClass(BASE,
|
||||
NamosBase,
|
||||
SoftDelete,
|
||||
Extra):
|
||||
__tablename__ = 'device_driver_class'
|
||||
|
||||
# TODO(kanagaraj-manickam) Correct the max python class path here
|
||||
python_class = sqlalchemy.Column(
|
||||
sqlalchemy.String(64),
|
||||
nullable=False
|
||||
)
|
||||
# service type like compute, network, volume, etc
|
||||
type = sqlalchemy.Column(
|
||||
sqlalchemy.String(64),
|
||||
nullable=False
|
||||
)
|
||||
|
||||
# TODO(kanagaraj-manickam) add vendor,
|
||||
# additional details like protocol, etc,
|
||||
# Capture all related driver details
|
||||
|
||||
|
||||
class Service(BASE,
|
||||
NamosBase,
|
||||
SoftDelete,
|
||||
Extra):
|
||||
__tablename__ = 'service'
|
||||
|
||||
keystone_service_id = sqlalchemy.Column(
|
||||
Uuid,
|
||||
nullable=False)
|
||||
|
||||
|
||||
class ServiceNode(BASE,
|
||||
NamosBase,
|
||||
SoftDelete,
|
||||
Description,
|
||||
Extra):
|
||||
__tablename__ = 'service_node'
|
||||
|
||||
fqdn = sqlalchemy.Column(
|
||||
sqlalchemy.String(128),
|
||||
nullable=False)
|
||||
region_id = sqlalchemy.Column(
|
||||
Uuid,
|
||||
sqlalchemy.ForeignKey('region.id'))
|
||||
|
||||
|
||||
class ServiceComponent(BASE,
|
||||
NamosBase,
|
||||
SoftDelete,
|
||||
Description,
|
||||
Extra):
|
||||
__tablename__ = 'service_component'
|
||||
|
||||
node_id = sqlalchemy.Column(
|
||||
Uuid,
|
||||
sqlalchemy.ForeignKey('service_node.id'),
|
||||
nullable=False)
|
||||
service_id = sqlalchemy.Column(
|
||||
Uuid,
|
||||
sqlalchemy.ForeignKey('service.id'),
|
||||
nullable=False)
|
||||
|
||||
|
||||
class ServiceWorker(BASE,
|
||||
NamosBase,
|
||||
SoftDelete,
|
||||
Extra):
|
||||
__tablename__ = 'service_worker'
|
||||
|
||||
pid = sqlalchemy.Column(
|
||||
sqlalchemy.String(32),
|
||||
nullable=False
|
||||
)
|
||||
host = sqlalchemy.Column(
|
||||
sqlalchemy.String(248),
|
||||
nullable=False
|
||||
)
|
||||
service_component_id = sqlalchemy.Column(
|
||||
Uuid,
|
||||
sqlalchemy.ForeignKey('service_component.id'),
|
||||
nullable=False)
|
||||
|
||||
|
||||
class OsloConfig(BASE,
|
||||
NamosBase,
|
||||
SoftDelete,
|
||||
Extra):
|
||||
__tablename__ = 'oslo_config'
|
||||
|
||||
default_value = sqlalchemy.Column(
|
||||
sqlalchemy.Text
|
||||
)
|
||||
help = sqlalchemy.Column(
|
||||
sqlalchemy.Text,
|
||||
nullable=False,
|
||||
default=''
|
||||
)
|
||||
type = sqlalchemy.Column(
|
||||
sqlalchemy.String(16),
|
||||
nullable=False
|
||||
)
|
||||
value = sqlalchemy.Column(
|
||||
sqlalchemy.Text
|
||||
)
|
||||
required = sqlalchemy.Column(
|
||||
sqlalchemy.Boolean,
|
||||
default=False
|
||||
)
|
||||
secret = sqlalchemy.Column(
|
||||
sqlalchemy.Boolean,
|
||||
default=False
|
||||
)
|
||||
file = sqlalchemy.Column(
|
||||
sqlalchemy.String(512)
|
||||
)
|
||||
service_worker_id = sqlalchemy.Column(
|
||||
Uuid,
|
||||
sqlalchemy.ForeignKey('service_worker.id'),
|
||||
nullable=False
|
||||
)
|
|
@ -0,0 +1,55 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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 json
|
||||
import uuid
|
||||
|
||||
from sqlalchemy.dialects import mysql
|
||||
from sqlalchemy.types import String
|
||||
from sqlalchemy.types import Text
|
||||
from sqlalchemy.types import TypeDecorator
|
||||
|
||||
|
||||
class Json(TypeDecorator):
|
||||
impl = Text
|
||||
|
||||
def load_dialect_impl(self, dialect):
|
||||
if dialect.name == 'mysql':
|
||||
return dialect.type_descriptor(mysql.LONGTEXT())
|
||||
else:
|
||||
return self.impl
|
||||
|
||||
def process_bind_param(self, value, dialect):
|
||||
return json.dumps(value)
|
||||
|
||||
def process_result_value(self, value, dialect):
|
||||
return json.loads(value)
|
||||
|
||||
|
||||
class Uuid(TypeDecorator):
|
||||
impl = String(36)
|
||||
|
||||
def process_bind_param(self, value, dialect):
|
||||
if value is not None:
|
||||
try:
|
||||
uuid.UUID(value, version=4)
|
||||
except ValueError:
|
||||
raise ValueError(
|
||||
"Invalid format. It should be in UUID v4 format")
|
||||
|
||||
return value
|
||||
|
||||
def process_result_value(self, value, dialect):
|
||||
return value
|
|
@ -2,4 +2,14 @@
|
|||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
|
||||
pbr>=1.6
|
||||
#common
|
||||
pbr>=1.6 # Apache-2.0
|
||||
oslo.config>=3.7.0 # Apache-2.0
|
||||
oslo.i18n>=2.1.0 # Apache-2.0
|
||||
oslo.log>=1.14.0 # Apache-2.0
|
||||
#db layer
|
||||
oslo.db>=4.1.0 # Apache-2.0
|
||||
SQLAlchemy<1.1.0,>=1.0.10 # MIT
|
||||
sqlalchemy-migrate>=0.9.6 # Apache-2.0
|
||||
PyMySQL
|
||||
#rpc service layer
|
||||
|
|
Loading…
Reference in New Issue