JavaScript within native command set scripting

Native command sets support JavaScript scripting functionality that will allow the creator to add their own logic flow around sending native commands to network resources and the ability to execute or return data from external commands.

Syntax

The first line of the native command set must be //#javascript or //#js to indicate to the workflow engine that scripting mode has been enabled.

The script must include a function named execute that accepts three parameters and returns true or false to indicate that the unit of work (UOW) has succeeded or failed.
Note: The parameter names are not fixed.
Here is an example of the script syntax:
//#javascript
function execute(scriptAuditLogger, deviceInterface, systemInterface) {
    //enter javascript logic here
    return true;
}
This could also be written as:
//#javascript
function execute(logger, device, system) {
    //enter javascript logic here
    return true;
}

At script runtime, the workflow engine passes three classes corresponding to the function parameters to the script. Whatever names are chosen for the parameters, the names must be used within the body of the function.

Restriction: Do not use the $ character when creating JavaScript within native command set scripting, for example in a regular expression. Use #single_dollar# instead (including the hashtags). Netcool Configuration Manager interprets the $ character as the beginning of a substitution variable, which allows the use of parameters in Native Command Sets. A single $ character is therefore interpreted as the beginning of a substitution, and if there is no closing $ character, an error occurs.

Methods

In order to describe the methods that are available for each class, the parameter names in the first example from the Syntax section will be used.

The scriptAuditLogger class that is passed into script function supports the following methods for sending messages to the unit of work log:
Table 1. Methods that support the scriptAuditLogger class
Method Description Example
void info(String message) Sends an audit log message to the UOW log. scriptAuditLogger.log(“This message will appear in Unit of work log”);
void error(String message, Exception exception) Sends an audit log error message to the UOW log. scriptAuditLogger.error(“This operation has failed”, e);
The deviceInterface class that is passed into the script function provides the ability to send native commands to the network resource. The following table describes the methods for sending native commands to a network resource.
Table 2. Methods that support the deviceInterface class
Method Description Example
String send(String command) Sends a command to device and returns response. var response = deviceInterface.send(“show ip interface brief”);
String send(String command, String responseRegExp) Sends a command to device and returns result of running a regular expression on the response. Only the first group match is returned. var response = deviceInterface.send(“show ip interface brief”, “^(\w+)\s”);
String sendAndExpect(String command, String expectedResponse Sends a command to a device, waits for the expected response, and returns the device's response. Use this method when an interactive command is to be sent. deviceInterface.sendAndExpect("copy run start", "[startup-config]?"); deviceInterface.send("\r");
String sendAndExpect(String command, String expectedResponse, String responseRegExp) Sends a command to a device, waits for the expected response, and returns the result of running a regular expression on the response. Only the first group match is returned. Use this method when an interactive command is to be sent.  
The systemInterface class that is passed into the script function provides the ability to execute external commands, retrieve data from external commands, and execute file operations to create, update and delete files, and to SFTP a file to a specified server.
Table 3. Methods that support the systemInterface class
Method Description Example
public Path createFile(String filePathName, String content) throws Exception Method to create a file, given the absolute file path and the content as a String. You need to add sun.nio.fs.UnixPath as an allowed class to System Properties to use this method. var response = system.createFile(source,"initial content of file\n");
public Path updateFile(String filePathName, String content) throws Exception Method to update a file, given the absolute file path and the content as a String. You need to add sun.nio.fs.UnixPath as an allowed class to System Properties to use this method. var response = system.updateFile(source,"appended update to file\n");
public void deleteFile(String filePathName) throws Exception Method to delete a file given the absolute file path, system.deleteFile(source);

public boolean sftpFile (String sourceFilePathName , String destinationFilePathName , Map<String,String> options) throws Exception

Method to SFTP a file to a specified server. You need the java.util package in System Properties as an allowed java package to use this method.
var source="/home/icosftp/testJSCreatedFile.xml";
   var response = system.createFile(source,"initial content of file\n");
   var destination="/home/timo/testJSCreatedFile.xml";
   var options=new java.util.HashMap();
   options.put("username","user1");
   options.put("password","pass1");
   options.put("remoteHost","10.168.1.1");
   system.sftpFile(source,destination,options);
String executeSystemCommand(String shellName, String shellArgs, String command, String checksum)

Executes a system command and returns the output of the system command.

The system command is a file that contains a shell script. The user must calculate a checksum for the file using icosutil. The checksum must then be entered in a native command set.

var response = systemInterface.executeSystemCommand(“/bin/sh”, “-c”, “getNetStat.sh”, “<generated checksum>”);

To generate a checksum for the getNetStat.sh script on the server run the following command: <install_dir>;/bin/icosutil CalculateChecksum getNetStat.sh
Important: If an external script is modified after a checksum has been generated, then a new checksum must be generated and the native command set script must be updated.
String executeSystemCommand(String shellName, String shellArgs, String command, String responseRegExp, String checksum)

Executes a system command and returns the result of running a regular expression on the output of the system command. Only the first group match is returned.

The system command is a file that contains a shell script. The user must calculate a checksum for the file using icosutil. The checksum must then be entered in a native command set.

var response = systemInterface.executeSystemCommand(“/bin/sh”, “-c”, “getExternalData.sh”, “^(w+)\s“, <generated checksum>”);

To generate a checksum for the getExternalData.sh script on the server run the following command: <install_dir>;/bin/icosutil CalculateChecksum getExternalData.sh
Important: If an external script is modified after a checksum has been generated, then a new checksum must be generated and the native command set script must be updated.

Restricted commands

Restriction: The following notes do not apply to a configuration change native command set.
Restricted commands are not permitted within an interrogation native command set that does not contain a script. For example, a user is prohibited from saving the following interrogation native command set:
reload
However, a user is allowed to save the following interrogation native command set:
//#javascript
function execute(scriptAuditLogger, deviceInterface, systemInterface) {
    var command = “reload”;
    deviceInterface.send(command);
    return true;
}
Note: Despite it being permitted to save this interrogation native command set, however, it would fail at runtime, because a restricted command within an interrogation native command set is prohibited from being sent to a device.

Disabling scripting

An administration user, that is, a user with View System and Manage System activities, can disable the scripting functionality by setting the following system property to false:
Scripting – Enable script execution
The system checks this property at runtime, and if set to 'false', will not allow scripts to be run.
The default setting is 'true'

Disabling external system commands

An administration user, that is, a user with View System and Manage System activities, can disable external system commands by setting the following system property to false:
Scripting – Enable external system command execution
The system checks this property at runtime, and if set to 'false', will not allow scripts to be run.
The default setting is 'true'

Allowing classes and packages in scripting

To allow external Java classes and packages to be used in a script, the following system properties need to be configured:
Note: In order to change system properties a user must have View System and Manage System activities assigned to their user group.
Scripting - Classes allowed in a script
This system property stores a list of allowed Java classes. It is checked at runtime to determine if classes in a script are permitted.
The default list is empty, which means that no classes are permitted until a system administrator has added them to this list.
The allowed classes list is comma-separated, for example:
java.lang.String
java.lang.String, java.lang.StringBuilder, java.util.ArrayList
Scripting - Packages allowed in a script
This system property stores a list of allowed Java packages. It is checked at runtime to determine if packages in a script are permitted.
The default list is empty, which means that no packages are permitted until a system administrator has added them to this list.
The allowed classes list is comma-separated, for example:
java.util
java.util, java.util.regex, java.text

Setting scripting timeout

An administration user, that is, a user with View System and Manage System activities, can edit the appropriate system property to define the length of time that scripts within a command set or compliance definition are allowed to run without completing before they are stopped:
Scripting - Maximum script execution time
The default script execution limit is 10 minutes, and a system administrator can set a time limit between one and 120 minutes.
If a script within a command set times out, the UOW is marked 'failed'.

Script samples

The following script determines whether a Cisco router's clock is synchronized with an NTP server. If it is not synchronized, the IP address of the unsynchronized master is retrieved and a ping command is issued.
//#javascript
function execute(scriptAuditLogger, deviceInterface, systemInterface) {
    var response = deviceInterface.send("show ntp status", "(Clock is unsynchronized)");

    if (response == null) {
        scriptAuditLogger.info("Clock IS synchronized");
        return true;
    } else {
        scriptAuditLogger.info("Clock is NOT synchronized");
        response = deviceInterface.send("show ntp association", "(#\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})");
        if (response != null) {
            var ipAddress = response.substring(1);
            scriptAuditLogger.info("IP address of master = " + ipAddress);
            response = deviceInterface.send("ping " + ipAddress);
            scriptAuditLogger.info(response);
        } else {
            scriptAuditLogger.info("NTP master is NOT configured.");
        }
        return false;
    }
}
The following script finds the IP addresses of a Cisco router's interfaces and performs a naming service lookup for each IP address.
//#javascript
importClass(java.util.regex.Pattern);
importClass(java.util.regex.Matcher);

function execute(logger, device, system) {
    var ipAddresses = device.send("show ip int brie | ex (Interface|unassigned|down)");
    logger.info(ipAddresses);

    var regexpression = "((?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]))";
    var pattern = Pattern.compile(regexpression, Pattern.MULTILINE);
    var matcher = pattern.matcher(ipAddresses);

    while (matcher.find()) {
        var ipAddress = matcher.group();
        logger.info("Found ip address [" + ipAddress + "]. Performing nslookup...");
        var response = system.executeSystemCommand("/bin/sh", "-c", "/home/icosuser/scripts/nslookup.sh " + ipAddress, "57b0b52e4a43da0591f90d4b7da6f6d189b985bbf4ec787a416104910f7610ac");
        logger.info(response);
    }

    return true;
}
Note: The shell script used in this example, nslookup.sh, was written and saved in the /home/icosuser/scripts directory on the Netcool Configuration Manager server. The script consisted of one line:
nslookup $1
Note: The script's checksum was calculated using the icosutil utility.