After the initial creation of a new workflow, you can start editing the workflow's
_page.py
file and other scripts to implement the desired
functionality.
<bluecat_gateway>
folder:<bluecat_gateway>/workflows/<category_name>/<workflow_name>
Where:
<bluecat_gateway>
is the BlueCat Gateway folder.<category_name>
is the nested Workflow Category (and optional subcategory) that you specified when creating the workflow in Gateway.-
<workflow_name>
is the Workflow Name that you specified when creating the workflow in Gateway.
For example, if the workflow name was example_workflow
and you entered a
category of Examples
, the files would be stored under
<bluecat_gateway>/workflows/Examples/example_workflow
.
While Gateway fills in each file with starter code, you can replace it with your own implementation. Once done, it can be called by any suitable REST client using Basic authentication.
The workflow script's app.route header
When implementing a workflow script, make sure that Flask's
app.route()
decorator is replaced with the
@route()
decorator. The @route()
decorator
enforces separation of namespaces between different workflows. If you don't use
@route()
, it is possible for function and endpoint name
collisions to occur, especially when multiple people develop workflows at the same
time.
Sample UI workflow scripts
# The workflow name must be the first part of any endpoints defined in this file.
# Doing otherwise risks collisions with other endpoint names, which can cause
# unexpected results and behavior.
@route(app, '/example_workflow/example_workflow_endpoint')
@util.workflow_permission_required('example_workflow_page')
@util.exception_catcher
@util.ui_secure_endpoint
def example_workflow_example_workflow_page():
form = GenericFormTemplate()
# Remove this line if your workflow does not need to select a configuration
form.configuration.choices = util.get_configurations(default_val=True)
return render_template(
'example_workflow_page.html',
form=form,
text=util.get_text(module_path(), config.language),
)
@route(app, '/example_workflow/form', methods=['POST'])
@util.workflow_permission_required('example_workflow_page')
@util.exception_catcher
@util.ui_secure_endpoint
def example_workflow_example_workflow_page_form():
form = GenericFormTemplate()
# Remove this line if your workflow does not need to select a configuration
form.configuration.choices = util.get_configurations(default_val=True)
if not form.validate_on_submit():
g.user.logger.info('Form data was not valid.')
return render_template(
'example_workflow_page.html',
form=form,
text=util.get_text(module_path(), config.language),
)
print(form.configuration.data)
print(form.email.data)
print(form.password.data)
print(form.mac_address.data)
print(form.ip_address.data)
print(form.url.data)
print(form.file.data)
print(form.boolean_checked.data)
print(form.boolean_unchecked.data)
print(form.date_time.data)
print(form.submit.data)
# Put form processing logic here
g.user.logger.info('SUCCESS')
flash('success', 'succeed')
return redirect(url_for('example_workflowexample_workflow_example_workflow_page'))
g.user.get_options()
. These
calls are obsolete and can cause unexpected behavior or failures in workflow
execution. If you used example scripts as a template for custom workflows, we
strongly recommend that you remove this line from your workflow scripts.Sample API workflow script
Since the new workflow was created as a REST API workflow, it will not show up on the
Available Actions menu. As with UI workflows, Gateway creates new files for your new API in the
<bluecat_gateway>/workflows/<category_name>/<workflow_name>
folder.
# Copyright 2020 BlueCat Networks. All rights reserved.
from flask import request, g, abort, jsonify
from bluecat import route, util
from main_app import app
@route(app, '/example_rest_workflow/example_rest_workflow_endpoint', methods=['GET', 'PUT', 'POST'])
@util.rest_workflow_permission_required('example_rest_workflow_page')
@util.rest_exception_catcher
def example_rest_workflow_example_rest_workflow_page():
# Put endpoint logic here
g.user.logger.info('SUCCESS')
return jsonify({"method": request.method})
Again, you can place your own implementation in this file. Once done, it can be called by any suitable REST client using Basic authentication.