/kynaptik

λ Fission Function which evaluates incoming stimulus (event/message) and determines an appropriate (configured) action (http, graphQL, ...)

Primary LanguageGoMIT LicenseMIT

Кynaptiꓘ

Codacy Badge build-status coverage-status maintainability quality-gate-status lines-of-code technical-debt stackshare go-version release

Serverless Function on Kubernetes (through Fission) providing a generic and configurable mean to trigger actions from incoming events.

👉 Purpose

Kynaptiꓘ is a function which specifies how a stimulus (i.e. incoming request, message) elicits a response (i.e. invocation of endpoint).

More broadly, it provides a platform with a versatile and generic Web Hook serving multiple purposes.

💡Principles

Kynaptiꓘ is a function that deploys on Fission FaaS, an amazing framework for serverless functions on Kubernetes.

The following diagram depicts how the main components interact:

overview

✨ Features

Kynaptiꓘ is a simple, lean function with a deliberately limited set of features. Development is driven by the KISS principle: "do one thing well".

  • Conditional actions: an action is executed only in case a message matches the defined condition. That condition is specified by an expression evaluated at running time against an environment containing the incoming message.
  • Extensible configuration of actions with templating: URL, HTTP method, headers and body.

🚨 At this moment, Fission mqtrigger processes incoming messages concurrently, which can cause unordered function calls. See FISSION#1569. Thus, depending on the use cases, it can lead to data inconsistency.

Out of scope:

  • No complex conditions, e.g. based on a state based on time (CEP)
  • No content enrichment: no way to access an external data source in order to augment a message with missing information.

The incoming messages are expected to be qualified enough for the processing.

  • Fire and forget behavior: the action (e.g. HTTP post) is done once, the result is not used (a log is emitted though)
  • No recovery policy: no retry if the action fails

🚀 Actions

Here's the currently supported actions:

Action Description Documentation
http Provides HTTP actions for calling external HTTP(S) resources. view documentation
graphql Provides GraphQL actions for calling external GraphQL APIs. view documentation

🛠 Configuration

configmap

Kynaptiꓘ is configured by a k8s ConfigMap which defines the configuration for the function.

The ConfigMap shall declares the key function-spec.yml under the key data, which contains the yaml configuration of the function.

For instance:

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: default
  name: kynaptik-http-configmap
data:
  function-spec.yml: |
    timeout: 10000

    preCondition: |
      data.foo == "bar"

    action: |
      uri: 'https://foo-bar'            
      method: GET
      headers:
        Content-Type: application/json
        X-Userid: |
          {{if eq .data.user.firstname "john"}}Rmlyc3Qgb3B0aW9u={{else}}U2Vjb25kIG9wdGlvbg=={{end}}
      body: |
        {
          "message": "Hello from {{.data.user.firstname}} {{.data.user.lastname}}"
        }
    postCondition: |
      response.StatusCode >= 200 and response.StatusCode < 300

The yaml configuration has the following structure:

  • preCondition: optional, specifies the condition (textual) to be satisfied for the function to be triggered. The condition is an expression (text) compliant with the syntax of antonmedv/expr engine. true by default.

  • action: specifies the action to perform. The action specification is templated using the go template engine. See section below to have details about the evaluation environment.

    • uri: mandatory, the URI of the endpoint to invoke. Shall resolve to a URI according to rfc3986. The scheme specifies the kind of action (see below) that will be performed: http, graphql...
    • timeout: optional, specifies the timeout for waiting for data (in ms).
    • ...: other fields depending on the kind of action.
  • postCondition: optional, specifies the condition (textual) to be satisfied for the response of the call be considered successful.

  • maxBodySize: optional, defines the maximum acceptable size (in bytes) of the incoming request body. No limit by default.

  • timeout: optional, specifies the timeout for waiting for data (in ms). No timeout by default.

The condition (either preCondition or postCondition) is an expression (text) compliant with the syntax of antonmedv/expr engine.

secrets

Along with a ConfigMap, Kynaptiꓘ supports k8s secrets which allows to inject sensitive information (such as passwords) in the function, and make them available in the execution context.

The secret shall declares the key function-secret.yml under the field data, which contains all the yaml secrets of the function.

For instance:

apiVersion: v1
kind: Secret
metadata:
  namespace: default
  name: kynaptik-http-secret
type: Opaque
data:
  function-secret.yml: |
    username: YWRtaW4=
    password: c+KCrGNy4oKsdA==

environment variables

Fission supports access to environment variables through PodSpecs, which defines the specifications of many behaviors of functions in a declarative manner. A complete documentation can be found here.

Within Kynaptiꓘ, environment variables can easily be retrieved using the template action env and providing the name of the variable as argument:

{{ env "FOO" }}

Variable expansion is also available as template action, as shown below:

{{ "Hello $FOO" | expandenv }}

📄 Evaluation context

The preCondition, postCondition expressions and the action template are processed against a context.

The data tag available in the context is following:

name description scope
data The incoming message (body only), serialized into a map structure, with preservation of primary types (numbers, strings). always
config The current configuration (as loaded from the ConfigMaps). always
secret The current secret (if provided). always
response The response returned by the invocation. Datatype depends on the action performed. only for postCondition

Some useful functions are also injected in the context covering a large set of operations: string, date, maths, encoding, environment... The functions are mainly brought by the Masterminds/sprig project. The complete description of those functions can be found here.