Skip to content

Instantly share code, notes, and snippets.

@cdot65
Created February 19, 2025 20:40
Show Gist options
  • Save cdot65/785011ebe36e076a3860f00910d00f83 to your computer and use it in GitHub Desktop.
Save cdot65/785011ebe36e076a3860f00910d00f83 to your computer and use it in GitHub Desktop.
(function () {
/**
* This script performs a POST request to update an external XML configuration.
* The goal is to insert a new URL as a <member> into an existing <list> for a specified URL category.
*
* Steps:
* 1. Retrieve and log input variables: the website URL, URL category, and request number.
* 2. Build an x-www-form-urlencoded request body:
* - Encode an XPath string that points to the configuration entry for the URL category.
* - Create an XML fragment with the new URL.
* 3. Create a RESTMessageV2 instance:
* - Attempt to use an existing REST message definition for URL category updates.
* - If unavailable, create a new instance manually.
* 4. Set necessary headers (including authentication and content type) and assign the MID Server.
* 5. Execute the POST request, check the HTTP status, and update the record with success or error details.
*/
//==========================================================================
// Step 1: Retrieve and log input variables
//==========================================================================
for (var key in current.variables) {
gs.info("Variable: " + key + " = " + current.variables[key]);
}
// Retrieve and log the website URL
var websiteUrl = current.variables.websiteUrl;
gs.info("DEBUG: websiteUrl raw value: " + websiteUrl + " (type: " + typeof websiteUrl + ")");
websiteUrl = websiteUrl + ""; // Force conversion to a plain string
gs.info("DEBUG: websiteUrl (converted): " + websiteUrl);
// Retrieve and log the URL category
var urlCategory = current.variables.category;
if (!urlCategory) {
gs.error("DEBUG: urlCategory variable is not provided.");
return;
}
gs.info("DEBUG: urlCategory = " + urlCategory);
// Retrieve the request number for logging and commenting purposes
var requestNumber = current.number; // e.g., "REQ0012345"
gs.info("DEBUG: requestNumber = " + requestNumber);
//==========================================================================
// Step 2: Build the x-www-form-urlencoded payload
//==========================================================================
// Construct the XPath string that targets the specific configuration entry by URL category
var xpathStr = "/config/shared/profiles/custom-url-category/entry[@name='" + urlCategory + "']";
var encodedXpath = encodeURIComponent(xpathStr);
gs.info("DEBUG: Encoded XPath: " + encodedXpath);
// Build the XML fragment to insert the new URL into the <list> element
var elementXML = "<list><member>" + websiteUrl + "</member></list><type>URL List</type>";
var encodedElement = encodeURIComponent(elementXML);
gs.info("DEBUG: Encoded Element XML: " + encodedElement);
// Assemble the complete request body for the POST call
var requestBody = "type=config&action=set&xpath=" + encodedXpath + "&element=" + encodedElement;
gs.info("DEBUG: POST request body: " + requestBody);
//==========================================================================
// Step 3: Create a RESTMessageV2 instance for the URL category update
//==========================================================================
var restMessage;
try {
// Attempt to use an existing REST message definition (adjust the name/method as needed)
restMessage = new sn_ws.RESTMessageV2('Palo Alto Networks Panorama', 'URL Category Update');
gs.info("DEBUG: Using existing REST message definition 'URL Category REST' with method 'SetURLCategory'.");
} catch (e) {
gs.info("DEBUG: REST message definition for URL Category not found. Creating a new RESTMessageV2 instance manually.");
restMessage = new sn_ws.RESTMessageV2();
restMessage.setEndpoint("https://panorama.example.io/api");
restMessage.setHttpMethod("POST");
}
// Specify the MID Server for external connectivity
restMessage.setMIDServer('midserver');
// Set required headers for an x-www-form-urlencoded request and API authentication
restMessage.setRequestHeader('X-PAN-KEY', 'your-api-key-goes-here');
restMessage.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// Attach the request body to the REST call
restMessage.setRequestBody(requestBody);
//==========================================================================
// Step 4: Execute the REST call and handle the response
//==========================================================================
gs.info("DEBUG: Initiating REST POST call execution.");
try {
var response = restMessage.execute();
var httpStatus = response.getStatusCode();
var responseBody = response.getBody();
gs.info("DEBUG: REST call executed. HTTP Status: " + httpStatus);
gs.info("DEBUG: REST call response: " + responseBody);
// Check if the HTTP status indicates an error (non-2xx status)
if (httpStatus < 200 || httpStatus >= 300) {
var errorMsg = response.getErrorMessage();
gs.error("DEBUG: REST call returned error status: " + httpStatus + ". Error: " + errorMsg + ". Response: " + responseBody);
// Update the record with error details
var grError = new GlideRecord(current.getTableName());
if (grError.get(current.sys_id)) {
grError.setWorkflow(false); // Prevent re-triggering workflows
grError.work_notes = "REST call error: HTTP " + httpStatus + " - " + errorMsg;
grError.update();
}
} else {
// On success, update the record with the API response details
var grSuccess = new GlideRecord(current.getTableName());
if (grSuccess.get(current.sys_id)) {
grSuccess.setWorkflow(false);
grSuccess.work_notes = "URL category updated successfully. API Response: " + responseBody;
grSuccess.update();
gs.info("DEBUG: Record updated with successful API response.");
} else {
gs.error("DEBUG: Unable to retrieve record for updating API response.");
}
}
} catch (ex) {
gs.error("DEBUG: Exception during REST call execution: " + ex);
var grEx = new GlideRecord(current.getTableName());
if (grEx.get(current.sys_id)) {
grEx.setWorkflow(false);
grEx.work_notes = "Exception during REST call: " + ex;
grEx.update();
}
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment