vFW and vDNS support added to azure-plugin
[multicloud/azure.git] / azure / aria / aria-extension-cloudify / src / aria / aria / parser / reading / yaml.py
1 # Licensed under the Apache License, Version 2.0 (the "License");
2 # you may not use this file except in compliance with the License.
3 # You may obtain a copy of the License at
4 #
5 # http://www.apache.org/licenses/LICENSE-2.0
6 #
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS,
9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 # See the License for the specific language governing permissions and
11 # limitations under the License.
12
13 from ruamel import yaml # @UnresolvedImport
14
15 from ...utils.collections import OrderedDict
16 from .reader import Reader
17 from .locator import Locator
18 from .exceptions import ReaderSyntaxError
19 from .locator import LocatableString, LocatableInt, LocatableFloat
20
21 # Add our types to ruamel.yaml
22 yaml.representer.RoundTripRepresenter.add_representer(
23     LocatableString, yaml.representer.RoundTripRepresenter.represent_unicode)
24 yaml.representer.RoundTripRepresenter.add_representer(
25     LocatableInt, yaml.representer.RoundTripRepresenter.represent_int)
26 yaml.representer.RoundTripRepresenter.add_representer(
27     LocatableFloat, yaml.representer.RoundTripRepresenter.represent_float)
28
29 MERGE_TAG = u'tag:yaml.org,2002:merge'
30 MAP_TAG = u'tag:yaml.org,2002:map'
31
32
33 class YamlLocator(Locator):
34     """
35     Map for agnostic raw data read from YAML.
36     """
37
38     def add_children(self, node):
39         if isinstance(node, yaml.SequenceNode):
40             self.children = []
41             for child_node in node.value:
42                 self.add_child(child_node)
43         elif isinstance(node, yaml.MappingNode):
44             self.children = {}
45             for k, child_node in node.value:
46                 self.add_child(child_node, k)
47
48     def add_child(self, node, key=None):
49         locator = YamlLocator(self.location, node.start_mark.line + 1, node.start_mark.column + 1)
50         if key is not None:
51             # Dict
52             if key.tag == MERGE_TAG:
53                 for merge_key, merge_node in node.value:
54                     self.add_child(merge_node, merge_key)
55             else:
56                 self.children[key.value] = locator
57         else:
58             # List
59             self.children.append(locator)
60         locator.add_children(node)
61
62
63 def construct_yaml_map(self, node):
64     data = OrderedDict()
65     yield data
66     value = self.construct_mapping(node)
67     data.update(value)
68
69
70 yaml.constructor.SafeConstructor.add_constructor(MAP_TAG, construct_yaml_map)
71
72
73 class YamlReader(Reader):
74     """
75     ARIA YAML reader.
76     """
77
78     def read(self):
79         data = self.load()
80         try:
81             data = unicode(data)
82             # see issue here:
83             # https://bitbucket.org/ruamel/yaml/issues/61/roundtriploader-causes-exceptions-with
84             #yaml_loader = yaml.RoundTripLoader(data)
85             yaml_loader = yaml.SafeLoader(data)
86             try:
87                 node = yaml_loader.get_single_node()
88                 locator = YamlLocator(self.loader.location, 0, 0)
89                 if node is not None:
90                     locator.add_children(node)
91                     raw = yaml_loader.construct_document(node)
92                 else:
93                     raw = OrderedDict()
94                 #locator.dump()
95                 setattr(raw, '_locator', locator)
96                 return raw
97             finally:
98                 yaml_loader.dispose()
99         except yaml.parser.MarkedYAMLError as e:
100             context = e.context or 'while parsing'
101             problem = e.problem
102             line = e.problem_mark.line
103             column = e.problem_mark.column
104             snippet = e.problem_mark.get_snippet()
105             raise ReaderSyntaxError('YAML %s: %s %s' %
106                                     (e.__class__.__name__, problem, context),
107                                     location=self.loader.location,
108                                     line=line,
109                                     column=column,
110                                     snippet=snippet,
111                                     cause=e)
112         except Exception as e:
113             raise ReaderSyntaxError('YAML: %s' % e, cause=e)