Advanced Route Plugins

Gloo uses a Virtual Service Custom Resource (CRD) to allow users to specify one or more Route rules to handle as a group. This guide will discuss plugins that can affect how matched routes act upon requests. Please refer to the Advanced Route Matching guide for more information on how to pattern match requests in routes and Route Action for more information on how to forward requests to upstream providers. This guide will discuss Route Plugins which allow you to fine-tune how requests and responses are handled.

Base example

You can use the glooctl command line to provide you a template manifest that you can start editing. The --dry-run option tells glooctl to NOT create the custom resource and instead output the custom resource manifest. This is a great way to get an initial manifest template that you can edit and then kubectl apply later. For example, the glooctl add route command will generate a VirtualService resource if it does not already exist, and it will add a route spec like the following which shows forwarding all requests to /petstore to the upstream default-petstore-8080 which will rewrite the matched query path with the specified path by prefixRewrite.

glooctl add route --dry-run \
  --name default \
  --path-prefix /petstore \
  --dest-name default-petstore-8080 \
  --dest-namespace gloo-system \
  --prefix-rewrite /api/pets
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  creationTimestamp: null
  name: 'default'
  namespace: 'gloo-system'
spec:
  virtualHost:
    domains:
    - '*'
    routes:
    - matcher:
        prefix: '/petstore'
      routeAction:
        single:
          upstream:
            name: 'default-petstore-8080'
            namespace: 'gloo-system'
      routePlugins:
        prefixRewrite:
          prefixRewrite: '/api/pets'
status: {}

Route Plugins

On any route, you can add each of the following types of plugins. Specifying a route plugin adds or modifies the behavior on an Envoy filter that is processing the request and response traffic.

Be aware that adding plugins can have a negative impact on the request latency so good idea to do some extra testing to validate latency impacts.

Route Transformations

Within a route, you can have RouteTransformations for either or both of the following.

Both of these are of type Transformation as the following describes.

Transformation

Transformation can contain zero or one of the following:

For example, to have a transformation template for the request and header body transform for the response, the following is a snippet of the manifest.

apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  name: 'default'
  namespace: 'gloo-system'
spec:
  virtualHost:
    domains:
    - '*'
    routes:
    - matcher:
        prefix: '/petstore'
      routeAction:
        single:
          upstream:
            name: 'default-petstore-8080'
            namespace: 'gloo-system'
      routePlugins:
        transformations:
          requestTransformation:
            transformationTemplate: { ... }
          responseTransformation:
            headerBodyTransform: {}
Header Body Transform

Specific to AWS Lambda Proxy Integration. AWS Lambda only permits functions to return JSON responses and this transformation can be used to unwrap that JSON body to provide a typical HTTP response that you’re more likely expecting. This transform expects a message who’s body is a JSON object that includes headers and body keys, and this transform will transform this to a typical HTTP message with headers and body where you’d expect.

apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  name: 'default'
  namespace: 'gloo-system'
spec:
  virtualHost:
    domains:
    - '*'
    routes:
    - matcher:
        prefix: '/petstore'
      routeAction:
        single:
          upstream:
            name: 'default-petstore-8080'
            namespace: 'gloo-system'
      routePlugins:
        transformations:
          responseTransformation:
            headerBodyTransform: {}
Transformation Template

TransformationTemplate provide advanced capabilities to modify the message’s headers and body.

And the Transformation Template can have only ONE of the following three options: body, passthrough, or mergeExtractorsToBody.

InjaTemplate

Inja Templates give you a powerful way to process JSON formatted data. For example, if you had a message body that contained the JSON { "name": "world" } then the Inja template Hello {{ name }} would become Hello world. The template variables, e.g., {{ name }}, is used as the key into a JSON object and is replaced with the key’s associated value.

Inja Templates default to using . notation for JSON keys, i.e., address.street => { "address": { "street": "value" } }. If advancedTemplates is true, Inja Templates use / notation, i.e., address/street => { "address": { "street": "value" } }

Gloo adds two additional functions that can be used within templates.

apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  name: 'default'
  namespace: 'gloo-system'
spec:
  virtualHost:
    domains:
    - '*'
    name: 'gloo-system.default'
    routes:
    - matcher:
        prefix: '/'
      routeAction:
        single:
          upstream:
            name: 'jsonplaceholder-80'
            namespace: 'gloo-system'
      routePlugins:
        transformations:
          responseTransformation:
            transformation_template:
              body:
                text: 'extractor ({{ foo }}) header ({{ header("date")}}) json ({{ phone }})'
              extractors:
                foo:
                  header: 'date'
                  regex: '\w*, (.+):(.+):(.+) GMT'
                  subgroup: 2

Faults

This can be used for testing the resilience of your services by intentionally injecting faults (errors and delays) into a percentage of your requests.

Abort specifies the percentage of request to error out.

Delay specifies the percentage of requests to delay.

apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  name: 'default'
  namespace: 'gloo-system'
spec:
  virtualHost:
    domains:
    - '*'
    routes:
    - matcher:
        prefix: '/petstore'
      routeAction:
        single:
          upstream:
            name: 'default-petstore-8080'
            namespace: 'gloo-system'
      routePlugins:
        faults:
          abort:
            percentage: 2.5
            httpStatus: 503
          delay:
            percentage: 5.3
            fixedDelay: '5s'

Prefix Rewrite

PrefixRewrite allows you to replace (rewrite) the matched request path with the specified value. Set to empty string ("") to remove the matched request path.

Timeout

The maximum Duration to try to handle the request, inclusive of error retries.

apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  name: 'default'
  namespace: 'gloo-system'
spec:
  virtualHost:
    domains:
    - '*'
    routes:
    - matcher:
        prefix: '/petstore'
      routeAction:
        single:
          upstream:
            name: 'default-petstore-8080'
            namespace: 'gloo-system'
      routePlugins:
        timeout: '20s'
        retries:
          retryOn: 'connect-failure'
          numRetries: 3
          perTryTimeout: '5s'

Retries

Specifies the retry policy for the route where you can say for a specific error condition how many times to retry and for how long to try.

apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  name: 'default'
  namespace: 'gloo-system'
spec:
  virtualHost:
    domains:
    - '*'
    routes:
    - matcher:
        prefix: '/petstore'
      routeAction:
        single:
          upstream:
            name: 'default-petstore-8080'
            namespace: 'gloo-system'
      routePlugins:
        retries:
          retryOn: 'connect-failure'
          numRetries: 3
          perTryTimeout: '5s'

Extensions

Extensions are arbitrary key-value pairs that can be stored on Gloo routes for the purposes of extending Gloo. This is used to support external plugins, as well as Gloo-Enterprise plugins.

apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
  name: 'default'
  namespace: 'gloo-system'
spec:
  virtualHost:
    domains:
    - '*'
    routes:
    - matcher:
        prefix: '/petstore'
      routeAction:
        single:
          upstream:
            name: 'default-petstore-8080'
            namespace: 'gloo-system'
      routePlugins:
        extensions:
          configs:
            my-custom-key: my-custom-value