From 521be5d44de958b7471d2fb1c1a4aed074129013 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Thu, 3 Oct 2019 15:57:56 -0400 Subject: [PATCH] Further Python3 compatibility changes With this as well as eficompressor and pyghmi updates, things seem to be in roughly working order --- .../confluent/config/configmanager.py | 57 +++++++------------ confluent_server/confluent/consoleserver.py | 6 +- confluent_server/confluent/log.py | 2 +- confluent_server/confluent/messages.py | 2 +- .../plugins/configuration/attributes.py | 4 +- .../plugins/hardwaremanagement/redfish.py | 6 +- confluent_server/confluent/util.py | 8 +++ 7 files changed, 38 insertions(+), 47 deletions(-) diff --git a/confluent_server/confluent/config/configmanager.py b/confluent_server/confluent/config/configmanager.py index 503fb3ec..7d558404 100644 --- a/confluent_server/confluent/config/configmanager.py +++ b/confluent_server/confluent/config/configmanager.py @@ -472,10 +472,8 @@ def crypt_value(value, key = _masterkey iv = os.urandom(12) crypter = AES.new(key, AES.MODE_GCM, nonce=iv) - try: - cryptval, hmac = crypter.encrypt_and_digest(value) - except TypeError: - cryptval, hmac = crypter.encrypt_and_digest(value.encode('utf-8')) + value = confluent.util.stringify(value).encode('utf-8') + cryptval, hmac = crypter.encrypt_and_digest(value) return iv, cryptval, hmac, '\x02' @@ -484,16 +482,19 @@ def _load_dict_from_dbm(dpath, tdb): dbe = dbm.open(tdb, 'r') currdict = _cfgstore for elem in dpath: + elem = confluent.util.stringify(elem) if elem not in currdict: currdict[elem] = {} currdict = currdict[elem] try: for tk in dbe.keys(): - currdict[tk] = cPickle.loads(dbe[tk]) + tks = confluent.util.stringify(tk) + currdict[tks] = cPickle.loads(dbe[tk]) except AttributeError: tk = dbe.firstkey() while tk != None: - currdict[tk] = cPickle.loads(dbe[tk]) + tks = confluent.util.stringify(tk) + currdict[tks] = cPickle.loads(dbe[tk]) tk = dbe.nextkey(tk) except dbm.error: return @@ -532,13 +533,7 @@ def set_global(globalname, value, sync=True): """ if _cfgstore is None: init(not sync) - try: - globalname = globalname.encode('utf-8') - except AttributeError: - # We have to remove the unicode-ness of the string, - # but if it is already bytes in python 3, then we will - # get an attributeerror, so pass - pass + globalname = confluent.util.stringify(globalname) with _dirtylock: if 'dirtyglobals' not in _cfgstore: _cfgstore['dirtyglobals'] = set() @@ -795,10 +790,7 @@ def apply_pending_collective_updates(): def _true_add_collective_member(name, address, fingerprint, sync=True): - try: - name = name.encode('utf-8') - except AttributeError: - pass + name = confluent.util.stringify(name) if _cfgstore is None: init(not sync) # use not sync to avoid read from disk if 'collective' not in _cfgstore: @@ -833,8 +825,7 @@ def get_collective_member_by_address(address): def _mark_dirtykey(category, key, tenant=None): - if type(key) in (str, unicode): - key = key.encode('utf-8') + key = confluent.util.stringify(key) with _dirtylock: if 'dirtykeys' not in _cfgstore: _cfgstore['dirtykeys'] = {} @@ -1314,7 +1305,7 @@ class ConfigManager(object): def _true_create_usergroup(self, groupname, role="Administrator"): if 'usergroups' not in self._cfgstore: self._cfgstore['usergroups'] = {} - groupname = groupname.encode('utf-8') + groupname = confluent.util.stringify(groupname) if groupname in self._cfgstore['usergroups']: raise Exception("Duplicate groupname requested") self._cfgstore['usergroups'][groupname] = {'role': role} @@ -1416,7 +1407,7 @@ class ConfigManager(object): raise Exception("Duplicate id requested") if 'users' not in self._cfgstore: self._cfgstore['users'] = {} - name = name.encode('utf-8') + name = confluent.util.stringify(name) if name in self._cfgstore['users']: raise Exception("Duplicate username requested") self._cfgstore['users'][name] = {'id': uid} @@ -1674,9 +1665,7 @@ class ConfigManager(object): "{0} node does not exist to add to {1}".format( node, group)) for group in attribmap: - group = group.encode('utf-8') - if not isinstance(group, str): - group = group.decode('utf-8') + group = confluent.util.stringify(group) if group not in self._cfgstore['nodegroups']: self._cfgstore['nodegroups'][group] = {'nodes': set()} cfgobj = self._cfgstore['nodegroups'][group] @@ -1734,8 +1723,8 @@ class ConfigManager(object): attributes = realattributes if type(groups) in (str, unicode): groups = (groups,) - for group in groups: - group = group.encode('utf-8') + for group in groups: + group = confluent.util.stringify(group) try: groupentry = self._cfgstore['nodegroups'][group] except KeyError: @@ -1849,9 +1838,7 @@ class ConfigManager(object): # set a reserved attribute for the sake of the change notification # framework to trigger on changeset[node] = {'_nodedeleted': 1} - node = node.encode('utf-8') - if not isinstance(node, str): - node = node.decode('utf-8') + node = confluent.util.stringify(node) if node in self._cfgstore['nodes']: self._sync_groups_to_node(node=node, groups=[], changeset=changeset) @@ -1899,7 +1886,7 @@ class ConfigManager(object): realattributes.append(attrname) attributes = realattributes for node in nodes: - node = node.encode('utf-8') + node = confluent.util.stringify(node) try: nodek = self._cfgstore['nodes'][node] except KeyError: @@ -2028,9 +2015,7 @@ class ConfigManager(object): # first do a sanity check of the input upfront # this mitigates risk of arguments being partially applied for node in attribmap: - node = node.encode('utf-8') - if not isinstance(node, str): - node = node.decode('utf-8') + node = confluent.util.stringify(node) if node == '': raise ValueError('"{0}" is not a valid node name'.format(node)) if autocreate: @@ -2085,10 +2070,8 @@ class ConfigManager(object): attrname, node) raise ValueError(errstr) attribmap[node][attrname] = attrval - for node in attribmap: - node = node.encode('utf-8') - if not isinstance(node, str): - node = node.decode('utf-8') + for node in attribmap: + node = confluent.util.stringify(node) exprmgr = None if node not in self._cfgstore['nodes']: newnodes.append(node) diff --git a/confluent_server/confluent/consoleserver.py b/confluent_server/confluent/consoleserver.py index c65a397d..fececf78 100644 --- a/confluent_server/confluent/consoleserver.py +++ b/confluent_server/confluent/consoleserver.py @@ -533,12 +533,12 @@ class ConsoleHandler(object): elif data == '': # ignore empty strings from a cconsole provider return - if '\x1b[?1l' in data: # request for ansi mode cursor keys + if b'\x1b[?1l' in data: # request for ansi mode cursor keys self.appmodedetected = False - if '\x1b[?1h' in data: # remember the session wants the client to use + if b'\x1b[?1h' in data: # remember the session wants the client to use # 'application mode' Thus far only observed on esxi self.appmodedetected = True - if '\x1b)0' in data: + if b'\x1b)0' in data: # console indicates it wants access to special drawing characters self.shiftin = b'0' eventdata = 0 diff --git a/confluent_server/confluent/log.py b/confluent_server/confluent/log.py index 19e744f5..8a978490 100644 --- a/confluent_server/confluent/log.py +++ b/confluent_server/confluent/log.py @@ -748,7 +748,7 @@ class Logger(object): pass def log(self, logdata=None, ltype=None, event=0, eventdata=None): - if type(logdata) not in (str, unicode, dict): + if type(logdata) not in (bytes, unicode, dict): raise Exception("Unsupported logdata") if ltype is None: if type(logdata) == dict: diff --git a/confluent_server/confluent/messages.py b/confluent_server/confluent/messages.py index ae8bc12f..07718a3d 100644 --- a/confluent_server/confluent/messages.py +++ b/confluent_server/confluent/messages.py @@ -1689,7 +1689,7 @@ class CryptedAttributes(Attributes): # for now, just keep the dictionary keys and discard crypt value self.desc = desc nkv = {} - for key in kv.iterkeys(): + for key in kv: nkv[key] = {'isset': False} try: if kv[key] is not None and kv[key]['cryptvalue'] != '': diff --git a/confluent_server/confluent/plugins/configuration/attributes.py b/confluent_server/confluent/plugins/configuration/attributes.py index 04da045f..04f62f09 100644 --- a/confluent_server/confluent/plugins/configuration/attributes.py +++ b/confluent_server/confluent/plugins/configuration/attributes.py @@ -134,7 +134,7 @@ def retrieve_nodes(nodes, element, configmanager, inputdata): attribute, {}).get('description', '')) elif element[-1] == 'current': for node in util.natural_sort(list(attributes)): - for attribute in sorted(attributes[node].iterkeys()): + for attribute in sorted(attributes[node]): currattr = attributes[node][attribute] try: desc = allattributes.node[attribute]['description'] @@ -185,7 +185,7 @@ def update_nodegroup(group, element, configmanager, inputdata): return yield_rename_resources(namemap, isnode=False) try: clearattribs = [] - for attrib in inputdata.attribs.iterkeys(): + for attrib in inputdata.attribs: if inputdata.attribs[attrib] is None: clearattribs.append(attrib) for attrib in clearattribs: diff --git a/confluent_server/confluent/plugins/hardwaremanagement/redfish.py b/confluent_server/confluent/plugins/hardwaremanagement/redfish.py index 93cc31af..f9b609ec 100644 --- a/confluent_server/confluent/plugins/hardwaremanagement/redfish.py +++ b/confluent_server/confluent/plugins/hardwaremanagement/redfish.py @@ -274,7 +274,7 @@ def perform_requests(operator, nodes, element, cfg, inputdata, realop): raise datum if (hasattr(datum, 'kvpairs') and datum.kvpairs and len(datum.kvpairs) == 1): - bundle.append((datum.kvpairs.keys()[0], datum)) + bundle.append((list(datum.kvpairs)[0], datum)) numnodes -= 1 else: yield datum @@ -376,8 +376,8 @@ class IpmiHandler(object): self.loggedin = True self.ipmicmd = persistent_ipmicmds[(node, tenant)] except socket.gaierror as ge: - if ge[0] == -2: - raise exc.TargetEndpointUnreachable(ge[1]) + if ge.errno == -2: + raise exc.TargetEndpointUnreachable(ge.strerror) raise self.ipmicmd = persistent_ipmicmds[(node, tenant)] diff --git a/confluent_server/confluent/util.py b/confluent_server/confluent/util.py index 07bd25ed..9f03cc32 100644 --- a/confluent_server/confluent/util.py +++ b/confluent_server/confluent/util.py @@ -27,6 +27,14 @@ import socket import ssl import struct +def stringify(instr): + # Normalize unicode and bytes to 'str', correcting for + # current python version + if isinstance(instr, bytes) and not isinstance(instr, str): + return instr.decode('utf-8') + elif not isinstance(instr, bytes) and not isinstance(instr, str): + return instr.encode('utf-8') + return instr def list_interface_indexes(): # Getting the interface indexes in a portable manner