# Constructing scenarios

Before creating your first scenario, it is recommended that you familiarize yourself with the terminology and general concepts of the Automation functionality:

Glossary of terms in the Automation section

Basics of the Automation functionality

In this section, we will consider the general principles for creating and building automation scenarios.

# Adding a scenario

  1. Go through the main menu to the section Actions→Automation to open the scenario management screen.

  2. To add a new scenario to the system, click the βž• New Scenario button in the upper right corner of the screen.

  3. Fill in the main parameters of the new scenario:

    • Scenario Owner - The Workgroup that will own the scenario.
    • Name - logically understandable name of the scenario.
    • Type - CMDBAutoDiscovery.
    • Description (optional).
    • Import script (optional). image
  4. Click the Create button - the scenario will be created and the scenario constructor will open.

  5. Each scenario starts with the Launch Event block - OnLogEvent - automatically added when creating each scenario.

    image

    • You cannot delete or modify the OnLogEvent block.
    • The outgoing pin (variable) Value contains data of a primary event passed to the collector via:
      • Public API
      • Integration
      • Acure Agent

# Event filtering

The next step is to filter events going into the Automation scenario.

To do this, add a local function block to the scenario:

  1. In the Object Manager, click βž• in the Local Functions category and a CodeFunction local function will be added.

    image

  2. From the action menu above the CodeFunction, select Add to Canvas</>.

  3. Double click on the added local function block to open the Object Inspector.

    image

  4. Change the Name of the local function, for example FilterEvents.

  5. Add Input pinInValue with type Monq.Cl.CollectorLogEvent (this system type describes the structure of Acure primary events).

  6. Configure Output pins as follows:

    • ok, type Exec
    • failed, type Exec

    image

  7. Switch to the edit mode of the current local function FilterEvents, click on the Editor tab while in the Object Inspector.

  8. Bring the function code to the following form:

    private async ValueTask<FuncResult> FilterEvents(Monq.Cl.CollectorLogEvent InValue) {
    if (InValue._stream.id == 248)
    {
      return new FuncResult("ok");
    }
    return new FuncResult("failed");
    }
    

    image

    In this example, the primary event field _stream.id (ID of the "Data Stream") is checked with the predefined value (248). If the primary event came via Data Stream with the identifier id == 248 the scenario will go further along the ok Output pin, otherwise along the failed Output pin.

  9. Connect the corresponding pins by dragging the link between them:

    • Block OnLogEvent pin Out ➞ Block FilterEvents pin In - connection for defining scenario execution sequence.

    • Block OnLogEvent pin Value ➞ Block FilterEvents pin InValue - connection for transfering variable values.

      image

# Event handling

An example of creating a Configuration Item (CI) by an event from Zabbix (the host field) will be considered.

# An example of a primary event from *Zabbix* monitoring system 
  "id": "50133",
  "clock": 1646785676,
  "acknowledged": 0,
  "name": "Disk space usage",
  "value": 1,
  "severity": 4,
  "trigger": {
    "id": "20170",
    "revealedDescription": "Disk space usage",
    "description": "Disk space usage",
    "revealedComments": "",
    "comments": "",
    "expression": "{25124}>90",
    "lastChangeTime": 0,
    "priority": 4,
    "state": 0,
    "status": 0,
    "url": "",
    "value": 1
  },
  "group": {
    "id": "24",
    "name": "d12-apps"
  },
  "host": {
    "id": "10452",
    "hostValue": "d12 Host",
    "name": "d12 Host"
  },
  "itemsIds": [
    37676
  ],
  "tags": [],
  "zabbixVersion": 5.4
}

# Declaring structures

First, you need to decompose the structure of the primary event into properties. To do this, you need the global BreakStruct function.

  1. Add the BreakStruct global function to the script using the right mouse button.

  2. Connect the incoming Object pin of the BreakStruct function to the outgoing Value pin of the OnLogEvent trigger event. The structure of the primary event will be automatically "mapped out" into the corresponding properties in the form of outgoing pins of the BreakStruct function.

    image

  3. We are interested in the outgoing source pin with the Dynamic type, which contains the source event with data from Zabbix. Namely, the host object, according to which we will create Configuration Items:

    "host": {
        "id": "10452",
        "hostValue": "d12 Host",
        "name": "d12 Host"
      }
    
  4. To work with the values ​​contained in the fragment, it is necessary to describe the structure of this object:

    1. Create a new structure in the Object Manager - click βž• in the Structures category - a local Struct structure will be added.

      image

    2. Click the left mouse button on the newly created structure to open the Object Inspector for this structure.

    3. Set the Name of the structure, for example ZabbixHostObject

    4. Add structure properties according to the JSON:

      • id, type String
      • hostValue, type String
      • name, type String

      image

    5. Structure declaration is completed at this stage.

# Access to event fields

Next, to access the host object and its properties, you need the global function BreakDynamic

  1. Add the BreakDynamic global function to the scenario using the right mouse button.

  2. Connect the incoming Object pin of the BreakDynamic function to the outgoing source pin of the previous global BreakStruct function.

    image

  3. Open the Object Inspector of the BreakDynamic function and add an output hosts pin with type ZabbixHostObject (previously declared structure).

    image

  4. Next, you need to "decompose" the structure of the host object again by adding another new global function BreakStruct and connecting the pins:

    • Outgoing host pin of BreakDynamic function ➞ Incoming Object pin of BreakStruct function

    image

  5. At this stage, we have access toZabbix event variables source.host.id, source.host.name, and source.host.hostValue as outgoing pins of the BreakStruct function.

  6. The next step is to prepare a request to create a Configuration Item using the Acure public API.

# Creating CI

An example of creating a CI with a default type and assigning as owner the current Workgroup (scenario owner) will be considered.

To create a CI, a request with the following minimum content is used:

{
  # CI identifier:
  "id": 0
  # CI name
  "name": "",
  # Description of CI
  "description": "",
  # ID of the Workgroup - owner of the CI:
  "ownerWorkGroup": {
    "id": 0
  }
}
  1. According to the request body presented above, it is necessary to create 2 structures:

    • createCIQuery - a structure describing the entire JSON,
    • ownerWorkGroup - structure describing object "ownerWorkGroup": {"id": 0 }
  2. Create a new structure in the Object Manager - click βž• in the Structures category - a local Struct structure will be added.

  3. Left-click on the newly created structure to open the Object Inspector for this structure.

  4. Set the Name of the structure, for example ownerWorkGroup

  5. Add structure properties according to the JSON:

    • id, type Integer64

    image

  6. Repeat steps 2-3 to create another structure.

  7. Set the Name of the structure, for example createCIQuery

  8. Add structure properties according to the JSON:

    • id, type String
    • name, type String
    • description, type String
    • ownerWorkGroup, type ownerWorkGroup - created structure.

    image

# Preparing the request body

Next, you need to generate a request to create a CI, where:

  • CI name = source.host.name
  • CI Description = source.host.id
  • CI Owner = Scenario Owner

Use the global function SetMembersInStruct to assign values ​​to the properties of the created structures.

# Assign the ID of the Workgroup that owns the scenario to the id variable in the ownerWorkGroup structure:

  1. Add the SetMembersInStruct global function to the script.

    image

  2. Create a new local variable in the Object Manager.

  3. In the Object Inspector, specify the name of the created variable, for example ownerWorkGroupVar. Set the variable type to ownerWorkGroup - the previously created structure.

    image

  4. Add the ownerWorkGroupVar variable to the scenario from the Object Manager using the context menu item Add to Canvas Get.

  5. Connect the ownerWorkGroupVar variable pin to the incoming Object pin of the SetMembersInStruct block and open the block in the Object Inspector.

    image

  6. Check the incoming pin Id in the object manager - it will be added as an Input pin of the current block.

    image

  7. Add the OwnerWorkGroupId system variable to the scenario and connect it to the incoming Id pin of the SetMembersInStruct block.

    image

  8. In order for this function to be executed when the scenario is run, connect the outgoing ok pin of the local FilterEvents function to the incoming In pin of the SetMembersInStruct function.

    image

# Set the "CI Name" and "CI Description" values ​​in the createCIQuery structure:

  1. Add another global function SetMembersInStruct to the scenario.

    image

  2. Create a new local variable in the Object Manager

  3. In the Object Inspector specify the name of the created variable, for example CreateCIQueryVar. Variable type = CreateCIQuery - the previously created structure.

    image

  4. Add the CreateCIQueryVar variable to the script from the Object Manager.

  5. Connect the CreateCIQueryVar variable pin to the incoming Object pin of the SetMembersInStruct block and open the block's Object Inspector.

    image

  6. Select the pins you want to set values to, they will appear as incoming pins of the SetMembersInStruct function block.

    image

  7. Perform the following link setup:

    • Incoming pin name of the function SetMembersInStruct ➞ Outgoing pin name of the function BreakStruct (passing the value of source.host.name to the body of the request to create CI).
    • Incoming description pin of the SetMembersInStruct function ➞ Outgoing id pin of the BreakStruct function (passing the value of source.host.id to the body of the request to create CI).
    • Incoming ownerWorkGroup pin of the SetMembersInStruct function ➞ Outgoing Result pin of the SetMembersInStruct function (passing the value of the scenario owner's Workgroup ID to the body of the request to create CI).
    • Incoming pin In of the function SetMembersInStruct ➞ Outgoing pin Out of the function SetMembersInStruct (indicate the order of execution of functions in the scenario).
  8. Set the value of the incoming pin id of the SetMemberInStruct function to 0 to automatically generate the Configuration Item identifier.

At this point, your scenario should look like this: image

Next, you need to send an HTTP POST request to the Acure public API with the prepared parameters. This requires the MonqHTTPRequest global function.

  1. Add the MonqHTTPRequest global function to the scenario using the context menu.

    image

  2. For authorization in the public API, a special token BearerToken is used. To authorize the request, you need the RobotToken system variable. Add it from the Object Manager.

    image

  3. Also for the HTTP request, you must specify the userspace identifier. The current value is stored in the UserspaceId system variable, add it to the scenario as well.

    image

  4. Perform the following link setup:

    • Incoming UserspaceId pin of the MonqHTTPRequest function ➞ Outgoing pin of the UserspaceId variable (pass the value of the space identifier in the header of the request to create CI).
    • Incoming pin BearerToken of the MonqHTTPRequest function ➞ Outgoing pin of the RobotToken variable (passing the value of the authorization token in the header of the request to create CI).
    • Incoming Body pin of the MonqHTTPRequest function ➞ Outgoing Result pin of the SetMembersInStruct function (passing the body of the HTTP request to create CI).
    • Incoming In pin of the MonqHTTPRequest function ➞ Outgoing Out pin of the SetMembersInStruct function (indicate the order of execution of functions in the scenario).

    image

  5. Set the incoming Url and Type pins of the MonqHTTPRequest function by specifying the appropriate values:

    • Url = https://<monq-global-domain>/api/public/sm/v2/rsm/config-items?makeNameUnique=false
    • Type = POST

    Replace <monq-global-domain> with the domain name of your Acure instance.

    image

  6. Click the Compile button on the top bar of the scenario constructor.

  7. Activate the scenario by using the Active/Inactive switch on the top panel of the scenario constructor.

    image

The finished scenario looks like this:

image

Now, when receiving an event from the Zabbix monitoring system about a problem or a recovery event, a Configuration Item will be created.

The functionality of the Automation module is not limited to this. This scenario can be extended with various conditions and checks, as well as making other public API requests.

If you have any difficulties, you can import the finished scenario into your system using the Import/Export functionality:

  1. Copy the code of the finished scenario to the clipboard: [zabbix-host.txt]
  2. Go to the Automation scenario management screen.
  3. Create a new scenario, set Owner and Name of the scenario.
  4. Paste the copied code into the import line.
  5. Click Create.
  6. Change the _stream.id parameter in the local FilterEvents function to the ID of the Data Stream whose events are to be processed by the automation scenario.