1 # Copyright 2016 RIFT.io Inc
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 from collections
import OrderedDict
19 from rift
.mano
.yang_translator
.common
.utils
import _
20 from rift
.mano
.yang_translator
.rwmano
.syntax
.tosca_resource \
26 class ToscaTemplate(object):
27 '''Container for full RIFT.io TOSCA template.'''
29 KEYS
= (TOSCA
, FILES
) = ('tosca', 'files')
31 def __init__(self
, log
):
35 def output_to_tosca(self
):
36 self
.log
.debug(_('Converting translated output to tosca template.'))
41 for resource
in self
.resources
:
42 if resource
.type == 'vnfd':
43 tmpl
= resource
.generate_tosca()
44 tmpl
= resource
.generate_tosca_template(tmpl
)
45 self
.log
.debug(_("TOSCA template generated for {0}:\n{1}").
46 format(resource
.name
, tmpl
))
47 vnfd_templates
[resource
.name
] = tmpl
49 for resource
in self
.resources
:
50 # Each NSD should generate separate templates
51 if resource
.type == 'nsd':
52 tmpl
= resource
.generate_tosca_type()
53 tmpl
= resource
.generate_tosca_template(tmpl
)
54 self
.log
.debug(_("TOSCA template generated for {0}:\n{1}").
55 format(resource
.name
, tmpl
))
56 templates
[resource
.name
] = {self
.TOSCA
: self
.output_to_yaml(tmpl
)}
57 files
= resource
.get_supporting_files()
59 templates
[resource
.name
][self
.FILES
] = files
61 for resource
in self
.resources
:
62 if resource
.type == 'vnfd':
63 tmpl
= vnfd_templates
[resource
.name
]
64 templates
[resource
.name
] = {self
.TOSCA
: self
.output_to_yaml(tmpl
)}
65 files
= resource
.get_supporting_files()
67 templates
[resource
.name
][self
.FILES
] = files
71 def represent_ordereddict(self
, dumper
, data
):
73 for key
, value
in data
.items():
74 node_key
= dumper
.represent_data(key
)
75 node_value
= dumper
.represent_data(value
)
76 nodes
.append((node_key
, node_value
))
77 return yaml
.nodes
.MappingNode(u
'tag:yaml.org,2002:map', nodes
)
79 def ordered_node(self
, node
):
80 order
= [ToscaResource
.TYPE
, ToscaResource
.DERIVED_FROM
,
81 ToscaResource
.DESC
, ToscaResource
.MEMBERS
,
82 ToscaResource
.PROPERTIES
, ToscaResource
.CAPABILITIES
,
83 ToscaResource
.REQUIREMENTS
,ToscaResource
.ARTIFACTS
,
84 ToscaResource
.INTERFACES
]
85 new_node
= OrderedDict()
86 self
.log
.debug("Node to oder: {}".format(node
))
89 new_node
.update({ent
: node
.pop(ent
)})
91 # Check if we missed any entry
93 self
.log
.warn(_("Did not sort these entries: {0}").
99 def ordered_nodes(self
, nodes
):
100 new_nodes
= OrderedDict()
101 if isinstance(nodes
, dict):
102 for name
, node
in nodes
.items():
103 new_nodes
.update({name
: self
.ordered_node(node
)})
108 def ordered_nodes_sub_mapping(self
, nodes
):
109 new_nodes
= OrderedDict()
110 if isinstance(nodes
, dict):
111 for name
, node
in nodes
.items():
112 new_nodes
.update({name
: node
})
117 def output_to_yaml(self
, tosca
):
118 self
.log
.debug(_('Converting translated output to yaml format.'))
119 dict_output
= OrderedDict()
120 dict_output
.update({'tosca_definitions_version':
121 tosca
['tosca_definitions_version']})
124 if ToscaResource
.DESC
in tosca
:
125 # Wrap the text to a new line if the line exceeds 80 characters.
126 wrapped_txt
= "\n ". \
127 join(textwrap
.wrap(tosca
[ToscaResource
.DESC
], 80))
128 desc_str
= ToscaResource
.DESC
+ ": >\n " + \
130 dict_output
.update({ToscaResource
.DESC
: tosca
[ToscaResource
.DESC
]})
132 if ToscaResource
.METADATA
in tosca
:
133 dict_output
.update({ToscaResource
.METADATA
:
134 tosca
[ToscaResource
.METADATA
]})
135 if ToscaResource
.IMPORT
in tosca
:
136 dict_output
.update({ToscaResource
.IMPORT
:
137 tosca
[ToscaResource
.IMPORT
]})
140 types_list
= [ToscaResource
.DATA_TYPES
, ToscaResource
.CAPABILITY_TYPES
,
141 ToscaResource
.NODE_TYPES
, ToscaResource
.ARTIFACT_TYPES
,
142 ToscaResource
.GROUP_TYPES
, ToscaResource
.POLICY_TYPES
]
143 for typ
in types_list
:
145 dict_output
.update({typ
: self
.ordered_nodes(tosca
[typ
])})
147 # Add topology template
148 topo_list
= [ToscaResource
.INPUTS
, ToscaResource
.NODE_TMPL
,
149 ToscaResource
.GROUPS
, ToscaResource
.POLICIES
,
150 ToscaResource
.OUTPUTS
]
151 if ToscaResource
.TOPOLOGY_TMPL
in tosca
:
153 for typ
in tosca
[ToscaResource
.TOPOLOGY_TMPL
]:
154 if typ
!= ToscaResource
.SUBSTITUTION_MAPPING
:
157 tosca
[ToscaResource
.TOPOLOGY_TMPL
][typ
])})
160 self
.ordered_nodes_sub_mapping(
161 tosca
[ToscaResource
.TOPOLOGY_TMPL
][typ
])})
162 dict_output
.update({ToscaResource
.TOPOLOGY_TMPL
: tmpl
})
164 yaml
.add_representer(OrderedDict
, self
.represent_ordereddict
)
165 yaml_string
= yaml
.dump(dict_output
, default_flow_style
=False)
166 # get rid of the '' from yaml.dump around numbers
167 yaml_string
= yaml_string
.replace('\'', '')
168 self
.log
.debug(_("YAML output:\n{0}").format(yaml_string
))