Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
def sip(request: Request, response: Response):
    try:
        pipe = rdbconn.pipeline()
        fsgvars = list()
        # get netalias
        netaliasnames = rdbconn.smembers('nameset:netalias')
        for netaliasname in netaliasnames:
            pipe.hget(f'base:netalias:{netaliasname}', 'addresses')
        details = pipe.execute()
        netaliases = dict()
        for netaliasname, detail in zip(netaliasnames, details):
            addresses = [
                address for address in fieldjsonify(detail)
                if address.get('member') == NODEID
            ][0]
            netaliases.update({netaliasname: addresses})
        # get the maping siprofile and data
        # {profilename1: profiledata1, profilename2: profiledata2}
        profilenames = rdbconn.smembers('nameset:sipprofile')
        for profilename in profilenames:
            pipe.hgetall(f'sipprofile:{profilename}')
        details = pipe.execute()
        sipprofiles = dict()
        for profilename, detail in zip(profilenames, details):
            sipdetail = jsonhash(detail)
            sip_address = sipdetail.pop('sip_address')
            sip_ip = netaliases[sip_address]['listen']
            ext_sip_ip = netaliases[sip_address]['advertise']
            rtp_address = sipdetail.pop('rtp_address')
            rtp_ip = netaliases[rtp_address]['listen']
            ext_rtp_ip = netaliases[rtp_address]['advertise']
            sipdetail.update({
                'sip_ip': sip_ip,
                'ext_sip_ip': ext_sip_ip,
                'rtp_ip': rtp_ip,
                'ext_rtp_ip': ext_rtp_ip
            })
            sipprofiles.update({profilename: sipdetail})
            # prepare vars
            fsgvars.append(f'{profilename}:advertising={ext_sip_ip}')

        # get the mapping siprofile name and interconnection name
        # {profilename1: [intconname,...], profilename2: [intconname,...]}
        map_profilename_intconnames = {}
        for profilenames in sipprofiles.keys():
            intcon_names = rdbconn.smembers(
                f'engagement:sipprofile:{profilenames}')
            out_intcon_names = list(
                filter(lambda name: name.startswith('out:'), intcon_names))
            map_profilename_intconnames[profilenames] = out_intcon_names

        # get the mapping siprofile name and gateway name
        # {profilename1: [gateway,...], profilename2: [gateway,...]}
        map_profilename_gwnames = dict()
        for profilename, intcons in map_profilename_intconnames.items():
            for intcon in intcons:
                pipe.hkeys(f'intcon:{intcon}:_gateways')
            allgws = pipe.execute()
            map_profilename_gwnames[profilename] = list(
                set([gw for gws in allgws for gw in gws]))

        # add gateway data to sip profile data
        map_profilename_gateways = dict()
        for profilename, gwnames in map_profilename_gwnames.items():
            for gwname in gwnames:
                pipe.hgetall(f'base:gateway:{gwname}')
            map_profilename_gateways[profilename] = list(
                filter(lambda gwdata: gwdata, map(jsonhash, pipe.execute())))
        for sipprofile in sipprofiles:
            gateways = map_profilename_gateways.get(sipprofile)
            if gateways:
                sipprofiles[sipprofile]['gateways'] = gateways

        # set var profile address by separated thread
        rdbconn.publish(
            NODEID_CHANNEL,
            json.dumps({
                'portion': 'cfgapi:sip',
                'delay': 30,
                'fsgvars': fsgvars,
                'requestid': get_request_uuid()
            }))
        # template
        result = fstpl.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=cfgapi, section=sip-setting, requestid={get_request_uuid()}, exception={e}, traceback={traceback.format_exc()}"
        )
    finally:
        return result
Ejemplo n.º 5
0
def kaminstance(data):
    result = True
    try:
        PIDDIR = f'/run/kamailio'
        CFGDIR = f'/usr/local/etc/kamailio'
        requestid = data.get('requestid')
        layer = data.get('layer')
        _layer = data.get('_layer')
        # ------------------------------------------------------------
        # TEARDOWN THE EXISTENT INSTANCE
        # ------------------------------------------------------------
        if _layer:
            pidkill = '/bin/pkill'
            _pidfile = f'{PIDDIR}/{_layer}.pid'
            _cfgfile = f'{CFGDIR}/{_layer}.cfg'
            _luafile = f'{CFGDIR}/{_layer}.lua'

            kamend = Popen([pidkill, '-F', _pidfile], stdout=PIPE, stderr=PIPE)
            _, stderr = bdecode(kamend.communicate())
            if stderr:
                stderr = stderr.replace('\n', '')
                logify(f"module=liberator, space=basemgr, action=kaminstance.kamend, requestid={requestid}, error={stderr}")
            else: logify(f"module=liberator, space=basemgr, action=kaminstance.kamend, requestid={requestid}, result=success")

            cfgdel = osdelete(_cfgfile)
            luadel = osdelete(_luafile)
            logify(f"module=liberator, space=basemgr, action=kaminstance.filedel, requestid={requestid}, cfgdel={cfgdel}, luadel={luadel}")
        # ------------------------------------------------------------
        # LAUNCH THE NEW INSTANCE
        # ------------------------------------------------------------
        if layer:
            pipe = rdbconn.pipeline()
            kambin = '/usr/local/sbin/kamailio'
            pidfile = f'{PIDDIR}/{layer}.pid'
            cfgfile = f'{CFGDIR}/{layer}.cfg'
            luafile = f'{CFGDIR}/{layer}.lua'

            kamcfgs = jsonhash(rdbconn.hgetall(f'access:service:{layer}'))
            netaliases = fieldjsonify(rdbconn.hget(f'base:netalias:{kamcfgs.get("sip_address")}', 'addresses'))
            addresses = [address for address in netaliases if address.get('member') == NODEID][0]
            kamcfgs.update({'listen': addresses.get('listen'), 'advertise': addresses.get('advertise')})

            if 'topology_hiding' in kamcfgs:
                kamcfgs.update({'randomsecret': randomstr()})

            domains = kamcfgs.get('domains')
            for domain in domains:
                pipe.hgetall(f'access:policy:{domain}')
            sockets = pipe.execute()
            policies = dict()
            swipaddrs = set()
            for domain, socket in zip(domains, sockets):
                srcsocket = listify(socket.get('srcsocket'))
                dstsocket = listify(socket.get('dstsocket'))
                policies[domain] = {'srcsocket': {'transport': srcsocket[0], 'ip': srcsocket[1], 'port': srcsocket[2]},
                                    'dstsocket': {'transport': dstsocket[0], 'ip': dstsocket[1], 'port': dstsocket[2]}}
                swipaddrs.add(dstsocket[1])
            kamcfgs.update({'policies': policies})
            # default domain
            if len(domains)==1: dftdomain = domains[0]
            else: dftdomain = 'default.domain'
            # configuration
            cfgtemplate = _KAM.get_template("layer.j2.cfg")
            cfgstream = cfgtemplate.render(_KAMCONST=_KAMCONST, kamcfgs=kamcfgs, layer=layer, piddir=PIDDIR, cfgdir=CFGDIR, nodeid=NODEID)
            with open(cfgfile, 'w') as kmf: kmf.write(cfgstream)
            # localization
            luatemplate = _KAM.get_template("layer.j2.lua")
            luastream = luatemplate.render(_KAMCONST=_KAMCONST, kamcfgs=kamcfgs, layer=layer, swipaddrs=swipaddrs, jsonpolicies=json.dumps(policies), dftdomain=dftdomain)
            with open(luafile, 'w') as lf: lf.write(luastream)

            kamrun = Popen([kambin, '-S', '-M', '16', '-P', pidfile, '-f', cfgfile], stdout=PIPE, stderr=PIPE)
            _, stderr = bdecode(kamrun.communicate())
            if stderr:
                result = False
                stderr = stderr.replace('\n', '')
                logify(f"module=liberator, space=basemgr, action=kaminstance.kamrun, requestid={requestid}, cfgfile={cfgfile}, error={stderr}")
            else: logify(f"module=liberator, space=basemgr, action=kaminstance.kamrun, requestid={requestid}, result=success")
    except Exception as e:
        result = False
        logify(f"module=liberator, space=basemgr, action=kaminstance, data={data}, exception={e}, traceback={traceback.format_exc()}")
    finally:
        return result