Added support to '!include' mechanism
The '!include' idiom is used to include an external YAML file into current one. Currently, it supports protocol like 'file', 'http' and 'https'(not tested).
This commit is contained in:
parent
d5fc91b091
commit
db29298dad
@ -11,7 +11,10 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
import six
|
import six
|
||||||
|
from six.moves import urllib
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from senlin.common import i18n
|
from senlin.common import i18n
|
||||||
@ -22,27 +25,56 @@ LOG = logging.getLogger(__name__)
|
|||||||
|
|
||||||
# Try LibYAML if available
|
# Try LibYAML if available
|
||||||
if hasattr(yaml, 'CSafeLoader'):
|
if hasattr(yaml, 'CSafeLoader'):
|
||||||
YamlLoader = yaml.CSafeLoader
|
Loader = yaml.CSafeLoader
|
||||||
else:
|
else:
|
||||||
YamlLoader = yaml.SafeLoader
|
Loader = yaml.SafeLoader
|
||||||
|
|
||||||
if hasattr(yaml, 'CSafeDumper'):
|
if hasattr(yaml, 'CSafeDumper'):
|
||||||
YamlDumper = yaml.CSafeDumper
|
Dumper = yaml.CSafeDumper
|
||||||
else:
|
else:
|
||||||
YamlDumper = yaml.SafeDumper
|
Dumper = yaml.SafeDumper
|
||||||
|
|
||||||
|
|
||||||
def _construct_yaml_str(self, node):
|
class YamlLoader(Loader):
|
||||||
# Override the default string handling function
|
def __init__(self, stream):
|
||||||
# to always return unicode objects
|
self._curdir = os.path.split(stream.name)[0]
|
||||||
return self.construct_scalar(node)
|
super(YamlLoader, self).__init__(stream)
|
||||||
|
|
||||||
YamlLoader.add_constructor(u'tag:yaml.org,2002:str', _construct_yaml_str)
|
def include(self, node):
|
||||||
|
url = self.construct_scalar(node)
|
||||||
|
components = urllib.parse.urlparse(url)
|
||||||
|
|
||||||
# Unquoted dates in YAML files get loaded as objects of type datetime.date
|
if components.scheme == '':
|
||||||
# which may cause problems in API layer. Therefore, make unicode string
|
try:
|
||||||
# out of timestamps until openstack.common.jsonutils can handle dates.
|
url = os.path.join(self._curdir, url)
|
||||||
YamlLoader.add_constructor(u'tag:yaml.org,2002:timestamp', _construct_yaml_str)
|
with open(url, 'r') as f:
|
||||||
|
return yaml.load(f, Loader)
|
||||||
|
except Exception as ex:
|
||||||
|
raise Exception('Failed loading file %s: %s' % (url,
|
||||||
|
six.text_type(ex)))
|
||||||
|
try:
|
||||||
|
resp = requests.get(url, stream=True)
|
||||||
|
resp.raise_for_status()
|
||||||
|
reader = resp.iter_content(chunk_size=1024)
|
||||||
|
result = ''
|
||||||
|
for chunk in reader:
|
||||||
|
result += chunk
|
||||||
|
return yaml.load(result, Loader)
|
||||||
|
except Exception as ex:
|
||||||
|
raise Exception('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):
|
def simple_parse(in_str):
|
||||||
|
Loading…
Reference in New Issue
Block a user