# 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 oslo_serialization import jsonutils import six from six.moves import urllib import yaml from senlin.common.i18n import _ # Try LibYAML if available if hasattr(yaml, 'CSafeLoader'): Loader = yaml.CSafeLoader else: Loader = yaml.SafeLoader if hasattr(yaml, 'CSafeDumper'): Dumper = yaml.CSafeDumper else: Dumper = yaml.SafeDumper class YamlLoader(Loader): def normalise_file_path_to_url(self, path): if urllib.parse.urlparse(path).scheme: return path path = os.path.abspath(path) return urllib.parse.urljoin('file:', urllib.request.pathname2url(path)) def include(self, node): try: url = self.normalise_file_path_to_url(self.construct_scalar(node)) tmpl = urllib.request.urlopen(url).read() return yaml.load(tmpl, Loader) except urllib.error.URLError as ex: raise IOError('Failed retrieving file %s: %s' % (url, six.text_type(ex))) def process_unicode(self, node): # Override the default string handling function to always return # unicode objects return self.construct_scalar(node) YamlLoader.add_constructor('!include', YamlLoader.include) YamlLoader.add_constructor(u'tag:yaml.org,2002:str', YamlLoader.process_unicode) YamlLoader.add_constructor(u'tag:yaml.org,2002:timestamp', YamlLoader.process_unicode) def simple_parse(in_str): try: out_dict = jsonutils.loads(in_str) except ValueError: try: out_dict = yaml.load(in_str, Loader=YamlLoader) except yaml.YAMLError as yea: yea = six.text_type(yea) msg = _('Error parsing input: %s') % yea raise ValueError(msg) else: if out_dict is None: out_dict = {} if not isinstance(out_dict, dict): msg = _('The input is not a JSON object or YAML mapping.') raise ValueError(msg) return out_dict