dictionary controllers for namespace and capability_type
Change-Id: I931425d6fe6f95d0d616d5e3f6efe852b2863b53
This commit is contained in:
parent
cd9adfe81d
commit
99287f3f00
77
config.py
77
config.py
@ -13,6 +13,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
# Server Specific Configurations
|
||||
server = {
|
||||
'port': '21075',
|
||||
@ -59,9 +61,84 @@ wsme = {
|
||||
'debug': True
|
||||
}
|
||||
|
||||
|
||||
# Custom Configurations must be in Python dictionary format::
|
||||
#
|
||||
# foo = {'bar':'baz'}
|
||||
#
|
||||
# All configurations are accessible at::
|
||||
# pecan.conf
|
||||
|
||||
# oslo config
|
||||
keystone_group = cfg.OptGroup('keystone')
|
||||
keystone_opts = [
|
||||
cfg.StrOpt('auth_url',
|
||||
default='http://192.168.40.10:5000/v2.0',
|
||||
help='keystone authorization url'),
|
||||
cfg.StrOpt('username',
|
||||
default='admin',
|
||||
help='keystone username'),
|
||||
cfg.StrOpt('password',
|
||||
default='secretword',
|
||||
help='keystone password'),
|
||||
cfg.StrOpt('tenant_name',
|
||||
default='admin',
|
||||
help='keystone tenant name')
|
||||
|
||||
]
|
||||
cfg.CONF.register_group(keystone_group)
|
||||
cfg.CONF.register_opts(keystone_opts, group=keystone_group)
|
||||
|
||||
# DEFAULT group
|
||||
default_controller_group = cfg.OptGroup('DEFAULT')
|
||||
default_controller_opts = [
|
||||
cfg.StrOpt(
|
||||
'persistence_type',
|
||||
default="memory",
|
||||
help=("persistence options. "
|
||||
"values = 'memory' or 'file' or 'db"))
|
||||
]
|
||||
|
||||
cfg.CONF.register_group(default_controller_group)
|
||||
cfg.CONF.register_opts(default_controller_opts,
|
||||
group=default_controller_group)
|
||||
|
||||
# FILE_PERSISTENCE group
|
||||
file_controller_group = cfg.OptGroup('FILE_PERSISTENCE')
|
||||
file_controller_opts = [
|
||||
cfg.StrOpt(
|
||||
'dictionary_folder',
|
||||
default="/tmp/graffiti-dictionary/",
|
||||
help=("Absolute path of the file for persisting dictionary")
|
||||
)
|
||||
]
|
||||
|
||||
cfg.CONF.register_group(file_controller_group)
|
||||
cfg.CONF.register_opts(file_controller_opts,
|
||||
group=file_controller_group)
|
||||
|
||||
|
||||
# Used for remote debugging, like pychcharms or pydev
|
||||
# To enable remote debugging in pycharms, requires that you put the
|
||||
# pycharm-debug.egg in the python path. E.g.
|
||||
#
|
||||
# Include the pycharm-debug.egg archive.
|
||||
# e.g. /home/<USERNAME>/pycharm-3.1.1/pycharm-debug.egg
|
||||
# You can do it in a number of ways, for example:
|
||||
# Add the archive to PYTHONPATH.e,g,
|
||||
# export PYTHONPATH+=.:/home/<USERNAME>/pycharm-3.1.1/pycharm-debug.egg
|
||||
# Append the archive to sys.path. e.g.
|
||||
# import sys
|
||||
# sys.path.append('/home/<USERNANE>/pycharm-3.1.1/pycharm-debug.egg')
|
||||
# Just copy the pydev from the archive to the directory where your remote
|
||||
# script resides.
|
||||
#
|
||||
# You will need to setup a debug configuration in your pycharms and start the
|
||||
# debugger BEFORE starting pecan
|
||||
# This is because the following code connects from here to your pycharms
|
||||
# (or your pydev)
|
||||
pydevd = {
|
||||
'enabled': True,
|
||||
'port': 22075,
|
||||
'bindhost': 'localhost'
|
||||
}
|
||||
|
7
etc/graffiti.conf.sample
Normal file
7
etc/graffiti.conf.sample
Normal file
@ -0,0 +1,7 @@
|
||||
[DEFAULT]
|
||||
|
||||
#Allowed values= memory, file, db. Default value is memory
|
||||
persistence_type=memory
|
||||
|
||||
[FILE_PERSISTENCE]
|
||||
dictionary_folder=/tmp/graffiti-dictionary/
|
@ -26,6 +26,22 @@ CONF = cfg.CONF
|
||||
|
||||
def setup_app(config):
|
||||
|
||||
if hasattr(config, 'pydevd') and config.pydevd.enabled:
|
||||
try:
|
||||
print(
|
||||
'Remote debug set to true(config.pydevd). '
|
||||
'Attempting connection'
|
||||
)
|
||||
import pydevd
|
||||
pydevd.settrace(
|
||||
config.pydevd.bindhost,
|
||||
port=config.pydevd.port,
|
||||
stdoutToServer=True,
|
||||
stderrToServer=True,
|
||||
suspend=False)
|
||||
except Exception as e:
|
||||
print "Debug Connection Error:", e
|
||||
|
||||
model.init_model()
|
||||
app_conf = dict(config.app)
|
||||
|
||||
|
@ -15,42 +15,122 @@
|
||||
|
||||
from pecan.rest import RestController
|
||||
|
||||
from wsme.api import Response
|
||||
from wsmeext.pecan import wsexpose
|
||||
|
||||
from graffiti.api.controllers.v1.captype_controller_factory \
|
||||
import CapTypeControllerFactory
|
||||
from graffiti.api.model.v1.capability_type import CapabilityType
|
||||
from ns_controller_factory import NSControllerFactory
|
||||
from oslo.config import cfg
|
||||
|
||||
|
||||
import six
|
||||
|
||||
capability_types = []
|
||||
|
||||
|
||||
class CapabilityTypeController(RestController):
|
||||
def __init__(self):
|
||||
super(RestController, self).__init__()
|
||||
self.status = 200
|
||||
self._cap_controller = None
|
||||
self._ns_controller = None
|
||||
self._load_controller()
|
||||
|
||||
def _load_controller(self):
|
||||
controller_type = cfg.CONF.DEFAULT.persistence_type
|
||||
self._cap_controller = CapTypeControllerFactory.create(controller_type)
|
||||
self._ns_controller = NSControllerFactory.get()
|
||||
|
||||
@wsexpose
|
||||
def options():
|
||||
pass
|
||||
|
||||
@wsexpose(CapabilityType, six.text_type)
|
||||
def get_one(self, name):
|
||||
global capability_types
|
||||
@wsexpose(CapabilityType, six.text_type, six.text_type)
|
||||
def get_one(self, name, namespace):
|
||||
captype = self._cap_controller.get_capability_type(name, namespace)
|
||||
return captype
|
||||
|
||||
for capability_type in capability_types:
|
||||
if capability_type.name.lower() == name.lower():
|
||||
return capability_type
|
||||
|
||||
res = CapabilityType(CapabilityType(), status_code=404,
|
||||
error="CapabilityType Not Found")
|
||||
return res
|
||||
|
||||
@wsexpose([CapabilityType])
|
||||
def get_all(self):
|
||||
global capability_types
|
||||
return capability_types
|
||||
@wsexpose([CapabilityType], six.text_type)
|
||||
def get_all(self, query_string=None):
|
||||
captype_list = self._cap_controller.find_capability_types(query_string)
|
||||
return captype_list
|
||||
|
||||
@wsexpose(CapabilityType, body=CapabilityType)
|
||||
def post(self, capability_type):
|
||||
global capability_types
|
||||
capability_types.append(capability_type)
|
||||
"""Create Capability Type
|
||||
@type capability_type:
|
||||
graffiti.api.model.v1.capability_type.CapabilityType
|
||||
@param capability_type: Capability type
|
||||
"""
|
||||
|
||||
# Check if namespace exists
|
||||
namespace_found = self.__check_existing_namespace(
|
||||
capability_type.namespace
|
||||
)
|
||||
|
||||
# Check if derived capability type exists
|
||||
derived_checked = self.__check_derived_capability(
|
||||
capability_type.derived_from
|
||||
)
|
||||
|
||||
if namespace_found and derived_checked:
|
||||
self._cap_controller.set_capability_type(
|
||||
capability_type
|
||||
)
|
||||
return capability_type
|
||||
else:
|
||||
res = Response(
|
||||
CapabilityType(),
|
||||
status_code=404,
|
||||
error="Provided namespace %s doesnt exist" %
|
||||
capability_type.namespace)
|
||||
return res
|
||||
|
||||
@wsexpose(CapabilityType, six.text_type, six.text_type,
|
||||
body=CapabilityType)
|
||||
def put(self, name, namespace, capability_type):
|
||||
|
||||
# Check if namespace exists
|
||||
namespace_found = self.__check_existing_namespace(
|
||||
capability_type.namespace
|
||||
)
|
||||
|
||||
# Check if derived capability type exists
|
||||
derived_checked = self.__check_derived_capability(
|
||||
capability_type.derived_from
|
||||
)
|
||||
|
||||
if namespace_found and derived_checked:
|
||||
self._cap_controller.put_capability_type(
|
||||
name, namespace, capability_type
|
||||
)
|
||||
return capability_type
|
||||
else:
|
||||
res = Response(
|
||||
CapabilityType(),
|
||||
status_code=404,
|
||||
error="Provided namespace %s doesnt exist" %
|
||||
capability_type.namespace)
|
||||
return res
|
||||
|
||||
@wsexpose(CapabilityType, six.text_type, six.text_type)
|
||||
def delete(self, name, namespace):
|
||||
captype = self._cap_controller.delete_capability_type(
|
||||
name,
|
||||
namespace
|
||||
)
|
||||
return captype
|
||||
|
||||
def __check_derived_capability(self, derived_from):
|
||||
derived_checked = True
|
||||
if derived_from:
|
||||
derived_checked = False
|
||||
derived_cap_found = self._cap_controller.get_capability_type(
|
||||
derived_from.name, derived_from.namespace)
|
||||
if derived_cap_found:
|
||||
derived_checked = True
|
||||
|
||||
return derived_checked
|
||||
|
||||
def __check_existing_namespace(self, namespace_name):
|
||||
return self._ns_controller.get_namespace(namespace_name)
|
||||
|
39
graffiti/api/controllers/v1/captype_controller.py
Normal file
39
graffiti/api/controllers/v1/captype_controller.py
Normal file
@ -0,0 +1,39 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
class CapabilityTypeControllerBase(object):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(CapabilityTypeControllerBase, self).__init__(**kwargs)
|
||||
self._type = 'None'
|
||||
|
||||
def get_capability_type(self, name, namespace):
|
||||
return None
|
||||
|
||||
def get_type(self):
|
||||
return self._type
|
||||
|
||||
def find_capability_types(self, query_string):
|
||||
return []
|
||||
|
||||
def set_capability_type(self, capability_type=None):
|
||||
pass
|
||||
|
||||
def put_capability_type(self, name, namespace, capability_type=None):
|
||||
pass
|
||||
|
||||
def delete_capability_type(self, name, namespace):
|
||||
pass
|
42
graffiti/api/controllers/v1/captype_controller_factory.py
Normal file
42
graffiti/api/controllers/v1/captype_controller_factory.py
Normal file
@ -0,0 +1,42 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 graffiti.api.controllers.v1.captype_db_controller \
|
||||
import DBCapabilityTypeController
|
||||
from graffiti.api.controllers.v1.captype_file_controller \
|
||||
import FileCapabilityTypeController
|
||||
from graffiti.api.controllers.v1.captype_mem_controller \
|
||||
import MemCapabilityTypeController
|
||||
|
||||
|
||||
class CapTypeControllerFactory(object):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(CapTypeControllerFactory, self).__init__(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def create(controller_type, **kwargs):
|
||||
if controller_type.lower() == 'memory':
|
||||
print "Dictionary persistence = memory"
|
||||
return MemCapabilityTypeController(**kwargs)
|
||||
elif controller_type.lower() == "db":
|
||||
print "Dictionary persistence = db"
|
||||
return DBCapabilityTypeController(**kwargs)
|
||||
elif controller_type.lower() == "file":
|
||||
print "Dictionary persistence = File"
|
||||
return FileCapabilityTypeController(**kwargs)
|
||||
|
||||
return None
|
39
graffiti/api/controllers/v1/captype_db_controller.py
Normal file
39
graffiti/api/controllers/v1/captype_db_controller.py
Normal file
@ -0,0 +1,39 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 captype_controller import CapabilityTypeControllerBase
|
||||
|
||||
|
||||
# TODO(Wayne): Implement the db controller
|
||||
class DBCapabilityTypeController(CapabilityTypeControllerBase):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(DBCapabilityTypeController, self).__init__(**kwargs)
|
||||
self._type = 'DBCapabilityTypeController'
|
||||
|
||||
def get_capability_type(self, name, namespace):
|
||||
pass
|
||||
|
||||
def find_capability_types(self, query_string):
|
||||
pass
|
||||
|
||||
def set_capability_type(self, capability_type=None):
|
||||
pass
|
||||
|
||||
def put_capability_type(self, name, namespace, capability_type=None):
|
||||
pass
|
||||
|
||||
def delete_capability_type(self, name, namespace):
|
||||
pass
|
84
graffiti/api/controllers/v1/captype_file_controller.py
Normal file
84
graffiti/api/controllers/v1/captype_file_controller.py
Normal file
@ -0,0 +1,84 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 captype_controller import CapabilityTypeControllerBase
|
||||
from graffiti.api.model.v1.capability_type import CapabilityType
|
||||
import json
|
||||
from oslo.config import cfg
|
||||
from wsme.rest.json import fromjson
|
||||
from wsme.rest.json import tojson
|
||||
|
||||
|
||||
class FileCapabilityTypeController(CapabilityTypeControllerBase):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(FileCapabilityTypeController, self).__init__(**kwargs)
|
||||
self._type = 'FileCapabilityTypeController'
|
||||
self._graffiti_folder = cfg.CONF.FILE_PERSISTENCE.dictionary_folder
|
||||
self._filename = "dictionary.json"
|
||||
self._dictionaryfile = self._graffiti_folder + self._filename
|
||||
self._capability_types = self.__file_to_memory()
|
||||
|
||||
def get_capability_type(self, name, namespace):
|
||||
id = namespace + ":" + name
|
||||
return self._capability_types[id]
|
||||
|
||||
def find_capability_types(self, query_string):
|
||||
return self._capability_types.itervalues()
|
||||
|
||||
def set_capability_type(self, capability_type):
|
||||
id = capability_type.namespace + ":" + capability_type.name
|
||||
self._capability_types[id] = capability_type
|
||||
self.__memory_to_file()
|
||||
return capability_type
|
||||
|
||||
def put_capability_type(self, name, namespace, capability_type):
|
||||
id = namespace + ":" + name
|
||||
self._capability_types[id] = capability_type
|
||||
self.__memory_to_file()
|
||||
return capability_type
|
||||
|
||||
def delete_capability_type(self, name, namespace):
|
||||
id = namespace + ":" + name
|
||||
capability_type = None
|
||||
if self._capability_types[id]:
|
||||
capability_type = self._capability_types[id]
|
||||
self._capability_types.pop(id)
|
||||
self.__memory_to_file()
|
||||
return capability_type
|
||||
|
||||
def __file_to_memory(self):
|
||||
try:
|
||||
capability_types = {}
|
||||
with open(self._dictionaryfile, "r") as gfile:
|
||||
doc = json.load(gfile)
|
||||
for id in doc:
|
||||
capability_types[id] = fromjson(CapabilityType, doc[id])
|
||||
return capability_types
|
||||
|
||||
except IOError:
|
||||
with open(self._dictionaryfile, "w+") as gfile:
|
||||
gfile.write("")
|
||||
return {}
|
||||
|
||||
def __memory_to_file(self):
|
||||
file_capability_types = {}
|
||||
for (id, capability_type) in self._capability_types.items():
|
||||
json_data = tojson(CapabilityType, capability_type)
|
||||
file_capability_types[id] = json_data
|
||||
|
||||
with open(self._dictionaryfile, "w+") as gfile:
|
||||
json.dump(file_capability_types, gfile)
|
52
graffiti/api/controllers/v1/captype_mem_controller.py
Normal file
52
graffiti/api/controllers/v1/captype_mem_controller.py
Normal file
@ -0,0 +1,52 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 captype_controller import CapabilityTypeControllerBase
|
||||
|
||||
|
||||
class MemCapabilityTypeController(CapabilityTypeControllerBase):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(MemCapabilityTypeController, self).__init__(**kwargs)
|
||||
self._type = 'MemCapabilityTypeController'
|
||||
self._capability_types = {}
|
||||
|
||||
def get_capability_type(self, name, namespace):
|
||||
id = namespace + ":" + name
|
||||
return self._capability_types[id]
|
||||
|
||||
def find_capability_types(self, query_string):
|
||||
return self._capability_types.itervalues()
|
||||
|
||||
def set_capability_type(self, capability_type):
|
||||
id = capability_type.namespace + ":" + capability_type.name
|
||||
self._capability_types[id] = capability_type
|
||||
|
||||
return capability_type
|
||||
|
||||
def put_capability_type(self, name, namespace, capability_type):
|
||||
id = namespace + ":" + name
|
||||
self._capability_types[id] = capability_type
|
||||
|
||||
return capability_type
|
||||
|
||||
def delete_capability_type(self, name, namespace):
|
||||
id = namespace + ":" + name
|
||||
capability_type = None
|
||||
if self._capability_types[id]:
|
||||
capability_type = self._capability_types[id]
|
||||
self._capability_types.pop(id)
|
||||
|
||||
return capability_type
|
@ -17,40 +17,55 @@ from pecan.rest import RestController
|
||||
|
||||
from wsmeext.pecan import wsexpose
|
||||
|
||||
from graffiti.api.controllers.v1.ns_controller_factory\
|
||||
import NSControllerFactory
|
||||
from graffiti.api.model.v1.namespace import Namespace
|
||||
|
||||
from oslo.config import cfg
|
||||
import six
|
||||
|
||||
namespaces = []
|
||||
|
||||
|
||||
class NamespaceController(RestController):
|
||||
def __init__(self):
|
||||
super(RestController, self).__init__()
|
||||
self.status = 200
|
||||
self._controller = self._load_controller()
|
||||
|
||||
def _load_controller(self):
|
||||
controller_type = cfg.CONF.DEFAULT.persistence_type
|
||||
_controller = NSControllerFactory.create(controller_type)
|
||||
return _controller
|
||||
|
||||
@wsexpose
|
||||
def options():
|
||||
def options(self):
|
||||
pass
|
||||
|
||||
@wsexpose(Namespace, six.text_type)
|
||||
def get_one(self, name):
|
||||
global namespaces
|
||||
|
||||
for namespace in namespaces:
|
||||
if namespace.name.lower() == name.lower():
|
||||
return namespace
|
||||
|
||||
res = Namespace(Namespace(), status_code=404,
|
||||
error="Namespace Not Found")
|
||||
return res
|
||||
def get_one(self, namespace_name):
|
||||
namespace = self._controller.get_namespace(namespace_name)
|
||||
return namespace
|
||||
|
||||
@wsexpose([Namespace])
|
||||
def get_all(self):
|
||||
global namespaces
|
||||
return namespaces
|
||||
def get_all(self, query_string=None):
|
||||
namespace_list = self._controller.find_namespaces(query_string)
|
||||
return namespace_list
|
||||
|
||||
@wsexpose(Namespace, body=Namespace)
|
||||
def post(self, namespace):
|
||||
global namespaces
|
||||
namespaces.append(namespace)
|
||||
"""Create Namespace
|
||||
:namespace param:
|
||||
graffiti.api.model.v1.namespace.Namespace
|
||||
"""
|
||||
|
||||
self._controller.set_namespace(namespace)
|
||||
return namespace
|
||||
|
||||
@wsexpose(Namespace, six.text_type, body=Namespace)
|
||||
def put(self, namespace_name, namespace):
|
||||
self._controller.put_namespace(namespace_name, namespace)
|
||||
return namespace
|
||||
|
||||
@wsexpose(Namespace, six.text_type)
|
||||
def delete(self, namespace_name):
|
||||
print "namespace", namespace_name
|
||||
namespace = self._controller.delete_namespace(namespace_name)
|
||||
return namespace
|
||||
|
39
graffiti/api/controllers/v1/ns_controller.py
Executable file
39
graffiti/api/controllers/v1/ns_controller.py
Executable file
@ -0,0 +1,39 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
class NSTypeControllerBase(object):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(NSTypeControllerBase, self).__init__(**kwargs)
|
||||
self._type = 'None'
|
||||
|
||||
def get_namespace(self, namespace_name):
|
||||
return None
|
||||
|
||||
def get_type(self):
|
||||
return self._type
|
||||
|
||||
def find_namespaces(self, query_string):
|
||||
return []
|
||||
|
||||
def set_namespace(self, namespace):
|
||||
pass
|
||||
|
||||
def put_namespace(self, namespace_name, namespace):
|
||||
pass
|
||||
|
||||
def delete_namespace(self, namespace_name):
|
||||
pass
|
57
graffiti/api/controllers/v1/ns_controller_factory.py
Executable file
57
graffiti/api/controllers/v1/ns_controller_factory.py
Executable file
@ -0,0 +1,57 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 graffiti.api.controllers.v1.ns_db_controller \
|
||||
import DBNSController
|
||||
from graffiti.api.controllers.v1.ns_file_controller \
|
||||
import FileNSController
|
||||
from graffiti.api.controllers.v1.ns_mem_controller \
|
||||
import MemNSController
|
||||
from oslo.config import cfg
|
||||
|
||||
|
||||
class NSControllerFactory(object):
|
||||
|
||||
__controller = None
|
||||
__controller_type = cfg.CONF.DEFAULT.persistence_type
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(NSControllerFactory, self).__init__(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def create(controller_type, **kwargs):
|
||||
if controller_type.lower() == 'memory':
|
||||
print "Namespace persistence = memory"
|
||||
NSControllerFactory.__controller = MemNSController(**kwargs)
|
||||
return NSControllerFactory.__controller
|
||||
elif controller_type.lower() == "db":
|
||||
print "Namespace persistence = db"
|
||||
NSControllerFactory.__controller = DBNSController(**kwargs)
|
||||
return NSControllerFactory.__controller
|
||||
elif controller_type.lower() == "file":
|
||||
print "Namespace persistence = File"
|
||||
NSControllerFactory.__controller = FileNSController(**kwargs)
|
||||
return NSControllerFactory.__controller
|
||||
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get():
|
||||
if NSControllerFactory.__controller:
|
||||
return NSControllerFactory.__controller
|
||||
else:
|
||||
return NSControllerFactory.create(
|
||||
NSControllerFactory.__controller_type)
|
43
graffiti/api/controllers/v1/ns_db_controller.py
Executable file
43
graffiti/api/controllers/v1/ns_db_controller.py
Executable file
@ -0,0 +1,43 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 ns_controller import NSTypeControllerBase
|
||||
|
||||
|
||||
# TODO(Wayne): Implement the db controller
|
||||
class DBNSController(NSTypeControllerBase):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(DBNSController, self).__init__(**kwargs)
|
||||
self._type = 'DBNSController'
|
||||
|
||||
def get_type(self):
|
||||
return self._type
|
||||
|
||||
def get_namespace(self, namespace_name):
|
||||
pass
|
||||
|
||||
def find_namespaces(self, query_string):
|
||||
pass
|
||||
|
||||
def set_namespace(self, namespace):
|
||||
pass
|
||||
|
||||
def put_namespace(self, namespace_name, namespace):
|
||||
pass
|
||||
|
||||
def delete_namespace(self, namespace_name):
|
||||
pass
|
80
graffiti/api/controllers/v1/ns_file_controller.py
Executable file
80
graffiti/api/controllers/v1/ns_file_controller.py
Executable file
@ -0,0 +1,80 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 graffiti.api.model.v1.namespace import Namespace
|
||||
import json
|
||||
from ns_controller import NSTypeControllerBase
|
||||
from oslo.config import cfg
|
||||
from wsme.rest.json import fromjson
|
||||
from wsme.rest.json import tojson
|
||||
|
||||
|
||||
class FileNSController(NSTypeControllerBase):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(FileNSController, self).__init__(**kwargs)
|
||||
self._type = 'FileNSController'
|
||||
self._graffiti_folder = cfg.CONF.FILE_PERSISTENCE.dictionary_folder
|
||||
self._filename = "namespaces.json"
|
||||
self._namespacefile = self._graffiti_folder + self._filename
|
||||
self._namespaces = self.__file_to_memory()
|
||||
|
||||
def get_namespace(self, namespace_name):
|
||||
return self._namespaces[namespace_name]
|
||||
|
||||
def find_namespaces(self, query_string):
|
||||
return self._namespaces.itervalues()
|
||||
|
||||
def set_namespace(self, namespace):
|
||||
self._namespaces[namespace.name] = namespace
|
||||
self.__memory_to_file()
|
||||
return namespace
|
||||
|
||||
def put_namespace(self, namespace_name, namespace):
|
||||
self._namespaces[namespace_name] = namespace
|
||||
self.__memory_to_file()
|
||||
return namespace
|
||||
|
||||
def delete_namespace(self, namespace_name):
|
||||
namespace = None
|
||||
if self._namespaces[namespace_name]:
|
||||
namespace = self._namespaces[namespace_name]
|
||||
self._namespaces.pop(namespace_name)
|
||||
self.__memory_to_file()
|
||||
return namespace
|
||||
|
||||
def __file_to_memory(self):
|
||||
try:
|
||||
namespaces = {}
|
||||
with open(self._namespacefile, "r") as gfile:
|
||||
doc = json.load(gfile)
|
||||
for namespace in doc:
|
||||
namespaces[namespace] = fromjson(Namespace, doc[namespace])
|
||||
return namespaces
|
||||
|
||||
except IOError:
|
||||
with open(self._namespacefile, "w+") as gfile:
|
||||
gfile.write("")
|
||||
return {}
|
||||
|
||||
def __memory_to_file(self):
|
||||
namespaces = {}
|
||||
for (namespace_name, namespace) in self._namespaces.items():
|
||||
json_data = tojson(Namespace, namespace)
|
||||
namespaces[namespace_name] = json_data
|
||||
|
||||
with open(self._namespacefile, "w+") as gfile:
|
||||
json.dump(namespaces, gfile)
|
49
graffiti/api/controllers/v1/ns_mem_controller.py
Executable file
49
graffiti/api/controllers/v1/ns_mem_controller.py
Executable file
@ -0,0 +1,49 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 ns_controller import NSTypeControllerBase
|
||||
|
||||
|
||||
class MemNSController(NSTypeControllerBase):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(MemNSController, self).__init__(**kwargs)
|
||||
self._type = 'MemNSController'
|
||||
self._namespaces = {}
|
||||
|
||||
def get_type(self):
|
||||
return self._type
|
||||
|
||||
def get_namespace(self, namespace_name):
|
||||
return self._namespaces[namespace_name]
|
||||
|
||||
def find_namespaces(self, query_string):
|
||||
return self._namespaces.itervalues()
|
||||
|
||||
def set_namespace(self, namespace):
|
||||
self._namespaces[namespace.name] = namespace
|
||||
return namespace
|
||||
|
||||
def put_namespace(self, namespace_name, namespace):
|
||||
self._namespaces[namespace.name] = namespace
|
||||
return namespace
|
||||
|
||||
def delete_namespace(self, namespace_name):
|
||||
namespace = None
|
||||
if self._namespaces[namespace_name]:
|
||||
namespace = self._namespaces[namespace_name]
|
||||
self._namespaces.pop(namespace_name)
|
||||
|
||||
return namespace
|
@ -13,15 +13,19 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import pecan
|
||||
from pecan.rest import RestController
|
||||
|
||||
|
||||
from wsme.api import Response
|
||||
from wsmeext.pecan import wsexpose
|
||||
|
||||
from graffiti.api.model.v1.resource import Resource
|
||||
from graffiti.api.plugins.glance_image import GlanceImage
|
||||
|
||||
from graffiti.api.model.v1.resource_controller_factory import \
|
||||
ResourceControllerFactory
|
||||
|
||||
from graffiti.api.model.v1.resource_dao_factory import \
|
||||
ResourceDAOFactory
|
||||
|
||||
from graffiti.common.utils import _
|
||||
|
||||
@ -29,6 +33,8 @@ from oslo.config import cfg
|
||||
|
||||
import six
|
||||
|
||||
import keystoneclient.v2_0.client as ksclient
|
||||
|
||||
|
||||
resource_controller_group = cfg.OptGroup('resource_controller')
|
||||
resource_controller_opts = [
|
||||
@ -42,6 +48,11 @@ cfg.CONF.register_opts(resource_controller_opts,
|
||||
|
||||
|
||||
class ResourceController(RestController):
|
||||
|
||||
# TODO(Lakshmi): Lookup supported types from plugin registry
|
||||
local_resource_type = 'GFT:Local'
|
||||
glance_resource_type = 'OS::Glance:Image'
|
||||
|
||||
def __init__(self):
|
||||
super(ResourceController, self).__init__()
|
||||
|
||||
@ -53,37 +64,98 @@ class ResourceController(RestController):
|
||||
controller_type = cfg.CONF.resource_controller.type
|
||||
controller_type = controller_type if controller_type else 'Local'
|
||||
|
||||
_controller = ResourceControllerFactory.create(controller_type)
|
||||
_controller = ResourceDAOFactory.create(controller_type)
|
||||
|
||||
return _controller
|
||||
|
||||
@wsexpose()
|
||||
def options():
|
||||
def options(self):
|
||||
pass
|
||||
|
||||
@wsexpose(Resource, six.text_type)
|
||||
def get_one(self, id):
|
||||
res = self._controller.get_resource(id)
|
||||
if res:
|
||||
@wsexpose(Resource, six.text_type, six.text_type, six.text_type,
|
||||
six.text_type)
|
||||
def get_one(self, resource_id, resource_type=None, param1=None,
|
||||
param2=None):
|
||||
print "args:", resource_id, resource_type, param1, param2
|
||||
error_str = None
|
||||
if not resource_type:
|
||||
res = self._controller.get_resource(resource_id)
|
||||
return res
|
||||
elif resource_type.lower() == \
|
||||
ResourceController.glance_resource_type.lower():
|
||||
auth_token = pecan.request.headers.get('X-Auth-Token')
|
||||
endpoint_id = param1
|
||||
image_id = resource_id
|
||||
glance_public_url = None
|
||||
keystone = ksclient.Client(
|
||||
auth_url=cfg.CONF.keystone.auth_url,
|
||||
username=cfg.CONF.keystone.username,
|
||||
password=cfg.CONF.keystone.password,
|
||||
tenant_name=cfg.CONF.keystone.tenant_name)
|
||||
for endpoint in keystone.endpoints.list():
|
||||
if endpoint.id == endpoint_id:
|
||||
glance_public_url = endpoint.publicurl
|
||||
|
||||
res = Response(Resource(), status_code=404, error="Resource Not Found")
|
||||
# TODO(Lakshmi): Load plugins with plugin framework
|
||||
if auth_token and glance_public_url:
|
||||
glance_plugin = GlanceImage(
|
||||
glance_public_url,
|
||||
keystone.auth_token
|
||||
)
|
||||
res = glance_plugin.get_resource(image_id)
|
||||
if res:
|
||||
return res
|
||||
else:
|
||||
error_str = "Resource not found"
|
||||
else:
|
||||
error_str = "auth_token and/or endpointid not found"
|
||||
|
||||
res = Response(Resource(), status_code=404, error=error_str)
|
||||
return res
|
||||
|
||||
@wsexpose([Resource], six.text_type)
|
||||
def get_all(self, query_string=None):
|
||||
|
||||
res_list = self._controller.find_resources(query_string)
|
||||
if res_list:
|
||||
return res_list
|
||||
return res_list.itervalues()
|
||||
|
||||
return []
|
||||
|
||||
@wsexpose(Resource, six.text_type, body=Resource)
|
||||
def put(self, id, resource):
|
||||
|
||||
self._controller.set_resource(id, resource_definition=resource)
|
||||
def put(self, resource_id, resource):
|
||||
"""Modify resource
|
||||
:resource param: graffiti.api.model.v1.resource.Resource
|
||||
"""
|
||||
resource_type = resource.type
|
||||
if not resource_type:
|
||||
resource_type = ResourceController.local_resource_type
|
||||
if resource_type.lower() == \
|
||||
ResourceController.local_resource_type.lower():
|
||||
self._controller.set_resource(
|
||||
resource_id,
|
||||
resource_definition=resource
|
||||
)
|
||||
elif resource_type.lower() == \
|
||||
ResourceController.glance_resource_type.lower():
|
||||
auth_token = pecan.request.headers.get('X-Auth-Token')
|
||||
endpoint_id = resource.provider.id
|
||||
glance_public_url = None
|
||||
keystone = ksclient.Client(
|
||||
auth_url=cfg.CONF.keystone.auth_url,
|
||||
username=cfg.CONF.keystone.username,
|
||||
password=cfg.CONF.keystone.password,
|
||||
tenant_name=cfg.CONF.keystone.tenant_name)
|
||||
for endpoint in keystone.endpoints.list():
|
||||
if endpoint.id == endpoint_id:
|
||||
glance_public_url = endpoint.publicurl
|
||||
|
||||
# TODO(Lakshmi): Load plugins with plugin framework
|
||||
if auth_token and glance_public_url:
|
||||
glance_plugin = GlanceImage(
|
||||
glance_public_url,
|
||||
keystone.auth_token
|
||||
)
|
||||
glance_plugin.update_resource(resource)
|
||||
return resource
|
||||
|
||||
@wsexpose(Resource, body=Resource)
|
||||
|
@ -13,7 +13,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
#import json
|
||||
# import json
|
||||
|
||||
from pecan.hooks import PecanHook
|
||||
|
||||
|
@ -16,11 +16,17 @@
|
||||
import wsme
|
||||
from wsme import types
|
||||
|
||||
from graffiti.api.model.v1.derived_type import DerivedType
|
||||
from graffiti.api.model.v1.property_type import PropertyType
|
||||
|
||||
|
||||
class CapabilityType(types.Base):
|
||||
|
||||
name = wsme.wsattr(types.text, mandatory=True)
|
||||
namespace = wsme.wsattr(types.text, mandatory=True)
|
||||
description = wsme.wsattr(types.text, mandatory=False)
|
||||
properties = wsme.wsattr({types.text: PropertyType}, mandatory=False)
|
||||
derived_from = wsme.wsattr(DerivedType, mandatory=False)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(CapabilityType, self).__init__(**kwargs)
|
||||
|
27
graffiti/api/model/v1/derived_type.py
Normal file
27
graffiti/api/model/v1/derived_type.py
Normal file
@ -0,0 +1,27 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 wsme
|
||||
from wsme import types
|
||||
|
||||
|
||||
class DerivedType(types.Base):
|
||||
name = wsme.wsattr(types.text, mandatory=True)
|
||||
namespace = wsme.wsattr(types.text, mandatory=True)
|
||||
|
||||
_wsme_attr_order = ('name', 'namespace')
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(DerivedType, self).__init__(**kwargs)
|
@ -13,6 +13,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
import wsme
|
||||
from wsme import types
|
||||
|
||||
@ -20,7 +21,7 @@ from wsme import types
|
||||
class Namespace(types.Base):
|
||||
name = wsme.wsattr(types.text, mandatory=True)
|
||||
scope = wsme.wsattr(types.text, mandatory=True)
|
||||
owner = wsme.wsattr(types.text, mandatory=True)
|
||||
owner = wsme.wsattr(types.text, mandatory=False)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(Namespace, self).__init__(**kwargs)
|
||||
|
27
graffiti/api/model/v1/property_item_type.py
Executable file
27
graffiti/api/model/v1/property_item_type.py
Executable file
@ -0,0 +1,27 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 wsme
|
||||
from wsme import types
|
||||
|
||||
|
||||
class ItemType(types.Base):
|
||||
type = wsme.wsattr(types.text, mandatory=True)
|
||||
enum = wsme.wsattr([types.text], mandatory=False)
|
||||
|
||||
_wsme_attr_order = ('type', 'enum')
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(ItemType, self).__init__(**kwargs)
|
50
graffiti/api/model/v1/property_type.py
Normal file
50
graffiti/api/model/v1/property_type.py
Normal file
@ -0,0 +1,50 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 graffiti.api.model.v1.property_item_type import ItemType
|
||||
import wsme
|
||||
from wsme import types
|
||||
|
||||
|
||||
class PropertyType(types.Base):
|
||||
type = wsme.wsattr(types.text, mandatory=True)
|
||||
description = wsme.wsattr(types.text, mandatory=False)
|
||||
default = wsme.wsattr(types.text, mandatory=False)
|
||||
required = wsme.wsattr(bool, mandatory=False, default=False)
|
||||
|
||||
# fields for type = string
|
||||
minimum = wsme.wsattr(int, mandatory=False)
|
||||
maximum = wsme.wsattr(int, mandatory=False)
|
||||
|
||||
# fields for type = integer, number
|
||||
minLength = wsme.wsattr(int, mandatory=False)
|
||||
maxLength = wsme.wsattr(int, mandatory=False)
|
||||
pattern = wsme.wsattr(types.text, mandatory=False)
|
||||
confidential = wsme.wsattr(bool, mandatory=False)
|
||||
|
||||
# fields for type = array
|
||||
items = wsme.wsattr(ItemType, mandatory=False)
|
||||
uniqueItems = wsme.wsattr(bool, mandatory=False)
|
||||
minItems = wsme.wsattr(int, mandatory=False)
|
||||
maxItems = wsme.wsattr(int, mandatory=False)
|
||||
additionalItems = wsme.wsattr(bool, mandatory=False)
|
||||
|
||||
_wsme_attr_order = ('type', 'description', 'default', 'required',
|
||||
'minimum', 'maximum', 'minLength', 'maxLength',
|
||||
'pattern', 'confidential', 'items', 'uniqueItems',
|
||||
'additionalItems')
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(PropertyType, self).__init__(**kwargs)
|
@ -14,10 +14,10 @@
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
class ResourceControllerBase(object):
|
||||
class ResourceDAOBase(object):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(ResourceControllerBase, self).__init__(**kwargs)
|
||||
super(ResourceDAOBase, self).__init__(**kwargs)
|
||||
|
||||
self._type = 'None'
|
||||
|
||||
@ -34,12 +34,12 @@ class ResourceControllerBase(object):
|
||||
pass
|
||||
|
||||
|
||||
class LocalResourceController(ResourceControllerBase):
|
||||
class LocalResourceDAO(ResourceDAOBase):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(LocalResourceController, self).__init__(**kwargs)
|
||||
super(LocalResourceDAO, self).__init__(**kwargs)
|
||||
|
||||
self._type = 'LocalResourceController'
|
||||
self._type = 'LocalResourceDAO'
|
||||
|
||||
self._resources = dict()
|
||||
self._last_id = 0
|
@ -13,17 +13,17 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from graffiti.api.model.v1.resource_controller import LocalResourceController
|
||||
from graffiti.api.model.v1.resource_dao import LocalResourceDAO
|
||||
|
||||
|
||||
class ResourceControllerFactory(object):
|
||||
class ResourceDAOFactory(object):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(ResourceControllerFactory, self).__init__(**kwargs)
|
||||
super(ResourceDAOFactory, self).__init__(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def create(controller_type, **kwargs):
|
||||
if controller_type.lower() == 'local':
|
||||
return LocalResourceController(**kwargs)
|
||||
def create(dao_type, **kwargs):
|
||||
if dao_type.lower() == 'local':
|
||||
return LocalResourceDAO(**kwargs)
|
||||
|
||||
return None
|
1
graffiti/api/plugins/__init__.py
Normal file
1
graffiti/api/plugins/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
__author__ = 'lakshmi'
|
95
graffiti/api/plugins/glance_image.py
Normal file
95
graffiti/api/plugins/glance_image.py
Normal file
@ -0,0 +1,95 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 glanceclient import Client
|
||||
from graffiti.api.model.v1.capability import Capability
|
||||
from graffiti.api.model.v1.property import Property
|
||||
from graffiti.api.model.v1.resource import Resource
|
||||
|
||||
|
||||
class GlanceImage(object):
|
||||
|
||||
def __init__(self, glance_endpoint, auth_token):
|
||||
self.glance_endpoint = glance_endpoint
|
||||
self.auth_token = auth_token
|
||||
self.glance = Client('1', endpoint=glance_endpoint, token=auth_token)
|
||||
self.separator = "."
|
||||
|
||||
def get_resource(self, image_id):
|
||||
# glance_image_properties = {
|
||||
# "GLANCE.MySQL.Port": "3605",
|
||||
# "GLANCE.MySQL.Home": "/opt/mysql",
|
||||
# "GLANCE.Apache.Port": "8080",
|
||||
# "GLANCE.Apache.docroot": "/var/apache/static"
|
||||
# }
|
||||
image = self.glance.images.get(image_id)
|
||||
glance_image_properties = image.properties
|
||||
image_resource = Resource()
|
||||
image_capability = Capability()
|
||||
image_capabilities = []
|
||||
image_resource.capabilities = image_capabilities
|
||||
|
||||
image_resource.id = image_id
|
||||
image_resource.type = 'image'
|
||||
# image_resource.name = "ubuntu 12.04"
|
||||
image_resource.name = image.name
|
||||
|
||||
for key in glance_image_properties:
|
||||
# replace if check with pattern matching
|
||||
if key.count(self.separator) == 2:
|
||||
(namespace, capability_type, prop_name) = key.split(".")
|
||||
image_properties = []
|
||||
image_property = Property()
|
||||
image_property.name = prop_name
|
||||
image_property.value = glance_image_properties[key]
|
||||
|
||||
image_capability = None
|
||||
for capability in image_resource.capabilities:
|
||||
if capability.capability_type_namespace == namespace and \
|
||||
capability.capability_type == capability_type:
|
||||
image_capability = capability
|
||||
|
||||
if not image_capability:
|
||||
image_capability = Capability()
|
||||
image_resource.capabilities.append(image_capability)
|
||||
|
||||
image_capability.capability_type_namespace = namespace
|
||||
image_capability.capability_type = capability_type
|
||||
image_properties.append(image_property)
|
||||
|
||||
image_capability.properties = image_properties
|
||||
|
||||
return image_resource
|
||||
|
||||
def update_resource(self, resource):
|
||||
"""Update Glance Image
|
||||
:type param: graffiti.api.model.v1.resource.Resource
|
||||
"""
|
||||
|
||||
image_properties = {}
|
||||
for capability in resource.capabilities:
|
||||
properties = capability.properties
|
||||
capability_type = capability.capability_type
|
||||
capability_type_namespace = capability.capability_type_namespace
|
||||
for property in properties:
|
||||
prop_name = capability_type_namespace + \
|
||||
self.separator + \
|
||||
capability_type + \
|
||||
self.separator + \
|
||||
property.name
|
||||
image_properties[prop_name] = property.value
|
||||
|
||||
image = self.glance.images.get(resource.id)
|
||||
image.update(properties=image_properties, purge_props=False)
|
@ -18,10 +18,39 @@
|
||||
import os
|
||||
|
||||
import fixtures
|
||||
from oslo.config import cfg
|
||||
import testtools
|
||||
|
||||
_TRUE_VALUES = ('True', 'true', '1', 'yes')
|
||||
|
||||
# DEFAULT group
|
||||
default_controller_group = cfg.OptGroup('DEFAULT')
|
||||
default_controller_opts = [
|
||||
cfg.StrOpt(
|
||||
'persistence_type',
|
||||
default="memory",
|
||||
help=("persistence options. "
|
||||
"values = 'memory' or 'file' or 'db"))
|
||||
]
|
||||
|
||||
cfg.CONF.register_group(default_controller_group)
|
||||
cfg.CONF.register_opts(default_controller_opts,
|
||||
group=default_controller_group)
|
||||
|
||||
# FILE_PERSISTENCE group
|
||||
file_controller_group = cfg.OptGroup('FILE_PERSISTENCE')
|
||||
file_controller_opts = [
|
||||
cfg.StrOpt(
|
||||
'dictionary_folder',
|
||||
default="/tmp/graffiti-dictionary-test/",
|
||||
help=("Absolute path of the file for persisting dictionary")
|
||||
)
|
||||
]
|
||||
|
||||
cfg.CONF.register_group(file_controller_group)
|
||||
cfg.CONF.register_opts(file_controller_opts,
|
||||
group=file_controller_group)
|
||||
|
||||
|
||||
class TestCase(testtools.TestCase):
|
||||
|
||||
|
@ -25,8 +25,12 @@ from graffiti.api.tests import base
|
||||
from graffiti.api.controllers.root import RootController
|
||||
from graffiti.api.controllers.versions import V1Controller
|
||||
|
||||
from graffiti.api.model.v1.resource_controller_factory \
|
||||
import ResourceControllerFactory
|
||||
from graffiti.api.controllers.v1.captype_controller_factory \
|
||||
import CapTypeControllerFactory
|
||||
from graffiti.api.controllers.v1.ns_controller_factory \
|
||||
import NSControllerFactory
|
||||
from graffiti.api.model.v1.resource_dao_factory \
|
||||
import ResourceDAOFactory
|
||||
|
||||
|
||||
class TestControllerV1(base.TestCase):
|
||||
@ -35,14 +39,48 @@ class TestControllerV1(base.TestCase):
|
||||
root = RootController()
|
||||
self.assertIn(hasattr(root, 'v1'), [True])
|
||||
|
||||
def test_v1_namespace_exists(self):
|
||||
v1 = V1Controller()
|
||||
self.assertIn(hasattr(v1, 'namespace'), [True])
|
||||
|
||||
def test_v1_namespace_controller_factory__memory(self):
|
||||
rc = NSControllerFactory.create('memory')
|
||||
self.assertEquals(rc.get_type(), 'MemNSController')
|
||||
|
||||
# TODO(Lakshmi): Create folder before any tests run
|
||||
# def test_v1_namespace_controller_factory__file(self):
|
||||
# rc = NSControllerFactory.create('file')
|
||||
# self.assertEquals(rc.get_type(), 'FileNSController')
|
||||
|
||||
def test_v1_namespace_controller_factory__db(self):
|
||||
rc = NSControllerFactory.create('db')
|
||||
self.assertEquals(rc.get_type(), 'DBNSController')
|
||||
|
||||
def test_v1_capability_type_exists(self):
|
||||
v1 = V1Controller()
|
||||
self.assertIn(hasattr(v1, 'capability_type'), [True])
|
||||
|
||||
def test_v1_capability_type_controller_factory__memory(self):
|
||||
rc = CapTypeControllerFactory.create('memory')
|
||||
self.assertEquals(rc.get_type(), 'MemCapabilityTypeController')
|
||||
|
||||
# TODO(Lakshmi): Create folder before any tests run
|
||||
# def test_v1_capability_type_controller_factory__file(self):
|
||||
# rc = CapTypeControllerFactory.create('file')
|
||||
# self.assertEquals(rc.get_type(), 'FileCapabilityTypeController')
|
||||
|
||||
def test_v1_capability_type_controller_factory__db(self):
|
||||
rc = CapTypeControllerFactory.create('db')
|
||||
self.assertEquals(rc.get_type(), 'DBCapabilityTypeController')
|
||||
|
||||
def test_v1_resource_exists(self):
|
||||
v1 = V1Controller()
|
||||
self.assertIn(hasattr(v1, 'resource'), [True])
|
||||
|
||||
def test_v1_resource_controller_factory__local(self):
|
||||
rc = ResourceControllerFactory.create('local')
|
||||
self.assertEquals(rc.get_type(), 'LocalResourceController')
|
||||
rc = ResourceDAOFactory.create('local')
|
||||
self.assertEquals(rc.get_type(), 'LocalResourceDAO')
|
||||
|
||||
def test_v1_resource_controller_factory__unknown(self):
|
||||
rc = ResourceControllerFactory.create('invalid_controller')
|
||||
rc = ResourceDAOFactory.create('invalid_controller')
|
||||
self.assertTrue(rc is None)
|
||||
|
@ -3,3 +3,4 @@ Babel>=0.9.6
|
||||
pecan>=0.4.4
|
||||
WSME>=0.6
|
||||
oslo.config
|
||||
python-glanceclient
|
||||
|
Loading…
Reference in New Issue
Block a user