0

I need to access defines and variables from the Kamailio configuration file in my Python script. So far, I am able to access the global variables only through self.my_var = int(KSR.pv.get("$sel(cfg_get.my_group.my_var)")) where this variable is defined in the configuration file as my_group.my_var = 664. How can I access the definitions (to know that #!ifdef MY_DEFINE succeeds or not)? Or at least the configuration file to read them myself ?

I found nothing about on the official documentation and even $sel(cfg_get.my_group.my_var) I found it elsewhere.

UPDATE These values are not normally available at runtime (preprocessing), so the native code can use them like this:

   #!define WITH_SIPTRACE
   #!substdef "!SERVER_ID!654!g"
   ...
   request_route {
    
    #!ifdef WITH_SIPTRACE
        xlog("L_NOTICE", "$C(yx)========= server_id=SERVER_ID NEW $rm $pr:$si:$sp$C(xx)\n");
    #!endif
    ...

Can this same behavior be achieved in Python ?

UPDATE 2 Found partial answer (below) in KSR.kx.get_def() and KSR.kx.get_defn().

LeeWo
  • 3
  • 4

2 Answers2

0

You should not change defines. There is no mechanism for that.

To make configurable parameters, use database or curl module + in-memory cache via htable module.

Here is htable optimization for auth, for example

AUTH WITH CACHING
# authentication with password caching using htable
modparam("htable", "htable", "auth=>size=10;autoexpire=300;")
modparam("auth_db", "load_credentials", "$avp(password)=password")
route[AUTHCACHE] {
if($sht(auth=>$au::passwd)!=$null) {
if (!pv_auth_check("$fd", "$sht(auth=>$au::passwd)", "0", "1")) {
auth_challenge("$fd", “1”);
exit;
}
} else {
# authenticate requests
if (!auth_check("$fd", "subscriber", "1")) {
auth_challenge("$fd", "0");
exit;
}
$sht(auth=>$au::passwd) = $avp(password);
}
# user authenticated - remove auth header
if(!is_method("REGISTER|PUBLISH"))
consume_credentials();
}

Here is how to get info from db using sql.

https://kamailio.org/docs/modules/5.0.x/modules/avpops.html#avpops.f.avp_db_query

avp_db_query("select password, ha1 from subscriber where username='$tu'",
    "$avp(i:678);$avp(i:679)");

As opensource sample of such optimization you can see code of kazoo project.

arheops
  • 15,544
  • 1
  • 21
  • 27
  • Thank you! Sorry for not being clear, but I am using Python (through KEMI), not Kamailio's native language. Also, I am not trying to change the defines, only to know what is defined and what is not. – LeeWo Aug 27 '21 at 10:44
  • Defines are pre-processing directives. All that are executed only once at startup to make valid config. Like in C/C++. There are no any defines nor excluded config sections in runtime at all. – arheops Aug 27 '21 at 20:28
  • Here is the description of how pre-processing works. On Kamailio it is exactly the same. https://www.geeksforgeeks.org/cc-preprocessors/ – arheops Aug 27 '21 at 20:31
  • Ok. Could you, please, show me the Python code that knows the value of a defined value ? – LeeWo Aug 30 '21 at 08:58
  • os.system("grep KEY /etc/kamailio/kamailio.cfg|cut -f 2 -d\= ") – arheops Aug 30 '21 at 12:44
  • Again, those values are in config only. Kamailio do NOT know about that at runtime. – arheops Aug 30 '21 at 12:45
  • Thank you, I updated my question ... Compared to my dumb solution, it is not clear how your solution answers the question. – LeeWo Aug 30 '21 at 13:24
  • Thank you, but I cannot use that Python code: there could be more configuration files and/or different locations. You cannot know these value at runtime, of course, but you DO take actions accordingly in the native code. I simply want the same possibility for Python. – – LeeWo Aug 30 '21 at 13:25
  • you should not use defines as you propose. It is pre-processor staff. Nothing to add. If you do not understand what is pre-processor, please take some time and read the article above. – arheops Aug 30 '21 at 16:40
0

A solution I dislike because it adds extra variables for each interesting definition.

On the configuration side:

####### Custom Parameters #########
/*
    Is there a better method to access these flags (!define)?
    For the constants (!substdef) there are KSR.kx.get_def(), KSR.kx.get_defn().
*/

#!ifdef WITH_OPTIONA
my_group.option_a = yes
#!else
my_group.option_a = no
#!endif

 #!ifdef WITH_OPTIONB
my_group.option_b = yes
#!else
my_group.option_b = no
#!endif

On the Python side:

def __init__(self):
    self.my_domain = KSR.kx.get_def("MY_DOMAIN")
    self.server_id = KSR.kx.get_defn("SERVER_ID")
    assert self.my_domain and self.server_id

    self.flags = None
    self.initialized = False

def real_init(self):
    '''
        Object data is initialized here, dynamically,
            because__init__ and child_init are called too early.
    '''
    def read_flags():
        flags = {}
        for i in ['option_a', 'option_b']:
            value = bool(int(KSR.pv.get("$sel(cfg_get.my_group.{})".format(i))))
            if value:
                flags[i[len('option_'):]] = True
        return flags
    self.flags = read_flags()

    self.initialized = True

Update Partial solution found: !substdef constants, but not !define ones.

Update 5.5.2 KSR.kx.ifdef() and KSR.kx.ifndef() added on the master branch, but not yet exported in a official release (the latest being 5.5.2) See kemix: added KSR.kx.ifdef() and KSR.kx.ifndef().

LeeWo
  • 3
  • 4