Skip to content
This repository was archived by the owner on Jan 4, 2022. It is now read-only.

API Interceptor Wiki

Prachi Damle edited this page Aug 24, 2017 · 4 revisions

API Interceptor Wiki

High level notes:

  • API Interceptors intercept configured Rancher API calls placed by UI/clients
  • API Interceptors can function as API controllers that can allow/deny certain APIs or APIs with certain data.
  • API Interceptors can modify the API command's JSON payload that will be processed by Rancher
  • Admin can specify multiple interceptors for an API request
  • Rancher behavior in case multiple interceptors are configured for an API:
    • When a Rancher API is called, each interceptor will be invoked one after the other
    • If one interceptor reports failure/rejection, then no more interceptor will be invoked further and the API will be terminated
    • If one interceptor returns a modified JSON payload, then this modified payload will be sent to the subsequent interceptor. The payload sent back if any by the last interceptor, will be used to process the API command at Rancher.
    • For API processing to proceed, all interceptors should report success

How to configure API Interceptors

  • Admin can configure the API Interceptors using Rancher UI under Admin -> Settings -> Advanced Settings
  • Edit the setting 'api.interceptor.config' and set the value to a json config content like below:
{
	"requestInterceptors": [{
		"type": "authTokenValidator",
		"paths": ["/v2-beta/projects", "/v2-beta/projects/{path:.*}"],
		"endpoint": "",
		"methods": ["post", "delete"],
		"secretToken": ""
	}, {
		"type": "http",
		"paths": ["/v2-beta/projects/{path:.*}"],
		"endpoint": "http://localhost:8092/external-interceptor",
		"methods": ["post", "delete", "get"],
		"secretToken": "pqrs"
	}, {
		"type": "http",
		"paths": ["/v2-beta/projects/{path:.*}"],
		"endpoint": "http://localhost:8094/another-external-interceptor",
		"methods": ["post", "delete", "get"],
		"secretToken": "xyz"
	}],

	"destinations": [{
		"paths": ["/v1/services/{id:.*}"],
		"destinationURL": "http://...:8080/"
	}]
}
  • Specify an array requestInterceptors[] where each interceptor defines:

    • type (Use "http" for an interceptor that is being served by an http endpoint)
    • endpoint (http endpoint that should be called)
    • paths[] (array of Rancher API request paths that should be intercepted)
    • methods[] (array of HTTP methods to narrow down the APIs to be intercepted by method)
    • secretToken (that is used to generate a HMAC signature sent to the Interceptor in request header "X-API-Auth-Signature")
  • Also destinations[] can be used to specify the final endpoint to send the API to after all interceptors are invoked.

  • Keep destinations[] empty so that by default all APIs get executed by the Rancher server.

Example configurations:

  • To add an interceptor for say Create Stack API for a particular environment (say "1a5"), interceptor config will be:
"requestInterceptors": [{
		"type": "http",
		"paths": ["/v2-beta/projects/1a5/stack"],
		"endpoint": "http://localhost:8092/external-interceptor",
		"methods": ["post"],
		"secretToken": "pqrs"
	}]
  • To add an interceptor for say Create Service API under a particular environment (say "1a5"), specify path as below:
"requestInterceptors": [{
		"type": "http",
		"paths": ["/v2-beta/projects/1a5/service"],
		"endpoint": "http://localhost:8092/external-interceptor",
		"methods": ["post"],
		"secretToken": "pqrs"
	}]
  • To add an interceptor for any API requests under a particular environment, specify path using regex as below:
"requestInterceptors": [{
		"type": "http",
		"paths": ["/v2-beta/projects/1a5/{path:.*}"],
		"endpoint": "http://localhost:8092/external-interceptor",
		"methods": ["post", "delete", "get"],
		"secretToken": "pqrs"
	}]

What is the payload sent to an Interceptor?

  • When Rancher calls an "http" Interceptor, it will POST following data to the interceptor endpoint:
POST http://localhost:8092/external-interceptor
request headers:
"X-API-Auth-Signature": <HMAC signature of the payload>
request JSON body
{
   UUID: 
   APIPath: "/v2-beta/projects/1a5/stack"
   envID: "1a5"
   headers: {} // The original headers (or the headers returned by the last interceptor)
   body: {} // The original API body (or the body returned by the last interceptor)
}

The underlying request data structure:

//APIRequestData defines the properties of a API Request Body sent to a filter
type APIRequestData struct {
   Headers       map[string][]string    `json:"headers,omitempty"`
   Body          map[string]interface{} `json:"body,omitempty"`
   UUID          string                 `json:"UUID,omitempty"`
   APIPath       string                 `json:"APIPath,omitempty"`
   APIMethod     string                 `json:"APIMethod,omitempty"`
   EnvID         string                 `json:"envID,omitempty"`
}

What is the response expected from an Interceptor?

  • An "http" Interceptor, should respond back in one of the following ways:

    • HTTP Status 200 (Success) and no JSON response
    • HTTP Status 200 (Success) but with JSON response having keys "headers" and/or "body"
    • HTTP Status 4XX or 5XX for failure, JSON response can carry a custom error "message" that is presented to the user.
  • JSON response to be returned, is of content-type 'application/json':

HTTP <status code>
response JSON body
{
	headers: {} // Any new headers 
	body: {} // The modified API body if any
        message: "" //Any custom status message to be returned for an error
}

The underlying response data structure:

//APIResponseData defines the properties of a API Request Body sent to a filter
type APIResponseData struct {
	Headers    map[string][]string    `json:"headers,omitempty"`
	Body       map[string]interface{} `json:"body,omitempty"`
	Message    string                 `json:"message,omitempty"`
}
  • To get the Rancher accountID if any is associated with the request, always specify the "authTokenValidator" Rancher's Interceptor as the first Interceptor in your config:
	"requestInterceptors": [{
		"type": "authTokenValidator",
		"paths": ["/v2-beta/projects", "/v2-beta/projects/{path:.*}"],
		"endpoint": "",
		"methods": ["post", "delete"],
		"secretToken": ""
	}, {}]
  • The "authTokenValidator" is a Rancher internal interceptor that will insert the account associated with a request, into the headers: {} in the payload. It will add a header "X-API-Account-Id" under the headers: {} that will give the accountId.

Clone this wiki locally