Document toolboxDocument toolbox

Sample Templates

This section contains sample templates that illustrate the following:

  • Session management using login and logout templates
  • Viewing event types
  • XML parsing and handling
  • Steps execution through backtracking and loops in a template
  • Operations using namespace variables
  • IP-related XC operations
  • WAPI integration
  • Endpoint reference

  • Active template functions


    For more information about configuring outbound notification rules, templates, and endpoints, see Outbound Notification Overview.

Note

Some of the templates are specific for Rapid7 servers.


Session Management Template

Following is a sample session management template for REST API endpoint:


{
   "name": "session",

   "version": "2.0",

   "type": "REST_ENDPOINT",

   "vendor_identifier": "Rapid7",

   "path": "/api/1.1/xml",

   "keepalive": true,

   "login_template": "login",

   "logout_template": "logout",

   "session_duration": 60000
}

Note

The login_template and logout_template lines specify the templates to be executed for login and logout.
The session_duration line specifies the length of the session. You must upload the login and logout templates before configuring a session management template that refers them.


Following is a sample session management template for DXL endpoint:

{"name": "session_tmplate",
"version": "3.0",
"type": "DXL_ENDPOINT",
"vendor_identifier": "DXL",
"dxl_keep_alive_interval": 60,
"dxl_topic": "/outbound/session"
}

Following is a sample session management template for syslog endpoint:

{
"version": "5.0",
"vendor_identifier": "SyslogEP",
"name": "Syslog Session",
"type": "SYSLOG_ENDPOINT",
"comment": "Syslog session template",
"path": "/wapi/v2.3/",
"override_path": true,
"timeout": 123,
"keepalive": true,
"retry": 1,
"retry_template": 0,
"rate_limit": 200
}

Login Template

{

   "name": "login",

   "version": "2.0",

   "vendor_identifier": "Rapid7",

   "type": "REST_EVENT",

   "event_type": ["SESSION"],

   "content_type": "text/xml",

   "quoting": "XMLA",

   "steps": [

      {

         "body": "${XC:ASSIGN:{H:Authorization}:{S:}}",

         "operation": "NOP",

         "name": "login: clear basic auth"

      },

      {

         "parse": "XMLA",

         "operation": "POST",

         "no_connection_debug": false,

         "name": "login: request",

         "body_list": [

            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",

         "<LoginRequest user-id=\"${UT::USERNAME}\" password=\"${UT::PASSWORD}\"/>"

         ]

    },

    {

        "operation": "CONDITION",

        "name": "login: errorcheck",

        "condition": {

           "statements": [

             {

                "op": "!=",

                "right": "${P:A:PARSE[[name]]}",

                "left": "LoginResponse"

             },

             {

                 "op": "!=",

                 "right": "1",

                 "left": "${P:A:PARSE{{success}}}"

            }

        ],

        "condition_type": "OR",

        "else_eval": "${XC:COPY:{S:SESSID}:{P:PARSE{{session-id}}}}",

        "error": true

      }

    }

  ]

}

Note

The else_eval line copies the session-id from the parsed reply (if successful); otherwise, it returns an error.


Logout Template

{

   "name": "logout",

   "version": "2.0",

   "type": "REST_EVENT",

   "vendor_identifier": "Rapid7",

   "event_type": ["SESSION"],

   "content_type": "text/xml",

   "quoting": "XMLA",

   "steps": [

      {

          "parse": "XMLA",

          "operation": "POST",

          "no_connection_debug": false,

          "name": "logout: request",

          "body_list": [

             "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",

             "<LogoutRequest session-id=\"${S::SESSID}\"/>"

          ]

       },

       {

          "operation": "CONDITION",

          "name": "logout: errorcheck",

          "condition": {

             "statements": [

               {

                  "op": "!=",

                  "right": "${P:A:PARSE[[name]]}",

                  "left": "LogoutResponse"

               },

               {

                  "op": "!=",

                  "right": "1",

                  "left": "${P:A:PARSE{{success}}}"

               }

            ],

            "condition_type": "OR",

            "error": true

         }

      }

   ]

}

Action Template

Sample Action Template for DXL Endpoint


{
"vendor_identifier": "DXL",
"version": "5.0",
"name": "action",
"type": "DXL_EVENT",
"event_type": [
"FIXED_ADDRESS_IPV4"
],
"dxl_topic": "/outbound/action",

"steps": [
{
"operation": "DXL_SEND_EVENT",
"name": "send_ip",
"body": "address ${E:A:values{ipv4addr}}",
"dxl_topic": "/outbound/step"
},
{
"operation": "DXL_SEND_REQUEST",
"name": "dxl_request",
"body_list": "address ${E:A:values{ipv4addr}}",
"dxl_topic": "/sample/service"
}
] 

}

Sample Action Template for DXL Endpoint Outbound

{
"version": "5.0",
"name": "DXL_action_template",
"type": "DXL_EVENT",
"event_type": ["RPZ","DXL"],
"action_type": "RPZ Action",
"comment": "Outbound API phase 5",
"content_type": "application/json",
"vendor_identifier": "McAfee",
"steps":
[
{
"operation": "DXL_SEND_EVENT",
"name": "dxl_event",
"body_list": [
"Hello Event"
],
"dxl_topic": "/outbound/demo"
},
{
"operation": "DXL_SEND_REQUEST",
"name": "dxl_request",
"body_list": [
"Hello Service"
],
"dxl_topic": "/isecg/sample/service"
},
{
"name": "log4",
"operation": "NOP",
"body": "${XC:DEBUG:{R:}}"
},
{
"name": "copy_rbody",
"operation": "NOP",
"body_list": [
"${XC:COPY:{L:data}:{R:BODY}}"
]
},
{
"name": "debugL",
"operation": "NOP",
"body": "${XC:DEBUG:{L:}}"
},
{
"operation": "DXL_SEND_EVENT",
"name": "resend_to_dxl",
"body_list": [
"Modified ${L::data}"
],
"dxl_topic": "/outbound/demo"
}
]
}

Sample Action Template for REST API Endpoint

Following is a sample action template for REST API endpoint:

{

   "name": "action",

   "vendor_identifier": "Rapid7",

   "version": "2.0",

   "content_type": "text/xml",

   "action_type": "add network or remove IP",

   "quoting": "XMLA",

   "type": "REST_EVENT",

   "event_type": [ "FIXED_ADDRESS_IPV4", "FIXED_ADDRESS_IPV6" ],

   "steps": [

     {

         "name": "check operation type",

         "operation": "CONDITION",

         "condition": {

   "statements": [

    {

         "op": "!=",

         "right": "${E:A:operation_type}",

         "left": "INSERT"

    },

    {

         "op": "!=",

         "right": "${E:A:operation_type}",

         "left": "DELETE"

    }

   ],

   "condition_type": "AND",

   "stop": true

     }

   },

   {

     "name": "send SiteListingRequest",

     "operation": "POST",

     "body_list": [

    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",

    "<SiteListingRequest session-id=\"${S::SESSID}\" />"

     ],

     "parse": "XMLA"

   },

   {

      "operation": "CONDITION",

      "name": "send SiteListingRequest (error check)",

      "condition": {

   "statements": [

    {

        "op": "!=",

        "right": "${P:A:PARSE[[name]]}",

        "left": "SiteListingResponse"

    },

    {

        "op": "!=",

        "right": "1",

        "left": "${P:A:PARSE{{success}}}"

     }

  ],

  "condition_type": "OR",

  "error": true,

  "else_eval": "${XC:COPY:{L:site_list}:{P:PARSE}"

     }

  },

  {

     "operation": "CONDITION",

     "name": "check whether site list is empty",

     "condition": {

 "statements": [{

   "op": "==",

   "right": "${L:L:site_list}",

   "left": "0"

  }],

  "condition_type": "AND",

  "stop": true

      }

  },

  {

      "operation": "VARIABLEOP",

      "name": "get the next site",

      "variable_ops": [{

  "operation": "POP",

  "type": "COMPOSITE",

  "destination": "L:a_site",

  "source": "L:site_list"

    }]

  },

  {

     "operation": "CONDITION",

     "name": "check site name",

     "condition": {

 "statements": [{

   "op": "!=",

   "right": "${L:A:a_site{{name}}}",

   "left": "${E:A:values{extattrs}{r7_site}{value}}"

  }],

  "condition_type": "AND",

  "next": "check whether site list is empty",

  "else_eval": "${XC:COPY:{L:site_id}:{L:a_site{{id}}}}"

     }

  },

  {

  "parse": "XMLA",

  "operation": "POST",

  "name": "send SiteConfigRequest",

  "body_list": [

"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",

"<SiteConfigRequest session-id=\"${S::SESSID}\" site-id=\"${L:A:site_id}\"/>"

    ]

  },

  {

     "operation": "CONDITION",

     "name": "send SiteConfigRequest (error check)",

     "condition": {

  "statements": [

     {

       "op": "!=",

       "right": "${P:A:PARSE[[name]]}",

       "left": "SiteConfigResponse"

     },

     {

       "op": "!=",

       "right": "1",

       "left": "${P:A:PARSE{{success}}}"

      }

  ],

  "condition_type": "OR",

  "else_eval": "${XC:COPY:{L:Site}:{P:PARSE{SiteConfigResponse}}}",

  "error": true

      }

  },

  {

      "operation": "CONDITION",

      "name": "check operation type again",

      "condition": {

   "statements": [{

    "op": "==",

    "right": "${E:A:operation_type}",

    "left": "INSERT"

  }],

  "condition_type": "AND",

  "eval":

"${XC:COPY:{L:network}:{E:values{network}}}${XC:NETWORKTORANGE:{L:network}:{L:range

}}",

  "next": "insert network"

    }

  },

  {

     "operation": "CONDITION",

     "name": "remove ip",

     "condition": {

  "statements": [{

    "op": "==",

    "right": "${E:A:event_type}",

    "left": "FIXED_ADDRESS_IPV4"

  }],

  "condition_type": "AND",

  "eval":

"${XC:COPY:{L:ip}:{E:values{ipv4addr}}}${XC:REMOVEIP:{L:ip}:{L:Site{Hosts}}}",

  "else_eval":

"${XC:COPY:{L:ip}:{E:values{ipv6addr}}}${XC:REMOVEIP:{L:ip}:{L:Site{Hosts}}}"

     }

  },

  {

     "operation": "CONDITION",

     "name": "jump to send",

     "condition": {

  "statements": [{

    "op": "==",

    "right": "",

    "left": ""

  }],

  "condition_type": "AND",

  "next": "send SiteSaveRequest"

     }

  },

  {

     "operation": "VARIABLEOP",

     "name": "insert network",

     "variable_ops": [{

  "operation": "PUSH",

  "type": "COMPOSITE",

  "source": "L:range",

  "destination": "L:Site{Site}{Hosts}"

      }]

  },

  {

       "parse": "XMLA",

       "operation": "POST",

       "name": "send SiteSaveRequest",

       "body_list": [

  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",

  "<SiteSaveRequest session-id=\"${S::SESSID}\">",

  "${L:x:Site}",

  "</SiteSaveRequest>"

     ]

  },

  {

     "operation": "CONDITION",

     "name": "send SiteSaveRequest (error check)",

     "condition": {

  "statements": [

   {

     "op": "!=",

     "right": "${P:A:PARSE[[name]]}",

     "left": "SiteSaveResponse"

   },

   {

     "op": "!=",

     "right": "1",

     "left": "${P:A:PARSE{{success}}}"

   }

  ],

  "condition_type": "OR",

  "error": true

     }

  },

  {

     "operation": "CONDITION",

     "name": "check operation type once more",

     "condition": {

  "statements": [{

    "op": "!=",

    "right": "${E:A:operation_type}",

     "left": "INSERT"

  }],

  "condition_type": "AND",

  "stop": true

     }

  },

  {

     "operation": "PUT",

     "name": "add an attribute with WAPI",

     "transport": {"path": "${E:A:values{_ref}}"},

     "wapi": "v2.6",

     "body": "{\"extattrs+\": {\"r7_added\": {\"value\": \"Added to the Rapid7 ${UT:A:TIME}\"}}}"

   }

 ]

}

Sample Action Template for Syslog Endpoint

{
"version": "5.0",
"name": "syslog_action_dns_record",
"type": "SYSLOG_EVENT",
"event_type": ["RPZ","DXL","DNS_RECORD","DNS_ZONE"],
"action_type": "Some Action",
"comment": "Syslog Events",
"content_type": "application/json",
"vendor_identifier": "syslog",
"steps":
[
{
"name": "syslog_send",
"operation": "SYSLOG_SEND_EVENT",
"body": "${E::object_type} ${E::operation_type} with name ${E::values{name}} on to zone ${E::values{zone}} for member ${E::member_ip} at timestamp ${E::timestamp}"
}
]
}

Action Template: Check Operation Type

{

           "name": "check operation type",

           "operation": "CONDITION",

           "condition": {

           "statements": [

            {

             "op": "!=",

             "right": "${E:A:operation_type}",

             "left": "INSERT"

            },

            {

             "op": "!=",

             "right": "${E:A:operation_type}",

             "left": "DELETE"

            }

        ],

        "condition_type": "AND",

        "stop": true

}

Note

The "check operation type" step checks the operation type. If it is neither INSERT nor DELETE, the template execution stops.


Action Template: Get the List of Sites

{

        "name": "send SiteListingRequest",

        "operation": "POST",

        "body_list": [

     "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",

     "<SiteListingRequest session-id=\"${S::SESSID}\" />"

        ],

        "parse": "XMLA"

     },

     {

        "operation": "CONDITION",

        "name": "send SiteListingRequest (error check)",

        "condition": {

     "statements": [

        {

        "op": "!=",

        "right": "${P:A:PARSE[[name]]}",

        "left": "SiteListingResponse"

      },

      {

        "op": "!=",

        "right": "1",

        "left": "${P:A:PARSE{{success}}}"

       }

    ],

    "condition_type": "OR",

    "error": true,

    "else_eval": "${XC:COPY:{L:site_list}:{P:PARSE}"

        }

    }

Note

The "send SiteListingRequest" and "send SiteListingRequest (error check)" steps request the list of sites on a Rapid7 server. If the response is successful, it copies the list to the L:site_list variable.


Action Template: Locate the Site ID by Name

{

       "operation": "CONDITION",

       "name": "check whether site list is empty",

       "condition": {

  "statements": [{

     "op": "==",

     "right": "${L:L:site_list}",

     "left": "0"

  }],

  "condition_type": "AND",

  "stop": true

     }

  },

  {

     "operation": "VARIABLEOP",

     "name": "get the next site",

     "variable_ops": [{

  "operation": "POP",

  "type": "COMPOSITE",

  "destination": "L:a_site",

  "source": "L:site_list"

     }]

  },

  {

      "operation": "CONDITION",

      "name": "check site name",

      "condition": {

  "statements": [{

    "op": "!=",

    "right": "${L:A:a_site{{name}}}",

    "left": "${E:A:values{extattrs}{r7_site}{value}}"

  }],

  "condition_type": "AND",

  "next": "check whether site list is empty",

  "else_eval": "${XC:COPY:{L:site_id}:{L:a_site{{id}}}}"

      }

  }

NOTES:

  • The "check whether site list is empty", "get the next site", and "check site name" steps form a loop for finding the site with specific name in the list of sites.
  • The "check whether site list is empty" step checks to see if the list is empty. If it is empty, the site with the specific name is not found and the execution of the template stops.
  • In the "get the next site" step, one element is copied to the L:a_site variable.
  • In the "check site name" step, the "name" attribute of a site (${L:A:a_site{{name}}}) is compared to the value of the "r7_site" extensible attribute of the fixed address in (${E:A:values{extattrs}{r7_site}{value}}). If they are the same, the site ID is stored to the L:site_id variable (${XC:COPY:{L:site_id}:{L:a_site{{id}}}}). If they are not the same, the execution is continued by the "check whether site list is empty" step.

Action Template: Get Site Configuration

{

            "parse": "XMLA",

            "operation": "POST",

            "name": "send SiteConfigRequest",

            "body_list": [

   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",

   "<SiteConfigRequest session-id=\"${S::SESSID}\" site-id=\"${L:A:site_id}\"/>"

          ]

   },

   {

        "operation": "CONDITION",

        "name": "send SiteConfigRequest (error check)",

        "condition": {

  "statements": [

    {

      "op": "!=",

      "right": "${P:A:PARSE[[name]]}",

      "left": "SiteConfigResponse"

  },

  {

      "op": "!=",

      "right": "1",

      "left": "${P:A:PARSE{{success}}}"

  }

 ],

 "condition_type": "OR",

 "else_eval": "${XC:COPY:{L:Site}:{P:PARSE{SiteConfigResponse}}}",

 "error": true

     }

 }

Note

Once site-id is known, steps "send SiteConfigRequest" and "send SiteConfigRequest (error check)" request and store the site configuration.


Action Template: Distinguish Between INSERT and DELETE

{

       "operation": "CONDITION",

       "name": "check operation type again",

       "condition": {

  "statements": [{

     "op": "==",

     "right": "${E:A:operation_type}",

     "left": "INSERT"

  }],

  "condition_type": "AND",

  "eval":

 "${XC:COPY:{L:network}:{E:values{network}}}${XC:NETWORKTORANGE:{L:network}:{L:range

 }}",

    "next": "insert network"

         }

    }

Note

The "check operation type again" step determines the operation type. If the operation is "INSERT", the network of the inserted fixed address is copied to the L:network variable (${XC:COPY:{L:network}:{E:values{network}}}) and transformed to a Rapid7 range to the L:range variable (${XC:NETWORKTORANGE:{L:network}:{L:range}}). After the range is stored, the template execution jumps to the "insert network" step.


Action Template: Delete an IP Address

{

         "operation": "CONDITION",

         "name": "remove ip",

         "condition": {

     "statements": [{

        "op": "==",

        "right": "${E:A:event_type}",

        "left": "FIXED_ADDRESS_IPV4"

     }],

     "condition_type": "AND",

     "eval":

 "${XC:COPY:{L:ip}:{E:values{ipv4addr}}}${XC:REMOVEIP:{L:ip}:{L:Site{Hosts}}}",

    "else_eval":

 "${XC:COPY:{L:ip}:{E:values{ipv6addr}}}${XC:REMOVEIP:{L:ip}:{L:Site{Hosts}}}"

      }

  },

  {

     "operation": "CONDITION",

     "name": "jump to send",

     "condition": {

  "statements": [{

    "op": "==",

    "right": "",

    "left": ""

  }],

  "condition_type": "AND",

  "next": "send SiteSaveRequest"

     }

   }

NOTES:

  • If the operation is not "INSERT" (i.e. "DELETE"), the "remove ip" step is executed. The step determines the type of fixed address. The corresponding address ({E:values{ipv4addr}} or {E:values{ipv6addr}}) is copied to the L:ip variable, and then the L:ip address is removed from the list of hosts in the site (${XC:REMOVEIP:{L:ip}:{L:Site{Hosts}}}).
  • The step "jump to send" skips the "inserting" step and jumps directly to the "send SiteSaveRequest" step.

Action Template: Add an IP Range

{

         "operation": "VARIABLEOP",

         "name": "insert network",

         "variable_ops": [{

     "operation": "PUSH",

     "type": "COMPOSITE",

     "source": "L:range",

     "destination": "L:Site{Site}{Hosts}"

         }]

      }

The step "insert network" pushes the L:range to the list of site’s "Hosts".

Action Template: Saving New Configuration

{

         "parse": "XMLA",

         "operation": "POST",

         "name": "send SiteSaveRequest",

         "body_list": [

     "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",

     "<SiteSaveRequest session-id=\"${S::SESSID}\">",

     "${L:x:Site}",

     "</SiteSaveRequest>"

         ]

      },

      {

        "operation": "CONDITION",

        "name": "send SiteSaveRequest (error check)",

        "condition": {

     "statements": [

      {

        "op": "!=",

        "right": "${P:A:PARSE[[name]]}",

        "left": "SiteSaveResponse"

      },

      {

        "op": "!=",

        "right": "1",

        "left": "${P:A:PARSE{{success}}}"

      }

],

"condition_type": "OR",

"error": true

    }

 }

Note

The "send SiteSaveRequest" and "send SiteSaveRequest (error check)" steps save new site configuration to the Rapid7 server.


Action Template: Add Extensible Attributes Using WAPI

{

           "operation": "CONDITION",

           "name": "check operation type once more",

           "condition": {

       "statements": [{

         "op": "!=",

         "right": "${E:A:operation_type}",

         "left": "INSERT"

     }],

     "condition_type": "AND",

     "stop": true

        }

    },

    {

       "operation": "PUT",

       "name": "add an attribute with WAPI",

       "transport": {"path": "${E:A:values{_ref}}"},

       "wapi": "v2.6",

       "body": "{\"extattrs+\": {\"r7_added\": {\"value\": \"Added to the Rapid7 ${UT:A:TIME}\"}}}"

           }

NOTES:

  • The "check operation type once more" step determines the operation type. If the operation is not "INSERT" (i.e. "DELETE"), the template execution stops.
  • For the "INSERT" operation, the last step "add an attribute with WAPI" is executed. This step adds an extensible attribute "r7_added" to the fixed address through RESTful API. The value of the attribute has the current timestamp (${UT:A:TIME}).

Action Template: Add a Host Record

The following sample template, if assigned to a DHCP network notification rule, will insert a host record for any added network that matches the rule, with a hostname and domain name set by extensible attributes in the network. Detailed explanations about this sample are included in Action Template with Comments: Add a Host Record.

{

         "version": "1.0",

         "name": "Insert host record",

         "comment": "Will automatically insert a host record for new network insertions, assumes the network has a 'Zone' extensible attribute, optionally a 'Hostname' extensible attribute as well",

         "type": "REST_EVENT",

         "event_type": [

             "NETWORK_IPV4"

        ],

        "action_type": "Insert a host record",

        "vendor_identifier": "WAPI 2.3",

        "transport": {

           "content_type": "application/json",

       },

       "steps":

       [

          {

              "name": "stop if it is not a network insert",

              "operation": "CONDITION",

              "condition": {

                 "condition_type": "AND",

                 "statements": [

                    {

                        "left": "${E:A:operation_type}",

                        "op": "!=",

                        "right": "INSERT"

                    }

               ],

               "stop": true

           }

        },

        {

            "name": "stop if we don't have the zone EA set, else save it",

            "operation": "CONDITION",

            "condition": {

                 "condition_type": "AND",

                 "statements": [

                    {

                         "left": "${E:A:values{extattrs}{Zone}{value}}",

                         "op": "==",

                         "right": ""

                     }

                ],

                "stop": true,

                "else_eval": "${XC:COPY:{L:ZONE}:{E:values{extattrs}{Zone}{value}}}"

            }

        },

        {

            "name": "get the hostname or use a default value",

            "operation": "CONDITION",

            "condition": {

               "condition_type": "AND",

               "statements": [

                   {

                       "left": "${E:A:values{extattrs}{Hostname}{value}}",

                       "op": "!=",

                       "right": ""

                   }

               ],

               "eval":

   "${XC:COPY:{L:HOSTNAME}:{E:values{extattrs}{Hostname}{value}}}",

               "else_eval": "${XC:ASSIGN:{L:HOSTNAME}:{S:defaulthostname}}"

            }

       },

       {

             "name": "insert the host record with the next available IP",

             "operation": "POST",

             "transport": {

                  "path": "record:host"

            },

            "body_list": [

                "{",

                "\"name\": \"${L:A:HOSTNAME}.${L:A:ZONE}\",",

                "\"ipv4addrs\": [{\"ipv4addr\":

   \"func:nextavailableip:${E:A:values{network}}\"}],",

                "\"comment\": \"Inserted via outbound\"",

                "}"

             ]

         }

     ]

}

Action Template with Comments: Add a Host Record

The comments (labeled as Note:) embedded in the sample template explain the operation for each section of the template. Note that the execution of this sample template will cause a single POST request to be sent with the following body for an insertion of a 10.0.0.0/24 network with the Zone extensible attribute set to test.com and the Hostname extensible attribute set to name:

{"name": "name.test.com","ipv4addrs": [{"ipv4addr":
"func:nextavailableip:10.0.0.0/24"}],"comment": "Inserted via a template"}


Note: The preamble of the template specifies the version, version, name and other relevant fields.


{
       "version": "1.0",
       "name": "Insert host record",

       "comment": "Will automatically insert a host record for new network insertions,assumes the network has a 'Zone' extensible attribute, optionally a 'Hostname' extensible attribute as well",

       "type": "REST_EVENT",


Note: The event_type field specifies that this template is used for IPv4 network events only.


"event_type": [

          "NETWORK_IPV4"

       ],


Note: The action_type and vendor_identifier fields describe the template type and the vendor type.


  "action_type": "Insert a host record",

  "vendor_identifier": "WAPI 2.3",


Note: The following specifies that the template is going to send JSON to the server.


  "transport": {

       "content_type": "application/json",

  },


Note: The following are steps that will be executed sequentially.


  "steps":

  [


Note: The first step will stop the execution, without an error, if the network event received is not an insertion – it could be a modify, for example.


{

     "name": "stop if it is not a network insert",

     "operation": "CONDITION",

     "condition": {


Note: You can specify only one statement: either AND or OR would work.


"condition_type": "AND",

"statements": [


Note: The match is to check if operation_type in the event is different from INSERT. It is a good practice to put the event variable on the left side so if it is not present in the event, the template would not fail.


{

"left": "${E:A:operation_type}",

"op": "!=",

"right": "INSERT"

}

],


Note: The directive that stops the execution if the condition matches.


"stop": true

}

},


Note: The second step will stop the execution if the inserted network does not have the Zone extensible attribute configured. If it has the extensible attribute, it will be put in a temporary local variable for easier access later on.


{

"name": "stop if we don't have the zone EA set, else save it",

"operation": "CONDITION",

"condition": {


Note: Similar to the previous section, we have only one statement, so either AND or OR would work. The condition ensures that the Zone extensible attribute is set to a value.


"condition_type": "AND",

"statements": [

{


Note: As previously mentioned, non-existent variable access in the left side of a condition will not cause an error, but instead return an empty value.


"left": "${E:A:values{extattrs}{Zone}{value}}",

"op": "==",

"right": ""

}

],


Note: If the extensible attribute is empty or nonexistent, the operation should stop here.


"stop": true,


Note: Otherwise, it will copy the zone value to the local ZONE variable.


"else_eval": "${XC:COPY:{L:ZONE}:{E:values{extattrs}{Zone}{value}}}"

}

},


Note: This step is similar to the zone step above. However, if the host name is not set, it will put a default host name in a local variable to provide the default.


{

"name": "get the hostname or use a default value",

"operation": "CONDITION",

"condition": {

"condition_type": "AND",

"statements": [

{

"left": "${E:A:values{extattrs}{Hostname}{value}}",

"op": "!=",

"right": ""

}

],


Note: This is executed if the extensible attribute is present, by copying its value to HOSTNAME.


"eval": "${XC:COPY:{L:HOSTNAME}:{E:values{extattrs}{Hostname}{value}}}",


Note: Otherwise, the following is executed if the extensible attribute is empty or not present, by assigning the defaulthostname string instead.


"else_eval": "${XC:ASSIGN:{L:HOSTNAME}:{S:defaulthostname}}"

}

},


Note: This step will finally contact the endpoint and in this case insert the host.


{
"name": "insert the host record with the next available IP",


Note: This defines the HTTP operation to use.


"operation": "POST",


Note: The endpoint is configured starting with https://master_ip/.... The endpoint template overrides the path with /wapi/v2.3/ so by default all template requests would go to https://master_ip/wapi/v2.3/. In this step, we want to insert a host, so record:host is appended to the URI above (no override is set here) to arrive to the valid RESTful URI https://master_ip/wapi/v2.3/record:host.


"transport": {

"path": "record:host"

},


Note: This is the text that will be sent to the server in the POST’s BODY.


"body_list": [

"{",


Note: This references the local variables that were previously assigned.


"\"name\": \"${L:A:HOSTNAME}.${L:A:ZONE}\",",


Note: This option signifies that the RESTful API will use the next available IP in the network as the address for this host.


"\"ipv4addrs\": [{\"ipv4addr\":

\"func:nextavailableip:${E:A:values{network}}\"}],",


Note: This is the comment stating that the action is done through the RESTful API template.


"\"comment\": \"Inserted via outbound\"",
"}"

]

     }

   ]

}

Endpoint reference

UT::ENDPOINT contains WAPI reference to the current endpoint object that can be used by WAPI steps. You can make changes to the endpoint configuration during a template execution.

Example:

{

"version": "4.0",

...

"steps": [

...

{

"operation": "PUT",

"name": "update_endpoint",

"transport": {"path": "${UT::ENDPOINT}"},

"wapi": "v2.7",

"body": "{\"comment\": \"outbound\"}"

},

...

],

...

}

Active Template Functions

Example:

{

"version": "4.0",

"name": "example",

"event_type": ["RPZ"],

"type": "REST_EVENT",

"functions": {

"functions": {

"is_ipv4_address": {

"steps": [

{

"operation": "CONDITION",

"condition": {

"statements": [

{

"left": "${L:A:address}",

"op": "!~",

"right": ":"

}

],

"condition_type": "AND",

"eval": "${XC:ASSIGN:{L:result}:{B:true}}",

"else_eval": "${XC:ASSIGN:{L:result}:{B:false}}"

}

}

]

}

},

"steps": [

...

{

"operation": "FUNCTION",

"function_name": "is_ipv4_address",

"body": "${XC:ASSIGN:{L:address}:{S:10.0.0.1}}"

},

...

]

}