def distributor(request: Request, response: Response): try: pipe = rdbconn.pipeline() profilenames = rdbconn.smembers('nameset:sipprofile') for profilename in profilenames: pipe.smembers(f'engagement:sipprofile:{profilename}') intconsets = pipe.execute() intconnameids = [ item for sublist in intconsets for item in sublist if item.startswith('out:') ] for intconnameid in intconnameids: pipe.hgetall(f'intcon:{intconnameid}:_gateways') details = pipe.execute() interconnections = dict() for intconnameid, detail in zip(intconnameids, details): intconname = getaname(intconnameid) interconnections.update({intconname: jsonhash(detail)}) result = fstpl.TemplateResponse("distributor.j2.xml", { "request": request, "interconnections": interconnections }, media_type="application/xml") response.status_code = 200 except Exception as e: response.status_code, result = 500, str() logify( f"module=liberator, space=cfgapi, section=distributor, requestid={get_request_uuid()}, exception={e}, traceback={traceback.format_exc()}" ) finally: return result
def distributor(request: Request, response: Response): try: pipe = rdbconn.pipeline() KEYPATTERN = 'intcon:out:*:_gateways' next, mainkeys = rdbconn.scan(0, KEYPATTERN, SCAN_COUNT) while next: next, tmpkeys = rdbconn.scan(next, KEYPATTERN, SCAN_COUNT) mainkeys += tmpkeys for mainkey in mainkeys: pipe.hgetall(mainkey) details = pipe.execute() interconnections = dict() for mainkey, detail in zip(mainkeys, details): intconname = getnameid(mainkey) interconnections[intconname] = jsonhash(detail) result = templates.TemplateResponse( "distributor.j2.xml", { "request": request, "interconnections": interconnections }, media_type="application/xml") response.status_code = 200 except Exception as e: response.status_code, result = 500, str() logify( f"module=liberator, space=fsxmlapi, section=distributor, requestid={get_request_uuid()}, exception={e}, traceback={traceback.format_exc()}" ) finally: return result
def run(self): logify(f"module=liberator, space=cdr, action=start_cdr_thread") rdbconn = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB, password=REDIS_PASSWORD, decode_responses=True) while not self.stop: try: reply = rdbconn.blpop('cdr:queue:new', REDIS_TIMEOUT) if reply: uuid = reply[1] score = int(time.time()) rdbconn.zadd('cdr:inprogress', {uuid: score}) detail_key = f'cdr:detail:{uuid}' detail_value = rdbconn.get(detail_key) if detail_value: details = json.loads(detail_value) # write cdr handler = CDRHandler(uuid, details) handler.start() except redis.RedisError as e: # wait and try again time.sleep(5) except Exception as e: logify( f"module=liberator, space=cdr, class=CDRMaster, action=run, exception={e}, tracings={traceback.format_exc()}" ) time.sleep(2) finally: pass
def acl(request: Request, response: Response): try: KEYPATTERN = 'intcon:in:*' next, mainkeys = rdbconn.scan(0, KEYPATTERN, SCAN_COUNT) while next: next, tmpkeys = rdbconn.scan(next, KEYPATTERN, SCAN_COUNT) mainkeys += tmpkeys for mainkey in mainkeys: pipe.hget(mainkey, 'sip_ips') data = list() for detail in pipe.execute(): if detail: data += hashlistify(detail) ip_addresses = set(data) result = templates.TemplateResponse("acl.j2.xml", { "request": request, "ip_addresses": ip_addresses }, media_type="application/xml") response.status_code = 200 except Exception as e: response.status_code, result = 500, str() logify( f"module=liberator, space=fsxmlapi, section=acl, requestid={get_request_uuid()}, exception={e}, traceback={traceback.format_exc()}" ) finally: return result
async def tracking(request: Request, call_next) -> Response: try: start_time = time.time() request_uuid = _request_uuid_ctx_var.set(str(uuid.uuid4())) clientip = request.client.host method = request.method.lower() url = request.url.path response = await call_next(request) status_code = response.status_code response_headers = dict(response.headers) response_media_type = response.media_type response_body = bytes() async for chunk in response.body_iterator: response_body += chunk response_body = response_body.decode() process_time = round(time.time() - start_time, 3) if url.startswith('/libresbc/'): logify( f'module=liberator, space=httpapi, action=middleware, processtime={process_time}, requestid={get_request_uuid()}, clientip={clientip}, request={method}:{url}, status_code={status_code}, response_body={response_body}' ) else: logify( f'module=liberator, space=httpapi, action=middleware, processtime={process_time}, requestid={get_request_uuid()}, clientip={clientip}, request={method}:{url}, status_code={status_code}' ) _request_uuid_ctx_var.reset(request_uuid) return Response(content=response_body, status_code=status_code, headers=response_headers, media_type=response_media_type) except: pass
def run(self): logify(f"module=liberator, space=basemgr, thread={self.getName()}, node={NODEID}, action=start") # portions _kamiauthfailure = 'kami:authfailure' _kamiattackavoid = 'kami:attackavoid' _kamiantiflooding = 'kami:antiflooding' _apiwhiteset = 'api:whiteset' _apiblackset = 'api:blackset' while True: try: pubsub = rdbconn.pubsub() pubsub.subscribe([SECURITY_CHANNEL]) for message in pubsub.listen(): msgtype = message.get("type") if msgtype == "message": data = json.loads(message.get("data")) portion = data.get('portion') srcips = data.get('srcips') ops = 'delete' if data.get('_flag') else 'add' if srcips and portion in [_kamiauthfailure, _kamiattackavoid, _kamiantiflooding]: bantime = data.get('bantime') nftsets('TemporaryBlocks', ops, srcips, bantime) if srcips and portion==_apiwhiteset: nftsets('WhiteHole', ops, srcips) if srcips and portion==_apiblackset: nftsets('BlackHole', ops, srcips) except redis.RedisError as e: time.sleep(5) except Exception as e: logify(f'module=liberator, space=basemgr, action=exception, exception={e}, tracings={traceback.format_exc()}') time.sleep(2) finally: if pubsub in locals(): pubsub.close()
def acl(request: Request, response: Response): try: pipe = rdbconn.pipeline() # IP LIST OF SIP PROFILE AND REALM # {profilename: realm} KEYPATTERN = 'sipprofile:*' next, mainkeys = rdbconn.scan(0, KEYPATTERN, SCAN_COUNT) while next: next, tmpkeys = rdbconn.scan(next, KEYPATTERN, SCAN_COUNT) mainkeys += tmpkeys for mainkey in mainkeys: pipe.hget(mainkey, 'realm') realms = pipe.execute() sipprofiles = dict() for mainkey, realm in zip(mainkeys, realms): sipprofiles[getnameid(mainkey)] = realm # DEFINED ACL LIST # [{'name': name, 'action': default-action, 'rules': [{'action': allow/deny, 'key': domain/cidr, 'value': ip/domain-value}]}] KEYPATTERN = 'base:acl:*' next, mainkeys = rdbconn.scan(0, KEYPATTERN, SCAN_COUNT) while next: next, tmpkeys = rdbconn.scan(next, KEYPATTERN, SCAN_COUNT) mainkeys += tmpkeys for mainkey in mainkeys: pipe.hgetall(mainkey) defined_acls = list() for detail in pipe.execute(): if detail: name = detail.get('name') action = detail.get('action') rulestrs = fieldjsonify(detail.get('rules')) rules = list( map( lambda rule: { 'action': rule[0], 'key': rule[1], 'value': rule[2] }, map(listify, rulestrs))) defined_acls.append({ 'name': name, 'action': action, 'rules': rules }) result = templates.TemplateResponse("acl.j2.xml", { "request": request, "sipprofiles": sipprofiles, "defined_acls": defined_acls }, media_type="application/xml") response.status_code = 200 except Exception as e: response.status_code, result = 500, str() logify( f"module=liberator, space=fsxmlapi, section=acl, requestid={get_request_uuid()}, exception={e}, traceback={traceback.format_exc()}" ) finally: return result
async def reqjson(request: Request): try: reqbody = await request.json() logify( f'module=liberator, space=httpapi, action=request, requestid={get_request_uuid()}, request_body={reqbody}' ) except: pass
def directory(request: Request, response: Response): try: pipe = rdbconn.pipeline() # IP LIST OF SIP PROFILE AND REALM profilenames = rdbconn.smembers('nameset:sipprofile') for profilename in profilenames: pipe.hget(f'sipprofile:{profilename}', 'realm' ) realms = pipe.execute() sipprofiles = dict() for profilename, realm in zip(profilenames, realms): sipprofiles.update({profilename: realm}) # IP LIST OF INBOUND INTERCONNECTION # {profilename: {profilename, sipaddrs, secret}} for profilename in profilenames: pipe.smembers(f'engagement:sipprofile:{profilename}') intconsets = pipe.execute() intconnameids = [item for sublist in intconsets for item in sublist if item.startswith('in:')] for intconnameid in intconnameids: pipe.hmget(f'intcon:{intconnameid}', 'sipprofile', 'sipaddrs', 'secret', 'authscheme', 'routing', 'ringready') details = pipe.execute() directories = dict() for intconnameid, detail in zip(intconnameids, details): intconname = getaname(intconnameid) profilename = detail[0] sipaddrs = fieldjsonify(detail[1]) secret = detail[2] authscheme = detail[3] routing = detail[4] ringready = fieldjsonify(detail[5]) if authscheme=='IP': password = DEFAULT_PASSWORD cidrs = sipaddrs elif authscheme=='DIGEST': password = secret cidrs = list() else: password = secret cidrs = sipaddrs for _profilename, _realm in sipprofiles.items(): if _profilename == profilename: a1hash = hashlib.md5(f'{intconname}:{_realm}:{password}'.encode()).hexdigest() directory = {'id': intconname, 'cidrs': cidrs, 'a1hash': a1hash, 'routing': routing, 'ringready': ringready} if _realm in directories: directories[_realm].append(directory) else: directories[_realm] = [directory] result = templates.TemplateResponse("directory.j2.xml", {"request": request, "directories": directories}, media_type="application/xml") response.status_code = 200 except Exception as e: response.status_code, result = 500, str() logify(f"module=liberator, space=fsxmlapi, section=directory, requestid={get_request_uuid()}, exception={e}, traceback={traceback.format_exc()}") finally: return result
def filesave(self): try: filename = f'{date.today().strftime("%Y-%m-%d")}.cdr.nice.json' cdrjson = json.dumps(self.details) logify(f"module=liberator, space=cdr, action=filesave, nodeid={NODEID}, data={cdrjson}, filename={filename}") with open(f'{LOGDIR}/cdr/{filename}', "a") as jsonfile: jsonfile.write(cdrjson + '\n') except Exception as e: logify(f"module=liberator, space=cdr, class=CDRHandler, action=filesave, exception={e}, tracings={traceback.format_exc()}")
def run(self): rdbconn = redis.StrictRedis(connection_pool=REDIS_CONNECTION_POOL) while not self.stop: events = rdbconn.blpop('event', REDIS_TIMEOUT) try: pass except Exception as e: logify(f"module=liberator, space=callenginectl, exception={e}") finally: pass
def esl(request: Request, response: Response): try: result = templates.TemplateResponse("event-socket.j2.xml", {"request": request, "host": ESL_HOST, "port": ESL_PORT, "password": ESL_SECRET}, media_type="application/xml") response.status_code = 200 except Exception as e: response.status_code, result = 500, str() logify(f"module=liberator, space=fsxmlapi, section=event-socket, requestid={get_request_uuid()}, exception={e}, traceback={traceback.format_exc()}") finally: return result
def switch(request: Request, response: Response): try: result = templates.TemplateResponse("switch.j2.xml", {"request": request, "switchattributes": CLUSTERS}, media_type="application/xml") response.status_code = 200 except Exception as e: response.status_code, result = 500, str() logify(f"module=liberator, space=fsxmlapi, section=switch, requestid={get_request_uuid()}, exception={e}, traceback={traceback.format_exc()}") finally: return result
def rclean(self): try: rdbconn = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB, password=REDIS_PASSWORD, decode_responses=True) pipe = rdbconn.pipeline() pipe.zrem('cdr:inprogress', self.uuid) pipe.delete(f'cdr:detail:{self.uuid}') pipe.execute() result = True except Exception as e: logify(f"module=liberator, space=cdr, class=CDRHandler, action=rclean, exception={e}, tracings={traceback.format_exc()}") result = False finally: return result
def switch(request: Request, response: Response): try: result = templates.TemplateResponse("switch.j2.xml", { "request": request, "max_sessions": MAX_SESSION, "sessions_per_second": MAX_SPS, "rtp_start_port": FIRST_RTP_PORT, "rtp_end_port": LAST_RTP_PORT }, media_type="application/xml") response.status_code = 200 except Exception as e: response.status_code, result = 500, str() logify( f"module=liberator, space=fsxmlapi, section=switch, requestid={get_request_uuid()}, exception={e}, traceback={traceback.format_exc()}" ) finally: return result
def fssocket(reqdata): result = False try: command = reqdata.get('command') fs = greenswitch.InboundESL(host=ESL_HOST, port=ESL_PORT, password=ESL_SECRET) fs.connect() response = fs.send(f'api {command}') if response: resultstr = response.data if '+OK' in resultstr[:3].upper(): result = True except Exception as e: logify( f"module=liberator, space=bases, action=fssocket, reqdata={reqdata}, exception={e}, tracings={traceback.format_exc()}" ) finally: return result
def acl(request: Request, response: Response): try: pipe = rdbconn.pipeline() # SIP PROFILE AND REALM profilenames = rdbconn.smembers('nameset:sipprofile') for profilename in profilenames: pipe.hget(f'sipprofile:{profilename}', 'realm') realms = pipe.execute() sipprofiles = dict() for profilename, realm in zip(profilenames, realms): sipprofiles.update({profilename: realm}) # ENGAGMENT ACL LIST # [{'name': name, 'action': default-action, 'rules': [{'action': allow/deny, 'key': domain/cidr, 'value': ip/domain-value}]}] for profilename in profilenames: pipe.hget(f'sipprofile:{profilename}', 'local_network_acl') engagedacls = [ acl for acl in pipe.execute() if acl not in _BUILTIN_ACLS_ ] for engagedacl in engagedacls: pipe.hgetall(f'base:acl:{engagedacl}') details = pipe.execute() acls = list() for detail in details: if detail: name = detail.get('name') action = detail.get('action') rules = fieldjsonify(detail.get('rules')) acls.append({'name': name, 'action': action, 'rules': rules}) result = fstpl.TemplateResponse("acl.j2.xml", { "request": request, "sipprofiles": sipprofiles, "acls": acls }, media_type="application/xml") response.status_code = 200 except Exception as e: response.status_code, result = 500, str() logify( f"module=liberator, space=cfgapi, section=acl, requestid={get_request_uuid()}, exception={e}, traceback={traceback.format_exc()}" ) finally: return result
def rdbinstance(): try: logify(f"module=liberator, space=basemgr, node={NODEID}, action=rdbinstance, state=initiating") rdbrun = Popen(['/usr/bin/redis-server', '--port', '0', '--pidfile', RDB_PIDFILE, '--unixsocket', RDB_USOCKET, '--unixsocketperm', '755', '--dbfilename', 'libresbc.rdb', '--dir', ETCDIR, '--loglevel', 'warning']) _, stderr = bdecode(rdbrun.communicate()) if stderr: logify(f"module=liberator, space=basemgr, action=rdbinstance.rdbrun, error={stderr}") else: logify(f"module=liberator, space=basemgr, action=rdbinstance.rdbrun, result=success") except Exception as e: logify(f'module=liberator, space=basemgr, action=exception, exception={e}, tracings={traceback.format_exc()}')
def httpsave(self): headers = {'Content-Type': 'application/json', 'X-Signature': f'{_APPLICATION} {_SWVERSION} ({NODEID})'} endpoints = HTTPCDR_ENDPOINTS; shuffle(endpoints) cdrjson = json.dumps(self.cdrdata) status = 0; attempt = 0 for endpoint in endpoints: attempt += 1; start = time.time() try: response = requests.post(endpoint, headers=headers, data=cdrjson, timeout=10, ) status = response.status_code if status==200: shortcdr = {'uuid': self.cdrdata.get('uuid'), 'seshid': self.cdrdata.get('seshid')} end = time.time() logify(f"module=liberator, space=cdr, class=CDRHandler, action=httpsave, nodeid={NODEID}, endpoint={endpoint}, status={status}, attempt={attempt}, shortcdr={shortcdr}, delay={round(end-start, 3)}") break except Exception as e: # once exception occurred, log the error then retry logify(f"module=liberator, space=cdr, class=CDRHandler, action=httpsave, nodeid={NODEID}, endpoint={endpoint}, status={status}, attempt={attempt}, exception={e}, tracings={traceback.format_exc()}") # return result if status==200: return True else: return False
async def tracking(request: Request, call_next) -> Response: try: start_time = time.time() request_uuid = _request_uuid_ctx_var.set(str(uuid.uuid4())) clientip = request.client.host method = request.method url = request.url response = await call_next(request) response_body = bytes() async for chunk in response.body_iterator: response_body += chunk response_body = response_body.decode() status_code = response.status_code process_time = round(time.time() - start_time, 3) logify( f'module=liberator, space=httpapi, action=middleware, requestid={get_request_uuid()}, clientip={clientip}, request={method}:{url}, status_code={status_code}, response_body={response_body}, processtime={process_time}' ) _request_uuid_ctx_var.reset(request_uuid) return response except: pass
def run(self): logify( f"module=liberator, space=bases, action=start_base_event_handler_thread" ) rdbconn = redis.StrictRedis(connection_pool=REDIS_CONNECTION_POOL) while not self.stop: events = list() try: intcon_api_event = f'event:api:peer:{NODEID}' events = rdbconn.blpop([intcon_api_event], REDIS_TIMEOUT) if events: eventkey, eventvalue = events[0], json.loads(events[1]) logify( f"module=liberator, space=bases, action=catch_event, eventkey={eventkey}, eventvalue={eventvalue}" ) if eventkey in [intcon_api_event]: subevent = eventvalue.get('subevent') prewait = eventvalue.get('prewait') requestid = eventvalue.get('requestid') data = eventvalue.get('data') # make the node run this task in different timestamp time.sleep(int(prewait)) else: pass except Exception as e: logify( f"module=liberator, space=bases, class=BaseEventHandler, action=run, events={events}, exception={e}, tracings={traceback.format_exc()}" ) time.sleep(5) finally: pass
def fssocket(data): result, fs = False, None try: commands = data.get('commands') requestid = data.get('requestid') # connecting fs = redfs.InboundESL(host=ESL_HOST, port=ESL_PORT, password=ESL_SECRET, timeout=10) for _ in range(0,3): try: fs.connect() if fs.connected: break except: delay = data.get('delay') if delay: time.sleep(delay) else: time.sleep(5) # send api commands if commands and fs.connected: result = True for command in commands: response = fs.send(f'api {command}') if response: resultstr = response.data if '+OK' in resultstr or 'Success' in resultstr or '+ok' in resultstr: _result = True else: _result = False logify(f"module=liberator, space=basemgr, action=fssocket, requestid={requestid}, command={command}, result={resultstr}") result = bool(result and _result) logify(f"module=liberator, space=basemgr, action=fssocket, connected={fs.connected}, requestid={requestid}, commands={commands}, result={result}") except Exception as e: logify(f"module=liberator, space=basemgr, action=fssocket, data={data}, exception={e}, tracings={traceback.format_exc()}") finally: if fs and fs.connected: fs.stop() return result
def run(self): logify(f"module=liberator, space=bases, node={NODEID}, action=start_base_event_handler_thread") callengine_acl_event = f'event:callengine:acl:{NODEID}' callengine_sipprofile_event = f'event:callengine:sipprofile:{NODEID}' callengine_gateway_event = f'event:callengine:gateway:{NODEID}' callengine_outcon_event = f'event:callengine:outbound:intcon:{NODEID}' callengine_incon_event = f'event:callengine:inbound:intcon:{NODEID}' callengine_startup_event = f'event:callengine:startup:{NODEID}' while not self.stop: events = None try: events = rdbconn.blpop([callengine_acl_event, callengine_sipprofile_event, callengine_gateway_event, callengine_outcon_event, callengine_incon_event], REDIS_TIMEOUT) if events: eventkey, eventvalue = events[0], json.loads(events[1]) logify(f"module=liberator, space=bases, action=catch_event, eventkey={eventkey}, eventvalue={eventvalue}") prewait = eventvalue.get('prewait') # requestid = eventvalue.get('requestid') # make the node run this task in different timestamp time.sleep(int(prewait)) # specify event if eventkey in [callengine_acl_event, callengine_incon_event]: eventvalue.update({'commands': ['reloadacl']}) threaded(fssocket, eventvalue) elif eventkey==callengine_sipprofile_event: action = eventvalue.get('action') sipprofile = eventvalue.get('sipprofile') _sipprofile = eventvalue.get('_sipprofile') if action=='create': eventvalue.update({'commands': [f'sofia profile {sipprofile} rescan', 'reloadxml']}) elif action=='delete': eventvalue.update({'commands': [f'sofia profile {_sipprofile} rescan', 'reloadxml']}) elif action=='update': eventvalue.update({'commands': [f'sofia profile {_sipprofile} restart', 'reloadxml']}) threaded(fssocket, eventvalue) elif eventkey==callengine_gateway_event: action = eventvalue.get('action') sipprofile = eventvalue.get('sipprofile') gateway = eventvalue.get('gateway') _gateway = eventvalue.get('_gateway') if action=='update': eventvalue.update({'commands': [f'sofia profile {sipprofile} killgw {gateway}', f'sofia profile {sipprofile} rescan']}) threaded(fssocket, eventvalue) elif eventkey==callengine_outcon_event: eventvalue.update({'commands': ['distributor_ctl reload']}) threaded(fssocket, eventvalue) elif eventvalue==callengine_startup_event: # doing reload firewall pass else: pass # firewall reload except Exception as e: logify(f"module=liberator, space=bases, class=BaseEventHandler, action=run, events={events}, exception={e}, tracings={traceback.format_exc()}") time.sleep(5) finally: pass
def basestartup(): result = False try: logify(f"module=liberator, space=basemgr, node={NODEID}, action=basestartup, state=initiating") data = {'portion': 'liberator:startup', 'requestid': '00000000-0000-0000-0000-000000000000'} fsinstance(data) nftupdate(data) layers = rdbconn.smembers('nameset:access:service') for layer in layers: data.update({'layer': layer, '_layer': layer}) kaminstance(data) result = True except redis.RedisError as e: time.sleep(10) except Exception as e: logify(f'module=liberator, space=basemgr, action=exception, exception={e}, tracings={traceback.format_exc()}') time.sleep(5) finally: logify(f"module=liberator, space=basemgr, node={NODEID}, action=basestartup, state={'completed' if result else 'dropped'}")
def fssocket(reqdata): result = True try: commands = reqdata.get('commands') requestid = reqdata.get('requestid') fs = greenswitch.InboundESL(host=ESL_HOST, port=ESL_PORT, password=ESL_SECRET) fs.connect() for command in commands: response = fs.send(f'api {command}') if response: resultstr = response.data if resultstr[:3]=='+OK': _result = True else: _result = False logify(f"module=liberator, space=bases, action=fssocket, requestid={requestid}, command={command}, result={resultstr}") result = bool(result and _result) logify(f"module=liberator, space=bases, action=fssocket, requestid={requestid}, commands={commands}, result={result}") except Exception as e: logify(f"module=liberator, space=bases, action=fssocket, reqdata={reqdata}, exception={e}, tracings={traceback.format_exc()}") finally: return result
def fsinstance(data): result = True xmlfile = '/usr/local/etc/freeswitch/freeswitch.xml' clifile = '/etc/fs_cli.conf' try: xmltemplate = _FSXML.get_template("xml/freeswitch.xml") xmlstream = xmltemplate.render(eslhost=ESL_HOST, eslport=ESL_PORT, eslpassword=ESL_SECRET) with open(xmlfile, 'w') as fsf: fsf.write(xmlstream) clitemplate = _FSXML.get_template("etc/fs_cli.conf") clistream = clitemplate.render(secret=ESL_SECRET) with open(clifile, 'w') as clif: clif.write(clistream) fsrun = Popen(['/usr/local/bin/freeswitch', '-nc', '-reincarnate'], stdout=PIPE, stderr=PIPE) _, stderr = bdecode(fsrun.communicate()) if stderr and not stderr.endswith('Backgrounding.'): result = False stderr = stderr.replace('\n', '') logify(f"module=liberator, space=basemgr, action=fsinstance.fsrun, error={stderr}") else: logify(f"module=liberator, space=basemgr, action=fsinstance.fsrun, result=success") except Exception as e: result = False logify(f"module=liberator, space=basemgr, action=fsinstance, data={data}, exception={e}, traceback={traceback.format_exc()}") finally: return result
def nftsets(setname, ops, srcips, bantime=None): result = True try: if bantime: if bantime == _DFTBANTIME: element = f'{{ {stringify(srcips, _nftdelimiter_)} }}' else: _es = [f'{srcip} timeout {bantime}s' for srcip in srcips] element = f'{{ {stringify(_es, _nftdelimiter_)} }}' else: element = f'{{ {stringify(srcips, _nftdelimiter_)} }}' nftcmd = Popen(['/usr/sbin/nft', ops, 'element', 'inet', 'LIBREFW', setname, element], stdout=PIPE, stderr=PIPE) _, stderr = bdecode(nftcmd.communicate()) if stderr: result = False stderr = stderr.replace('\n', '') logify(f"module=liberator, space=basemgr, action=nftsets, error={stderr}") else: logify(f"module=liberator, space=basemgr, action=nftsets, ops={ops}, setname={setname}, srcips={srcips}, result=success") except Exception as e: result = False logify(f"module=liberator, space=basemgr, action=nftsets, exception={e}, traceback={traceback.format_exc()}") finally: return result
def acl(request: Request, response: Response): try: pipe = rdbconn.pipeline() # IP LIST OF INBOUND INTERCONNECTION # {sipprofile: [list of ips]} KEYPATTERN = 'intcon:in:*' next, mainkeys = rdbconn.scan(0, KEYPATTERN, SCAN_COUNT) while next: next, tmpkeys = rdbconn.scan(next, KEYPATTERN, SCAN_COUNT) mainkeys += tmpkeys for mainkey in mainkeys: pipe.hmget(mainkey, 'sipprofile', 'sip_ips', 'auth_username') sipprofile_ips = dict() for details in pipe.execute(): if details: if not fieldjsonify(details[2]): sipprofile = details[0] sip_ips = fieldjsonify(details[1]) if sipprofile in sipprofile_ips: sipprofile_ips[sipprofile] += sip_ips else: sipprofile_ips[sipprofile] = sip_ips # DEFINED ACL LIST # [{'name': name, 'action': default-action, 'rules': [{'action': allow/deny, 'key': domain/cidr, 'value': ip/domain-value}]}] KEYPATTERN = 'base:acl:*' next, mainkeys = rdbconn.scan(0, KEYPATTERN, SCAN_COUNT) while next: next, tmpkeys = rdbconn.scan(next, KEYPATTERN, SCAN_COUNT) mainkeys += tmpkeys for mainkey in mainkeys: pipe.hgetall(mainkey) defined_acls = list() for detail in pipe.execute(): if detail: name = detail.get('name') action = detail.get('action') rulestrs = fieldjsonify(detail.get('rules')) rules = list( map( lambda rule: { 'action': rule[0], 'key': rule[1], 'value': rule[2] }, map(listify, rulestrs))) defined_acls.append({ 'name': name, 'action': action, 'rules': rules }) result = templates.TemplateResponse("acl.j2.xml", { "request": request, "sipprofile_ips": sipprofile_ips, "defined_acls": defined_acls }, media_type="application/xml") response.status_code = 200 except Exception as e: response.status_code, result = 500, str() logify( f"module=liberator, space=fsxmlapi, section=acl, requestid={get_request_uuid()}, exception={e}, traceback={traceback.format_exc()}" ) finally: return result
def sip(request: Request, response: Response): try: pipe = rdbconn.pipeline() # get netalias # {profilename1: profiledata1, profilename2: profiledata2} KEYPATTERN = 'base:netalias:*' next, mainkeys = rdbconn.scan(0, KEYPATTERN, SCAN_COUNT) while next: next, tmpkeys = rdbconn.scan(next, KEYPATTERN, SCAN_COUNT) mainkeys += tmpkeys for mainkey in mainkeys: pipe.hget(mainkey, 'addresses') details = pipe.execute() netaliases = dict() for mainkey, detail in zip(mainkeys, details): aliasname = getnameid(mainkey) addresses = list(map(listify, fieldjsonify(detail))) netaliases[aliasname] = { address[0]: { 'listen': address[1], 'advertise': address[2] } for address in addresses } # get the maping siprofile and data # {profilename1: profiledata1, profilename2: profiledata2} KEYPATTERN = 'sipprofile:*' next, mainkeys = rdbconn.scan(0, KEYPATTERN, SCAN_COUNT) while next: next, tmpkeys = rdbconn.scan(next, KEYPATTERN, SCAN_COUNT) mainkeys += tmpkeys for mainkey in mainkeys: pipe.hgetall(mainkey) details = pipe.execute() sipprofiles = dict() for mainkey, detail in zip(mainkeys, details): sipprofiles[getnameid(mainkey)] = jsonhash(detail) # get the mapping siprofile name and interconnection name # {profilename1: [intconname,...], profilename2: [intconname,...]} KEYPATTERN = 'intcon:out:*' next, mainkeys = rdbconn.scan(0, KEYPATTERN, SCAN_COUNT) while next: next, tmpkeys = rdbconn.scan(next, KEYPATTERN, SCAN_COUNT) mainkeys += tmpkeys for mainkey in mainkeys: if not mainkey.endswith('_gateways'): pipe.hget(mainkey, 'sipprofile') profilenames = pipe.execute() profile_intcons_maps = dict() for mainkey, profilename in zip(mainkeys, profilenames): intconname = getnameid(mainkey) if profilename not in profile_intcons_maps: profile_intcons_maps[profilename] = [intconname] else: if profilename not in profile_intcons_maps[profilename]: profile_intcons_maps[profilename].append(profilename) # get the mapping siprofile name and gateway name # {profilename1: [gateway,...], profilename2: [gateway,...]} profile_gwnames_maps = dict() for profile, intcons in profile_intcons_maps.items(): for intcon in intcons: pipe.hkeys(f'intcon:out:{intcon}:_gateways') profile_gwnames_maps[profile] = list( set([gw for gws in pipe.execute() for gw in gws])) # add gateway data to sip profile data profile_gateways_maps = dict() for profile, gwnames in profile_gwnames_maps.items(): for gwname in gwnames: pipe.hgetall(f'gateway:{gwname}') profile_gateways_maps[profile] = list(map(jsonhash, pipe.execute())) for sipprofile in sipprofiles: if 'gateways' in sipprofiles[sipprofile]: sipprofiles[sipprofile]['gateways'] = profile_gateways_maps[ sipprofile] # template result = templates.TemplateResponse("sip-setting.j2.xml", { "request": request, "sipprofiles": sipprofiles, 'netaliases': netaliases, 'NODEID': NODEID }, media_type="application/xml") response.status_code = 200 except Exception as e: response.status_code, result = 500, str() logify( f"module=liberator, space=fsxmlapi, section=sip-setting, requestid={get_request_uuid()}, exception={e}, traceback={traceback.format_exc()}" ) finally: return result
from api import httpapi from basemgr import BaseEventHandler #--------------------------------------------------------------------------------------------------------------------------- # MAIN APPLICATION #--------------------------------------------------------------------------------------------------------------------------- if __name__ == '__main__': try: debugy('module=liberator, space=main, action=initialize') # EVENT HANDLER eventthead = BaseEventHandler() eventthead.start() # HTTP API uvicorn.run('api:httpapi', host='127.0.0.1', port=8080, workers=4, reload=True) except Exception as e: logify( f'module=liberator, space=main, exception: {e}, traceback: {traceback.format_exc()}' ) finally: debugy('module=liberator, space=main, action=liberator_stopping') for thrd in threading.enumerate(): thrd.stop = True logify( f'module=liberator, space=main, action=teardown, id={thrd.ident}, name={thrd.getName()}' ) syslog.closelog()