diff --git a/confluent_client/confluent/client.py b/confluent_client/confluent/client.py index c2c2a560..5f322705 100644 --- a/confluent_client/confluent/client.py +++ b/confluent_client/confluent/client.py @@ -1,7 +1,7 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2014 IBM Corporation -# Copyright 2015-2016 Lenovo +# Copyright 2015-2018 Lenovo # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -483,23 +483,23 @@ def updateattrib(session, updateargs, nodetype, noderange, options): else: if "=" in updateargs[1]: try: - if len(updateargs[1:]) > 1: - for val in updateargs[1:]: - val = val.split('=') - if (nodetype == "nodegroups"): - exitcode = session.simple_nodegroups_command(noderange, 'attributes/all', - val[1],val[0]) - else: - exitcode = session.simple_noderange_command(noderange, 'attributes/all', - val[1], val[0]) - else: - val = updateargs[1].split('=') - if nodetype == "nodegroups" : - exitcode = session.simple_nodegroups_command(noderange, 'attributes/all', - val[1], val[0]) + for val in updateargs[1:]: + val = val.split('=') + if val[0][-1] in (',', '-'): + key = val[0][:-1] + if val[0][-1] == ',': + value = {'prepend': val[1]} + elif val[0][-1] in ('-', '^'): + value = {'remove': val[1]} + else: + key = val[0] + value = val[1] + if (nodetype == "nodegroups"): + exitcode = session.simple_nodegroups_command(noderange, 'attributes/all', + value, key) else: exitcode = session.simple_noderange_command(noderange, 'attributes/all', - val[1], val[0]) + value, key) except: sys.stderr.write('Error: {0} not a valid expression\n'.format(str(updateargs[1:]))) exitcode = 1 diff --git a/confluent_client/doc/man/nodeattrib.ronn b/confluent_client/doc/man/nodeattrib.ronn index 92f2f89b..ca3f830a 100644 --- a/confluent_client/doc/man/nodeattrib.ronn +++ b/confluent_client/doc/man/nodeattrib.ronn @@ -21,6 +21,9 @@ For a full list of attributes, run `nodeattrib all` against a node. If `-c` is specified, this will set the nodeattribute to a null valid. This is different from setting the value to an empty string. +For the `groups` attribute, it is possible to add a group by doing +`groups,=`` and to remove by doing `groups^=` + Note that `nodeattrib ` will likely not provide the expected behavior. See nodegroupattrib(8) command on how to manage attributes on a group level. diff --git a/confluent_server/confluent/config/configmanager.py b/confluent_server/confluent/config/configmanager.py index ea952f38..1ba5ec10 100644 --- a/confluent_server/confluent/config/configmanager.py +++ b/confluent_server/confluent/config/configmanager.py @@ -1,7 +1,7 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2014 IBM Corporation -# Copyright 2015 Lenovo +# Copyright 2015-2018 Lenovo # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -1043,6 +1043,18 @@ class ConfigManager(object): raise ValueError(errstr) attribmap[group][attr] = attrval if attr == 'nodes': + if isinstance(attribmap[group][attr], dict): + currnodes = list(self.get_nodegroup_attributes( + group, ['nodes']).get('nodes', [])) + if attribmap[group][attr].get('prepend', False): + newnodes = attribmap[group][attr][ + 'prepend'].split(',') + attribmap[group][attr] = newnodes + currnodes + elif attribmap[group][attr].get('remove', False): + delnodes = attribmap[group][attr][ + 'remove'].split(',') + attribmap[group][attr] = [ + x for x in currnodes if x not in delnodes] if not isinstance(attribmap[group][attr], list): if type(attribmap[group][attr]) is unicode or type(attribmap[group][attr]) is str: attribmap[group][attr]=attribmap[group][attr].split(",") @@ -1291,7 +1303,20 @@ class ConfigManager(object): except KeyError: pass if attrname == 'groups': - if type(attribmap[node]['groups']) != list: + if isinstance(attribmap[node]['groups'], dict): + currgroups = self.get_node_attributes( + node, 'groups').get(node, {}).get('groups', []) + if attribmap[node]['groups'].get('prepend', False): + newgroups = attribmap[node]['groups'][ + 'prepend'].split(',') + attribmap[node]['groups'] = newgroups + currgroups + elif attribmap[node]['groups'].get('remove', False): + delgroups = attribmap[node]['groups'][ + 'remove'].split(',') + newgroups = [ + x for x in currgroups if x not in delgroups] + attribmap[node]['groups'] = newgroups + elif type(attribmap[node]['groups']) != list: attribmap[node]['groups']=attribmap[node]['groups'].split(",") for group in attribmap[node]['groups']: if group not in self._cfgstore['nodegroups']: