|
@@ -11,8 +11,9 @@ from datetime import datetime
|
|
|
from resource_management import shell
|
|
|
from resource_management.exceptions import Fail
|
|
|
from resource_management.providers import find_provider
|
|
|
-from resource_management.utils import AttributeDictionary
|
|
|
+from resource_management.utils import AttributeDictionary, ParamsAttributeDictionary
|
|
|
from resource_management.system import System
|
|
|
+from string import Template
|
|
|
|
|
|
|
|
|
class Environment(object):
|
|
@@ -32,6 +33,7 @@ class Environment(object):
|
|
|
self.config = AttributeDictionary()
|
|
|
self.resources = {}
|
|
|
self.resource_list = []
|
|
|
+ Substitutor.default_prefixes = []
|
|
|
self.delayed_actions = set()
|
|
|
self.update_config({
|
|
|
# current time
|
|
@@ -43,7 +45,7 @@ class Environment(object):
|
|
|
# dir where templates,failes dirs are
|
|
|
'basedir': basedir,
|
|
|
# variables, which can be used in templates
|
|
|
- 'params': params,
|
|
|
+ 'params': ParamsAttributeDictionary(Substitutor, params),
|
|
|
})
|
|
|
|
|
|
def backup_file(self, path):
|
|
@@ -87,6 +89,9 @@ class Environment(object):
|
|
|
self.log.info(
|
|
|
"%s sending %s action to %s (delayed)" % (resource, action, res))
|
|
|
self.delayed_actions |= resource.subscriptions['delayed']
|
|
|
+
|
|
|
+ def set_default_prefixes(self, dict):
|
|
|
+ Substitutor.default_prefixes = dict
|
|
|
|
|
|
def _check_condition(self, cond):
|
|
|
if hasattr(cond, '__call__'):
|
|
@@ -157,3 +162,78 @@ class Environment(object):
|
|
|
self.resources = state['resources']
|
|
|
self.resource_list = state['resource_list']
|
|
|
self.delayed_actions = state['delayed_actions']
|
|
|
+
|
|
|
+
|
|
|
+class Substitutor():
|
|
|
+ log = logging.getLogger("resource_management.resource")
|
|
|
+ default_prefixes = []
|
|
|
+
|
|
|
+ class ExtendedTemplate(Template):
|
|
|
+ """
|
|
|
+ This is done to support substitution of dictionaries in dictionaries
|
|
|
+ ( ':' sign)
|
|
|
+
|
|
|
+ default is:
|
|
|
+ idpattern = r'[_a-z][_a-z0-9]*'
|
|
|
+ """
|
|
|
+ idpattern = r'[_a-z][_a-z0-9:]*'
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def _get_subdict(name, dic):
|
|
|
+ """
|
|
|
+ "a:b:c" => a[b][c]
|
|
|
+
|
|
|
+ doesn't use prefixes
|
|
|
+ """
|
|
|
+ name_parts = name.split(':')
|
|
|
+ curr = dic
|
|
|
+
|
|
|
+ for x in name_parts:
|
|
|
+ curr = curr[x]
|
|
|
+ return curr
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def get_subdict(name, dic):
|
|
|
+ """
|
|
|
+ "a:b:c" => a[b][c]
|
|
|
+
|
|
|
+ can use prefixes
|
|
|
+ """
|
|
|
+ prefixes = list(Substitutor.default_prefixes)
|
|
|
+ prefixes.insert(0, None) # for not prefixed case
|
|
|
+ name_parts = name.split(':')
|
|
|
+ is_found = False
|
|
|
+ result = None
|
|
|
+
|
|
|
+ for prefix in prefixes:
|
|
|
+ curr = Substitutor._get_subdict(prefix,dic) if prefix else dic
|
|
|
+
|
|
|
+ try:
|
|
|
+ for x in name_parts:
|
|
|
+ curr = curr[x]
|
|
|
+ except (KeyError, TypeError):
|
|
|
+ continue
|
|
|
+
|
|
|
+ if is_found:
|
|
|
+ raise Fail("Variable ${%s} found more than one time, please check your default prefixes!" % name)
|
|
|
+
|
|
|
+ is_found = True
|
|
|
+ result = curr
|
|
|
+
|
|
|
+ if not result:
|
|
|
+ raise Fail("Configuration on ${%s} cannot be resolved" % name)
|
|
|
+
|
|
|
+ return result
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def substitute(val):
|
|
|
+ env = Environment.get_instance()
|
|
|
+ dic = env.config.params
|
|
|
+
|
|
|
+ if dic and isinstance(val, str):
|
|
|
+ result = Substitutor.ExtendedTemplate(val).substitute(dic)
|
|
|
+ if '$' in val:
|
|
|
+ Substitutor.log.debug("%s after substitution is %s", val, result)
|
|
|
+ return result
|
|
|
+
|
|
|
+ return val
|