The configuration section

The configuration section specifies several subsections: the parameter, the resource, the scale and the resilience subsections.

The parameter subsection is stored within the parameter field, and it represents the configuration parameter data that a component can consume.

The parameter subsection is defined, essentially, as a JSON structure, where the leaf nodes are given the types they can adopt (CUE types).

This is a very simple example of a parameter section

config: parameter: {
  targets: {
    upperbound: <= 100  | *100                // Must be less than 100, defaults to 100
    lowerbound: < upperbound | *upperbound    // Must be less than the upperbound, equal to it by default
    lowerbound: uint                          // additional restriction for lowerbound (>= 0)
  }

  groupname: string
}

Resources and the resource subsection

In Kumori Platform there are two kinds of resources, registerable and direct request resources. At this point in time, we have only one kind of direct request resources: volatile volumes and the following kinds of registerable resources:

  • persistent volumes

  • secrets

  • ports

  • domains

  • certificates

  • certificate authorities

The definition of the resource subsection is a simple name tree of resources:

config: resource: #ResourceTree

Where #ResourceTree is defined as follows,

#ResourceTree: [string]: (#Resource | #ResourceTree)

#Resource: #Volume | #Secret | #Port | #Domain | #Certificate | #CA

#Volume: #Volatile | #Persistent

#Volatile:   volume: {size: uint, unit: string}
#Persistent: volume: string

#Secret:      secret:      string
#Port:        port:        string
#Domain:      domain:      string
#Certificate: certificate: string
#CA:          ca:          string

We see in the above, that Volatile volumes are directly requested, providing directly the "amount" of the resource that is required (as a pair size/unit).

On the contrary, the rest of resources (all of them registerable) are represented by simple structures with specific field names, whose value is a string (the registered ID of the registered resource).

Registerable resources are assumed to have been registered into the platform beforehand. The result of such a registration is an id in the form a string for that resource. Resource references for registerable resources must resolve for this id.

Secrets

An example of registerable resource is a secret. A secret is essentially, a piece of information that the platform stores securely, and makes sure it is injected within a running component instance that has been configured to receive it.

Secrets can be injected by mapping them to files within the running component (more on mapping files later), or to environment variables.

Secrets are an example of data resources, infinitely shareable/assignable to multiple containers/roles/deplooyments.

Persistent Volumes

Another kind of registerable resource is a persistent volume. Persistent volumes must be mapped to a directory in a component (see ahead for mappings).

Persistent volumes, as the name implies, are guaranteed to survive component instance restarts. In a very real way they identify an instance of a component through its life cycle: the state of the persistent volume and the ID of the instance must be related in order for that state to be useful under normal operation.

We leave further explanation of persistent volume operation for when the feature is fully implemented. Suffice it to say, that a registered resource of this kind will have replicas at each one of the component’s instances that specify it into a mapped mount point, and our APIs will provide ways to access and manage each one of the replicas.

Ports

TCP ports are a scarce resource in a cluster. They can be reserved, and assigned to a special kind of builtin service: the inbound service.

A TCP port cannot be shared among inbound instances, but it can be assigned to data carrying constructs (files, and environment variables)

Domains

A domain needs to be reserved in a cluster in order assign it to an inbound. As with ports, domains cannot be shared among inbounds, although they can be assigned to data constructs (files and environment variables)

Certificates

A certificate is a special kind of secret. It can be assigned to multiple inbound instances. It can also be assigned to data carrying constructs (file/env).

Certificate Authoritie

Similar to certificates.

Volatile Volumes

Volatile volumes, like persistent volumes, should be mapped to a mount point of the running component. Unlike Persistent volumes, their state is not guaranteed to persist through the lifecyle of an instance mounting it.

Note that a volatile volume has no identity manageable by a service integrator or developer. It just specifies the amount of storage requested for it.

Given its characteristic, volatile storage should contain no state associated with the identity of the instance on which it is mounted, having only forensic value after an instance restarts/is eliminated.

Currently Kumori Platform does not offer any way to access a volatile volume after the component instance it was mapped to has been removed. A feature giving access to it (for forensic scenarios) is being considered.

Tag configuration

Configuration referring to the tags available through client channels can be accessed within the reserved path: /kumori/config.json.

This file contains a JSON dictionary, keyed by client channel name. For each client channel name, in turn, we have a dictionary keyed by tag number. Each entry of such sub-dictionary contains metadata for the tag.

Metadata for the tag is, in turn, divided into two sections: auto and user. The auto section is filled by the platform and contains structural info pertaining to the target component for the tag (e.g. its ref). The user section contains the metadata the integrator of the service configured associated to the version of the component linked to (see the description of service apps)

An example of the schema a component can use in /kumori/config.json is as follows:

{
  "channels": {
    "restapiclient": {
      "0": [
        {
          "auto": {
            "compRef": {
              "domain": "kumori.systems.examples",
              "kind": "component",
              "name": "calccacheworker",
              "version": [
                0,
                0,
                1
              ]
            },
            "roleName": "worker"
          },
          "user": {}
        }
      ]
    }
  }
}

Thus, under the key channels we find all client channels. For each client channel, we find a key per tag associated to the client channel.

For each tag, we find an array of metadata dictionaries. Each entry in the array contains a dictionary with just two entries: the auto entry, with data the platform provides, usually containing the ref of the component linked to, and the role name in the topology of the service.

Usually there is only one entry per tag. Multiple entries will be found when subservices are used when specifying a role within a service application.