Creating Custom Usecase Templates

Usecase-1: Add load_module directive.

Note:
The builtin-load-modules-v1-example use case that implements this use case is included in the NGINX Management Suite App Delivery Manager package.

The goal of the use case is to add load_module directive for a module statically to all instance-groups. The simplest way would be to modify the builtin-v1-instance-group.tmpl and add the directive there. But we recommend not modifying the base templates. Here is how this can be done using use case templates.

1. Create the directory under usecases

Create a new directory with the use case name under /etc/nms/modules/adm/templates/usecases called load-modules.

2. Create the use case template

We need to create a use case template that will be invoked from builtin-v1-instance-group.tmpl and from the injection point in the main context. The builtin base template already defines this injection point {{ $input.ExecUseCaseTemplates "main" }}. Create a use case template with the name main-instance-group.tmpl.

3. Add the directive

Inside main-instance-group.tmpl, add the load_module directive.

Usecase-2: Expand the Gateway REST API

Note:
The builtin-gateway-comments-v1-example use case, which is included in the App Delivery Manager package, implements this use case.
The use case’s goal is to Expand the gateway API to allow the addition of comments to Gateway server blocks. The comments can be added in two ways.

  • Comments specified in top level customExtensions apply to all server blocks generated by the URIs.
  • Comments specified in uri level customExtension apply to only the server block for that URI.

1. Create the directory under use cases

Create a new directory with the use case name under /etc/nms/modules/adm/templates/usecases called gateway-comments-example.

2. Create the use case template

We need to create a use case template that will be invoked from a Gateway base template and from the injection point in the server block context. The builtin base template already defines this injection point {{ $input.ExecUseCaseTemplates "server" $serverIndex}}. To hook in to this injection point, create a template with name server-gateway.tmpl.

Template can access the template input and data inside it as shown below. The example show how to

  • Get Gateway template input.
  • Get the index of the server block being rendered and the server block details.
  • Get the top level customExtension.
  • Get the URI/Server level customExtension.
{{$input := .}}
{{$gwData := .Data.V1}}
{{$argsLen := len $input.Args}}
{{$serverIndex := index $input.Args 0}}
{{$server := index $gwData.servers $serverIndex}}

{{$topCe := $gwData.customExtensions}}
{{$uriCe := $server.customExtensions}}

This data can now be used to implement custom logic. In our case we will add comments using this as shown below.

{{if and $topCe $topCe.commentsUsecase  $topCe.commentsUsecase.allUriComments}}
    {{range $comment := $topCe.commentsUsecase.allUriComments}}
        # {{$comment}}
    {{end}}
{{end}}

{{if and $uriCe $uriCe.commentsUsecase  $uriCe.commentsUsecase.uriSpecificComments}}
    {{range $comment := $uriCe.commentsUsecase.uriSpecificComments}}
        # {{$comment}}
    {{end}}
{{end}}

3. Create the schema

This use case expands the Gateway API. We need to define the JSON schema used to validate the template input and render additional fields in the UI. Create file gateway.json under the use case directory. Describe the API and validation needed in the JSON schema as shown below.

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
        "v1": {
            "type": "object",
            "properties": {
                "customExtensions": {
                    "type": [
                        "object",
                        "null"
                    ],
                    "properties": {
                        "commentsUsecase": {
                            "type": "object",
                            "description": "Add these comments to all server blocks",
                            "properties": {
                                "allUriComments": {
                                    "type": "array",
                                    "items": {
                                        "type": "string",
                                        "maxLength": 10
                                    }
                                }
                            }
                        }
                    }
                },
                "servers": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "customExtensions": {
                                "type": "object",
                                "properties": {
                                    "commentsUsecase": {
                                        "type": "object",
                                        "description": "Add these comments to all server blocks",
                                        "properties": {
                                            "uriSpecificComments": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string",
                                                    "maxLength": 10
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "required": []
}

Starting point for custom use cases

App Delivery Manager installation includes builtin-empty-v1-example use case. This contains all possible templates and schemas a use case can have. The templates provide a starting point for writing and experiementing with use cases.