TOSCA definition types for TOSCA library.
Create a TOSCA metamodel covering various TOSCA types including node type, relationship type, capabilities type, interfaces and properties. Also, a small change, renamed heat-translator subdir to 'translator' as tox doesn't like dash in the name. Change-Id: I59e496063f8f1d7fd8557278a690b65d2a400a43 Partially implements blueprint heat-translator-tosca
This commit is contained in:
parent
d4d826ef96
commit
0c1591bf15
@ -3,4 +3,4 @@
|
|||||||
# The list of modules to copy from oslo-incubator.git
|
# The list of modules to copy from oslo-incubator.git
|
||||||
|
|
||||||
# The base module to hold the copy of openstack.common
|
# The base module to hold the copy of openstack.common
|
||||||
base=heat-translator
|
base=translator
|
@ -1,2 +1,3 @@
|
|||||||
pbr>=0.5.21,<1.0
|
pbr>=0.5.21,<1.0
|
||||||
Babel>=0.9.6
|
Babel>=0.9.6
|
||||||
|
PyYAML>=3.1.0
|
14
setup.cfg
14
setup.cfg
@ -21,7 +21,7 @@ classifier =
|
|||||||
|
|
||||||
[files]
|
[files]
|
||||||
packages =
|
packages =
|
||||||
heat-translator
|
translator
|
||||||
|
|
||||||
[build_sphinx]
|
[build_sphinx]
|
||||||
source-dir = doc/source
|
source-dir = doc/source
|
||||||
@ -32,15 +32,15 @@ all_files = 1
|
|||||||
upload-dir = doc/build/html
|
upload-dir = doc/build/html
|
||||||
|
|
||||||
[compile_catalog]
|
[compile_catalog]
|
||||||
directory = heat-translator/locale
|
directory = translator/locale
|
||||||
domain = heat-translator
|
domain = translator
|
||||||
|
|
||||||
[update_catalog]
|
[update_catalog]
|
||||||
domain = heat-translator
|
domain = translator
|
||||||
output_dir = heat-translator/locale
|
output_dir = translator/locale
|
||||||
input_file = heat-translator/locale/heat-translator.pot
|
input_file = translator/locale/translator.pot
|
||||||
|
|
||||||
[extract_messages]
|
[extract_messages]
|
||||||
keywords = _ gettext ngettext l_ lazy_gettext
|
keywords = _ gettext ngettext l_ lazy_gettext
|
||||||
mapping_file = babel.cfg
|
mapping_file = babel.cfg
|
||||||
output_file = heat-translator/locale/heat-translator.pot
|
output_file = translator/locale/translator.pot
|
19
translator/__init__.py
Normal file
19
translator/__init__.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# -*- 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 pbr.version
|
||||||
|
|
||||||
|
|
||||||
|
__version__ = pbr.version.VersionInfo(
|
||||||
|
'translator').version_string()
|
0
translator/toscalib/__init__.py
Normal file
0
translator/toscalib/__init__.py
Normal file
246
translator/toscalib/elements/TOSCA_definition.yaml
Normal file
246
translator/toscalib/elements/TOSCA_definition.yaml
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# The content of this file reflects TOSCA Simple Profile in YAML. It
|
||||||
|
# describes the definition for TOSCA types including Node Type,
|
||||||
|
# Relationship Type, Capability Type and Interfaces.
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# Node Type.
|
||||||
|
# A Node Type is a reusable entity that defines the type of one or more
|
||||||
|
# Node Templates.
|
||||||
|
##########################################################################
|
||||||
|
tosca.nodes.Root:
|
||||||
|
description: >
|
||||||
|
The TOSCA root node all other TOSCA base node types derive from.
|
||||||
|
capabilities:
|
||||||
|
feature: tosca.capabilities.Feature
|
||||||
|
interfaces: [ tosca.interfaces.node.Lifecycle ]
|
||||||
|
|
||||||
|
tosca.nodes.Compute:
|
||||||
|
derived_from: tosca.nodes.Root
|
||||||
|
properties:
|
||||||
|
num_cpus:
|
||||||
|
required: no
|
||||||
|
type: integer
|
||||||
|
constraints:
|
||||||
|
- greater_or_equal: 1
|
||||||
|
description: >
|
||||||
|
Number of (actual or virtual) CPUs associated with the Compute node.
|
||||||
|
disk_size:
|
||||||
|
required: no
|
||||||
|
type: integer
|
||||||
|
constraints:
|
||||||
|
- greater_or_equal: 0
|
||||||
|
description: >
|
||||||
|
Size of the local disk, in Gigabytes (GB), available to applications
|
||||||
|
running on the Compute node.
|
||||||
|
mem_size:
|
||||||
|
required: no
|
||||||
|
type: integer
|
||||||
|
constraints:
|
||||||
|
- greater_or_equal: 0
|
||||||
|
description: >
|
||||||
|
Size of memory, in Megabytes (MB), available to applications running
|
||||||
|
on the Compute node.
|
||||||
|
os_arch:
|
||||||
|
required: no
|
||||||
|
default: x86_64
|
||||||
|
type: string
|
||||||
|
description: >
|
||||||
|
The host Operating System (OS) architecture.
|
||||||
|
os_type:
|
||||||
|
required: yes
|
||||||
|
type: string
|
||||||
|
description: >
|
||||||
|
The host Operating System (OS) type.
|
||||||
|
os_distribution:
|
||||||
|
required: no
|
||||||
|
type: string
|
||||||
|
description: >
|
||||||
|
The host Operating System (OS) distribution. Examples of valid values
|
||||||
|
for an “os_type” of “Linux” would include:
|
||||||
|
debian, fedora, rhel and ubuntu.
|
||||||
|
os_version:
|
||||||
|
required: no
|
||||||
|
type: integer
|
||||||
|
description: >
|
||||||
|
The host Operating System version.
|
||||||
|
ip_address:
|
||||||
|
required: no
|
||||||
|
type: string
|
||||||
|
description: >
|
||||||
|
The primary IP address assigned by the cloud provider that applications
|
||||||
|
may use to access the Compute node.
|
||||||
|
capabilities:
|
||||||
|
host:
|
||||||
|
type: tosca.capabilities.Container
|
||||||
|
|
||||||
|
tosca.nodes.SoftwareComponent:
|
||||||
|
derived_from: tosca.nodes.Root
|
||||||
|
properties:
|
||||||
|
version:
|
||||||
|
required: no
|
||||||
|
type: string
|
||||||
|
description: >
|
||||||
|
Software component version.
|
||||||
|
requirements:
|
||||||
|
- host: tosca.nodes.Compute
|
||||||
|
|
||||||
|
tosca.nodes.DBMS:
|
||||||
|
derived_from: tosca.nodes.SoftwareComponent
|
||||||
|
properties:
|
||||||
|
dbms_port:
|
||||||
|
required: no
|
||||||
|
type: integer
|
||||||
|
description: >
|
||||||
|
The port the DBMS service will listen to for data and requests.
|
||||||
|
dbms_root_password:
|
||||||
|
required: yes
|
||||||
|
type: string
|
||||||
|
description: >
|
||||||
|
The root password for the DBMS service.
|
||||||
|
capabilities:
|
||||||
|
host:
|
||||||
|
type: tosca.capabilities.Container
|
||||||
|
properties:
|
||||||
|
containee_types: [tosca.nodes.Database]
|
||||||
|
|
||||||
|
tosca.nodes.Database:
|
||||||
|
derived_from: tosca.nodes.Root
|
||||||
|
properties:
|
||||||
|
db_user:
|
||||||
|
required: yes
|
||||||
|
type: string
|
||||||
|
description: >
|
||||||
|
User account name for DB administration
|
||||||
|
db_name:
|
||||||
|
required: yes
|
||||||
|
type: string
|
||||||
|
description: >
|
||||||
|
The name of the database.
|
||||||
|
db_user:
|
||||||
|
required: yes
|
||||||
|
type: string
|
||||||
|
description: >
|
||||||
|
The user name of the DB user.
|
||||||
|
db_password:
|
||||||
|
required: yes
|
||||||
|
type: string
|
||||||
|
description: >
|
||||||
|
The password for the DB user account
|
||||||
|
requirements:
|
||||||
|
- host: tosca.nodes.DBMS
|
||||||
|
capabilities:
|
||||||
|
database_endpoint:
|
||||||
|
type: tosca.capabilities.Endpoint
|
||||||
|
|
||||||
|
tosca.nodes.WebServer:
|
||||||
|
derived_from: tosca.nodes.SoftwareComponent
|
||||||
|
capabilities:
|
||||||
|
http_endpoint:
|
||||||
|
type: tosca.capabilities.Endpoint
|
||||||
|
https_endpoint:
|
||||||
|
type: tosca.capabilities.Endpoint
|
||||||
|
host:
|
||||||
|
type: tosca.capabilities.Container
|
||||||
|
properties:
|
||||||
|
containee_types: [tosca.nodes.WebApplication]
|
||||||
|
|
||||||
|
tosca.nodes.WebApplication:
|
||||||
|
derived_from: tosca.nodes.Root
|
||||||
|
requirements:
|
||||||
|
- host: tosca.nodes.WebServer
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# Relationship Type.
|
||||||
|
# A Relationship Type is a reusable entity that defines the type of one
|
||||||
|
# or more relationships between Node Types or Node Templates.
|
||||||
|
##########################################################################
|
||||||
|
tosca.relationships.Root:
|
||||||
|
interfaces: [ tosca.interfaces.relationship.Configure ]
|
||||||
|
|
||||||
|
tosca.relationships.DependsOn:
|
||||||
|
derived_from: tosca.relationships.Root
|
||||||
|
valid_targets: [ tosca.capabilities.Feature ]
|
||||||
|
|
||||||
|
tosca.relationships.HostedOn:
|
||||||
|
derived_from: tosca.relationships.DependsOn
|
||||||
|
valid_targets: [ tosca.capabilities.Container ]
|
||||||
|
|
||||||
|
tosca.relationships.ConnectsTo:
|
||||||
|
derived_from: tosca.relationships.DependsOn
|
||||||
|
valid_targets: [ tosca.capabilities.Endpoint ]
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# Capability Type.
|
||||||
|
# A Capability Type is a reusable entity that describes a kind of
|
||||||
|
# capability that a Node Type can declare to expose.
|
||||||
|
##########################################################################
|
||||||
|
tosca.capabilities.Root:
|
||||||
|
|
||||||
|
tosca.capabilities.Feature:
|
||||||
|
derived_from: tosca.capabilities.Root
|
||||||
|
|
||||||
|
tosca.capabilities.Container:
|
||||||
|
derived_from: tosca.capabilities.Feature
|
||||||
|
|
||||||
|
tosca.capabilities.Endpoint:
|
||||||
|
derived_from: tosca.capabilities.Feature
|
||||||
|
properties:
|
||||||
|
protocol:
|
||||||
|
type: string
|
||||||
|
default: http
|
||||||
|
port:
|
||||||
|
type: integer
|
||||||
|
constraints:
|
||||||
|
- greater_or_equal: 1
|
||||||
|
- less_or_equal: 65535
|
||||||
|
secure:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
|
tosca.capabilities.DatabaseEndpoint:
|
||||||
|
derived_from: tosca.capabilities.Endpoint
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# Interfaces Type.
|
||||||
|
# The Interfaces element describes a list of one or more interface
|
||||||
|
# definitions for a modelable entity (e.g., a Node or Relationship Type)
|
||||||
|
# as defined within the TOSCA Simple Profile specification.
|
||||||
|
##########################################################################
|
||||||
|
tosca.interfaces.node.Lifecycle:
|
||||||
|
create:
|
||||||
|
description: Basic lifecycle create operation.
|
||||||
|
configure:
|
||||||
|
description: Basic lifecycle configure operation.
|
||||||
|
start:
|
||||||
|
description: Basic lifecycle start operation.
|
||||||
|
stop:
|
||||||
|
description: Basic lifecycle stop operation.
|
||||||
|
delete:
|
||||||
|
description: Basic lifecycle delete operation.
|
||||||
|
|
||||||
|
tosca.interfaces.relationship.Configure:
|
||||||
|
post_configure_source:
|
||||||
|
description: Operation to post-configure the source endpoint.
|
||||||
|
post_configure_target:
|
||||||
|
description: Operation to post-configure the target endpoint.
|
||||||
|
add_target:
|
||||||
|
description: Operation to add a target node.
|
||||||
|
remove_target:
|
||||||
|
description: Operation to remove a target node.
|
0
translator/toscalib/elements/__init__.py
Normal file
0
translator/toscalib/elements/__init__.py
Normal file
54
translator/toscalib/elements/capabilitytype.py
Normal file
54
translator/toscalib/elements/capabilitytype.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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.toscalib.elements.entitytype import EntityType
|
||||||
|
from translator.toscalib.elements.properties import PropertyDef
|
||||||
|
|
||||||
|
|
||||||
|
class CapabilityTypeDef(EntityType):
|
||||||
|
'''TOSCA built-in capabilities type.'''
|
||||||
|
|
||||||
|
def __init__(self, name, ctype, ntype, properties):
|
||||||
|
self.name = name
|
||||||
|
self.type = ctype
|
||||||
|
self.nodetype = ntype
|
||||||
|
self.properties = properties
|
||||||
|
self.defs = {}
|
||||||
|
if ntype:
|
||||||
|
self.defs = self.TOSCA_DEF[ctype]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def properties_def(self):
|
||||||
|
'''Return a list of property objects.'''
|
||||||
|
properties = []
|
||||||
|
props = self.entity_value(self.defs, 'properties')
|
||||||
|
if props:
|
||||||
|
if isinstance(props, dict):
|
||||||
|
for prop, schema in props.items():
|
||||||
|
prop_val = None
|
||||||
|
for k, v in schema.items():
|
||||||
|
if k == 'default':
|
||||||
|
prop_val = v
|
||||||
|
properties.append(PropertyDef(prop, self.type,
|
||||||
|
schema, prop_val))
|
||||||
|
if self.properties:
|
||||||
|
for prop, value in self.properties.items():
|
||||||
|
properties.append(PropertyDef(prop, self.type, None, value))
|
||||||
|
return properties
|
||||||
|
|
||||||
|
@property
|
||||||
|
def parent_type(self):
|
||||||
|
'''Return a capability this capability is derived from.'''
|
||||||
|
return self.derived_from(self.defs)
|
102
translator/toscalib/elements/constraints.py
Normal file
102
translator/toscalib/elements/constraints.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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 numbers
|
||||||
|
from translator.toscalib.utils.gettextutils import _
|
||||||
|
|
||||||
|
|
||||||
|
class Constraint(object):
|
||||||
|
CONSTRAINTS = (EQUAL, GREATER_THAN,
|
||||||
|
GREATER_OR_EQUAL, LESS_THAN, LESS_OR_EQUAL, IN_RANGE,
|
||||||
|
VALID_VALUES, LENGTH, MIN_LENGHT, MAX_LENGTH, PATTERN) = \
|
||||||
|
('equal', 'greater_than', 'greater_or_equal', 'less_than',
|
||||||
|
'less_or_equal', 'in_range', 'valid_values', 'length',
|
||||||
|
'min_length', 'max_length', 'pattern')
|
||||||
|
|
||||||
|
def __init__(self, propertyname, value, constraint):
|
||||||
|
self.propertyname = propertyname
|
||||||
|
self.value = value
|
||||||
|
self.constraint = constraint
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
for key, value in self.constraint.items():
|
||||||
|
if key == self.GREATER_OR_EQUAL:
|
||||||
|
self.validate_greater_than(value)
|
||||||
|
|
||||||
|
def validate_equal(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def validate_greater_than(self, value):
|
||||||
|
if self.value < value:
|
||||||
|
raise ValueError(_("%(prop)s value requires to be "
|
||||||
|
"greater than %(val)s")
|
||||||
|
% {'prop': self.propertyname, 'val': value})
|
||||||
|
|
||||||
|
def validate_greater_or_equal(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def validate_less_than(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def validate_less_or_equal(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def validate_in_range(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def validate_valid_values(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def validate_length(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def validate_min_length(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def validate_max_length(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def validate_pattern(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def validate_integer(value):
|
||||||
|
if not isinstance(value, (int, long)):
|
||||||
|
raise TypeError(_('Value is not an integer for %s') % value)
|
||||||
|
return Constraint.validate_number(value)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def validate_number(value):
|
||||||
|
return Constraint.str_to_num(value)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def validate_string(value):
|
||||||
|
if not isinstance(value, basestring):
|
||||||
|
raise ValueError(_('Value must be a string %s') % value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def validate_list(self, value):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def str_to_num(value):
|
||||||
|
'''Convert a string representation of a number into a numeric type.'''
|
||||||
|
if isinstance(value, numbers.Number):
|
||||||
|
return value
|
||||||
|
try:
|
||||||
|
return int(value)
|
||||||
|
except ValueError:
|
||||||
|
return float(value)
|
44
translator/toscalib/elements/entitytype.py
Normal file
44
translator/toscalib/elements/entitytype.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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 logging
|
||||||
|
import os
|
||||||
|
import translator.toscalib.utils.yamlparser
|
||||||
|
|
||||||
|
log = logging.getLogger('tosca')
|
||||||
|
|
||||||
|
|
||||||
|
class EntityType(object):
|
||||||
|
'''Base class for TOSCA elements.'''
|
||||||
|
|
||||||
|
'''TOSCA definition file.'''
|
||||||
|
TOSCA_DEF_FILE = os.path.join(
|
||||||
|
os.path.dirname(os.path.abspath(__file__)),
|
||||||
|
"TOSCA_definition.yaml")
|
||||||
|
|
||||||
|
TOSCA_DEF = translator.toscalib.utils.yamlparser.load_yaml(TOSCA_DEF_FILE)
|
||||||
|
|
||||||
|
RELATIONSHIP_TYPE = (DEPENDSON, HOSTEDON, CONNECTSTO) = \
|
||||||
|
('tosca.relationships.DependsOn',
|
||||||
|
'tosca.relationships.HostedOn',
|
||||||
|
'tosca.relationships.ConnectsTo')
|
||||||
|
|
||||||
|
def derived_from(self, defs):
|
||||||
|
'''Return a type this type is derived from.'''
|
||||||
|
return self.entity_value(defs, 'derived_from')
|
||||||
|
|
||||||
|
def entity_value(self, defs, key):
|
||||||
|
if key in defs:
|
||||||
|
return defs[key]
|
64
translator/toscalib/elements/interfaces.py
Normal file
64
translator/toscalib/elements/interfaces.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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.toscalib.elements.statefulentitytype import StatefulEntityType
|
||||||
|
|
||||||
|
SECTIONS = (LIFECYCLE, CONFIGURE) = \
|
||||||
|
('tosca.interfaces.node.Lifecycle',
|
||||||
|
'tosca.interfaces.relationship.Configure')
|
||||||
|
|
||||||
|
|
||||||
|
class InterfacesDef(StatefulEntityType):
|
||||||
|
'''TOSCA built-in interfaces type.'''
|
||||||
|
|
||||||
|
def __init__(self, ntype, interfacetype,
|
||||||
|
tpl_name=None, name=None, value=None):
|
||||||
|
self.nodetype = ntype
|
||||||
|
self.tpl_name = tpl_name
|
||||||
|
self.type = interfacetype
|
||||||
|
self.name = name
|
||||||
|
self.value = value
|
||||||
|
self.implementation = None
|
||||||
|
self.input = None
|
||||||
|
self.defs = {}
|
||||||
|
if ntype:
|
||||||
|
self.defs = self.TOSCA_DEF[interfacetype]
|
||||||
|
if value:
|
||||||
|
if isinstance(self.value, dict):
|
||||||
|
for i, j in self.value.items():
|
||||||
|
if i == 'implementation':
|
||||||
|
self.implementation = j
|
||||||
|
if i == 'input':
|
||||||
|
self.input = j
|
||||||
|
else:
|
||||||
|
self.implementation = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def lifecycle_ops(self):
|
||||||
|
if self.defs:
|
||||||
|
if self.type == LIFECYCLE:
|
||||||
|
return self._ops()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def configure_ops(self):
|
||||||
|
if self.defs:
|
||||||
|
if self.type == CONFIGURE:
|
||||||
|
return self._ops()
|
||||||
|
|
||||||
|
def _ops(self):
|
||||||
|
ops = []
|
||||||
|
for name in list(self.defs.keys()):
|
||||||
|
ops.append(name)
|
||||||
|
return ops
|
174
translator/toscalib/elements/nodetype.py
Normal file
174
translator/toscalib/elements/nodetype.py
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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.toscalib.elements.capabilitytype import CapabilityTypeDef
|
||||||
|
from translator.toscalib.elements.interfaces import InterfacesDef
|
||||||
|
from translator.toscalib.elements.properties import PropertyDef
|
||||||
|
from translator.toscalib.elements.relationshiptype import RelationshipType
|
||||||
|
from translator.toscalib.elements.statefulentitytype import StatefulEntityType
|
||||||
|
from translator.toscalib.utils.gettextutils import _
|
||||||
|
|
||||||
|
|
||||||
|
SECTIONS = (DERIVED_FROM, PROPERTIES, REQUIREMENTS,
|
||||||
|
INTERFACES, CAPABILITIES) = \
|
||||||
|
('derived_from', 'properties', 'requirements', 'interfaces',
|
||||||
|
'capabilities')
|
||||||
|
|
||||||
|
|
||||||
|
class NodeType(StatefulEntityType):
|
||||||
|
'''TOSCA built-in node type.'''
|
||||||
|
|
||||||
|
def __init__(self, ntype):
|
||||||
|
super(NodeType, self).__init__()
|
||||||
|
if ntype not in list(self.TOSCA_DEF.keys()):
|
||||||
|
raise ValueError(_('Node type %(ntype)s is not a valid type.')
|
||||||
|
% {'ntype': ntype})
|
||||||
|
self.defs = self.TOSCA_DEF[ntype]
|
||||||
|
self.type = ntype
|
||||||
|
self.related = {}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def parent_type(self):
|
||||||
|
'''Return a node this node is derived from.'''
|
||||||
|
pnode = self.derived_from(self.defs)
|
||||||
|
if pnode:
|
||||||
|
return NodeType(pnode)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def properties_def(self):
|
||||||
|
'''Return a list of property definition objects.'''
|
||||||
|
properties = []
|
||||||
|
props = self._get_value(PROPERTIES)
|
||||||
|
if props:
|
||||||
|
for prop, schema in props.items():
|
||||||
|
properties.append(PropertyDef(prop, self.type, schema))
|
||||||
|
return properties
|
||||||
|
|
||||||
|
@property
|
||||||
|
def relationship(self):
|
||||||
|
'''Return a dictionary of relationships to other node types.
|
||||||
|
|
||||||
|
This method returns a dictionary of named relationships that nodes
|
||||||
|
of the current node type (self) can have to other nodes (of specific
|
||||||
|
types) in a TOSCA template.
|
||||||
|
|
||||||
|
'''
|
||||||
|
relationship = {}
|
||||||
|
requires = self.requirements
|
||||||
|
if requires is None:
|
||||||
|
requires = self._get_value(REQUIREMENTS, None, True)
|
||||||
|
if requires:
|
||||||
|
for req in requires:
|
||||||
|
for key, value in req.items():
|
||||||
|
relation = self._get_relation(key, value)
|
||||||
|
rtype = RelationshipType(relation)
|
||||||
|
relatednode = NodeType(value)
|
||||||
|
relationship[rtype] = relatednode
|
||||||
|
return relationship
|
||||||
|
|
||||||
|
def _get_relation(self, key, ndtype):
|
||||||
|
relation = None
|
||||||
|
ntype = NodeType(ndtype)
|
||||||
|
cap = ntype.capabilities
|
||||||
|
for c in cap:
|
||||||
|
if c.name == key:
|
||||||
|
for r in self.RELATIONSHIP_TYPE:
|
||||||
|
rtypedef = ntype.TOSCA_DEF[r]
|
||||||
|
for properties in rtypedef.values():
|
||||||
|
if c.type in properties:
|
||||||
|
relation = r
|
||||||
|
break
|
||||||
|
if relation:
|
||||||
|
break
|
||||||
|
return relation
|
||||||
|
|
||||||
|
@property
|
||||||
|
def capabilities(self):
|
||||||
|
'''Return a list of capability objects.'''
|
||||||
|
typecapabilities = []
|
||||||
|
self.cap_prop = None
|
||||||
|
self.cap_type = None
|
||||||
|
caps = self._get_value(CAPABILITIES)
|
||||||
|
if caps is None:
|
||||||
|
caps = self._get_value(CAPABILITIES, None, True)
|
||||||
|
if caps:
|
||||||
|
cproperties = None
|
||||||
|
for name, value in caps.items():
|
||||||
|
ctype = value.get('type')
|
||||||
|
if 'properties' in value:
|
||||||
|
cproperties = value.get('properties')
|
||||||
|
cap = CapabilityTypeDef(name, ctype,
|
||||||
|
self.type, cproperties)
|
||||||
|
typecapabilities.append(cap)
|
||||||
|
return typecapabilities
|
||||||
|
|
||||||
|
@property
|
||||||
|
def requirements(self):
|
||||||
|
return self._get_value(REQUIREMENTS)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def interfaces(self):
|
||||||
|
return self._get_value(INTERFACES)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def lifecycle_inputs(self):
|
||||||
|
'''Return inputs to life cycle operations if found.'''
|
||||||
|
inputs = []
|
||||||
|
interfaces = self.interfaces
|
||||||
|
if interfaces:
|
||||||
|
for name, value in interfaces.items():
|
||||||
|
if name == 'tosca.interfaces.node.Lifecycle':
|
||||||
|
for x, y in value.items():
|
||||||
|
if x == 'inputs':
|
||||||
|
for i in y.iterkeys():
|
||||||
|
inputs.append(i)
|
||||||
|
return inputs
|
||||||
|
|
||||||
|
@property
|
||||||
|
def lifecycle_operations(self):
|
||||||
|
'''Return available life cycle operations if found.'''
|
||||||
|
ops = None
|
||||||
|
interfaces = self.interfaces
|
||||||
|
if interfaces:
|
||||||
|
i = InterfacesDef(self.type, 'tosca.interfaces.node.Lifecycle')
|
||||||
|
ops = i.lifecycle_ops
|
||||||
|
return ops
|
||||||
|
|
||||||
|
def get_capability(self, name):
|
||||||
|
for key, value in self.capabilities:
|
||||||
|
if key == name:
|
||||||
|
return value
|
||||||
|
|
||||||
|
def get_capability_type(self, name):
|
||||||
|
for key, value in self.get_capability(name):
|
||||||
|
if key == type:
|
||||||
|
return value
|
||||||
|
|
||||||
|
def _get_value(self, key, defs=None, parent=None):
|
||||||
|
value = None
|
||||||
|
if defs is None:
|
||||||
|
defs = self.defs
|
||||||
|
value = self.entity_value(defs, key)
|
||||||
|
if parent and not value:
|
||||||
|
p = self.parent_type
|
||||||
|
while value is None:
|
||||||
|
#check parent node
|
||||||
|
if not p:
|
||||||
|
break
|
||||||
|
if p and p.type == 'tosca.nodes.Root':
|
||||||
|
break
|
||||||
|
value = self.entity_value(defs, key)
|
||||||
|
p = p.parent_type
|
||||||
|
return value
|
87
translator/toscalib/elements/properties.py
Normal file
87
translator/toscalib/elements/properties.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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.toscalib.elements.constraints import Constraint
|
||||||
|
|
||||||
|
|
||||||
|
class PropertyDef(object):
|
||||||
|
'''TOSCA built-in Property type.'''
|
||||||
|
|
||||||
|
PROPERTY_KEYS = (
|
||||||
|
TYPE, REQUIRED, DESCRIPTION, DEFAULT, CONSTRAINTS,
|
||||||
|
) = (
|
||||||
|
'type', 'required', 'description', 'default', 'constraints'
|
||||||
|
)
|
||||||
|
PROPERTIY_TYPES = (
|
||||||
|
INTEGER,
|
||||||
|
STRING, NUMBER, BOOLEAN,
|
||||||
|
LIST
|
||||||
|
) = (
|
||||||
|
'integer',
|
||||||
|
'string', 'number', 'boolean',
|
||||||
|
'list'
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, name, nodetype, schema=None, value=None, tpl_name=None):
|
||||||
|
self.name = name
|
||||||
|
self.nodetype = nodetype
|
||||||
|
self.schema = schema
|
||||||
|
self.value = value
|
||||||
|
self.tpl_name = tpl_name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def required(self):
|
||||||
|
if self.schema:
|
||||||
|
for prop_key, prop_vale in self.schema.items():
|
||||||
|
if prop_key == self.REQUIRED and prop_vale:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def constraints(self):
|
||||||
|
if self.schema:
|
||||||
|
if self.CONSTRAINTS in self.schema:
|
||||||
|
return self.schema[self.CONSTRAINTS]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def description(self):
|
||||||
|
if self.schema:
|
||||||
|
if self.DESCRIPTION in self.schema:
|
||||||
|
return self.schema[self.DESCRIPTION]
|
||||||
|
return ''
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
'''Validate if not a reference property.'''
|
||||||
|
if not isinstance(self.value, dict):
|
||||||
|
self._validate_constraints()
|
||||||
|
self._validate_datatype()
|
||||||
|
|
||||||
|
def _validate_datatype(self):
|
||||||
|
if self.schema:
|
||||||
|
dtype = self.schema[self.TYPE]
|
||||||
|
if dtype == self.STRING:
|
||||||
|
return Constraint.validate_string(self.value)
|
||||||
|
elif dtype == self.INTEGER:
|
||||||
|
return Constraint.validate_integer(self.value)
|
||||||
|
elif dtype == self.NUMBER:
|
||||||
|
return Constraint.validate_number(self.value)
|
||||||
|
elif dtype == self.LIST:
|
||||||
|
return Constraint.validate_list(self.value)
|
||||||
|
|
||||||
|
def _validate_constraints(self):
|
||||||
|
constraints = self.constraints
|
||||||
|
if constraints:
|
||||||
|
for constraint in constraints:
|
||||||
|
Constraint(self.name, self.value, constraint).validate()
|
34
translator/toscalib/elements/relationshiptype.py
Normal file
34
translator/toscalib/elements/relationshiptype.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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.toscalib.elements.statefulentitytype import StatefulEntityType
|
||||||
|
|
||||||
|
|
||||||
|
class RelationshipType(StatefulEntityType):
|
||||||
|
'''TOSCA built-in relationship type.'''
|
||||||
|
|
||||||
|
def __init__(self, type):
|
||||||
|
super(RelationshipType, self).__init__()
|
||||||
|
self.defs = self.TOSCA_DEF[type]
|
||||||
|
self.type = type
|
||||||
|
|
||||||
|
@property
|
||||||
|
def valid_targets(self):
|
||||||
|
return self.entity_value(self.defs, 'valid_targets')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def parent_type(self):
|
||||||
|
'''Return a relationship this relationship is derived from.'''
|
||||||
|
return self.derived_from(self.defs)
|
29
translator/toscalib/elements/statefulentitytype.py
Normal file
29
translator/toscalib/elements/statefulentitytype.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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.toscalib.elements.entitytype import EntityType
|
||||||
|
|
||||||
|
|
||||||
|
class StatefulEntityType(EntityType):
|
||||||
|
'''Class representing TOSCA states.'''
|
||||||
|
|
||||||
|
interfaces_node_lifecycle_operations = ['create',
|
||||||
|
'configure', 'start',
|
||||||
|
'stop', 'delete']
|
||||||
|
|
||||||
|
interfaces_relationship_confiure_operations = ['post_configure_source',
|
||||||
|
'post_configure_target',
|
||||||
|
'add_target',
|
||||||
|
'remove_target']
|
13
translator/toscalib/tests/__init__.py
Normal file
13
translator/toscalib/tests/__init__.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# -*- 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.
|
53
translator/toscalib/tests/base.py
Normal file
53
translator/toscalib/tests/base.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright 2010-2011 OpenStack Foundation
|
||||||
|
# Copyright (c) 2013 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 os
|
||||||
|
|
||||||
|
import fixtures
|
||||||
|
import testtools
|
||||||
|
|
||||||
|
_TRUE_VALUES = ('True', 'true', '1', 'yes')
|
||||||
|
|
||||||
|
|
||||||
|
class TestCase(testtools.TestCase):
|
||||||
|
|
||||||
|
"""Test case base class for all unit tests."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""Run before each test method to initialize test environment."""
|
||||||
|
|
||||||
|
super(TestCase, self).setUp()
|
||||||
|
test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0)
|
||||||
|
try:
|
||||||
|
test_timeout = int(test_timeout)
|
||||||
|
except ValueError:
|
||||||
|
# If timeout value is invalid do not set a timeout.
|
||||||
|
test_timeout = 0
|
||||||
|
if test_timeout > 0:
|
||||||
|
self.useFixture(fixtures.Timeout(test_timeout, gentle=True))
|
||||||
|
|
||||||
|
self.useFixture(fixtures.NestedTempfile())
|
||||||
|
self.useFixture(fixtures.TempHomeDir())
|
||||||
|
|
||||||
|
if os.environ.get('OS_STDOUT_CAPTURE') in _TRUE_VALUES:
|
||||||
|
stdout = self.useFixture(fixtures.StringStream('stdout')).stream
|
||||||
|
self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout))
|
||||||
|
if os.environ.get('OS_STDERR_CAPTURE') in _TRUE_VALUES:
|
||||||
|
stderr = self.useFixture(fixtures.StringStream('stderr')).stream
|
||||||
|
self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
|
||||||
|
|
||||||
|
self.log_fixture = self.useFixture(fixtures.FakeLogger())
|
64
translator/toscalib/tests/test_toscadef.py
Normal file
64
translator/toscalib/tests/test_toscadef.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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.toscalib.elements.nodetype import NodeType
|
||||||
|
from translator.toscalib.tests.base import TestCase
|
||||||
|
|
||||||
|
compute_type = NodeType('tosca.nodes.Compute')
|
||||||
|
component_type = NodeType('tosca.nodes.SoftwareComponent')
|
||||||
|
|
||||||
|
|
||||||
|
class ToscaDefTest(TestCase):
|
||||||
|
def test_type(self):
|
||||||
|
self.assertEqual(compute_type.type, "tosca.nodes.Compute")
|
||||||
|
self.assertRaises(ValueError, NodeType, 'tosca.nodes.Invalid')
|
||||||
|
|
||||||
|
def test_parent_type(self):
|
||||||
|
self.assertEqual(compute_type.parent_type.type, "tosca.nodes.Root")
|
||||||
|
|
||||||
|
def test_capabilities(self):
|
||||||
|
self.assertEqual(
|
||||||
|
['tosca.capabilities.Container'],
|
||||||
|
[c.type for c in compute_type.capabilities])
|
||||||
|
|
||||||
|
def test_properties_def(self):
|
||||||
|
self.assertEqual(
|
||||||
|
['disk_size', 'ip_address', 'mem_size',
|
||||||
|
'num_cpus', 'os_arch', 'os_distribution',
|
||||||
|
'os_type', 'os_version'],
|
||||||
|
sorted([p.name for p in compute_type.properties_def]))
|
||||||
|
self.assertTrue([p.required for p in compute_type.properties_def
|
||||||
|
if p.name == 'os_type'])
|
||||||
|
|
||||||
|
def test_requirements(self):
|
||||||
|
self.assertEqual(compute_type.requirements, None)
|
||||||
|
self.assertEqual(
|
||||||
|
[{'host': 'tosca.nodes.Compute'}],
|
||||||
|
[r for r in component_type.requirements])
|
||||||
|
|
||||||
|
def test_relationship(self):
|
||||||
|
self.assertEqual(
|
||||||
|
[('tosca.relationships.HostedOn', 'tosca.nodes.Compute')],
|
||||||
|
[(relation.type, node.type) for
|
||||||
|
relation, node in component_type.relationship.items()])
|
||||||
|
self.assertIn(
|
||||||
|
('tosca.relationships.HostedOn', ['tosca.capabilities.Container']),
|
||||||
|
[(relation.type, relation.valid_targets) for
|
||||||
|
relation in list(component_type.relationship.keys())])
|
||||||
|
|
||||||
|
def test_interfaces(self):
|
||||||
|
self.assertEqual(compute_type.interfaces, None)
|
||||||
|
root_node = NodeType('tosca.nodes.Root')
|
||||||
|
self.assertIn('tosca.interfaces.node.Lifecycle', root_node.interfaces)
|
0
translator/toscalib/utils/__init__.py
Normal file
0
translator/toscalib/utils/__init__.py
Normal file
25
translator/toscalib/utils/gettextutils.py
Normal file
25
translator/toscalib/utils/gettextutils.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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 gettext
|
||||||
|
import os
|
||||||
|
|
||||||
|
_localedir = os.environ.get('heat-translator'.upper() + '_LOCALEDIR')
|
||||||
|
_t = gettext.translation('heat-translator', localedir=_localedir,
|
||||||
|
fallback=True)
|
||||||
|
|
||||||
|
|
||||||
|
def _(msg):
|
||||||
|
return _t.gettext(msg)
|
@ -21,15 +21,6 @@ else:
|
|||||||
yaml_loader = yaml.SafeLoader
|
yaml_loader = yaml.SafeLoader
|
||||||
|
|
||||||
|
|
||||||
class Loader(object):
|
def load_yaml(path):
|
||||||
def __init__(self, file_name):
|
with open(path) as f:
|
||||||
self.file_name = file_name
|
return yaml.load(f.read(), Loader=yaml_loader)
|
||||||
|
|
||||||
def load(self):
|
|
||||||
f = open(self.file_name, 'r')
|
|
||||||
profile = f.read()
|
|
||||||
try:
|
|
||||||
doc = yaml.load(profile, Loader=yaml_loader)
|
|
||||||
except yaml.YAMLError as error:
|
|
||||||
raise ValueError(error)
|
|
||||||
return doc
|
|
Loading…
x
Reference in New Issue
Block a user