Calling Programs
Calling programs or command line scripts is a very powerful feature that can be used to check configuration of the system or perform advanced automation steps.
Additionally, you can access information about the underlying system, e.g. the operating system type/name and environmental variables in order to tailor your script to work across multiple os types.
Because of the power of this automation, it can be disabled centrally by using the
Options are to disable globally, enable only for non-root users and enable globally. |
Code Walkthrough
The os global variable is the key object to allow access to the underlying operating system and information about the operating system in use.
Calling a simple program
In the following very simple check we will use the built in command whoami
to
report back the user that the agent is running under.
Using the method exec(..) we can simply call the command. This method returns an ExecResult object and the command line output is simply available on the out property. In this simple check, we set that to the check message property to create a simple JavaScript based custom check that can be run on all monitored system types:
const agentUser = os.exec("whoami");
check.message = agentUser.out;
Handling Errors
The above example works for simple commands that you know will execute, but perhaps this command could also throw an error which would need to be checked. The ExecResult object has a property exitCode that can be used to control the flow of your check.
let willFail;
try {
willFail = os.exec("this_doesnt_exist");
} catch (e) {
// Catch any exception (raised on Windows)
// and create an object with our results:
willFail = {
out: e.getMessage(),
exitCode: -1
};
}
// Format the message output as the command output
check.message = willFail.out;
if (willFail.exitCode != 0) {
// Handle the error case
// check.status is by default OK
check.status = CRITICAL;
}
This check will always fail (unless for some reason you have a command called
this_doesnt_exist
available) to demonstrate this feature. We always set the
check message to contain the output the command produced, in this case something
like command not found
is printed but this depends on the operating system.
And we set the status of the check to CRITICAL
in this error case.
Handling OS differences
Sometimes the command to execute will differ between operating systems. You can use the osName property to differentiate between operating systems in your landscape and call different commands, or add different options depending on the type. This means you have a single custom check that can be rolled out to all servers rather than needing to define specific system selectors for different checks and future changes in check logic need only be made in one place.
Using the osName property is simple as seen in this example that will output the running processes in both Windows and Linux environments.
const isWindows = os.osName.toLowerCase().indexOf("windows") > -1;
let cmd = '';
if (isWindows) {
cmd = "tasklist";
} else {
cmd = "ps aux"
}
check.message = os.exec(cmd).out;
The check message is simply the text output, you could extend this check further to create a table of results. Note that the different operating systems commandes return the information in different formats, and on Windows, the line endings are different and may need to be handled differently. See the examples section for the full code for this.
Developing such multi-os checks are accelerated with the test run feature for custom JavaScript checks. Here you can add multiple systems (choose one Linux and one Windows) and see the result of your changes in both systems immediately.
Using Cloud APIs
With the cloudMetaData property on the os global object, we also have access to information the virtualisation provider has about this virtual machine. For example in Google Cloud Platform (GCP):
const cloudMD = os.cloudMetaData;
if (cloudMD) {
const project = cloudMD["project-id"];
const name = cloudMD.name;
console.log(`Running in GCP ${project} / ${name}`);
}
The structure of cloudMetaData is dependant on the cloud/virtualisation provider in use and can be changed at any time by the provider. You can |
Examples
The example is a bit silly, but it demonstrates how it works. Simply create a JavaScript based custom check (RUN_JS) for a Linux server, copy & paste the code example below, and you can see it work.
const result = os.exec("sh -c 'ls -al /opt'");
if (result.exitCode === 0) {
check.status = OK;
check.message = "The content of directory /opt is:\n";
}
else {
check.status = WARNING;
check.message = "Command failed!\n";
}
check.message = check.message + result.out;
This example is an extension of the cross-platform code walkthrough that will format the output of the process list command in a custom check.
const isWindows = os.osName.toLowerCase().indexOf("windows") > -1;
// on Windows, we call 'tasklist'
// whereas on Linux based systems it's 'ps aux'
const cmd = isWindows ? "tasklist" : "ps aux";
// Each command has a different number of header rows
const skipRows = isWindows ? 3 : 1;
// Call the command and split the output by each line
const rows = os.exec(cmd).out.split('\n');
// Create a table output with two columns:
// | PID | Name |
check.addTableColumn("PID");
check.addTableColumn("Name");
// Process each row
rows.forEach((row, index) => {
// Skip the header rows
if (index < skipRows) return;
// Split the row by whitespace
const parts = row.split(/\s+/);
if (parts.length > 1) {
// Create a new row in the table
check.newRow();
// The process id is always 2nd in the table
const pid = parts[1];
// The name of the process is in different columns
const name = isWindows ? parts[0] : parts[10];
// Add the data to the check output
check.addCell(pid);
check.addCell(name);
}
});
API Reference
Global Variable os
The global variable os is used to access the operating system of the managed object. Using the powerful exec methods allow access to collect information or perform actions by executing built in or custom programs at the operating system level.
exec(..)
exec(commandLine: string): ExecResult
Execute a command on the operating system of the Agent.
Specify a shell/terminal command to execute as you would enter a command in a command line environment directly on the operating system. Please note that operating system commands may be disabled by system-wide settings.
If the command creates files or performs tasks, make sure to clean up after the command has been executed.
This command will wait for 30s before exiting.
- Parameters
-
-
commandLine
: stringcommand line argument to execute
-
- Returns
-
the result of the execution
exec(..)
exec(commandLine: string, timeoutMs: number): ExecResult
Execute a command on the operating system of the Agent.
Specify a shell/terminal command to execute as you would enter a command in a command line environment directly on the operating system. Please note that operating system commands may be disabled by system-wide settings.
If the command creates files or performs tasks, make sure to clean up after the command has been executed.
This command will wait for the specified time given in ms to the parameter timeoutMS before exiting.
- Parameters
-
-
commandLine
: stringcommand line argument to execute
-
timeoutMs
: numberthe timeout in ms to wait until failure
-
- Returns
-
the result of the execution
execSSH(..)
execSSH(credentials: any, commandLine: string): ExecResult
Executes the given command with the user set in credentials (with no timeout).
Example:
// Use with automation credentials:
const osCmd = os.execSSH(action.input.otherUser, 'id');
console.log(osCmd.exitCode); // Print exit code
console.log(osCmd.out); // Print command result
- Since
-
21.11.4
- Parameters
-
-
credentials
: anythe credentials used to execute the command
-
commandLine
: stringcommand line argument to execute
-
- Returns
-
the result of the execution
execSSH(..)
execSSH(credentials: any, commandLine: string, timeoutMs: number): ExecResult
Executes the given command with the user set in credentials.
Example:
// Use with automation credentials:
const osCmd = os.execSSH(action.input.otherUser, 'id', 10000);
console.log(osCmd.exitCode); // Print exit code
console.log(osCmd.out); // Print command result
- Since
-
21.11.4
- Parameters
-
-
credentials
: anythe credentials used to execute the command
-
commandLine
: stringcommand line argument to execute
-
timeoutMs
: numberthe timeout in ms to wait until failure (set to 0 for no timeout)
-
- Returns
-
the result of the execution
getCloudMetaData( )
getCloudMetaData(): any
If the monitored object is running on a supported hyper-visor environment, e.g. Google Compute Platform, return a JSON object of information we’ve retrieved about this virtual machine and this environment.
Avantra uses this information to enrich our landscape information in the server UI, however a check developer could use this information to perform additional web API calls to perform actions on this environment or to report other useful information back to Avantra.
- Since
-
21.11
- Returns
-
any
a JSON object or null if not running on a supported hyper-visor
- See Also
getOsName( )
getOsName(): string
Return the type of operating system that this Agent is running on.
This can be used to tailor specific commands to the operating system in use so that the checks or automation can be made generic across OS type.
- Returns
-
string
the name of the underlying operating system
- See Also
getenv(..)
getenv(name: string): string
Returns the value of a specific environment variable set for this execution of the check on the Agent.
- Parameters
-
-
name
: stringthe name of the environment variable
-
- Returns
-
string
the value of the environment variable
sleep(..)
sleep(milliseconds: number): void
Causes the current script execution to sleep for the specified number of milliseconds. It is highly recommended to use this sleep function to pause a script execution.
- Since
-
23.0
- Parameters
-
-
milliseconds
: numberthe length of time to sleep in milliseconds
-
cloudMetaData
readonly cloudMetaData: any
If the monitored object is running on a supported hyper-visor environment, e.g. Google Compute Platform, return a JSON object of information we’ve retrieved about this virtual machine and this environment.
Avantra uses this information to enrich our landscape information in the server UI, however a check developer could use this information to perform additional web API calls to perform actions on this environment or to report other useful information back to Avantra.
- See Also
- Type
-
any
- Modifiers
-
Readonly
- Since
-
21.11
Class ExecResult
This class captures the response of executing a command on the operating system.
getExitCode( )
getExitCode(): number
Returns the exit code from executing the command
- Returns
-
number
the exit code of the command executed
- See Also
getOut( )
getOut(): string
Returns the output of the command (i.e. the output of the command line console when the command is executed).
- Returns
-
string
the console output/result of the command
- See Also
exitCode
readonly exitCode: number
The exit code of the command executed
- See Also
- Type
-
number
- Modifiers
-
Readonly