Skip to main content

Sandbox Specification

Overview

A Signadot Sandbox specification describes a set of sandboxed Kubernetes workloads and endpoints for accessing them. The specification can be expressed in json or yaml formats, as structured data, for example

name: my-sandbox
spec:
tags:
dev: jane
cluster: my-cluster
description: Testing sandboxes
forks:
- forkOf:
kind: Deployment
namespace: example
name: my-app
customizations:
images:
- image: example.com/my-app:dev-abcdef
env:
- name: EXTRA_ENV
value: foo
endpoints:
- name: my-endpoint
port: 8080 # port that the pod listens on.
protocol: http # or grpc

This document details all the fields and constraints associated with a valid sandbox specification. A cheatsheet is available here.

Global constraints

The names of host endpoints and fork endpoints must be unique across the spec.

Update constraints

A sandbox may be updated. Only some fields are mutable, the rest are immutable. In addition, some constraints apply.

Any field named endpoints may be modified arbitrarily. As this field is of type array, that means that one can add or remove or change endpoints.

Any entry in spec.forks, identified by the keyforkOf may be modified arbitrarily, but not deleted. Additionally, one may add entries to spec.forks.

No other field may be modified. In particular, as the name of a sandbox acts as an identifier, one cannot rename a sandbox. Also, spec.resources is immutable.

name

The name is a string used to identify the sandbox. The name must be unique amongst all sandboxes associated with the Signadot organisation used to create the sandbox.

A name must match the regular expression ^[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?$ and be no longer than 30 bytes in length.

The name is required and immutable.

spec

The sandbox spec is required and contains all components of the specification except the name. Some parts of the spec are mutable and some are immutable.

spec.cluster

The cluster associated with a sandbox is a string which identifies a cluster registered with Signadot by name. In general, the cluster should have the Signadot Operator installed. The cluster name should not exceed 255 bytes in length.

cluster is required and immutable.

spec.description

The sandbox description is an optional string providing a short summary of what the sandbox is used for. The description must not exceed 255 bytes. The sandbox description is immutable.

spec.tags

Tags are a map from strings to strings, for example

spec:
tags:
dev: jane
feature: x

A tag key must not exceed 255 bytes in length and must contain at least 1 character. Additionally, it must contain only the characters

A-Z // upercase alphabetic
a-z // lowercase alphabetic
0-9 // numeric
- // dash
_ // underscore

A tag value can be an arbitrary string which also must not exceed 255 bytes in length and must contain at least one character. However, value contents are not otherwise restricted.

Sandbox tags are optional and immutable.

Futher information is available here.

spec.forks

Forks is an array of descriptions of forked Kubernetes workloads dedicated to serving the sandbox. Each field of the description is detailed below, and as a whole, a fork details how to run the forked workload as a set of customizations applied to the workload's baseline configuration. Each fork can also contain specifications of associated endpoints.

spec.forks[_].forkOf

forkOf is required within a fork and defines what baseline workload to fork. There should be at most one forkOf for a given workload, and the fork should describe a valid workload running in the cluster under the field cluster. One can add baseline workloads to fork to a spec but one cannot remove baseline workloads from a spec.

An annotated example follows.

spec:
forks:
- forkOf:
# kind specifies the Kubernetes kind of workload to fork. It may be
# either 'Deployment' or 'ArgoRollout'.
kind: Deployment
# namespace within which the workload resides.
namespace: backend
# the name of the workload to fork
name: my-app

spec.forks[_].customizations

A customizations object specifies how to customize the baseline workload to the sandbox under specification.

customizations is optional and mutable.

images

images specifies a set of custom images to run in the forked workload in place of the images configured for the baseline.

spec:
forks:
- customizations:
images:
- container: main
image: docker.io/my-company/my-service:dev

Each image item contains an optional container field, which is a string field that holds the name of a container in a pod spec in the workload to be forked. The image field is required and must house a valid docker reference to an image. It is also mutable.

In the event that container is empty or not specified, the main container of the pod spec will be used. The main container is the first container in the list of containers to run for a pod. Only one item without a container may exist in the list of image specifications.

A container name must appear at most once in the list.

images is optional and mutable; one can change the list of images arbitrarily, provided the above constraints are respected.

env

env specifies a set of environmental variables to set up for the containers associated with a pod. The following example shows the different ways environmental variables can be defined.

spec:
forks:
- forkOf:
# ...
customizations:
env:
- name: APP_ROOT
value: /app-dev
- container: main
name: DBHOST
valueFrom:
resource:
name: testdb
outputKey: dbhost
- container: main
name: SENTIMENT_ANALYSIS_ADDR
valueFrom:
fork:
forkOf:
kind: Deployment
namespace: backend
name: sentiment-analysis
expression: "{{.Service.Host}}:{{.Service.Port}}"

# the valueFrom items above refer to elements of the spec shown below
- forkOf:
kind: Deployment
namespace: backend
name: sentiment-analysis

# resource whose plugin generates an output key 'dbhost'
resources:
- name: testdb
# ...

The first item is a simple string key, value pair, defining the environment variable APP_ROOT. No container is specified, so the main container is inferred. Containers are infered for any item without a container specified.

The second item defines DBHOST, making reference to a resource associated with the sandbox, which is made available by a resource plugin that provides an output key 'dbhost'. The full documentation for resources is available here.

The third item defines SENTIMENT_ANALYSIS_ADDR to be the address of another forked workload in the sandbox, using cross fork references. The full documentation for cross fork references is available here.

env is optional and mutable.

patch

patch is optional and mutable. Moreover, patch is intended only as an escape hatch to accomodate uncommon Kubernetes workload configurations. In most cases, patch should not be used.

patch specifies a patch to be applied to the forked workload specification after custom images and environmental variables are set.

spec:
forks:
- customizations:
patch:
type: strategic # one of json, merge, strategic
value: '{"spec":{"template":{"spec":{"containers":[{"name":main, "ports":["containerPort": 4242}]}}}}'

patch contains two fields, type and value. type must be one of

The value field provides the contents of the patch as a string.

The example above shows a strategic merge patch which sets the containerPort to the container "main" to value 4242.

spec.forks[_].endpoints

The endpoints field in a fork specifies an array of endpoints which result in URLs which, in turn, resolve to the forked workload. One specifies the name, port, and protocol for a fork endpoint:

forks:
- forkOf: ...
endpoints:
- name: my-app
port: 8080
protocol: http # or grpc

The name must be unique amongst all endpoints, even endpoints in other forks and host endpoints (see below). The name is required.

The port specifies the port number to which the resulting URL will resolve.

The protocol specifies what protocol is used at the given port within the fork. One may specify either http or grpc.

Given an endpoint in a spec, Signadot will create URLs which allow accessing the fork at the given port using the specified protocol. These URLs are available via the Signadot API server when accessing the sandbox.

endpoints is optional and mutable.

Further documentation about endpoints is available here.

spec.endpoints

The top level endpoints field in a spec is an array of host endpoints. Each host endpoint operates in the same fashion as a fork endpoint, as specified above. However, in addition, one must specify the host to which the resulting URL will resolve. The host is a string representing a host name which will be resolved via DNS in the cluster in which the sandbox resides.

spec:
endpoints:
- name: event-store
host: event-store.backend.svc
port: 8080
protocol: http

endpoints is optional and mutable.

Further documentation about endpoints is available here.

spec.resources

The top level resources field in a spec provides information about external resources associated with a sandbox, such as a database or message queue.

resources is an array of objects specifying the usage of a resource provided by a resource plugin, which needs to be installed in the cluster associated with the sandbox under specification. An example follows

spec:
resources:
- name: testdb
plugin: sd-mariadb
params:
dbname: testdb

A single resource item contains 3 elements: a name for the resource as viewed by the sandbox, a plugin giving the name of a resource plugin installed in the cluster for provisioning the resource, and a set of key, value string params.

The name must be unique amongst all names in the resource list.

Full documentation for sandbox resources are available here and the field resources is optional and immutable.