How to enable and consume Gizmo APIs

CLOUD ON-PREMISES

Applies to Gizmo 2.0

This article describes how to enable and consume Gizmo APIs.

Requirement
Ensure Gizmo product is installed.

Instructions

Follow this procedure to configure a reverse proxy using IIS.

Required Components Installation and Configuration

  • Open IIS.

  • Click on the server name.

  • Click on the link at the right Get New Web Platfom Components to install the Web Platform Installer.

  • In the Applications menu, search for ‘arr’ and click the Add button on the right for ‘Application Request Routing 3.0’.

  • Search for ‘URL rewrite’ to verify if it’s already installed. If not, add it to the items to install and then click on install.

Then, the proxy service should be activated by modifying the ‘Application Request Routing Cache' and checking the enable box inside the option ‘Server Proxy Settings’.
This will allow the reverse proxy type redirection.

Reverse Proxy Website Configuration

To redirect successfully the requests to each API, the creation and configuration of a new website has to be done.

  • Right-click on the ‘Sites’ folder and then in ‘add website’.

The website can be different, but in this case, it will be gsxapi as the goal is to centralize the APIs.

For the physical path, it’s enough to create and select an empty folder as the APIs are already configured in Gizmo in the default port 80. This empty site will be used just as a centralized endpoint to reach them.

  • Inside the path C:/inetpub, create the folder according to the name of the website and select it as the root directory.

The port used in this case will be 8080 but it could be another port different from 80 or 443. The hostname should be empty to allow the access from the same network using the name of the server.

After this configuration, the following PowerShell command has to be executed in Administrator mode, in order to allow the access to the server using the port of the website (in this case port 8080 but it could be any other port).

New-NetFirewallRule -DisplayName "GSX - Allow Port 8080 for API" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8080

Rewrite URL Rules Configuration

The following is the list of all the microservices and their corresponding API routes to be created:

Microservice Name

Internal URL

API Routes

Gsx.Microservice.ScanConfiguration

http://localhost:60000

  • ​/api​/v1​/health

  • ​/api​/v1​/admin​/machineid

  • ​/api​/v1​/credential

  • ​/api​/v1​/credential​/{credentialId}

  • ​/api​/v1​/host

  • ​/api​/v1​/host​/{hostId}

  • ​/api​/v1​/license

  • ​/api​/v1​/license​/templates

  • ​/api​/v1​/prerequisite​/{prerequisiteName}

  • ​/api​/v1​/prerequisite

  • ​/api​/v1​/robotapp

  • ​/api​/v1​/robotapp​/{robotAppGuid}

  • ​/api​/v1​/robotapp​/robotManager​/{robotManagerGuid}

  • ​/api​/v1​/robotapp​/scanConfig​/{scanConfigGuid}

  • ​/api​/v1​/robotmanager

  • ​/api​/v1​/robotmanager​/{robotManagerGuid}

  • ​/api​/v1​/scanconfiguration

  • ​/api​/v1​/scanconfiguration​/{scanConfigurationGuid}

  • ​/api​/v1​/scanconfiguration​/template​/{templateGuid}

  • ​/api​/v1​/tag​/keys

  • ​/api​/v1​/tag​/keys​/{tagKeyId}

  • ​/api​/v1​/template

  • ​/api​/v1​/template​/{templateGuid}

Gsx.Microservice.DataTier

http://localhost:60001

  • /api/v1/health

  • /api/v1/propertydefinitions

  • /api/v1/propertydefinitions/{propertyid}

  • /api/v1/scanresults

  • /api/v1/scanresults/robot/{robotguid}

  • /api/v1/scanresults/robotmanager/{robotmanagerguid}

Gsx.Microservice.StatusCalculation

http://localhost:60003

  • ​/api​/v1​/health

  • ​/api​/v1​/statuses​/descriptions​/composed

  • ​/api​/v1​/statuses​/result​/aggregated​/last

Gsx.Microservice.Alert

http://localhost:60004

  • /api/v1/health

  • /api/v1/alerts

  • /api/v1/alerts/{guid}

  • /api/v1/alerts/robothealth

  • /api/v1/alerts/status

  • /api/v1/alerts/{alertguid}/alertroutes

  • /api/v1/outputroutes

  • /api/v1/outputroutes/{guid}

The rewrite rules have to be configured for each microservice and its API routes, the URL rewrite rules for the microservice Gsx.Microservice.DataTier will be configured as an example:

Internal URL

API routes

http://localhost:60001

  • /api/v1/health

  • /api/v1/propertydefinitions

  • /api/v1/propertydefinitions/{propertyid}

  • /api/v1/scanresults

  • /api/v1/scanresults/robot/{robotguid}

  • /api/v1/scanresults/robotmanager/{robotmanagerguid}

The following are the routes for each one, an inbound rule will be created as the others are contained inside them:

  • /api/v1/health

  • /api/v1/propertydefinitions

  • /api/v1/scanresults

An outbound rule will be created to provide communication through the port 60001 and provide a response from the API routes of this microservice.

The objective is to access these API routes by using the URL: http://serverFQDN:8080/<APIroute>

Follow this procedure to achieve this configuration.

Inbound Rules

The inbound rules are created by getting inside the URL Rewrite module, clicking in ‘add rule(s)’ button and selecting inbound blank rule as shown below:

The following are the configuration elements needed in the inbound rule:

The inbound rule for the API route /api/v1/health should look like this. If everything is ok, click on Apply to create the rule.

The Inbound rules for the routes /api/v1/propertydefinitions and /api/v1/scanresults should look like this:

Outbound Rule

To configure a new outbound rule, follow the same steps as the inbound but select the option ‘blank outbound rule’.

The following are the configuration elements needed in the outbound rule:

  • name: according to the API name associated to the port number. (example: Gsx.Microservice.DataTier)

  • precondition: the following configuration should be done for the precondition.

Procedure

From the drop-down list, check if the precondition ResponseIsHTML already exists and select it.
If not, follow these steps:

  • Select the option <Create New Precondition…> as shown below:

  • In the creation window of new precondition, put the name ‘ResponseisHTML’ and click the ‘Add’ button.

  • In Condition Input enter the value {RESPONSE_CONTENT_TYPE} and in the pattern, put the ‘^text/html’ to match the response content type.

  • Click the OK button.

Once this precondition is created, it will be available to be selected for the other outbound rules of the other microservices.

Go back to the Outbound Rule creation page:

  • Matching Scope: Response

  • Match the content within: A, Form, Img

  • Content: Matches Pattern Using: Regular Expressions

  • Pattern: It has the structure: ^http(s)?://localhost:<APIportNumber>(.*) For example: ^http(s)?://localhost:60001(.*)

  • Rewrite URL: Set the URL http{R:1}://localhost{R:2}

The outbound rule configured looks like this:

  • If everything is ok, click Apply to create it.

  • At the end you will have the following rules created for this microservice’s API:

This procedure has to be done for the other microservice’s API routes in order to access them.

Windows Authentication Configuration

To activate the windows authentication for the APIs, the following steps have to be followed:

  • Open the server manager and click on ‘Add Roles and Features’, then check the feature ‘Windows Authentication’.

  • After the installation, go to the website for the reverse proxy and open the ‘authentication’ feature.

  • Disable the ‘Anonymous Authentication’ option and activate the 'Windows Authentication'.

And the service is configured and running, every request will be ask for authentication.

Consume the APIs example

The objective of this section is to show how to consume the APIs and retrieve a status and a statistic from a specific configuration.

Requirements

  • Scan Results API must be available (api/v1/scanresults)

  • Status API must be available (api/v1/statuses/result/aggregated/last)

  • One or more Robots deployed

Step by step code example

Retrieve the AppGuid

We need to retrieve the AppGuid from the robot we want to get the status and one statistic.

  • Open Gizmo Web UI URL from any browser (e.g http(s)://<machine_fqdn>)

  • Click on the Robots Management page.

  • Hover the configuration you want to get the status and statistics from, then right-click to copy its AppGuid.

  • Paste the AppGuid in a notepad as we will be using it in PowerShell in the next steps.

  • From a different machine than the one where the Gizmo product is installed, you have to open a PowerShell console (no administration rights are required here).

  • For the status code values we need to execute the following commands.

Declare and set the following variables:

# The machine FQDN where Gizmo product is installed
$MachineFqdn = 'example.com'

# The port you chose to use for the gsxapi site
$Port = 8080

# The GUID from the scan configuration deployed
$AppGuid = 'guid-from-your-conf-example'

To retrieve one specific value from the scan results from the last hour only, we will have to declare and set the following variables:

# The property ID you want to get the value from
# in this case, it will be the status code from a deployed URL configuration
$PropertyId = 59

# The start date is the current date and time formatted as the Round-trip date/time pattern
$ScanResultsStartDate = (get-date).ToString('o')

# The end date is the current date and time minus 1 hour
$ScanResultsEndDate = (get-date).AddHours(-1).ToString('o')

# In order to generate the URL we need to get the statistic from the scan results
# we have to first create the parameters that will be used in the request
# that will use the range of dates defined in the start and end date
$Parameters = "start=$($ScanResultsStartDate)&end=$($ScanResultsEndDate)"

# The parameters have to be encoded in order to be valid when using the API
$EncodedParameters = [System.Web.HttpUtility]::UrlEncode("$Parameters")

# Now we can generate the URL by adding the machine FQDN, the Port, the api
# and the encoded parameters
$Url = "http://$($MachineFqdn):$($Port)/api/v1/scanresults?$($EncodedParameters)"

From the URL generated, we can now target the API with the Invoke-RestMethod PowerShell command:

# This command will get all the scan results from the past hour as a JSON string
$Response = Invoke-RestMethod -Uri "$Url"

# We now convert the string to a PowerShell object
$ResponseAsObject = $Response | ConvertFrom-Json

# We now filter the results by AppGuid to only retrieve the one we're interested in
$ResponseFiltered = $ResponseAsObject | Where-Object { $_.AppGuid -eq $AppGuid }

Once the scan results are filtered by AppGuid, we can format the results from the PropertyId 59 (http status code) to show the ScanDate, the AppGuid and the Value.

# Declaring the variable that will print the values from
$Output = @()

# Filling the $output variable with the Scan result date, appguid, and status code value
foreach ($ScanResult in $ResponseFiltered) {
    $Object = New-Object -TypeName Psobject
    $Object | Add-Member -MemberType NoteProperty -Name 'ScanDate' -Value ($ScanResult.ScanDate)
    $Object | Add-Member -MemberType NoteProperty -Name 'AppGuid' -Value ($ScanResult.AppGuid)
    $Object | Add-Member -MemberType NoteProperty -Name 'Value' -Value ($ScanResult.ScanResultProperties | where PropertyId -eq $PropertyId | Select-Object -ExpandProperty Value)
    $Output += $Object
}

# Printing the output variable
$Output


ScanDate                          AppGuid                              Value
--------                          -------                              -----
2020-09-01T18:14:00.7406288+02:00 0e121f62-d9e3-45ba-91b5-f7f60a83115d   200
2020-09-01T18:19:00.7190875+02:00 0e121f62-d9e3-45ba-91b5-f7f60a83115d   200
2020-09-01T18:24:00.7319177+02:00 0e121f62-d9e3-45ba-91b5-f7f60a83115d   200
2020-09-01T18:29:00.7136474+02:00 0e121f62-d9e3-45ba-91b5-f7f60a83115d   200
2020-09-01T18:34:00.7358304+02:00 0e121f62-d9e3-45ba-91b5-f7f60a83115d   200
2020-09-01T18:39:00.7117602+02:00 0e121f62-d9e3-45ba-91b5-f7f60a83115d   200
2020-09-01T18:44:00.7132164+02:00 0e121f62-d9e3-45ba-91b5-f7f60a83115d   200

For the URL deployed configuration Status, we need to execute the following commands:

# The URL used to get the last aggregated status
$Url = "http://$($MachineFqdn):$($Port)/api/v1/statuses/result/aggregated/last"

# This command will get all the last aggregated statuses
$ResponseAsObject = Invoke-RestMethod -Uri "$Url"

# We now filter the results by AppGuid to only retrieve the last status we're interested in
$ResponseFiltered = $ResponseAsObject | Where-Object { $_.AppGuid -eq $AppGuid }

# Declaring the variable that will print the values from
$Output = @()

# Filling the $output variable with the last status date UTC, appguid, display status and messages
foreach ($Status in $ResponseFiltered) {
    $Object = New-Object -TypeName Psobject
    $Object | Add-Member -MemberType NoteProperty -Name 'LastStatusDateUTC' -Value $Status.LastStatusDateUTC
    $Object | Add-Member -MemberType NoteProperty -Name 'AppGuid' -Value $Status.AppGuid
    $Object | Add-Member -MemberType NoteProperty -Name 'DisplayStatus' -Value $Status.DisplayStatus
    $Object | Add-Member -MemberType NoteProperty -Name 'Messages' -Value ($Status.Messages -join "`n")
    $Output += $Object
}

# Printing the output variable
$Output

LastStatusDateUTC           AppGuid                              DisplayStatus Messages
-----------------           -------                              ------------- --------
2020-09-02T12:49:00.7168794 0e121f62-d9e3-45ba-91b5-f7f60a83115d             1 []

Full code example

$MachineFqdn = 'example.com'
$Port = 8080
$AppGuid = '0e121f62-d9e3-45ba-91b5-f7f60a83115d'

#region Scan Results
$PropertyId = 59
$ScanResultsStartDate = '2020-09-01T19:26:37.2823082+02:00'
$ScanResultsEndDate = '2020-09-01T20:26:37.2823082+02:00'
$Parameters = "start=$($ScanResultsStartDate)&end=$($ScanResultsEndDate)"
$EncodedParameters = [System.Web.HttpUtility]::UrlEncode("$Parameters")
$Url = "http://$($MachineFqdn):$($Port)/api/v1/scanresults?$($EncodedParameters)"

$Response = Invoke-RestMethod -Uri "$Url"
$ResponseAsObject = $Response | ConvertFrom-Json
$ResponseFiltered = $ResponseAsObject | Where-Object { $_.AppGuid -eq $AppGuid }

$Output = @()

foreach ($ScanResult in $ResponseFiltered) {
    $Object = New-Object -TypeName Psobject
    $Object | Add-Member -MemberType NoteProperty -Name 'ScanDate' -Value ($ScanResult.ScanDate)
    $Object | Add-Member -MemberType NoteProperty -Name 'AppGuid' -Value ($ScanResult.AppGuid)
    $Object | Add-Member -MemberType NoteProperty -Name 'Value' -Value ($ScanResult.ScanResultProperties | where PropertyId -eq $PropertyId | Select-Object -ExpandProperty Value)
    $Output += $Object
}

$Output
#endregion Scan Results

#region Statuses
$Url = "http://$($MachineFqdn):$($Port)/api/v1/statuses/result/aggregated/last"

$ResponseAsObject = Invoke-RestMethod -Uri "$Url"
$ResponseFiltered = $ResponseAsObject | Where-Object { $_.AppGuid -eq $AppGuid }

$Output = @()

foreach ($Status in $ResponseFiltered) {
    $Object = New-Object -TypeName Psobject
    $Object | Add-Member -MemberType NoteProperty -Name 'LastStatusDateUTC' -Value $Status.LastStatusDateUTC
    $Object | Add-Member -MemberType NoteProperty -Name 'AppGuid' -Value $Status.AppGuid
    $Object | Add-Member -MemberType NoteProperty -Name 'DisplayStatus' -Value $Status.DisplayStatus
    $Object | Add-Member -MemberType NoteProperty -Name 'Messages' -Value ($Status.Messages -join "`n")
    $Output += $Object
}

$Output
#endregion Statuses