COREmanager Documentation
en En
es Es

Changing system behavior through event handlers

ISPsystem products based on COREmanager use an event processing mechanism that allows users to: 

  • add additional checks (validation, access);
  • modify standard behavior;
  • integrate external services.

To implement it, you need to:

  1. Create an event processing module script.
  2. Register it in the system.

Let us review these actions on the task - during creation or deletion of the billing platform user create or delete an account in samba for him.

Example of a script

To perform Samba integration with BILLmanager or Clouden:

  1. If the CGI library is not installed on your system, install it using the command:
    Installation on AlmaLinux
    dnf install perl-CGI
  2. Create a processing module file /usr/local/mgr5/addon/samba.pl with the following contents:

    Sample script
    #!/usr/bin/perl
    use CGI;
    my $Q = new CGI;
    $func = $Q->param("func");
    $elid = $Q->param("elid");
    if ($func eq "user.add") {  
        if ($Q->param("sok") && $elid eq "") {
        # the user is created    
            $name = $Q->param("name");    
            $password = $Q->param("passwd");
            system("(echo \"$password\"; echo \"$password\") | smbpasswd -a $name");  
        }
    } elsif ($func eq "user.delete") {
         # users are deleted
         @all_users = split(", ", $elid);
         for (@all_users) {
           system("smbpasswd -x $_");
         }
    }
    print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc/>\n";
  3. Set permissions on the file processing module:
    chmod 750 /usr/local/mgr5/addon/samba.pl
    chown 0:0 /usr/local/mgr5/addon/samba.pl
  4. Create a configuration XML file /usr/local/mgr5/etc/xml/billmgr_mod_samba.xml with the plugin description:

    <mgrdata>
     <processing module name="samba.pl" type="cgi">
       <event after="yes" name="user.add" postdata="yes"/>
       <event after="yes" name="user.delete" postdata="yes"/>
     </processing module>
    </mgrdata>
  5. Restart the billing platform:

    /usr/local/mgr5/sbin/mgrctl -m billmgr exit

    If the configuration is correct, the log /usr/local/mgr5/var/billmgr.log will contain records about processing module registration for the specified events:

    Sample output
    action EXTINFO Register event 'samba.pl' for action 'user.edit'
    action EXTINFO Register event 'samba.pl' for action 'user.delete'

If something went wrong, to debug external scripts:

  1. Enable maximum logging. To do this, add a line to the /usr/local/mgr5/etc/debug.conf file:

    *.external 9
  2. Restart the billing platform. After restarting, lines with the external prefix will appear in the log. For example:
    Sample output
    external WARNING Addon 'addon/samba.pl' is not executable

The following describes the steps taken in more detail.

Plugin description

The example shows how to launch the script when executing platform functions. Let's consider the configuration block:

<processing module name="samba.pl" type="cgi">
  <event after="yes" name="user.edit" postdata="yes"/>
  <event after="yes" name="user.delete" postdata="yes"/>
</processing module>

Block configuration components:

  • processing module — tag, describes the event processing module (script);
  • samba.pl — script name. All scripts must be located in the /usr/local/mgr5/addon directory;
  • type="cgi" — CGI interface data transfer method;
  • event — tag, registers an event to call the processing module script;
  • after="yes" — attribute. Runs the script after the main function. For more details on internal function names, see the article List of functions and parameters.

processing module

The processing module determines the type of operation by the func parameter. To determine which function initiated the start of the processing module, get the value of the parameter:

$func = $Q->param("func");

Depending on the value of func, follow the instructions in one of the subsections:

  • Handling user.edit;
  • Handling user.delete.

Handling user.edit

The user.edit event occurs when:

  • receiving user data;
  • saving changes;
  • creating a user.

Check the parameters to determine the type of operation:

  • parameter sok is empty or missing — user data request. The user name is passed in the elid parameter;
  • parameter sok is not empty (usually yes or ok) and parameter elid is not empty — change user data. User name is passed in elid parameter;
  • parameter sok is not empty and parameter elid is not empty — user creation.
Example check for creating a user:
if ($Q->param("sok") && $elid eq "") {

The described logic of the sok and elid parameters is valid for functions to create or edit other objects.

Handling user.delete

The user.delete event occurs when a user is deleted. The delete operation supports group execution. To delete multiple users in one call, specify multiple names separated by “, ” (comma and space) in the elid parameter:

  1. Create an array of names:
    @all_users = split(", ", $elid);
  2. Remove each of the users from the Samba password database using an external command.

After performing the operations, the processing module must return an XML document with the results of its work to the standard output. If no result is required, it is sufficient to return an empty but valid XML document:

Example of a command
print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc/>\n";

Advanced event management

To replace the default event handling, use:

  • before="yes" attribute — execution prior to the main action;
  • <skipaction/> tag — locking the standard function;
  • after="yes" attribute — performing additional actions after treatment. Does not work if the <skipaction/> tag.

To set up the configuration:

  1. Create an XML processing module configuration:
    Sample file
        <mgrdata>
    		<processing module name="test.py" type="xml">
    			<event name="register.activationsend" before="yes"/>
    		</processing module>
    	</mgrdata>
    More
  2. Create an executable file /usr/local/mgr5/addon/test.py:
    Sample file
    #!/usr/bin/env python3
    
    print("<doc>");
    print("<skipaction/>");
    print("</doc>");
    
    More
  3. Customize the permissions:
    chmod 750 /usr/local/mgr5/addon/test.py
    chown root:root /usr/local/mgr5/addon/test.py
  4. Restart the billing platform:

    /usr/local/mgr5/sbin/mgrctl -m billmgr exit

When you call the function register.activationsend:

  1. The standard platform action will not be performed.
  2. The contents of the /usr/local/mgr5/addon/test.py script will be executed, since the register.activationsend function in the processing module is replaced by this file.
  3. An entry will appear in the log:
Sample output
[INFO] external: Executing: /usr/local/mgr5/addon/test.py

The example shows the correct XML output to stdout in the executable. It:

  • does not contain specific commands;
  • shows how to replace an action in billing with an action in an executable file.

You must independently ensure:

  • processing of input parameters (func, elid, sok, etc.);
  • correct XML output to stdout;
  • performing all necessary operations instead of the system.

Dependent functions will use data generated by your script.

Be sure to check the integrity of data in the database after replacing actions.

Order of execution and access to data

If the processing module lacks data in the input XML file (for example, the payment.add button is missing), this may be related to the moment when the script is launched.

To ensure that the processing module receives the complete set of data, including data added by the system later, specify the following in the processing module's XML configuration:

<event name="desktop" after="yes" proirity="after" base="project"/>

Block configuration components:

  • name="desktop" — name of the function for which the processing module is triggered;
  • after="yes" — run the script after the main action;
  • proirity="after" — indicates that the processing module should run after all standard response modifications. For example, adding balance node;
  • base="project" — binding to the module (in this case, BILLmanager or Clouden), rather than to CORE;
Please note: the attribute is called proirity, not priority — this is a feature of COREmanager, retained for compatibility.

Before specifying proirity="after" base="project", processing occurs as follows:

  1. Request. 
  2. Preprocessing.
  3. Execution of main logic.
  4. Execution of external plugin code.
  5. Add processing module. For example, balance.
  6. Platform response.

After specifying proirity="after" base="project", the order changes:

  1. Request. 
  2. Preprocessing.
  3. Execution of main logic.
  4. Add processing module. For example, balance.
  5. Execution of external plugin code.
  6. Platform response.
Useful tips