XML Parsing in DataScripts

Overview

Starting with Avi Vantage 21.1.1, the capability to parse XML payloads in DataScripts is introduced. Using this capability, you can get insights into your XML payload or take some action based on the parameters in the XML body.

Avi has added an XML parser that is used to process XML.

The XML parsers requires a wrapper. For using this, the Avi XML parser is used at the beginning of the DataScript:


local avixmlparser = require("avixmlparser")
success, document = avixmlparser.parse(body)​
success, contents = avixmlparser.search(document, xpath)​

The avixmlparser has two functions:

  1. Parse
  2. Search
Function Parameter Returns
Parse Request Body Returns two values:
1. The first value shows if the parse is succussful.
2. The second value is the parsed information
If the parse fails, then the second value is the error information.
Search 1. Document object
2. XPath: You can use XPath expressions to extract relevant attributes like password and username from the XML payloads
Returns two values:
1. The first value shows if the parse is successful.
2. The second value displays the search results

Use Cases

  • Horizon – Load balancing UAG servers:


XML is the control protocol for Horizon. There is a lot of information in the payload that can be of interest to take any custom actions like Username, client type ( Horizon client: Windows/ MAC, etc) can be useful.

Note: If you are using DataScript for Horizon related use cases, ensure that the request body buffering is disabled for /ice URLs. Otherwise, the tunnel connection would not establish.

To disable the body buffering selectively in the DataScript,add the following under the Request event,


HTTP_REQ event:
local function starts_with(str, start)
   return str:sub(1, #start) == start
end

if starts_with(avi.http.get_uri(), "/ice/tunnel") then
  avi.http.set_request_body_buffer_size(0)
end

HTTP_REQ_DATA event:
local avixmlparser = require("avixmlparser")
local body = avi.http.get_req_body(2048)
local xpath = "/broker/do-submit-authentication/screen[name='windows-password']/params/param[name='username']/values/value"
local succ_parse, document = avixmlparser.parse(body)
if succ_parse then
    local succ_search, contents = avixmlparser.search(document, xpath)
    if succ_search then
        for i, v in ipairs(contents) do
            if v ~= nil then
              avi.vs.log(v) end
        end
    else avi.vs.log(contents)
    end
else avi.vs.log(document)
end

Horizon

Here, we first get the request body.
Then the request body is parsed.
If the parse is successful, xpath is used to search the body.

If the search is successful, the search results are displayed.
we first get the request body. Then we parse the request body. If the parse is successful, we use xpath to search the body and if the search is successful, then we get the search results.
If the search fails, then the error information can be logged.

The logs are displayed as shown below:

Logs

Logs

  • The most common example is to print username in Avi app logs.

The DataScript to extract Username from an XML API Request is shown below:

Logs


local avixmlparser = require("avixmlparser")
local body = avi.http.get_req_body(2048)
local xpath = "/broker/do-submit-authentication/screen[name='windows-password']/params/param[name='username']/values/value"
local succ_parse, document = avixmlparser.parse(body)
if succ_parse then
   local succ_search, contents = avixmlparser.search(document, xpath)
   if succ_search then
       for i, v in ipairs(contents) do
           if v ~= nil then
             avi.http.set_userid(v) end
       end
   else avi.vs.log(contents)
   end
else avi.vs.log(document)
end
  • Add a string group with some MAC addresses in it. Write a DataScript referring to that string group.
    Only the user whose MAC address is present should be authenticated. The other connections should be closed.

Referring to the sample XML above, the xpath for MAC address is

 
  local xpath = “/broker/do-submit-authentication/environment-information/info[@name=‘MAC_Address’]”