def __init__(self, path, nodes, inputdata): self.inputbynode = {} self.stripped = False if not inputdata: raise exc.InvalidArgumentException('missing input data') if 'hw_addr' in inputdata: raise exc.InvalidArgumentException('hw_addr is a read only field') if 'ipv4_address' not in inputdata: inputdata['ipv4_address'] = None if 'ipv4_gateway' not in inputdata: inputdata['ipv4_gateway'] = None if 'ipv4_configuration' in inputdata: if inputdata['ipv4_configuration'].lower() not in ['dhcp','static']: raise exc.InvalidArgumentException( 'Unrecognized ipv4_configuration') else: inputdata['ipv4_configuration'] = None if nodes is None: raise exc.InvalidArgumentException( 'This only supports per-node input') for node in nodes: self.inputbynode[node] = inputdata
def start_term(authname, cfm, connection, params, path, authdata, skipauth): elems = path.split('/') if len(elems) < 4 or elems[1] != 'nodes': raise exc.InvalidArgumentException('Invalid path {0}'.format(path)) node = elems[2] ccons = ClientConsole(connection) skipreplay = False if params and 'skipreplay' in params and params['skipreplay']: skipreplay = True if elems[3] == "console": consession = consoleserver.ConsoleSession(node=node, configmanager=cfm, username=authname, datacallback=ccons.sendall, skipreplay=skipreplay) elif len(elems) >= 6 and elems[3:5] == ['shell', 'sessions']: if len(elems) == 7: sessionid = elems[5] else: sessionid = None consession = shellserver.ShellSession(node=node, configmanager=cfm, username=authname, datacallback=ccons.sendall, skipreplay=skipreplay, sessionid=sessionid) else: raise exc.InvalidArgumentException('Invalid path {0}'.format(path)) if consession is None: raise Exception("TODO") term_interact(authdata, authname, ccons, cfm, connection, consession, skipauth)
def __init__(self, path, nodes, inputdata, multinode=False): self.alertcfg = {} if multinode: # keys are node names for node in inputdata: self.alertcfg[node] = inputdata[node] for key in inputdata[node]: if key not in self.valid_alert_params: raise exc.InvalidArgumentException( 'Unrecognized alert parameter ' + key) if isinstance(inputdata[node][key], dict): self.alertcfg[node][key] = \ self.valid_alert_params[key]( inputdata[node][key]['value']) else: self.alertcfg[node][key] = \ self.valid_alert_params[key](inputdata[node][key]) else: for key in inputdata: if key not in self.valid_alert_params: raise exc.InvalidArgumentException( 'Unrecognized alert parameter ' + key) if isinstance(inputdata[key], dict): inputdata[key] = self.valid_alert_params[key]( inputdata[key]['value']) else: inputdata[key] = self.valid_alert_params[key]( inputdata[key]) for node in nodes: self.alertcfg[node] = inputdata
def update_nodegroup(group, element, configmanager, inputdata): if element == 'check': check = inputdata.attribs decrypt = configmanager.decrypt configmanager.decrypt = True currinfo = configmanager.get_nodegroup_attributes(group, list(check)) configmanager.decrypt = decrypt for inf in check: checkvalue = check[inf] if isinstance(checkvalue, dict): checkvalue = checkvalue.get('value', None) currvalue = currinfo.get(inf, {}).get('value') if checkvalue == currvalue: raise exc.InvalidArgumentException( 'Checked value matches existing value') return retrieve_nodegroup(group, element, configmanager, inputdata) if 'rename' in element: namemap = {} namemap[group] = inputdata.attribs['rename'] configmanager.rename_nodegroups(namemap) return yield_rename_resources(namemap, isnode=False) try: clearattribs = [] for attrib in inputdata.attribs: if inputdata.attribs[attrib] is None: clearattribs.append(attrib) for attrib in clearattribs: del inputdata.attribs[attrib] if clearattribs: configmanager.clear_group_attributes(group, clearattribs) configmanager.set_group_attributes({group: inputdata.attribs}) except ValueError as e: raise exc.InvalidArgumentException(str(e)) return retrieve_nodegroup(group, element, configmanager, inputdata)
def handle_api_request(configmanager, inputdata, operation, pathcomponents): if operation == 'retrieve': return handle_read_api_request(pathcomponents) elif (operation in ('update', 'create') and pathcomponents == ['discovery', 'rescan']): if inputdata != {'rescan': 'start'}: raise exc.InvalidArgumentException() rescan() return (msg.KeyValueData({'rescan': 'started'}), ) elif operation in ('update', 'create'): if 'node' not in inputdata: raise exc.InvalidArgumentException('Missing node name in input') mac = _get_mac_from_query(pathcomponents) info = known_info[mac] if info['handler'] is None: raise exc.NotImplementedException('Unable to {0} to {1}'.format( operation, '/'.join(pathcomponents))) handler = info['handler'].NodeHandler(info, configmanager) eval_node(configmanager, handler, info, inputdata['node'], manual=True) return [msg.AssignedResource(inputdata['node'])] elif operation == 'delete': mac = _get_mac_from_query(pathcomponents) del known_info[mac] return [msg.DeletedResource(mac)] raise exc.NotImplementedException('Unable to {0} to {1}'.format( operation, '/'.join(pathcomponents)))
def start_term(authname, cfm, connection, params, path, authdata, skipauth): elems = path.split('/') if len(elems) < 4 or elems[1] != 'nodes': raise exc.InvalidArgumentException('Invalid path {0}'.format(path)) node = elems[2] ccons = ClientConsole(connection) skipreplay = False if params and 'skipreplay' in params and params['skipreplay']: skipreplay = True if elems[3] == "console": consession = consoleserver.ConsoleSession(node=node, configmanager=cfm, username=authname, datacallback=ccons.sendall, skipreplay=skipreplay) elif len(elems) >= 6 and elems[3:5] == ['shell', 'sessions']: if len(elems) == 7: sessionid = elems[5] else: sessionid = None consession = shellserver.ShellSession(node=node, configmanager=cfm, username=authname, datacallback=ccons.sendall, skipreplay=skipreplay, sessionid=sessionid) else: raise exc.InvalidArgumentException('Invalid path {0}'.format(path)) if consession is None: raise Exception("TODO") send_data(connection, {'started': 1}) ccons.startsending() bufferage = consession.get_buffer_age() if bufferage is not False: send_data(connection, {'bufferage': bufferage}) while consession is not None: data = tlvdata.recv(connection) if type(data) == dict: if data['operation'] == 'stop': consession.destroy() return elif data['operation'] == 'break': consession.send_break() continue elif data['operation'] == 'reopen': consession.reopen() continue else: process_request(connection, data, cfm, authdata, authname, skipauth) continue if not data: consession.destroy() return consession.write(data)
def update_nodes(nodes, element, configmanager, inputdata): updatedict = {} if not nodes: raise exc.InvalidArgumentException( 'No action to take, noderange is empty (if trying to define ' 'group attributes, use nodegroupattrib)') if element[-1] == 'check': for node in nodes: check = inputdata.get_attributes(node, allattributes.node) currinfo = configmanager.get_node_attributes(node, list(check), decrypt=True) for inf in check: checkvalue = check[inf] if isinstance(checkvalue, dict): checkvalue = checkvalue.get('value', None) currvalue = currinfo.get(node, {}).get(inf, {}).get('value') if checkvalue == currvalue: raise exc.InvalidArgumentException( 'Checked value matches existing value') return retrieve(nodes, element, configmanager, inputdata) if 'rename' in element: namemap = {} for node in nodes: rename = inputdata.get_attributes(node) namemap[node] = rename['rename'] configmanager.rename_nodes(namemap) return yield_rename_resources(namemap, isnode=True) for node in nodes: updatenode = inputdata.get_attributes(node, allattributes.node) clearattribs = [] if updatenode: for attrib in list(updatenode): if updatenode[attrib] is None: del updatenode[attrib] if attrib in allattributes.node or attrib.startswith( 'custom.') or attrib.startswith('net.'): clearattribs.append(attrib) else: foundattrib = False for candattrib in allattributes.node: if fnmatch(candattrib, attrib): clearattribs.append(candattrib) foundattrib = True if not foundattrib: raise exc.InvalidArgumentException( "No attribute matches '" + attrib + "' (try wildcard if trying to clear a group)") if len(clearattribs) > 0: configmanager.clear_node_attributes([node], clearattribs) updatedict[node] = updatenode try: configmanager.set_node_attributes(updatedict) except ValueError as e: raise exc.InvalidArgumentException(str(e)) return retrieve(nodes, element, configmanager, inputdata)
def create_group(inputdata, configmanager): try: groupname = inputdata['name'] del inputdata['name'] attribmap = {groupname: inputdata} except KeyError: raise exc.InvalidArgumentException() try: configmanager.add_group_attributes(attribmap) except ValueError as e: raise exc.InvalidArgumentException(str(e))
def create_node(inputdata, configmanager): try: nodename = inputdata['name'] del inputdata['name'] attribmap = {nodename: inputdata} except KeyError: raise exc.InvalidArgumentException('name not specified') try: configmanager.add_node_attributes(attribmap) except ValueError as e: raise exc.InvalidArgumentException(str(e))
def abbreviate_noderange(configmanager, inputdata, operation): if operation != 'create': raise exc.InvalidArgumentException( 'Must be a create with nodes in list') if 'nodes' not in inputdata: raise exc.InvalidArgumentException( 'Must be given list of nodes under key named nodes') if isinstance(inputdata['nodes'], str) or isinstance( inputdata['nodes'], unicode): inputdata['nodes'] = inputdata['nodes'].split(',') return (msg.KeyValueData({ 'noderange': noderange.ReverseNodeRange(inputdata['nodes'], configmanager).noderange }), )
def __init__(self, path, nodes, inputdata): self.inputbynode = {} self.stripped = False if not inputdata or 'server' not in inputdata: raise exc.InvalidArgumentException('missing input data') if len(inputdata['server']) > 256: raise exc.InvalidArgumentException( 'identifier must be less than or = 256 chars') if nodes is None: raise exc.InvalidArgumentException( 'This only supports per-node input') for node in nodes: self.inputbynode[node] = str(inputdata['server'])
def create_noderange(inputdata, configmanager): try: noder = inputdata['name'] del inputdata['name'] attribmap = {} for node in noderange.NodeRange(noder).nodes: attribmap[node] = inputdata except KeyError: raise exc.InvalidArgumentException('name not specified') try: configmanager.add_node_attributes(attribmap) except ValueError as e: raise exc.InvalidArgumentException(str(e)) for node in attribmap: yield msg.CreatedResource(node)
def create_user(inputdata, configmanager): try: username = inputdata['name'] del inputdata['name'] except (KeyError, ValueError): raise exc.InvalidArgumentException() configmanager.create_user(username, attributemap=inputdata)
def create_usergroup(inputdata, configmanager): try: groupname = inputdata['name'] del inputdata['name'] except (KeyError, ValueError): raise exc.InvalidArgumentException() configmanager.create_usergroup(groupname)
def __init__(self, media): self.worker = None self.profiles = [] identity = fingerprint(media) if not identity: raise exc.InvalidArgumentException('Unsupported Media') self.percent = 0.0 identity, _ = identity self.phase = 'copying' if not identity: raise Exception('Unrecognized OS Media') if 'subname' in identity: importkey = '{0}-{1}'.format(identity['name'], identity['subname']) else: importkey = identity['name'] if importkey in importing: raise Exception('Media import already in progress for this media') self.importkey = importkey importing[importkey] = self self.importkey = importkey self.osname = identity['name'] self.oscategory = identity.get('category', None) targpath = identity['name'] self.distpath = '/var/lib/confluent/distributions/' + targpath if identity.get('subname', None): targpath += '/' + identity['subname'] self.targpath = '/var/lib/confluent/distributions/' + targpath if os.path.exists(self.targpath): raise Exception('{0} already exists'.format(self.targpath)) self.filename = os.path.abspath(media) self.importer = eventlet.spawn(self.importmedia)
def __init__(self, path, inputdata, nodes=None): self.nodeattribs = {} if not inputdata: raise exc.InvalidArgumentException('no request data provided') if nodes is None: self.attribs = inputdata for attrib in self.attribs: if type(self.attribs[attrib]) in (str, unicode): try: # ok, try to use format against the string # store back result to the attribute to # handle things like '{{' and '}}' # if any weird sort of error should # happen, it means the string has something # that formatter is looking to fulfill, but # is unable to do so, meaning it is an expression tv = self.attribs[attrib].format() self.attribs[attrib] = tv except (KeyError, IndexError): # this means format() actually thought there was work # that suggested parameters, push it in as an # expression self.attribs[attrib] = { 'expression': self.attribs[attrib] } return for node in nodes: self.nodeattribs[node] = inputdata
def handle_async(env, querydict, threadset): global _cleanthread # This may be one of two things, a request for a new async stream # or a request for next data from async stream # httpapi otherwise handles requests an injecting them to queue if 'asyncid' not in querydict or not querydict['asyncid']: # This is a new request, create a new multiplexer currsess = AsyncSession() yield messages.AsyncSession(currsess.asyncid) return if querydict['asyncid'] not in _asyncsessions: raise exc.InvalidArgumentException('Invalid or expired async id') mythreadid = greenlet.getcurrent() threadset.add(mythreadid) loggedout = None currsess = None try: currsess = _asyncsessions[querydict['asyncid']]['asyncsession'] for rsp in currsess.get_responses(): yield messages.AsyncMessage(rsp) except greenlet.GreenletExit as ge: loggedout = ge threadset.discard(mythreadid) if loggedout is not None: currsess.destroy() raise exc.LoggedOut()
def decode_alert(varbinds, configmanager): """Decode an SNMP alert for a server Given the agentaddr, OID for the trap, and a dict of varbinds, ascertain the node identity and then request a decode :param varbinds: A dictionary of OID to value varbinds. Also supported are special keywords 'enterprise' and 'specificTrap' for SNMPv1 traps. """ try: agentaddr = varbinds['.1.3.6.1.6.3.18.1.3.0'] except KeyError: agentaddr = varbinds['1.3.6.1.6.3.18.1.3.0'] node = lookuptools.node_by_manager(agentaddr) if node is None: raise exc.InvalidArgumentException( 'Unable to find a node with specified manager') return confluent.core.handle_path( '/nodes/{0}/events/hardware/decode'.format(node), 'update', configmanager, varbinds, autostrip=False)
def __init__(self, path, nodes, inputdata, configmanager=None): self.inputbynode = {} self.stripped = False if not inputdata: raise exc.InvalidArgumentException('missing input data') if 'hw_addr' in inputdata: raise exc.InvalidArgumentException('hw_addr is a read only field') if 'ipv4_address' not in inputdata: inputdata['ipv4_address'] = None if 'ipv4_gateway' not in inputdata: inputdata['ipv4_gateway'] = None if 'ipv4_configuration' in inputdata: if inputdata['ipv4_configuration'].lower() not in [ 'dhcp', 'static' ]: raise exc.InvalidArgumentException( 'Unrecognized ipv4_configuration') else: inputdata['ipv4_configuration'] = None if nodes is None: raise exc.InvalidArgumentException( 'This only supports per-node input') nodeattrmap = {} for attr in inputdata: try: if inputdata[attr] is not None: inputdata[attr].format() except (KeyError, IndexError): nodeattrmap[attr] = {} for expanded in configmanager.expand_attrib_expression( nodes, inputdata[attr]): node, value = expanded nodeattrmap[attr][node] = value if not nodeattrmap: for node in nodes: self.inputbynode[node] = inputdata return # an expression was encountered for node in nodes: self.inputbynode[node] = deepcopy(inputdata) for attr in self.inputbynode[node]: if attr in nodeattrmap: self.inputbynode[node][attr] = nodeattrmap[attr][node]
def _get_mac_from_query(pathcomponents): _, queryparms, _, _ = _parameterize_path(pathcomponents[1:]) if 'by-mac' not in queryparms: raise exc.InvalidArgumentException('Must target using "by-mac"') mac = queryparms['by-mac'].replace('-', ':') if mac not in known_info: raise exc.NotFoundException('{0} not found'.format(mac)) return mac
def create_usergroup(inputdata, configmanager): try: groupname = inputdata['name'] role = inputdata['role'] del inputdata['name'] del inputdata['role'] except (KeyError, ValueError): raise exc.InvalidArgumentException("Missing user name or role") configmanager.create_usergroup(groupname, role)
def __init__(self, path, inputdata, nodes=None): self.nodeattribs = {} if not inputdata: raise exc.InvalidArgumentException('no request data provided') if nodes is None: self.attribs = inputdata return for node in nodes: self.nodeattribs[node] = inputdata
def run_handler(hdlr, env): asyncsessid = env['HTTP_CONFLUENTASYNCID'] try: asyncsession = _asyncsessions[asyncsessid]['asyncsession'] requestid = env['HTTP_CONFLUENTREQUESTID'] except KeyError: raise exc.InvalidArgumentException( 'Invalid Session ID or missing request id') eventlet.spawn_n(asyncsession.run_handler, hdlr, requestid) return requestid
def close_enough(fuzz, literal): if fuzz == literal: return True fuzz = '^' + fuzz.replace('-', '[/: -]') + '$' try: matcher = re.compile(fuzz) except Exception: raise exc.InvalidArgumentException( 'Invalid regular expression specified') return bool(matcher.match(literal))
def handle_api_request(configmanager, inputdata, operation, pathcomponents): if operation == 'retrieve': return handle_read_api_request(pathcomponents) if (operation in ('update', 'create') and pathcomponents == ['networking', 'macs', 'rescan']): if inputdata != {'rescan': 'start'}: raise exc.InvalidArgumentException() eventlet.spawn_n(rescan, configmanager) return [msg.KeyValueData({'rescan': 'started'})] raise exc.NotImplementedException( 'Operation {0} on {1} not implemented'.format( operation, '/'.join(pathcomponents)))
def __init__(self, path, nodes, inputdata): self.inputbynode = {} self.stripped = False if not inputdata: raise exc.InvalidArgumentException('missing input data') if self.keyname not in inputdata: # assume we have nested information for key in nodes: if key not in inputdata: raise exc.InvalidArgumentException(key + ' not in request') datum = inputdata[key] if self.keyname not in datum: raise exc.InvalidArgumentException( 'missing {0} argument'.format(self.keyname)) elif datum[self.keyname] not in self.valid_values: raise exc.InvalidArgumentException( datum[self.keyname] + ' is not one of ' + ','.join(self.valid_values)) self.inputbynode[key] = datum[self.keyname] else: # we have a state argument not by node datum = inputdata if self.keyname not in datum: raise exc.InvalidArgumentException( 'missing {0} argument'.format(self.keyname)) elif datum[self.keyname] not in self.valid_values: raise exc.InvalidArgumentException(datum[self.keyname] + ' is not one of ' + ','.join(self.valid_values)) for node in nodes: self.inputbynode[node] = datum[self.keyname]
def update_nodegroup(group, element, configmanager, inputdata): try: clearattribs = [] for attrib in inputdata.attribs.iterkeys(): if inputdata.attribs[attrib] is None: clearattribs.append(attrib) for attrib in clearattribs: del inputdata.attribs[attrib] if clearattribs: configmanager.clear_group_attributes(group, clearattribs) configmanager.set_group_attributes({group: inputdata.attribs}) except ValueError as e: raise exc.InvalidArgumentException(str(e)) return retrieve_nodegroup(group, element, configmanager, inputdata)
def update_nodes(nodes, element, configmanager, inputdata): updatedict = {} if not nodes: raise exc.InvalidArgumentException( 'No action to take, noderange is empty (if trying to define ' 'group attributes, use nodegroupattrib)') for node in nodes: updatenode = inputdata.get_attributes(node, allattributes.node) clearattribs = [] if updatenode: for attrib in updatenode.iterkeys(): if updatenode[attrib] is None: clearattribs.append(attrib) if len(clearattribs) > 0: for attrib in clearattribs: del updatenode[attrib] configmanager.clear_node_attributes([node], clearattribs) updatedict[node] = updatenode try: configmanager.set_node_attributes(updatedict) except ValueError as e: raise exc.InvalidArgumentException(str(e)) return retrieve(nodes, element, configmanager, inputdata)
def get_enclosure_chain_head(nodename, cfg): ne = True members = [nodename] while ne: ne = cfg.get_node_attributes(nodename, 'enclosure.extends').get( nodename, {}).get('enclosure.extends', {}).get('value', None) if not ne: return nodename if ne in members: raise exc.InvalidArgumentException( 'Circular chain that includes ' + nodename) nodename = ne members.append(nodename) return nodename
def remove_updates(nodes, tenant, element): if len(element) < 5: raise exc.InvalidArgumentException() upid = element[-1] for node in nodes: try: upd = updatesbytarget[(node, tenant)][upid] except KeyError: raise exc.NotFoundException('No active update matches request') upd.cancel() del updatesbytarget[(node, tenant)][upid] yield msg.DeletedResource( 'nodes/{0}/inventory/firmware/updates/active/{1}'.format( node, upid))