Support importing TOSCA custom node types

Currently TOSCA normative types and custom node types are defined in a single
file. This patch separates them in a desired fashion and provides import
support for custom node types in a TOSCA template.

implements blueprint tosca-custom-types

Change-Id: I73b1f51b8fc98058c606f72ae2a6f90afbe3777c
This commit is contained in:
Sahdev Zala 2014-06-17 21:19:48 -05:00
parent e76adf3c6c
commit 37851cabfc
6 changed files with 67 additions and 37 deletions

View File

@ -166,34 +166,6 @@ tosca.nodes.WebApplication:
requirements:
- host: tosca.nodes.WebServer
tosca.nodes.WebApplication.WordPress:
derived_from: tosca.nodes.WebApplication
properties:
admin_user:
required: no
type: string
admin_password:
required: no
type: string
db_host:
required: no
type: string
requirements:
- database_endpoint: tosca.nodes.Database
interfaces:
tosca.interfaces.node.Lifecycle:
inputs:
db_host:
type: string
db_port:
type: integer
db_name:
type: string
db_user:
type: string
db_password:
type: string
##########################################################################
# Relationship Type.
# A Relationship Type is a reusable entity that defines the type of one

View File

@ -30,12 +30,15 @@ SECTIONS = (DERIVED_FROM, PROPERTIES, REQUIREMENTS,
class NodeType(StatefulEntityType):
'''TOSCA built-in node type.'''
def __init__(self, ntype):
def __init__(self, ntype, custom_def=None):
super(NodeType, self).__init__()
if ntype not in list(self.TOSCA_DEF.keys()):
if ntype in list(self.TOSCA_DEF.keys()):
self.defs = self.TOSCA_DEF[ntype]
elif custom_def and ntype in list(custom_def.keys()):
self.defs = custom_def[ntype]
else:
raise ValueError(_('Node type %(ntype)s is not a valid type.')
% {'ntype': ntype})
self.defs = self.TOSCA_DEF[ntype]
self.type = ntype
self.related = {}

View File

@ -32,9 +32,9 @@ log = logging.getLogger('tosca')
class NodeTemplate(object):
'''Node template from a Tosca profile.'''
def __init__(self, name, node_templates):
def __init__(self, name, node_templates, custom_def=None):
self.name = name
self.node_type = NodeType(node_templates[name]['type'])
self.node_type = NodeType(node_templates[name]['type'], custom_def)
self.node_templates = node_templates
self.node_template = node_templates[self.name]
self.type = self.node_template['type']

View File

@ -0,0 +1,30 @@
tosca_definitions_version: tosca_simple_1.0
node_types:
tosca.nodes.WebApplication.WordPress:
derived_from: tosca.nodes.WebApplication
properties:
admin_user:
required: no
type: string
admin_password:
required: no
type: string
db_host:
required: no
type: string
requirements:
- database_endpoint: tosca.nodes.Database
interfaces:
tosca.interfaces.node.Lifecycle:
inputs:
db_host:
type: string
db_port:
type: integer
db_name:
type: string
db_user:
type: string
db_password:
type: string

View File

@ -3,6 +3,9 @@ tosca_definitions_version: tosca_simple_1.0
description: >
TOSCA simple profile with wordpress, web server and mysql on the same server.
imports:
- custom_types/wordpress.yaml
inputs:
cpus:
type: integer

View File

@ -15,6 +15,7 @@
import logging
import os
from translator.toscalib.nodetemplate import NodeTemplate
from translator.toscalib.parameters import Input, Output
from translator.toscalib.tpl_relationship_graph import ToscaGraph
@ -22,18 +23,21 @@ from translator.toscalib.utils.gettextutils import _
import translator.toscalib.utils.yamlparser
SECTIONS = (VERSION, DESCRIPTION, INPUTS,
SECTIONS = (VERSION, DESCRIPTION, IMPORTS, INPUTS,
NODE_TEMPLATES, OUTPUTS) = \
('tosca_definitions_version', 'description', 'inputs',
('tosca_definitions_version', 'description', 'imports', 'inputs',
'node_templates', 'outputs')
log = logging.getLogger("tosca.model")
YAML_LOADER = translator.toscalib.utils.yamlparser.load_yaml
class ToscaTemplate(object):
'''Load the template data.'''
def __init__(self, path):
self.tpl = translator.toscalib.utils.yamlparser.load_yaml(path)
self.tpl = YAML_LOADER(path)
self.path = path
self.version = self._tpl_version()
self.description = self._tpl_description()
self.inputs = self._inputs()
@ -53,10 +57,24 @@ class ToscaTemplate(object):
return inputs
def _nodetemplates(self):
custom_types = {}
imports = self._tpl_imports()
if imports:
for definition in imports:
if os.path.isabs(definition):
def_file = definition
else:
tpl_dir = os.path.dirname(os.path.abspath(self.path))
def_file = os.path.join(tpl_dir, definition)
custom_type = YAML_LOADER(def_file)
node_types = custom_type['node_types']
for name in node_types:
defintion = node_types[name]
custom_types[name] = defintion
nodetemplates = []
tpls = self._tpl_nodetemplates()
for name, value in tpls.items():
tpl = NodeTemplate(name, tpls)
tpl = NodeTemplate(name, tpls, custom_types)
tpl.validate()
nodetemplates.append(tpl)
return nodetemplates
@ -73,6 +91,10 @@ class ToscaTemplate(object):
def _tpl_description(self):
return self.tpl[DESCRIPTION].rstrip()
def _tpl_imports(self):
if IMPORTS in self.tpl:
return self.tpl[IMPORTS]
def _tpl_inputs(self):
return self.tpl[INPUTS]