The WasmPlugin
custom resource spec provides the configuration that the Proxy-WASM
module reads from.
The spec is embedded in the host and read by the Proxy-WASM
module. Typically, the configurations are in the JSON file format for the modules to parse, however the WasmPlugin
resource can interpret the spec value as YAML and convert it to JSON for consumption by the module.
If you use the Proxy-WASM
module in stand-alone mode, you must write the configuration using the JSON format. Using the JSON format means using escaping and quoting where needed within the host
configuration files, for example Envoy
. When you use the WebAssembly module with the WasmPlugin
resource, the configuration is in the YAML format. In this case, an invalid configuration forces the module to show diagnostics based on its JSON representation to a sidecar’s logging stream.
|
The EnvoyFilter custom resource is not a supported API, although it can be used in some 3scale Istio adapter or Service Mesh releases. Using the EnvoyFilter custom resource is not recommended. Use the WasmPlugin API instead of the EnvoyFilter custom resource.
If you must use the EnvoyFilter custom resource, you must specify the spec in JSON format.
|
Configuring the 3scale WebAssembly module
The architecture of the 3scale WebAssembly module configuration depends on the 3scale account and authorization service, and the list of services to handle.
Prerequisites
The prerequisites are a set of minimum mandatory fields in all cases:
-
For the 3scale account and authorization service: the backend-listener
URL.
-
For the list of services to handle: the service IDs and at least one credential look up method and where to find it.
-
You will find examples for dealing with userkey
, appid
with appkey
, and OpenID Connect (OIDC) patterns.
-
The WebAssembly module uses the settings you specified in the static configuration. For example, if you add a mapping rule configuration to the module, it will always apply, even when the 3scale Admin Portal has no such mapping rule. The rest of the WasmPlugin
resource exists around the spec.pluginConfig
YAML entry.
The 3scale WebAssembly module api object
The api
top-level string from the 3scale WebAssembly module defines which version of the configuration the module will use.
|
A non-existent or unsupported version of the api object renders the 3scale WebAssembly module inoperable.
|
The api
top-level string example
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: <threescale_wasm_plugin_name>
namespace: <bookinfo>
spec:
pluginConfig:
api: v1
...
The api
entry defines the rest of the values for the configuration. The only accepted value is v1
. New settings that break compatibility with the current configuration or need more logic that modules using v1
cannot handle, will require different values.
The 3scale WebAssembly module system object
The system
top-level object specifies how to access the 3scale Account Management API for a specific account. The upstream
field is the most important part of the object. The system
object is optional, but recommended unless you are providing a fully static configuration for the 3scale WebAssembly module, which is an option if you do not want to provide connectivity to the system component of 3scale.
When you provide static configuration objects in addition to the system
object, the static ones always take precedence.
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: <threescale_wasm_plugin_name>
spec:
pluginConfig:
system:
name: <saas_porta>
upstream: <object>
token: <my_account_token>
ttl: 300
...
Table 1. system
object fields
Name |
Description |
Required |
|
An identifier for the 3scale service, currently not referenced elsewhere. |
Optional |
|
The details about a network host to be contacted. upstream refers to the 3scale Account Management API host known as system.
|
Yes |
|
A 3scale personal access token with read permissions. |
Yes |
|
The minimum amount of seconds to consider a configuration retrieved from this host as valid before trying to fetch new changes. The default is 600 seconds (10 minutes). Note: there is no maximum amount, but the module will generally fetch any configuration within a reasonable amount of time after this TTL elapses. |
Optional |
The 3scale WebAssembly module upstream object
The upstream
object describes an external host to which the proxy can perform calls.
apiVersion: maistra.io/v1
upstream:
name: outbound|443||multitenant.3scale.net
url: "https://myaccount-admin.3scale.net/"
timeout: 5000
...
Table 2. upstream
object fields
Name |
Description |
Required |
|
name is not a free-form identifier. It is the identifier for the external host as defined by the proxy configuration. In the case of stand-alone Envoy configurations, it maps to the name of a Cluster, also known as upstream in other proxies. Note: the value of this field, because the Service Mesh and 3scale Istio adapter control plane configure the name according to a format using a vertical bar (|) as the separator of multiple fields. For the purposes of this integration, always use the format: outbound|<port>||<hostname> .
|
Yes |
|
The complete URL to access the described service. Unless implied by the scheme, you must include the TCP port. |
Yes |
|
Timeout in milliseconds so that connections to this service that take more than the amount of time to respond will be considered errors. Default is 1000 seconds. |
Optional |
The 3scale WebAssembly module backend object
The backend
top-level object specifies how to access the 3scale Service Management API for authorizing and reporting HTTP requests. This service is provided by the Backend component of 3scale.
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: <threescale_wasm_plugin_name>
spec:
pluginConfig:
...
backend:
name: backend
upstream: <object>
...
Table 3. backend
object fields
Name |
Description |
Required |
|
An identifier for the 3scale backend, currently not referenced elsewhere. |
Optional |
|
The details about a network host to be contacted. This must refer to the 3scale Account Management API host, known, system. |
Yes. The most important and required field. |
The 3scale WebAssembly module services object
The services
top-level object specifies which service identifiers are handled by this particular instance of the module
.
Since accounts have multiple services, you must specify which ones are handled. The rest of the configuration revolves around how to configure services.
The services
field is required. It is an array that must contain at least one service to be useful.
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: <threescale_wasm_plugin_name>
spec:
pluginConfig:
...
services:
- id: "2555417834789"
token: service_token
authorities:
- "*.app"
- 0.0.0.0
- "0.0.0.0:8443"
credentials: <object>
mapping_rules: <object>
...
Each element in the services
array represents a 3scale service.
Table 4. services
object fields
Name |
Description |
Required |
|
An identifier for this 3scale service, currently not referenced elsewhere. |
Yes |
|
This token can be found in the proxy configuration for your service in System or you can retrieve the it from System with following curl command:
curl https://<system_host>/admin/api/services/<service_id>/proxy/configs/production/latest.json?access_token=<access_token>" | jq '.proxy_config.content.backend_authentication_value
|
Optional |
|
An array of strings, each one representing the Authority of a URL to match. These strings accept glob patterns supporting the asterisk (*), plus sign (+), and question mark (?) matchers. |
Yes |
|
An object defining which kind of credentials to look for and where. |
Yes |
|
An array of objects representing mapping rules and 3scale methods to hit. |
Optional |
The 3scale WebAssembly module credentials object
The credentials
object is a component of the service
object. credentials
specifies which kind of credentials to be looked up and the steps to perform this action.
All fields are optional, but you must specify at least one, user_key
or app_id
. The order in which you specify each credential is irrelevant because it is pre-established by the module. Only specify one instance of each credential.
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: <threescale_wasm_plugin_name>
spec:
pluginConfig:
...
services:
- credentials:
user_key: <array_of_lookup_queries>
app_id: <array_of_lookup_queries>
app_key: <array_of_lookup_queries>
...
Table 5. credentials
object fields
Name |
Description |
Required |
|
This is an array of lookup queries that defines a 3scale user key. A user key is commonly known as an API key. |
Optional |
|
This is an array of lookup queries that define a 3scale application identifier. Application identifiers are provided by 3scale or by using an identity provider like Red Hat Single Sign-On (RH-SS0), or OpenID Connect (OIDC). The resolution of the lookup queries specified here, whenever it is successful and resolves to two values, it sets up the app_id and the app_key .
|
Optional |
|
This is an array of lookup queries that define a 3scale application key. Application keys without a resolved app_id are useless, so only specify this field when app_id has been specified.
|
Optional |
The 3scale WebAssembly module lookup queries
The lookup query
object is part of any of the fields in the credentials
object. It specifies how a given credential field should be found and processed. When evaluated, a successful resolution means that one or more values were found. A failed resolution means that no values were found.
Arrays of lookup queries
describe a short-circuit or relationship: a successful resolution of one of the queries stops the evaluation of any remaining queries and assigns the value or values to the specified credential-type. Each query in the array is independent of each other.
A lookup query
is made up of a single field, a source object, which can be one of a number of source types. See the following example:
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: <threescale_wasm_plugin_name>
spec:
pluginConfig:
...
services:
- credentials:
user_key:
- <source_type>: <object>
- <source_type>: <object>
...
app_id:
- <source_type>: <object>
...
app_key:
- <source_type>: <object>
...
...
The 3scale WebAssembly module source object
A source
object exists as part of an array of sources within any of the credentials
object fields. The object field name, referred to as a source
-type is any one of the following:
-
header
: The lookup query receives HTTP request headers as input.
-
query_string
: The lookup query
receives the URL query string parameters as input.
-
filter
: The lookup query
receives filter metadata as input.
All source
-type objects have at least the following two fields:
Table 6. source
-type object fields
Name |
Description |
Required |
|
An array of strings, each one a key , referring to entries found in the input data.
|
Yes |
|
An array of operations that perform a key entry match. The array is a pipeline where operations receive inputs and generate outputs on the next operation. An operation failing to provide an output resolves the lookup query as failed. The pipeline order of the operations determines the evaluation order.
|
Optional |
The filter
field name has a required path
entry to show the path in the metadata you use to look up data.
When a key
matches the input data, the rest of the keys are not evaluated and the source resolution algorithm jumps to executing the operations
(ops
) specified, if any. If no ops
are specified, the result value of the matching key
, if any, is returned.
Operations
provide a way to specify certain conditions and transformations for inputs you have after the first phase looks up a key
. Use operations
when you need to transform, decode, and assert properties, however they do not provide a mature language to deal with all needs and lack Turing-completeness.
A stack stored the outputs of operations
. When evaluated, the lookup query
finishes by assigning the value or values at the bottom of the stack, depending on how many values the credential consumes.
The 3scale WebAssembly module operations object
Each element in the ops
array belonging to a specific source type
is an operation
object that either applies transformations to values or performs tests. The field name to use for such an object is the name of the operation
itself, and any values are the parameters to the operation
, which could be structure objects, for example, maps with fields and values, lists, or strings.
Most operations
attend to one or more inputs, and produce one or more outputs. When they consume inputs or produce outputs, they work with a stack of values: each value consumed by the operations is popped from the stack of values and initially populated with any source
matches. The values outputted by them are pushed to the stack. Other operations
do not consume or produce outputs other than asserting certain properties, but they inspect a stack of values.
|
When resolution finishes, the values picked up by the next step, such as assigning the values to be an app_id , app_key , or user_key , are taken from the bottom values of the stack.
|
There are a few different operations
categories:
-
decode
: These transform an input value by decoding it to get a different format.
-
string
: These take a string value as input and perform transformations and checks on it.
-
stack
: These take a set of values in the input and perform multiple stack transformations and selection of specific positions in the stack.
-
check
: These assert properties about sets of operations in a side-effect free way.
-
control
: These perform operations that allow for modifying the evaluation flow.
-
format
: These parse the format-specific structure of input values and look up values in it.
All operations are specified by the name identifiers as strings.
The 3scale WebAssembly module mapping_rules object
The mapping_rules
object is part of the service
object. It specifies a set of REST path patterns and related 3scale metrics and count increments to use when the patterns match.
You need the value if no dynamic configuration is provided in the system
top-level object. If the object is provided in addition to the system
top-level entry, then the mapping_rules
object is evaluated first.
mapping_rules
is an array object. Each element of that array is a mapping_rule
object. The evaluated matching mapping rules on an incoming request provide the set of 3scale methods
for authorization and reporting to the APIManager. When multiple matching rules refer to the same methods
, there is a summation of deltas
when calling into 3scale. For example, if two rules increase the Hits method twice with deltas
of 1 and 3, a single method entry for Hits reporting to 3scale has a delta
of 4.
The 3scale WebAssembly module mapping_rule object
The mapping_rule
object is part of an array in the mapping_rules
object.
The mapping_rule
object fields specify the following information:
-
The HTTP request method to match.
-
A pattern to match the path against.
-
The 3scale methods to report along with the amount to report. The order in which you specify the fields determines the evaluation order.
Table 7. mapping_rule
object fields
Name |
Description |
Required |
|
Specifies a string representing an HTTP request method, also known as verb. Values accepted match the any one of the accepted HTTP method names, case-insensitive. A special value of any matches any method. |
Yes |
|
The pattern to match the HTTP request’s URI path component. This pattern follows the same syntax as documented by 3scale. It allows wildcards (use of the asterisk (*) character) using any sequence of characters between braces such as {this} .
|
Yes |
|
A list of usage objects. When the rule matches, all methods with their deltas are added to the list of methods sent to 3scale for authorization and reporting.
Embed the usages object with the following required fields:
|
Yes |
|
Whether the successful matching of this rule should stop the evaluation of more mapping rules. |
Optional Boolean. The default is false
|
The following example is independent of existing hierarchies between methods in 3scale. That is, anything run on the 3scale side will not affect this. For example, the Hits metric might be a parent of them all, so it stores 4 hits due to the sum of all reported methods in the authorized request and calls the 3scale Authrep
API endpoint.
The example below uses a GET
request to a path, /products/1/sold
, that matches all the rules.
mapping_rules
GET
request example
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: <threescale_wasm_plugin_name>
spec:
pluginConfig:
...
mapping_rules:
- method: GET
pattern: /
usages:
- name: hits
delta: 1
- method: GET
pattern: /products/
usages:
- name: products
delta: 1
- method: ANY
pattern: /products/{id}/sold
usages:
- name: sales
delta: 1
- name: products
delta: 1
...
All usages
get added to the request the module performs to 3scale with usage data as follows:
-
Hits: 1
-
products: 2
-
sales: 1