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
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"
}
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
Following is a sample action template for DXL endpoint:
{
"vendor_identifier": "DXL",
"version": "3.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"
}
]
}
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}\"}}}"
  }
 ]
}
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 theL: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 theL: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 theL:ip
variable, and then theL: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\"",
"}"
]
    }
  ]
}