def _full_updatemacmap(configmanager): global vintage global _macmap global _nodesbymac global _switchportmap global _macsbyswitch global switchbackoff start = util.monotonic_time() with mapupdating: vintage = util.monotonic_time() # Clear all existing entries _macmap = {} _nodesbymac = {} _switchportmap = {} _macsbyswitch = {} if configmanager.tenant is not None: raise exc.ForbiddenRequest( 'Network topology not available to tenants') # here's a list of switches... need to add nodes that are switches nodelocations = configmanager.get_node_attributes( configmanager.list_nodes(), ('net*.switch', 'net*.switchport')) switches = set([]) for node in nodelocations: cfg = nodelocations[node] for attr in cfg: if not attr.endswith('.switch') or 'value' not in cfg[attr]: continue curswitch = cfg[attr].get('value', None) if not curswitch: continue switches.add(curswitch) switchportattr = attr + 'port' if switchportattr in cfg: portname = cfg[switchportattr].get('value', '') if not portname: continue if curswitch not in _switchportmap: _switchportmap[curswitch] = {} if portname in _switchportmap[curswitch]: log.log({ 'error': 'Duplicate switch topology config ' 'for {0} and {1}'.format( node, _switchportmap[curswitch][portname]) }) _switchportmap[curswitch][portname] = None else: _switchportmap[curswitch][portname] = node switchauth = get_switchcreds(configmanager, switches) pool = GreenPool(64) for ans in pool.imap(_map_switch, switchauth): vintage = util.monotonic_time() yield ans endtime = util.monotonic_time() duration = endtime - start duration = duration * 15 # wait 15 times as long as it takes to walk # avoid spending a large portion of the time hitting switches with snmp # requests if duration > switchbackoff: switchbackoff = duration
def update_macmap(configmanager): """Interrogate switches to build/update mac table Begin a rebuild process. This process is a generator that will yield as each switch interrogation completes, allowing a caller to recheck the cache as results become possible, rather than having to wait for the process to complete to interrogate. """ global _macmap global _nodesbymac global _switchportmap # Clear all existing entries _macmap = {} _nodesbymac = {} _switchportmap = {} if configmanager.tenant is not None: raise exc.ForbiddenRequest('Network topology not available to tenants') nodelocations = configmanager.get_node_attributes( configmanager.list_nodes(), ('hardwaremanagement.switch', 'hardwaremanagement.switchport')) switches = set([]) for node in nodelocations: cfg = nodelocations[node] if 'hardwaremanagement.switch' in cfg: curswitch = cfg['hardwaremanagement.switch']['value'] switches.add(curswitch) if 'hardwaremanagement.switchport' in cfg: portname = cfg['hardwaremanagement.switchport']['value'] if curswitch not in _switchportmap: _switchportmap[curswitch] = {} if portname in _switchportmap[curswitch]: log.log({ 'warning': 'Duplicate switch topology config for ' '{0} and {1}'.format( node, _switchportmap[curswitch][portname]) }) _switchportmap[curswitch][portname] = node switchcfg = configmanager.get_node_attributes( switches, ('secret.hardwaremanagementuser', 'secret.hardwaremanagementpassword'), decrypt=True) switchauth = [] for switch in switches: password = '******' user = None if (switch in switchcfg and 'secret.hardwaremanagementpassword' in switchcfg[switch]): password = switchcfg[switch]['secret.hardwaremanagementpassword'][ 'value'] if 'secret.hardwaremanagementuser' in switchcfg[switch]: user = switchcfg[switch]['secret.hardwaremanagementuser'][ 'value'] switchauth.append((switch, password, user)) pool = GreenPool() for res in pool.imap(_map_switch, switchauth): yield res print(repr(_macmap))
def process_request(connection, request, cfm, authdata, authname, skipauth): if isinstance(request, tlvdata.ClientFile): cfm.add_client_file(request) return if not isinstance(request, dict): raise exc.InvalidArgumentException operation = request['operation'] path = request['path'] params = request.get('parameters', {}) hdlr = None auditmsg = { 'operation': operation, 'target': path, } if not skipauth: authdata = auth.authorize(authdata[2], path, authdata[3], operation) if not authdata: auditmsg['allowed'] = False auditlog.log(auditmsg) raise exc.ForbiddenRequest() auditmsg['user'] = authdata[2] if authdata[3] is not None: auditmsg['tenant'] = authdata[3] auditmsg['allowed'] = True if _should_authlog(path, operation): tlvdata.unicode_dictvalues(auditmsg) auditlog.log(auditmsg) try: if operation == 'start': return start_term(authname, cfm, connection, params, path, authdata, skipauth) elif operation == 'shutdown' and skipauth: configmanager.ConfigManager.shutdown() else: hdlr = pluginapi.handle_path(path, operation, cfm, params) except exc.NotFoundException as e: send_data(connection, { "errorcode": 404, "error": "Target not found - " + str(e) }) send_data(connection, {"_requestdone": 1}) except exc.InvalidArgumentException as e: send_data(connection, { "errorcode": 400, "error": "Bad Request - " + str(e) }) send_data(connection, {"_requestdone": 1}) send_response(hdlr, connection) return
def _full_updatemacmap(configmanager): global vintage global _macmap global _nodesbymac global _switchportmap global _macsbyswitch with mapupdating: vintage = util.monotonic_time() # Clear all existing entries _macmap = {} _nodesbymac = {} _switchportmap = {} _macsbyswitch = {} if configmanager.tenant is not None: raise exc.ForbiddenRequest( 'Network topology not available to tenants') nodelocations = configmanager.get_node_attributes( configmanager.list_nodes(), ('net*.switch', 'net*.switchport')) switches = set([]) for node in nodelocations: cfg = nodelocations[node] for attr in cfg: if not attr.endswith('.switch') or 'value' not in cfg[attr]: continue curswitch = cfg[attr].get('value', None) if not curswitch: continue switches.add(curswitch) switchportattr = attr + 'port' if switchportattr in cfg: portname = cfg[switchportattr].get('value', '') if not portname: continue if curswitch not in _switchportmap: _switchportmap[curswitch] = {} if portname in _switchportmap[curswitch]: log.log({ 'error': 'Duplicate switch topology config ' 'for {0} and {1}'.format( node, _switchportmap[curswitch][portname]) }) _switchportmap[curswitch][portname] = None else: _switchportmap[curswitch][portname] = node switchcfg = configmanager.get_node_attributes( switches, ('secret.hardwaremanagementuser', 'secret.snmpcommunity', 'secret.hardwaremanagementpassword'), decrypt=True) switchauth = [] for switch in switches: if not switch: continue switchparms = switchcfg.get(switch, {}) user = None password = switchparms.get('secret.snmpcommunity', {}).get('value', None) if not password: password = switchparms.get('secret.hardwaremanagementpassword', {}).get('value', 'public') user = switchparms.get('secret.hardwaremanagementuser', {}).get('value', None) switchauth.append((switch, password, user)) pool = GreenPool() for ans in pool.imap(_map_switch, switchauth): vintage = util.monotonic_time() yield ans