From 811ca617475f81af411c8781cca216a5c6f4090a Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 3 Mar 2014 14:48:46 -0500 Subject: [PATCH] Fix problem where broken expressions were not gracefully handled Now when expressions can not be completed, the reason is presented as 'broken'. Additionally, when unsetting a value that would affect expressions, perform appropriate changes. --- TODO | 5 ----- confluent/config/configmanager.py | 18 ++++++++++++++++-- confluent/messages.py | 4 ++++ plugins/configuration/attributes.py | 4 ++-- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/TODO b/TODO index 7857611a..6ea5a5cc 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,4 @@ -Reordering a group does not reorder inheritance preferences --Setting multiple values at once where one is an expression including the othe - can fail because the expression is attempted to set before - the next setting comes to work and then we get a stack trace - Should leave value out of it and set 'broken' with a reason as the - value to the key -expressionkeys never gets smaller - perf impact -need event notification for config change- e.g. set attribute triggers consol session object check to see if credentials changed diff --git a/confluent/config/configmanager.py b/confluent/config/configmanager.py index df4f1007..acf80b77 100644 --- a/confluent/config/configmanager.py +++ b/confluent/config/configmanager.py @@ -299,7 +299,12 @@ def _decode_attribute(attribute, nodeobj, formatter=None, decrypt=False): # set methods induce recalculation as appropriate to get a cached value if 'expression' in nodeobj[attribute] and formatter is not None: retdict = copy.deepcopy(nodeobj[attribute]) - retdict['value'] = formatter.format(retdict['expression']) + if 'value' in retdict: + del retdict['value'] + try: + retdict['value'] = formatter.format(retdict['expression']) + except Exception as e: + retdict['broken'] = str(e) return retdict elif 'value' in nodeobj[attribute]: return nodeobj[attribute] @@ -501,6 +506,8 @@ class ConfigManager(object): # if the attribute is not set, this will search for a candidate # if it is set, but inheritedfrom, search for a replacement, just # in case + if not 'groups' in nodecfg: + return for group in nodecfg['groups']: if attrib in self._cfgstore['groups'][group]: if srcgroup is not None and group != srcgroup: @@ -630,12 +637,19 @@ class ConfigManager(object): nodek = self._cfgstore['nodes'][node] except KeyError: continue + recalcexpressions = False for attrib in attributes: if attrib in nodek and 'inheritedfrom' not in nodek[attrib]: # if the attribute is set and not inherited, # delete it and check for inheritence to backfil data del nodek[attrib] self._do_inheritance(nodek, attrib, node) + if ('_expressionkeys' in nodek and + attrib in nodek['_expressionkeys']): + recalcexpressions = True + if recalcexpressions: + exprmgr = _ExpressionFormat(nodek, node) + self._recalculate_expressions(nodek, formatter=exprmgr) self._bg_sync_to_file() def set_node_attributes(self, attribmap): @@ -644,8 +658,8 @@ class ConfigManager(object): # TODO(jbjohnso): multi mgr support, here if we have peers, # pickle the arguments and fire them off in eventlet # flows to peers, all should have the same result - exprmgr = None for node in attribmap.iterkeys(): + exprmgr = None if node not in self._cfgstore['nodes']: self._cfgstore['nodes'][node] = {} cfgobj = self._cfgstore['nodes'][node] diff --git a/confluent/messages.py b/confluent/messages.py index d3e5e573..7019e79e 100644 --- a/confluent/messages.py +++ b/confluent/messages.py @@ -42,6 +42,10 @@ class ConfluentMessage(object): notes.append('Inherited from %s' % val['inheritedfrom']) if 'expression' in val: notes.append('Derived from expression "%s"' % val['expression']) + elif val is not None and 'expression' in val and 'broken' in val: + value = "*BROKEN*" + notes.append('Derived from expression "%s"' % val['expression']) + notes.append('Broken because of %s' % val['broken']) elif val is not None and 'expression' in val: value = val['expression'] if value is None: diff --git a/plugins/configuration/attributes.py b/plugins/configuration/attributes.py index 3f0cb7c8..43b99661 100644 --- a/plugins/configuration/attributes.py +++ b/plugins/configuration/attributes.py @@ -62,7 +62,7 @@ def retrieve_nodegroup(nodegroup, element, configmanager, inputdata): else: print attribute print repr(currattr) - raise Exception("BUGGY ATTRIBUTE FOR NODE") + raise Exception("BUGGY ATTRIBUTE FOR NODEGROUP") def retrieve_nodes(nodes, element, configmanager, inputdata): @@ -96,7 +96,7 @@ def retrieve_nodes(nodes, element, configmanager, inputdata): desc = allattributes.node[attribute]['description'] except KeyError: desc = 'Unknown' - if 'value' in currattr: + if 'value' in currattr or 'expression' in currattr: yield msg.Attributes(node, {attribute: currattr}, desc)