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:
- Parse
- 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
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:
- 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:
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’]”