Implementation of tosca.node.ObjectStorage
Added tosca.node.ObjectStorage in TOSCA_defintions.yaml Implementation in toscalib and hot Implemented unit testcases in hot and tosca Added testcase to compare hot generated output for object store template with expected template Change-Id: I93a380e7d2e3a1febd9830f3f6f53eb8ecda347b Implements: blueprint tosca-object-storage
This commit is contained in:
parent
5a8dfe40f6
commit
99739b10b4
70
translator/hot/tosca/tests/test_tosca_objectstore.py
Normal file
70
translator/hot/tosca/tests/test_tosca_objectstore.py
Normal file
@ -0,0 +1,70 @@
|
||||
# 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 translator.hot.tosca.tosca_object_storage import ToscaObjectStorage
|
||||
from translator.toscalib.nodetemplate import NodeTemplate
|
||||
from translator.toscalib.tests.base import TestCase
|
||||
import translator.toscalib.utils.yamlparser
|
||||
|
||||
|
||||
class ToscaObjectStoreTest(TestCase):
|
||||
|
||||
def _tosca_objectstore_test(self, tpl_snippet, expectedprops):
|
||||
nodetemplates = (translator.toscalib.utils.yamlparser.
|
||||
simple_parse(tpl_snippet)['node_templates'])
|
||||
name = list(nodetemplates.keys())[0]
|
||||
try:
|
||||
nodetemplate = NodeTemplate(name, nodetemplates)
|
||||
tosca_object_store = ToscaObjectStorage(nodetemplate)
|
||||
tosca_object_store.handle_properties()
|
||||
if not self._compare_properties(tosca_object_store.properties,
|
||||
expectedprops):
|
||||
raise Exception(_("Hot Properties are not"
|
||||
" same as expected properties"))
|
||||
except Exception:
|
||||
# for time being rethrowing. Will be handled future based
|
||||
# on new development
|
||||
raise
|
||||
|
||||
def _compare_properties(self, hotprops, expectedprops):
|
||||
return all(item in hotprops.items() for item in expectedprops.items())
|
||||
|
||||
def test_node_objectstorage_with_properties(self):
|
||||
tpl_snippet = '''
|
||||
node_templates:
|
||||
server:
|
||||
type: tosca.nodes.ObjectStorage
|
||||
properties:
|
||||
store_name: test
|
||||
store_size: 1024
|
||||
store_maxsize: 1 MB
|
||||
'''
|
||||
expectedprops = {'name': 'test',
|
||||
'X-Container-Meta': {'Quota-Bytes': 1000000}}
|
||||
self._tosca_objectstore_test(
|
||||
tpl_snippet,
|
||||
expectedprops)
|
||||
|
||||
def test_node_objectstorage_with_few_properties(self):
|
||||
tpl_snippet = '''
|
||||
node_templates:
|
||||
server:
|
||||
type: tosca.nodes.ObjectStorage
|
||||
properties:
|
||||
store_name: test
|
||||
store_size: 1024
|
||||
'''
|
||||
expectedprops = {'name': 'test',
|
||||
'X-Container-Meta': {'Quota-Bytes': 1024}}
|
||||
self._tosca_objectstore_test(
|
||||
tpl_snippet,
|
||||
expectedprops)
|
53
translator/hot/tosca/tosca_object_storage.py
Normal file
53
translator/hot/tosca/tosca_object_storage.py
Normal file
@ -0,0 +1,53 @@
|
||||
#
|
||||
# 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 translator.hot.syntax.hot_resource import HotResource
|
||||
from translator.toscalib.elements.constraints import Constraint
|
||||
|
||||
|
||||
class ToscaObjectStorage(HotResource):
|
||||
'''Translate TOSCA node type tosca.nodes.ObjectStorage.'''
|
||||
|
||||
def __init__(self, nodetemplate):
|
||||
super(ToscaObjectStorage, self).__init__(nodetemplate,
|
||||
type='OS::Swift::Container')
|
||||
pass
|
||||
|
||||
def handle_properties(self):
|
||||
tosca_props = self._get_tosca_props(
|
||||
self.nodetemplate.get_properties_objects())
|
||||
objectstore_props = {}
|
||||
container_quota = {}
|
||||
skip_check = False
|
||||
|
||||
for key, value in tosca_props.items():
|
||||
if key == "store_name":
|
||||
objectstore_props["name"] = value
|
||||
elif key == "store_size" or key == "store_maxsize":
|
||||
#currently heat is not supporting dynamically increase
|
||||
#the container quota-size.
|
||||
#if both defined in tosca template, consider store_maxsize.
|
||||
if skip_check:
|
||||
continue
|
||||
quota_size = None
|
||||
if "store_maxsize" in tosca_props.keys():
|
||||
quota_size = tosca_props["store_maxsize"]
|
||||
else:
|
||||
quota_size = tosca_props["store_size"]
|
||||
container_quota["Quota-Bytes"] = \
|
||||
Constraint.get_num_from_scalar_unit_size(quota_size)
|
||||
objectstore_props["X-Container-Meta"] = container_quota
|
||||
skip_check = True
|
||||
|
||||
objectstore_props["X-Container-Read"] = '".r:*"'
|
||||
self.properties = objectstore_props
|
@ -23,6 +23,7 @@ from translator.hot.tosca.tosca_dbms import ToscaDbms
|
||||
from translator.hot.tosca.tosca_network_network import ToscaNetwork
|
||||
from translator.hot.tosca.tosca_network_port import ToscaNetworkPort
|
||||
from translator.hot.tosca.tosca_nodejs import ToscaNodejs
|
||||
from translator.hot.tosca.tosca_object_storage import ToscaObjectStorage
|
||||
from translator.hot.tosca.tosca_webserver import ToscaWebserver
|
||||
from translator.hot.tosca.tosca_wordpress import ToscaWordpress
|
||||
from translator.toscalib.functions import GetAttribute
|
||||
@ -57,7 +58,8 @@ TOSCA_TO_HOT_TYPE = {'tosca.nodes.Compute': ToscaCompute,
|
||||
'tosca.nodes.BlockStorage': ToscaBlockStorage,
|
||||
'tosca.nodes.SoftwareComponent.Nodejs': ToscaNodejs,
|
||||
'tosca.nodes.network.Network': ToscaNetwork,
|
||||
'tosca.nodes.network.Port': ToscaNetworkPort}
|
||||
'tosca.nodes.network.Port': ToscaNetworkPort,
|
||||
'tosca.nodes.ObjectStorage': ToscaObjectStorage}
|
||||
|
||||
TOSCA_TO_HOT_REQUIRES = {'container': 'server', 'host': 'server',
|
||||
'dependency': 'depends_on', "connects": 'depends_on'}
|
||||
|
46
translator/tests/test_objectstore_template.py
Normal file
46
translator/tests/test_objectstore_template.py
Normal file
@ -0,0 +1,46 @@
|
||||
# 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
|
||||
|
||||
from translator.common.utils import CompareUtils
|
||||
from translator.hot.tosca_translator import TOSCATranslator
|
||||
from translator.toscalib.tests.base import TestCase
|
||||
from translator.toscalib.tosca_template import ToscaTemplate
|
||||
|
||||
|
||||
class ToscaObjectStoreTemplateTest(TestCase):
|
||||
|
||||
def test_single_template_objectstore(self):
|
||||
tosca_yaml_file = "../toscalib/tests/data/storage/" + \
|
||||
"tosca_single_object_store.yaml"
|
||||
tosca_tpl = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
tosca_yaml_file)
|
||||
parsed_params = {'objectstore_name': 'test_obj_store'}
|
||||
tosca = ToscaTemplate(tosca_tpl)
|
||||
translate = TOSCATranslator(tosca, parsed_params)
|
||||
hot_translated_output = translate.translate()
|
||||
|
||||
#load expected hot yaml file
|
||||
hot_yaml_file = "../toscalib/tests/data/hot_output/" + \
|
||||
"hot_single_object_store.yaml"
|
||||
hot_tpl = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
hot_yaml_file)
|
||||
with open(hot_tpl) as f:
|
||||
hot_expected_output = f.read()
|
||||
|
||||
#compare generated and expected hot templates
|
||||
status = CompareUtils.compare_hot_yamls(hot_translated_output,
|
||||
hot_expected_output)
|
||||
self.assertEqual(status, True)
|
@ -285,6 +285,33 @@ tosca.nodes.network.Port:
|
||||
nodes. It indicates which network this port will connect to.
|
||||
type: tosca.capabilities.network.Linkable
|
||||
|
||||
tosca.nodes.ObjectStorage:
|
||||
derived_from: tosca.nodes.Root
|
||||
description: >
|
||||
The TOSCA ObjectStorage node represents storage that provides the ability
|
||||
to store data as objects (or BLOBs of data) without consideration for the
|
||||
underlying filesystem or devices
|
||||
properties:
|
||||
store_name:
|
||||
type: string
|
||||
required: yes
|
||||
description: >
|
||||
The logical name of the object store (or container).
|
||||
store_size:
|
||||
type: scalar-unit.size
|
||||
required: no
|
||||
constraints:
|
||||
- greater_or_equal: 0 GB
|
||||
description: >
|
||||
The requested initial storage size.
|
||||
store_maxsize:
|
||||
type: scalar-unit.size
|
||||
required: no
|
||||
constraints:
|
||||
- greater_or_equal: 0 GB
|
||||
description: >
|
||||
The requested maximum storage size.
|
||||
|
||||
##########################################################################
|
||||
# Relationship Type.
|
||||
# A Relationship Type is a reusable entity that defines the type of one
|
||||
|
@ -0,0 +1,19 @@
|
||||
heat_template_version: 2013-05-23
|
||||
|
||||
description: >
|
||||
Tosca template for testing a objectstorage template.
|
||||
|
||||
parameters:
|
||||
objectstore_name:
|
||||
type: string
|
||||
default: test_obj_store
|
||||
resources:
|
||||
obj_store_server:
|
||||
type: OS::Swift::Container
|
||||
properties:
|
||||
X-Container-Meta:
|
||||
Quota-Bytes: 1000000000
|
||||
X-Container-Read: ".r:*"
|
||||
name:
|
||||
get_param: objectstore_name
|
||||
outputs: {}
|
@ -0,0 +1,16 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_0_0
|
||||
|
||||
description: >
|
||||
Tosca template for testing a objectstorage template.
|
||||
|
||||
inputs:
|
||||
objectstore_name:
|
||||
type: string
|
||||
|
||||
node_templates:
|
||||
obj_store_server:
|
||||
type: tosca.nodes.ObjectStorage
|
||||
properties:
|
||||
store_name: { get_input: objectstore_name }
|
||||
store_size: 1024
|
||||
store_maxsize: 1 GB
|
@ -506,3 +506,50 @@ class ToscaTemplateValidationTest(TestCase):
|
||||
tpl_snippet,
|
||||
exception.ValidationError,
|
||||
expectedmessage)
|
||||
|
||||
def test_node_template_objectstorage_without_required_property(self):
|
||||
tpl_snippet = '''
|
||||
node_templates:
|
||||
server:
|
||||
type: tosca.nodes.ObjectStorage
|
||||
properties:
|
||||
store_maxsize: 1 GB
|
||||
'''
|
||||
expectedmessage = ('Properties of template server is missing '
|
||||
'required field: '
|
||||
'"[\'store_name\']".')
|
||||
|
||||
self._single_node_template_content_test(
|
||||
tpl_snippet,
|
||||
exception.MissingRequiredFieldError,
|
||||
expectedmessage)
|
||||
|
||||
def test_node_template_objectstorage_with_invalid_scalar_unit(self):
|
||||
tpl_snippet = '''
|
||||
node_templates:
|
||||
server:
|
||||
type: tosca.nodes.ObjectStorage
|
||||
properties:
|
||||
store_name: test
|
||||
store_maxsize: -1
|
||||
'''
|
||||
expectedmessage = ('"-1" is not a valid scalar-unit')
|
||||
self._single_node_template_content_test(
|
||||
tpl_snippet,
|
||||
ValueError,
|
||||
expectedmessage)
|
||||
|
||||
def test_node_template_objectstorage_with_invalid_scalar_type(self):
|
||||
tpl_snippet = '''
|
||||
node_templates:
|
||||
server:
|
||||
type: tosca.nodes.ObjectStorage
|
||||
properties:
|
||||
store_name: test
|
||||
store_maxsize: 1 XB
|
||||
'''
|
||||
expectedmessage = ('"1 XB" is not a valid scalar-unit')
|
||||
self._single_node_template_content_test(
|
||||
tpl_snippet,
|
||||
ValueError,
|
||||
expectedmessage)
|
||||
|
Loading…
x
Reference in New Issue
Block a user