A Gateway workflow is a Python package that extends the Flask web application that the Gateway platform runs. It adds functions to handle HTTP requests and produce responses. Usually, it interacts with BlueCat Address Manager to perform the tasks a user wants. The BlueCat Gateway platform provides to the workflow a client to access the Gateway API. It is already configured with the necessary authentication token for user sessions in Address Manager. The platform creates the user session in Address Manager upon the user login in Gateway. The workflow itself should not have to deal with logging in and logging out of Address Manager.
The following example defines an endpoint that takes in a BlueCat Address Manager configuration’s name and returns an HTTP response with a JSON-formatted body that contains the ID, name, and IP address of the server objects in that configuration.
# file: example1.py
# Import tools from the web framework.
from flask import g, jsonify
# Import tools from the platform.
from bluecat import route
from bluecat.gateway.decorators import api_exc_handler, require_user
from main_app import app
def get_server_address(interfaces: list[dict]) -> str:
"""Determine the address of the server from the list of interfaces it has."""
for interface in interfaces:
if interface["type"] == "NetworkInterface":
return interface["managementAddress"]
return None
# Define a function to handle HTTP requests (a Flask view function).
@route(app, "/example/servers/<string:config_name>", methods=["GET"])
# If the function raises an exception, respond with a standardized error body.
@api_exc_handler
# If the request is not authenticated, raise an exception.
@require_user
def get_servers(config_name):
# Get the client to BAM RESTful v2 API.
client = g.user.bam_api.v2
# Make a call to BAM RESTful v2 API.
response = client.http_get(
"/servers",
params={
"filter": f"configuration.name:'{config_name}'",
"fields": (
"id,name,_embedded.interfaces.type,"
"_embedded.interfaces.managementAddress,embed(interfaces)"
),
},
headers={
"Accept": "application/json"
}
)
# The response data contains list and a count.
servers = response["data"]
# Restructure the data from BAM into what the response should include.
result = [
{
"name": server["name"],
"address": get_server_address(server["_embedded"]["interfaces"]),
}
for server in servers
]
# Respond with server names and addresses formatted as JSON response.
return jsonify(result)
The following file is also needed to add the example to the set of workflows included when Gateway is initialized.
# file: __init__.py
type = "api"
sub_pages = [
{
"name": "example1"
}
]
Place both files can in a folder named example1
in the
workflows
folder in the custom workspace.
/bluecat_gateway
to a folder on the host. That folder becomes
a custom workspace. A custom workspace lets you safely build workflows and changes
without accidentally modifying core Gateway files.How this works
The function
get_servers
will be called when an HTTP request is made to
/example/servers/<configuration_name>
. The Address Manager configuration’s name is passed as part of the URL path.
route
registers the handler in the application. Note that to
avoid collisions between view function names by different workflows, you should use
the route
provided by the platform instead of the one from the
application itself. Also, the first part of the path should be the name of the
workflow.
The client to the Address Manager RESTful v2 API is obtained
from g.user.bam_api.v2
. This is an instance of class
bluecat_libraries.address_manager.apiv2.Client
. (For more
details about this class, see Client class.)
The client’s authentication is already set for the Address Manager user
session of the user making the request to Gateway. That allows the
direct use of method http_get
to make an HTTP GET
request to Address Manager's RESTful API. The parameters are similar to the
ones from Python package requests
, which is used to make the actual
call.
The HTTP request would look something like this:
GET https://<Address Manager IP Address>/api/v2/servers?filters=configuration.name:{CONFGIRUATION_NAME}&fields=id,name,_embedded.interfaces.type,_embedded.interfaces.managementAddress,embed(interfaces) HTTP/1.1
Authorization: <Authentication scheme and token>
Accept: application/json
This request does the following:
-
It requests server data from the
servers
resource. -
It requests only servers in a configuration with a certain name.
-
It requests only fields that are necessary. The interface is embedded so that the address can be resolved from the retrieved fields.
-
It requests that the format of the returned data be in JSON, without unnecessary extra HAL data.
http://<Address Manager IP Address>/api/docs
For more details on the Address Manager RESTful v2 API itself, see the Address Manager RESTful v2 API Guide.