From f9dc92ecb6d5c6337085f344ff181329a9639dda Mon Sep 17 00:00:00 2001 From: Markus Hilger Date: Sat, 1 Aug 2026 22:54:47 +0200 Subject: [PATCH] Fix -e attribute setting for dotted attribute names nodeattrib/nodegroupattrib -e replaced '.' with '_' in the attribute name before handing it to the server, not just when looking up the environment variable. Any attribute with a dot in it was therefore rejected, e.g. $ export info_note=test $ nodeattrib -e gpu1 info.note Traceback (most recent call last): File "/opt/confluent/bin/nodeattrib", line 97, in exitcode=client.updateattrib(session,args,nodetype, noderange, options, argassign) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/confluent/lib/python/confluent/client.py", line 688, in updateattrib key, os.environ[key.upper()]) ~~~~~~~~~~^^^^^^^^^^^^^ File "", line 714, in __getitem__ KeyError: 'INFO_NOTE' $ export INFO_NOTE=test $ nodeattrib -e gpu1 info.note Error: Bad Request - info_note attribute on node gpu1 is invalid Keep the attribute name intact and derive the environment variable name from it separately. A missing environment variable now reports which variable names were looked for instead of raising a bare KeyError traceback. --- confluent_client/confluent/client.py | 30 ++++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/confluent_client/confluent/client.py b/confluent_client/confluent/client.py index 1ffea6ec..01da116d 100644 --- a/confluent_client/confluent/client.py +++ b/confluent_client/confluent/client.py @@ -682,23 +682,31 @@ def updateattrib(session, updateargs, nodetype, noderange, options, dictassign=N sys.stderr.write('Error: ' + res['error'] + '\n') sys.exit(exitcode) elif hasattr(options, 'environment') and options.environment: - for key in updateargs[1:]: - key = key.replace('.', '_') - value = os.environ.get( - key, os.environ[key.upper()]) - # Let's do one pass to make sure that there's not a usage problem - for key in updateargs[1:]: - key = key.replace('.', '_') - value = os.environ.get( - key, os.environ[key.upper()]) + # The environment variable name substitutes '_' for '.' + attrvalues = {} + # Let's do one pass to make sure that there's not a usage problem + for attrib in updateargs[1:]: + envkey = attrib.replace('.', '_') + if envkey in os.environ: + attrvalues[attrib] = os.environ[envkey] + elif envkey.upper() in os.environ: + attrvalues[attrib] = os.environ[envkey.upper()] + else: + sys.stderr.write( + 'Error: {0} requested, but neither {1} nor {2} is set in ' + 'the environment\n'.format(attrib, envkey, envkey.upper())) + sys.exit(1) + for attrib in updateargs[1:]: if (nodetype == "nodegroups"): exitcode = session.simple_nodegroups_command(noderange, 'attributes/all', - value, key) + attrvalues[attrib], + attrib) else: exitcode = session.simple_noderange_command(noderange, 'attributes/all', - value, key) + attrvalues[attrib], + attrib) sys.exit(exitcode) elif dictassign: for key in dictassign: