diff --git a/confluent_client/confluent/tlvdata.py b/confluent_client/confluent/tlvdata.py index 18a3328b..f7d567fe 100644 --- a/confluent_client/confluent/tlvdata.py +++ b/confluent_client/confluent/tlvdata.py @@ -25,6 +25,11 @@ try: except NameError: unicode = str +try: + range = xrange +except NameError: + pass + def decodestr(value): ret = None try: @@ -40,7 +45,7 @@ def decodestr(value): def unicode_dictvalues(dictdata): for key in dictdata: - if isinstance(dictdata[key], str): + if isinstance(dictdata[key], bytes): dictdata[key] = decodestr(dictdata[key]) elif isinstance(dictdata[key], datetime): dictdata[key] = dictdata[key].strftime('%Y-%m-%dT%H:%M:%S') @@ -51,7 +56,7 @@ def unicode_dictvalues(dictdata): def _unicode_list(currlist): - for i in xrange(len(currlist)): + for i in range(len(currlist)): if isinstance(currlist[i], str): currlist[i] = decodestr(currlist[i]) elif isinstance(currlist[i], dict): @@ -66,7 +71,7 @@ def send(handle, data): data = data.encode('utf-8') except AttributeError: pass - if isinstance(data, str) or isinstance(data, unicode): + if isinstance(data, bytes) or isinstance(data, unicode): # plain text, e.g. console data tl = len(data) if tl == 0: diff --git a/confluent_server/confluent/config/configmanager.py b/confluent_server/confluent/config/configmanager.py index 859598a8..503fb3ec 100644 --- a/confluent_server/confluent/config/configmanager.py +++ b/confluent_server/confluent/config/configmanager.py @@ -1826,7 +1826,8 @@ class ConfigManager(object): 'nodeattrs': {node: [attrname]}, 'callback': attribwatcher[watchkey][notifierid] } - for watcher in notifdata.itervalues(): + for watcher in notifdata: + watcher = notifdata[watcher] callback = watcher['callback'] eventlet.spawn_n(_do_notifier, self, watcher, callback) @@ -1840,7 +1841,8 @@ class ConfigManager(object): def _true_del_nodes(self, nodes): if self.tenant in self._nodecollwatchers: - for watcher in self._nodecollwatchers[self.tenant].itervalues(): + for watcher in self._nodecollwatchers[self.tenant]: + watcher = self._nodecollwatchers[self.tenant][watcher] watcher(added=(), deleting=nodes, renamed=(), configmanager=self) changeset = {} for node in nodes: @@ -1968,7 +1970,8 @@ class ConfigManager(object): self._recalculate_expressions(cfgobj, formatter=exprmgr, node=renamemap[name], changeset=changeset) if self.tenant in self._nodecollwatchers: nodecollwatchers = self._nodecollwatchers[self.tenant] - for watcher in nodecollwatchers.itervalues(): + for watcher in nodecollwatchers: + watcher = nodecollwatchers[watcher] eventlet.spawn_n(_do_add_watcher, watcher, (), self, renamemap) self._bg_sync_to_file() @@ -2026,7 +2029,7 @@ class ConfigManager(object): # this mitigates risk of arguments being partially applied for node in attribmap: node = node.encode('utf-8') - if not isinstance(group, str): + if not isinstance(node, str): node = node.decode('utf-8') if node == '': raise ValueError('"{0}" is not a valid node name'.format(node)) @@ -2128,7 +2131,8 @@ class ConfigManager(object): if newnodes: if self.tenant in self._nodecollwatchers: nodecollwatchers = self._nodecollwatchers[self.tenant] - for watcher in nodecollwatchers.itervalues(): + for watcher in nodecollwatchers: + watcher = nodecollwatchers[watcher] eventlet.spawn_n(_do_add_watcher, watcher, newnodes, self) self._bg_sync_to_file() #TODO: wait for synchronization to suceed/fail??) diff --git a/confluent_server/confluent/consoleserver.py b/confluent_server/confluent/consoleserver.py index 0413d1a6..c65a397d 100644 --- a/confluent_server/confluent/consoleserver.py +++ b/confluent_server/confluent/consoleserver.py @@ -94,7 +94,7 @@ def _utf8_normalize(data, shiftin, decoder): def pytechars2line(chars, maxlen=None): - line = '\x1b[m' # start at default params + line = b'\x1b[m' # start at default params lb = False # last bold li = False # last italic lu = False # last underline @@ -130,9 +130,12 @@ def pytechars2line(chars, maxlen=None): csi.append(7 if lr else 27) if csi: line += b'\x1b[' + b';'.join(['{0}'.format(x) for x in csi]) + b'm' - if not hasdata and char.data.encode('utf-8').rstrip(): + if not hasdata and char.data.rstrip(): hasdata = True - line += char.data.encode('utf-8') + chardata = char.data + if not isinstance(chardata, bytes): + chardata = chardata.encode('utf-8') + line += chardata if maxlen and len >= maxlen: break len += 1 @@ -185,7 +188,7 @@ class ConsoleHandler(object): if termstate & 1: self.appmodedetected = True if termstate & 2: - self.shiftin = '0' + self.shiftin = b'0' self.users = {} self._attribwatcher = None self._console = None @@ -210,6 +213,8 @@ class ConsoleHandler(object): return retrytime + (retrytime * random.random()) def feedbuffer(self, data): + if not isinstance(data, bytes): + data = data.encode('utf-8') try: self.termstream.feed(data) except StopIteration: # corrupt parser state, start over @@ -535,7 +540,7 @@ class ConsoleHandler(object): self.appmodedetected = True if '\x1b)0' in data: # console indicates it wants access to special drawing characters - self.shiftin = '0' + self.shiftin = b'0' eventdata = 0 if self.appmodedetected: eventdata |= 1 @@ -588,20 +593,23 @@ class ConsoleHandler(object): if pendingbl: retdata += pendingbl pendingbl = b'' - retdata += nline + '\r\n' + retdata += nline + b'\r\n' else: - pendingbl += nline + '\r\n' + pendingbl += nline + b'\r\n' if len(retdata) > 6: retdata = retdata[:-2] # remove the last \r\n - retdata += b'\x1b[{0};{1}H'.format(self.buffer.cursor.y + 1, - self.buffer.cursor.x + 1) + cursordata = '\x1b[{0};{1}H'.format(self.buffer.cursor.y + 1, + self.buffer.cursor.x + 1) + if not isinstance(cursordata, bytes): + cursordata = cursordata.encode('utf-8') + retdata += cursordata if self.shiftin is not None: # detected that terminal requested a # shiftin character set, relay that to the terminal that cannected - retdata += '\x1b)' + self.shiftin + retdata += b'\x1b)' + self.shiftin if self.appmodedetected: - retdata += '\x1b[?1h' + retdata += b'\x1b[?1h' else: - retdata += '\x1b[?1l' + retdata += b'\x1b[?1l' return retdata, connstate def write(self, data): diff --git a/confluent_server/confluent/core.py b/confluent_server/confluent/core.py index b5a4e19c..a92e9439 100644 --- a/confluent_server/confluent/core.py +++ b/confluent_server/confluent/core.py @@ -86,7 +86,10 @@ def seek_element(currplace, currkey): def nested_lookup(nestdict, key): try: - return reduce(seek_element, key, nestdict) + currloc = nestdict + for currk in key: + currloc = seek_element(currloc, currk) + return currloc except TypeError: raise exc.NotFoundException("Invalid element requested") diff --git a/confluent_server/confluent/discovery/protocols/slp.py b/confluent_server/confluent/discovery/protocols/slp.py index f3eec2e7..1a4fedd0 100644 --- a/confluent_server/confluent/discovery/protocols/slp.py +++ b/confluent_server/confluent/discovery/protocols/slp.py @@ -49,7 +49,6 @@ except AttributeError: IPPROTO_IPV6 = 41 # Assume Windows value if socket is missing it - def _parse_slp_header(packet): packet = bytearray(packet) if len(packet) < 16 or packet[0] != 2: @@ -247,7 +246,11 @@ def _grab_rsps(socks, rsps, interval, xidmap): def _parse_attrlist(attrstr): attribs = {} + previousattrlen = None while attrstr: + if len(attrstr) == previousattrlen: + raise Exception('Looping in attrstr parsing') + previousattrlen = len(attrstr) if attrstr[0] == '(': if b')' not in attrstr: attribs['INCOMPLETE'] = True @@ -274,9 +277,9 @@ def _parse_attrlist(attrstr): val = finalval if 'uuid' in attrname and len(val) == 16: lebytes = struct.unpack_from( - 'HHI', buffer(val[8:])) + '>HHI', memoryview(val[8:])) val = '{0:08X}-{1:04X}-{2:04X}-{3:04X}-' \ '{4:04X}{5:08X}'.format( lebytes[0], lebytes[1], lebytes[2], bebytes[0], @@ -287,9 +290,9 @@ def _parse_attrlist(attrstr): elif attrstr[0] == b','[0]: attrstr = attrstr[1:] elif b',' in attrstr: - currattr = attrstr[:attrstr.index(',')] + currattr = attrstr[:attrstr.index(b',')] attribs[currattr] = None - attrstr = attrstr[attrstr.index(','):] + attrstr = attrstr[attrstr.index(b','):] else: currattr = attrstr attribs[currattr] = None diff --git a/confluent_server/confluent/messages.py b/confluent_server/confluent/messages.py index d328d26c..ae8bc12f 100644 --- a/confluent_server/confluent/messages.py +++ b/confluent_server/confluent/messages.py @@ -25,6 +25,11 @@ from copy import deepcopy from datetime import datetime import json +try: + unicode +except NameError: + unicode = str + valid_health_values = set([ 'ok', 'warning', @@ -54,7 +59,7 @@ def _htmlify_structure(indict): if isinstance(indict, dict): for key in sorted(indict): ret += "
  • {0}: ".format(key) - if type(indict[key]) in (str, unicode, float, int): + if type(indict[key]) in (bytes, unicode, float, int): ret += str(indict[key]) elif isinstance(indict[key], datetime): ret += indict[key].strftime('%Y-%m-%dT%H:%M:%S') @@ -62,7 +67,7 @@ def _htmlify_structure(indict): ret += _htmlify_structure(indict[key]) elif isinstance(indict, list): if len(indict) > 0: - if type(indict[0]) in (str, unicode, None): + if type(indict[0]) in (bytes, unicode, None): nd = [] for datum in indict: if datum is None: @@ -156,7 +161,7 @@ class ConfluentMessage(object): '\r').format(valtype, key, self.desc) return snippet - if (isinstance(val, bool) or isinstance(val, str) or + if (isinstance(val, bool) or isinstance(val, bytes) or isinstance(val, unicode)): value = str(val) elif val is not None and 'value' in val: @@ -587,7 +592,7 @@ class InputConfigChangeSet(InputExpression): endattrs = {} for attr in attrs: origval = attrs[attr] - if isinstance(origval, str) or isinstance(origval, unicode): + if isinstance(origval, bytes) or isinstance(origval, unicode): origval = {'expression': origval} if 'expression' not in origval: endattrs[attr] = attrs[attr] @@ -614,7 +619,7 @@ class InputAttributes(ConfluentMessage): if nodes is None: self.attribs = inputdata for attrib in self.attribs: - if type(self.attribs[attrib]) in (str, unicode): + if type(self.attribs[attrib]) in (bytes, unicode): try: # ok, try to use format against the string # store back result to the attribute to @@ -640,7 +645,7 @@ class InputAttributes(ConfluentMessage): return {} nodeattr = deepcopy(self.nodeattribs[node]) for attr in nodeattr: - if type(nodeattr[attr]) in (str, unicode): + if type(nodeattr[attr]) in (bytes, unicode): try: # as above, use format() to see if string follows # expression, store value back in case of escapes @@ -743,7 +748,7 @@ class InputCredential(ConfluentMessage): if len(path) == 4: inputdata['uid'] = path[-1] # if the operation is 'create' check if all fields are present - if (isinstance(inputdata['uid'], str) and + if (type(inputdata['uid']) in (bytes, unicode) and not inputdata['uid'].isdigit()): inputdata['uid'] = inputdata['uid'] else: @@ -769,7 +774,7 @@ class InputCredential(ConfluentMessage): return {} credential = deepcopy(self.credentials[node]) for attr in credential: - if type(credential[attr]) in (str, unicode): + if type(credential[attr]) in (bytes, unicode): try: # as above, use format() to see if string follows # expression, store value back in case of escapes @@ -1359,7 +1364,7 @@ class AlertDestination(ConfluentMessage): class InputAlertDestination(ConfluentMessage): valid_alert_params = { - 'acknowledge': lambda x: False if type(x) in (unicode,str) and x.lower() == 'false' else bool(x), + 'acknowledge': lambda x: False if type(x) in (unicode, bytes) and x.lower() == 'false' else bool(x), 'acknowledge_timeout': lambda x: int(x) if x and x.isdigit() else None, 'ip': lambda x: x, 'retries': lambda x: int(x) @@ -1573,7 +1578,7 @@ class Attributes(ConfluentMessage): nkv = {} self.notnode = name is None for key in kv: - if type(kv[key]) in (str, unicode): + if type(kv[key]) in (bytes, unicode): nkv[key] = {'value': kv[key]} else: nkv[key] = kv[key] diff --git a/confluent_server/confluent/noderange.py b/confluent_server/confluent/noderange.py index 245227f2..9b4b9b46 100644 --- a/confluent_server/confluent/noderange.py +++ b/confluent_server/confluent/noderange.py @@ -25,6 +25,11 @@ import itertools import pyparsing as pp import re +try: + range = xrange +except NameError: + pass + # construct custom grammar with pyparsing _nodeword = pp.Word(pp.alphanums + '~^$/=-_:.*+!') _nodebracket = pp.QuotedString(quoteChar='[', endQuoteChar=']', @@ -166,7 +171,7 @@ class NodeRange(object): return self.failorreturn(seqrange) finalfmt = '' iterators = [] - for idx in xrange(len(leftbits)): + for idx in range(len(leftbits)): if leftbits[idx] == rightbits[idx]: finalfmt += leftbits[idx] elif leftbits[idx][0] in pp.alphas: @@ -181,7 +186,7 @@ class NodeRange(object): if leftnum > rightnum: width = len(rightbits[idx]) minnum = rightnum - maxnum = leftnum + 1 # xrange goes to n-1... + maxnum = leftnum + 1 # range goes to n-1... elif rightnum > leftnum: width = len(leftbits[idx]) minnum = leftnum @@ -189,7 +194,7 @@ class NodeRange(object): else: # differently padded, but same number... return self.failorreturn(seqrange) numformat = '{0:0%d}' % width - for num in xrange(minnum, maxnum): + for num in range(minnum, maxnum): curseq.append(numformat.format(num)) results = set([]) for combo in itertools.product(*iterators): @@ -222,7 +227,7 @@ class NodeRange(object): if self.cfm is None: raise Exception('Verification configmanager required') return set(self.cfm.filter_node_attributes(element, filternodes)) - for idx in xrange(len(element)): + for idx in range(len(element)): if element[idx][0] == '[': nodes = set([]) for numeric in NodeRange(element[idx][1:-1]).nodes: diff --git a/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py b/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py index e5fb8b35..e6c90faf 100644 --- a/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py +++ b/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py @@ -383,7 +383,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 @@ -491,8 +491,8 @@ class IpmiHandler(object): # raise exc.TargetEndpointUnreachable( # "Login process to " + connparams['bmc'] + " died") 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)]