Control Plane YAML Specification
potctl deploys Edge Compute Networks (ECNs) from YAML. Control plane resources define the Controller, Router, optional NATS, and optional system Edgelet nodes on the same hosts. Platform train v3.8.0 uses embedded OIDC by default.
| Kind | Deploy target | Primary doc section |
|---|---|---|
KubernetesControlPlane | Kubernetes cluster (operator-managed) | Kubernetes Control Plane |
ControlPlane | Remote hosts over SSH | Remote Control Plane |
LocalControlPlane | Local machine (dev / quick start) | Local Control Plane |
Controller | Add a Controller to an existing remote Control Plane | Controller add-on |
See Embedded OIDC Authentication and External OIDC Authentication for auth setup. When NATS is enabled, use NATS Account Rules and NATS User Rules. For TLS and certificates, see Certificates for Router and NATS and Airgap Deployment.
Do not copy Keycloak blocks from the v3.7.3 snapshot. v3.8 Control Plane YAML uses auth.mode: embedded or auth.mode: external instead of auth.realm and auth.realmKey.
metadata.controlPlaneType is retired. Use kind: KubernetesControlPlane, kind: ControlPlane, or kind: LocalControlPlane.
Image overrides
Override platform images under spec.images (Kubernetes) or spec.controller.package.image plus spec.systemMicroservices (local and remote). Defaults match the v3.8.0 release train:
| Component | Default tag | YAML key |
|---|---|---|
| Controller | v3.8.0 | spec.images.controller or spec.controller.package.image |
| Operator | 3.8.0 | spec.images.operator (Kubernetes only) |
| Router | 3.8.0 | spec.images.router or spec.systemMicroservices.router |
| NATS | 2.14.3 | spec.images.nats or spec.systemMicroservices.nats |
| Edgelet (system node) | 1.0.0 | spec.systemAgent.package.container.image or package.version |
Registry host comes from your build flavor ({{REGISTRY}} in examples). Default Edgelet image: ghcr.io/datasance/edgelet:1.0.0.
Router and NATS on local or remote Control Planes use four architecture keys: amd64, arm64, riscv64, and arm.
Shared spec blocks
These blocks appear on one or more Control Plane kinds. The field availability matrix at the end lists which kind accepts each block.
metadata
| Field | Required | Description |
|---|---|---|
metadata.name | Yes | Unique Control Plane name in the potctl namespace. Lowercase alphanumeric; hyphens allowed. |
metadata.namespace | No | Namespace for potctl state. Defaults to the active namespace from the CLI flag. |
spec.iofogUser
First REST API user created on the Controller after deploy.
| Field | Required | Description |
|---|---|---|
name | No | Given name. |
surname | No | Family name. |
email | Yes | Login email. Deploy fails when empty. |
password | No | REST API password. If set: at least 12 characters, one uppercase letter, one special character. Omit to enter interactively at deploy time (Kubernetes). |
accessToken | No | Runtime state. Do not set in deploy YAML. |
refreshToken | No | Runtime state. Do not set in deploy YAML. |
spec.auth
| Field | Required | Description |
|---|---|---|
mode | Yes | embedded (default quick start) or external (corporate IdP). |
insecureAllowHttp | No | Allow http:// in controller.publicUrl. Use for local dev only. |
insecureAllowBootstrapLog | No | Log bootstrap admin credentials once at first boot (embedded). |
bootstrap.username | Yes when mode: embedded | First OIDC admin username. |
bootstrap.password | Yes when mode: embedded | Bootstrap admin password in YAML. Same complexity rules as iofogUser.password. |
issuerUrl | Yes when mode: external | Full OIDC issuer URL (for example https://idp.example.com/realms/pot). |
client.id | Yes when mode: external | OAuth client ID for the Controller. |
client.secret | Yes when mode: external | OAuth client secret. |
consoleClient | No | EdgeOps Console SPA OAuth client ID. |
consoleClientEnabled | No | Register and enable the Console OAuth client. |
rateLimit.enabled | No | Enable OIDC endpoint rate limiting. |
rateLimit.maxRequestsPerWindow | No | Max requests per window when rate limiting is on. |
rateLimit.windowMs | No | Rate limit window in milliseconds. |
sessionStore.type | No | BFF session store: memory or database. |
sessionStore.ttlMs | No | Session TTL in milliseconds. |
sessionStore.secret | No | Encryption secret for BFF sessions. |
tokenTtl.accessTokenTtlSeconds | No | Access token lifetime. |
tokenTtl.refreshTokenTtlSeconds | No | Refresh token lifetime. |
oidcTtl.interactionTtlSeconds | No | OIDC interaction lifetime. |
oidcTtl.grantTtlSeconds | No | OIDC grant lifetime. |
oidcTtl.sessionTtlSeconds | No | OIDC session lifetime. |
oidcTtl.idTokenTtlSeconds | No | ID token lifetime. |
Embedded mode sets the issuer to {controller.publicUrl}/oidc. See Controller configuration for environment variable names.
spec.database
External MySQL or PostgreSQL. Required when you run more than one Controller replica (Kubernetes) or more than one remote Controller host.
| Field | Required | Description |
|---|---|---|
provider | When HA | postgres or mysql. |
host | When provider set | Database hostname. |
port | When provider set | Database port. |
user | When provider set | Database username. |
password | When provider set | Database password. |
databaseName | When provider set | Database name. |
ssl | No | Enable TLS to the database. |
ca | No | Base64-encoded CA certificate for database TLS. |
Single Controller installs use embedded SQLite on the host (remote/local) or in the pod (Kubernetes with one replica).
spec.events
Controller audit event settings.
| Field | Description |
|---|---|
auditEnabled | Enable audit logging. |
retentionDays | Days to retain audit events. |
cleanupInterval | Cleanup interval in seconds. |
captureIpAddress | Record client IP addresses in audit entries. |
spec.controller
Runtime Controller settings applied at deploy time.
| Field | K8s | Remote / local | Description |
|---|---|---|---|
publicUrl | Yes | Yes | Public Controller URL. Embedded OIDC issuer is {publicUrl}/oidc. |
consoleUrl | Yes | Yes | Public EdgeOps Console URL for OAuth redirects. potctl backfills from publicUrl when empty. |
consolePort | Yes | No | Console listen port hint for Kubernetes ingress mapping (default cluster binding is port 8008). |
trustProxy | Yes | No | Honor X-Forwarded-* when Controller sits behind a reverse proxy. |
logLevel | Yes | Yes | Controller log level (for example info, debug). |
https | Yes | Yes | Prefer HTTPS when resolving endpoints. |
pidBaseDir | Yes | Yes | Base directory for Controller PID files on remote/local hosts. |
secretName | Yes | No | Kubernetes TLS secret for the Controller Service when not using ingress TLS. |
package.image | Via images | Yes | Controller container image on remote/local hosts. |
package.registry | No | Yes | Private registry host. Required with username and password when any credential field is set. |
package.username | No | Yes | Registry username for private Controller image pulls. |
package.password | No | Yes | Registry password. |
package.email | No | Yes | Registry email (optional). |
When both spec.endpoint and controller.publicUrl are set on remote or local Control Planes, they must match.
spec.vault
Optional secret store for the Controller. See Controller configuration.
| Field | Description |
|---|---|
enabled | Enable vault integration. |
provider | Required when enabled: hashicorp, openbao, vault, aws, aws-secrets-manager, azure, azure-key-vault, google, or google-secret-manager. |
basePath | Required when enabled. Base path inside the vault. |
hashicorp.address | Vault server address (HashiCorp / OpenBao / Vault providers). |
hashicorp.token | Vault token. |
hashicorp.mount | Secret engine mount path. |
aws.region | AWS region. |
aws.accessKeyId | AWS access key ID. |
aws.accessKey | AWS secret access key. |
azure.url | Azure Key Vault URL. |
azure.tenantId | Azure tenant ID. |
azure.clientId | Azure client ID. |
azure.clientSecret | Azure client secret. |
google.projectId | Google Cloud project ID. |
google.credentials | Google service account credentials JSON. |
TLS and trust (spec.ca, spec.tls, site CAs)
Remote and local Control Planes accept base64-encoded PEM material in YAML. All certificate and key values must be valid base64.
| Field | Kinds | Description |
|---|---|---|
ca | All | Trust anchor potctl stores for Controller API verification. |
tls.ca | Remote, local | Optional CA for Controller listener TLS. |
tls.cert | Remote, local | Controller TLS certificate (PEM, base64). Must be set together with tls.key. |
tls.key | Remote, local | Controller TLS private key (PEM, base64). |
routerSiteCA.tlsCert / tlsKey | Remote, local | Router site CA certificate and key. |
routerLocalCA.tlsCert / tlsKey | Remote, local | Router local CA certificate and key. |
natsSiteCA.tlsCert / tlsKey | Remote, local | NATS site CA certificate and key. |
natsLocalCA.tlsCert / tlsKey | Remote, local | NATS local CA certificate and key. |
controllers[].tls | Remote | Per-Controller TLS override (same shape as spec.tls). |
On Kubernetes, create secrets pot-site-ca and default-router-local-ca in the Control Plane namespace when you bring your own Router or NATS CA. See Certificates for Router and NATS.
spec.systemMicroservices (remote and local)
Per-architecture Router and NATS images deployed as system microservices.
| Field | Description |
|---|---|
router.amd64 | Router image for amd64 hosts. |
router.arm64 | Router image for arm64 hosts. |
router.riscv64 | Router image for riscv64 hosts. |
router.arm | Router image for 32-bit ARM hosts. |
nats.amd64 | NATS image for amd64 hosts. |
nats.arm64 | NATS image for arm64 hosts. |
nats.riscv64 | NATS image for riscv64 hosts. |
nats.arm | NATS image for 32-bit ARM hosts. |
List all four keys when your fleet mixes CPU architectures, especially with airgap: true.
Kubernetes Control Plane
The KubernetesControlPlane kind deploys the Controller, Router, and NATS on a Kubernetes cluster. The operator manages lifecycle, replicas, Services, ingress settings, optional vault, and external database settings.
---
apiVersion: datasance.com/v3
kind: KubernetesControlPlane
metadata:
name: pot
namespace: default
spec:
config: .kube/config
iofogUser:
name: Foo
surname: Bar
password: "TestPassword12!"
replicas:
controller: 2
nats: 2
controller:
publicUrl: https://controller.example.com
trustProxy: true
consolePort: 8080
consoleUrl: https://console.example.com
logLevel: info
https: true
auth:
mode: embedded
insecureAllowHttp: false
insecureAllowBootstrapLog: false
bootstrap:
username: admin
password: "LocalTest12!"
events:
auditEnabled: true
retentionDays: 14
cleanupInterval: 86400
captureIpAddress: true
images:
pullSecret: my-registry-secret
operator: ghcr.io/datasance/operator:3.8.0
controller: ghcr.io/datasance/controller:v3.8.0
router: ghcr.io/datasance/router:3.8.0
nats: ghcr.io/datasance/nats:2.14.3
nats:
enabled: true
jetStream:
storageSize: "10Gi"
memoryStoreSize: "1Gi"
storageClassName: ""
services:
controller:
type: ClusterIP
annotations: {}
externalTrafficPolicy: Cluster
router:
type: ClusterIP
annotations: {}
nats:
type: ClusterIP
annotations: {}
natsServer:
type: ClusterIP
annotations: {}
ingresses:
controller:
annotations: {}
ingressClassName: nginx
host: controller.example.com
secretName: controller-tls
router:
address: router.example.com
messagePort: 5671
interiorPort: 55671
edgePort: 45671
nats:
address: nats.example.com
serverPort: 4222
clusterPort: 6222
leafPort: 7422
mqttPort: 8883
httpPort: 8222
database:
provider: postgres
user: dbuser
host: db.example.com
port: 5432
password: secret
databaseName: iofog
ssl: true
ca: "<base64 CA>"
vault:
enabled: false
provider: hashicorp
basePath: secret/pot
hashicorp:
address: https://vault.example.com
token: "<token>"
mount: secret
Kubernetes-only fields
| Field | Required | Description |
|---|---|---|
config | Yes | Path to the kubeconfig potctl uses to install operator resources. |
replicas.controller | No | Controller pod count (default 1). Values greater than 1 require database. |
replicas.nats | No | NATS StatefulSet replicas when NATS is enabled. Must be at least 2 when set. Omit for operator default. |
images.pullSecret | No | Kubernetes imagePullSecret name for private registries. |
images.operator | No | Operator image. |
images.controller | No | Controller image. |
images.router | No | Router image. |
images.nats | No | NATS image. |
nats.enabled | No | Enable NATS hub (default true when nats block is omitted). |
nats.jetStream.storageSize | No | JetStream PVC size (for example 10Gi). |
nats.jetStream.memoryStoreSize | No | JetStream memory store size. |
nats.jetStream.storageClassName | No | StorageClass for JetStream PVCs. Empty string uses cluster default. |
services.controller.type | No | Kubernetes Service type (ClusterIP, LoadBalancer, NodePort). |
services.controller.annotations | No | Service annotations. |
services.controller.externalTrafficPolicy | No | Cluster or Local. Use Cluster on k3s/OrbStack when type is LoadBalancer. |
services.router.* | No | Same fields as controller Service. |
services.nats.* | No | Service for NATS leaf/advertised endpoints. |
services.natsServer.* | No | Service for NATS server cluster port. |
ingresses.controller.host | When Controller Service is ClusterIP | Ingress hostname for the Controller API. |
ingresses.controller.secretName | When Controller Service is ClusterIP | TLS secret for Controller ingress. |
ingresses.controller.ingressClassName | No | Ingress class (for example nginx). |
ingresses.controller.annotations | No | Ingress annotations. |
ingresses.router.address | When Router Service is ClusterIP | Advertised router hostname. |
ingresses.router.messagePort | When Router Service is ClusterIP | Skupper messaging port (default 5671). |
ingresses.router.interiorPort | When Router Service is ClusterIP | Interior router port (default 55671). |
ingresses.router.edgePort | When Router Service is ClusterIP | Edge router port (default 45671). |
ingresses.nats.address | No | Advertised NATS hostname. |
ingresses.nats.serverPort | No | NATS client port (default 4222). |
ingresses.nats.clusterPort | No | NATS cluster port (default 6222). |
ingresses.nats.leafPort | No | NATS leaf port (default 7422). |
ingresses.nats.mqttPort | No | NATS MQTT port (default 8883). |
ingresses.nats.httpPort | No | NATS monitoring HTTP port (default 8222). |
endpoint | No | Runtime: Controller URL after deploy. Usually omitted from input YAML. |
controllerPods | No | Runtime: operator-managed pod list. Do not set in deploy YAML. |
When services.controller.type is ClusterIP, you must set ingresses.controller.host and ingresses.controller.secretName.
When services.router.type is ClusterIP, you must set ingresses.router.address, messagePort, interiorPort, and edgePort.
Use LoadBalancer Services (with externalTrafficPolicy: Cluster on lightweight clusters) to skip ingress requirements for dev clusters.
Ingress settings for Router and NATS configure advertised addresses and ports. They do not always create Kubernetes Ingress objects, depending on your cluster setup.
Router and NATS deploy with TLS by default. Without your own CA, the operator creates self-signed certificates. See Certificates for Router and NATS.
Kubernetes dev example (LoadBalancer)
For local Kubernetes (k3s, OrbStack), prefer LoadBalancer Services instead of ingress:
---
apiVersion: datasance.com/v3
kind: KubernetesControlPlane
metadata:
name: pot-dev
spec:
config: ~/.kube/config
iofogUser:
controller:
trustProxy: false
https: false
auth:
mode: embedded
insecureAllowHttp: true
bootstrap:
username: admin
password: "LocalTest12!"
images:
controller: ghcr.io/datasance/controller:v3.8.0
router: ghcr.io/datasance/router:3.8.0
nats: ghcr.io/datasance/nats:2.14.3
nats:
enabled: true
services:
controller:
type: LoadBalancer
externalTrafficPolicy: Cluster
router:
type: LoadBalancer
externalTrafficPolicy: Cluster
nats:
type: LoadBalancer
externalTrafficPolicy: Cluster
Remote Control Plane
The ControlPlane kind deploys the Controller (and Router, NATS, and a system Edgelet node) on remote hosts over SSH. Set nats.enabled: true to run NATS alongside each Controller. Set airgap: true for air-gapped installs.
Each entry in controllers[] must include a systemAgent block. Deploy validation fails when it is missing. At minimum set systemAgent.config.arch and containerEngine.
---
apiVersion: datasance.com/v3
kind: ControlPlane
metadata:
name: remote
spec:
endpoint: https://controller.example.com
iofogUser:
name: Foo
surname: Bar
password: "TestPassword12!"
controller:
publicUrl: https://controller.example.com
consoleUrl: https://console.example.com
logLevel: info
package:
image: ghcr.io/datasance/controller:v3.8.0
auth:
mode: embedded
insecureAllowHttp: false
bootstrap:
username: admin
password: "RemoteTest12!"
systemMicroservices:
router:
amd64: ghcr.io/datasance/router:3.8.0
arm64: ghcr.io/datasance/router:3.8.0
riscv64: ghcr.io/datasance/router:3.8.0
arm: ghcr.io/datasance/router:3.8.0
nats:
amd64: ghcr.io/datasance/nats:2.14.3
arm64: ghcr.io/datasance/nats:2.14.3
riscv64: ghcr.io/datasance/nats:2.14.3
arm: ghcr.io/datasance/nats:2.14.3
nats:
enabled: true
events:
auditEnabled: true
retentionDays: 14
cleanupInterval: 86400
captureIpAddress: true
database:
provider: postgres
user: dbuser
host: db.example.com
port: 5432
password: secret
databaseName: iofog
controllers:
- name: remote-1
host: 10.0.128.192
ssh:
user: foo
keyFile: ~/.ssh/id_rsa
port: 22
systemAgent:
package:
container:
image: ghcr.io/datasance/edgelet:1.0.0
config:
arch: amd64
host: 10.0.128.192
containerEngine: edgelet
containerEngineUrl: unix:///run/edgelet/containerd.sock
deploymentType: native
- name: remote-2
host: 10.0.128.193
ssh:
user: foo
keyFile: ~/.ssh/id_rsa
port: 22
systemAgent:
package:
container:
image: ghcr.io/datasance/edgelet:1.0.0
config:
arch: amd64
host: 10.0.128.193
containerEngine: edgelet
deploymentType: native
Remote-only fields
| Field | Required | Description |
|---|---|---|
endpoint | No | Load-balancer or shared front-end URL. Must match controller.publicUrl when both are set. |
airgap | No | Pull images on the operator machine and transfer over SSH. Requires systemAgent.config.arch on each controller. See Airgap Deployment. |
nats.enabled | No | Deploy NATS hub microservice on each Controller host. |
controllers | Yes | List of Controller hosts (at least one). |
controllers[].name | Yes | Unique lowercase alphanumeric name per Controller. |
controllers[].host | Yes | SSH target hostname or IP. |
controllers[].ssh.user | Yes | SSH username. |
controllers[].ssh.keyFile | Yes | Path to SSH private key on the operator machine. |
controllers[].ssh.port | No | SSH port (default 22). |
controllers[].systemAgent | Yes | System Edgelet node on the Controller host. See System Edgelet on Control Plane hosts. |
controllers[].tls | No | Per-host TLS material (same shape as spec.tls). |
controllers[].endpoint | No | Runtime: resolved Controller URL for this host. |
controllers[].created | No | Runtime: deploy timestamp. |
When controllers has more than one entry, database with a non-empty provider is required.
Single remote Controller
For one Controller host, omit database and list a single entry under controllers:
---
apiVersion: datasance.com/v3
kind: ControlPlane
metadata:
name: remote-single
spec:
endpoint: https://controller.example.com
iofogUser:
controller:
publicUrl: https://controller.example.com
consoleUrl: https://console.example.com
package:
image: ghcr.io/datasance/controller:v3.8.0
auth:
mode: embedded
bootstrap:
username: admin
password: "RemoteTest12!"
controllers:
- name: remote-1
host: 10.0.128.192
ssh:
user: foo
keyFile: ~/.ssh/id_rsa
systemAgent:
config:
arch: amd64
containerEngine: edgelet
host: 10.0.128.192
Local Control Plane
The LocalControlPlane kind deploys the Controller with a system Edgelet node on the same machine. Use it for quick starts and development. Set nats.enabled: true to enable NATS.
spec.systemAgent is required. Set systemAgent.config.arch at minimum.
---
apiVersion: datasance.com/v3
kind: LocalControlPlane
metadata:
name: buffalo
namespace: default
spec:
endpoint: http://127.0.0.1:51121
iofogUser:
name: Foo
surname: Bar
password: "TestPassword12!"
controller:
publicUrl: http://127.0.0.1:51121
consoleUrl: http://127.0.0.1:8008
logLevel: info
package:
image: ghcr.io/datasance/controller:v3.8.0
auth:
mode: embedded
insecureAllowHttp: true
bootstrap:
username: admin
password: "LocalTest12!"
systemMicroservices:
router:
amd64: ghcr.io/datasance/router:3.8.0
arm64: ghcr.io/datasance/router:3.8.0
riscv64: ghcr.io/datasance/router:3.8.0
arm: ghcr.io/datasance/router:3.8.0
nats:
amd64: ghcr.io/datasance/nats:2.14.3
arm64: ghcr.io/datasance/nats:2.14.3
riscv64: ghcr.io/datasance/nats:2.14.3
arm: ghcr.io/datasance/nats:2.14.3
nats:
enabled: true
events:
auditEnabled: true
retentionDays: 14
systemAgent:
package:
container:
image: ghcr.io/datasance/edgelet:1.0.0
config:
arch: amd64
containerEngine: edgelet
containerEngineUrl: unix:///run/edgelet/containerd.sock
deploymentType: native
Local-only fields
| Field | Required | Description |
|---|---|---|
airgap | No | Air-gapped local install. Pair with pinned images under controller.package and systemMicroservices. |
systemAgent | Yes | System Edgelet node co-deployed with the Controller. |
controllers | No | Optional list of local Controller records (runtime). Most installs omit this block. |
auth.insecureAllowHttp | No | Allow http:// URLs for local development. |
Shared remote/local fields (endpoint, ca, tls, site CA blocks, vault, database, nats.enabled) use the same shapes as the shared spec blocks.
Controller add-on
Add another Controller to an existing remote Control Plane with the Controller kind. The namespace must already contain a full ControlPlane deploy with auth.mode and spec.controller populated.
---
apiVersion: datasance.com/v3
kind: Controller
metadata:
name: alpaca
namespace: default
spec:
host: 30.40.50.5
ssh:
user: foo
keyFile: ~/.ssh/id_rsa
port: 22
systemAgent:
package:
container:
image: ghcr.io/datasance/edgelet:1.0.0
config:
arch: amd64
host: 30.40.50.5
containerEngine: edgelet
deploymentType: native
| Field | Description |
|---|---|
metadata.name | Unique Controller name. Lowercase alphanumeric; hyphens allowed. Must not duplicate an existing controller name or host in the namespace. |
host | Remote host potctl reaches over SSH. |
ssh.user | SSH username. |
ssh.keyFile | Path to the private SSH key. |
ssh.port | SSH port (default 22). |
systemAgent | Required. System Edgelet on the new Controller host (same shape as controllers[].systemAgent). |
tls | Optional per-Controller TLS override. |
endpoint | Runtime: resolved URL after deploy. |
created | Runtime: deploy timestamp. |
You cannot add a second Controller when the stored Control Plane uses SQLite (no database.provider). Configure database on the original ControlPlane YAML before scaling out.
Deploy with potctl connect -f controller.yaml or include the resource in a multi-document file. If the namespace has no prior Control Plane metadata, deploy the full ControlPlane YAML first.
System Edgelet on Control Plane hosts
Remote and local Control Planes deploy a system Edgelet node on the Controller host. The YAML shape matches standalone Agent deploy specs under systemAgent (or controllers[].systemAgent on remote).
Package fields
| Field | Description |
|---|---|
package.version | Edgelet binary release tag for native installs. |
package.container.image | Edgelet container image (default train: ghcr.io/datasance/edgelet:1.0.0). |
package.container.registry | Registry host for air-gapped or private pulls. |
package.container.username | Registry username. |
package.container.password | Registry password. |
package.wasm.<handler>.url | Download URL for a Wasm shim bundle. |
package.wasm.<handler>.path | Local path to a Wasm shim bundle on the operator machine. |
package.wasm.<handler>.sha256 | Optional SHA-256 digest (64 hex characters). |
Allowed Wasm handlers include spin and edgelet-wasmtime. Wasm packages are not supported when containerEngine is podman.
Script fields
Optional custom install scripts use the same shape as Agent installation scripts: scripts.dir, scripts.deps, scripts.install, and scripts.uninstall.
Config fields
Runtime Edgelet settings live under systemAgent.config. They use the same fields as Agent / AgentConfig documented in Configuration fields.
On Control Plane hosts, when you set router or NATS mode explicitly:
routerConfig.routerModemust beinterior(notedge).natsConfig.natsModemust beserver(notleaf).
Omit these fields to accept operator defaults for system nodes.
External OIDC example
---
apiVersion: datasance.com/v3
kind: ControlPlane
metadata:
name: remote-oidc
spec:
iofogUser:
controller:
publicUrl: https://controller.example.com
consoleUrl: https://console.example.com
package:
image: ghcr.io/datasance/controller:v3.8.0
auth:
mode: external
issuerUrl: https://idp.example.com/realms/pot
client:
id: pot-controller
secret: "<client-secret>"
consoleClient: pot-console
consoleClientEnabled: true
controllers:
- name: remote-1
host: 10.0.0.10
ssh:
user: admin
keyFile: ~/.ssh/id_rsa
systemAgent:
config:
arch: amd64
containerEngine: edgelet
host: 10.0.0.10
Edge Compute Network
Define an entire ECN in one YAML file by listing multiple resources separated by ---. The example below shows a remote Control Plane with two Controllers and two Edgelet nodes.
---
apiVersion: datasance.com/v3
kind: ControlPlane
metadata:
name: buffalo
namespace: default
spec:
iofogUser:
name: John
surname: Doe
password: "TestPassword12!"
controller:
publicUrl: https://controller.example.com:51121
consoleUrl: https://console.example.com:8008
package:
image: ghcr.io/datasance/controller:v3.8.0
auth:
mode: embedded
bootstrap:
username: admin
password: "LocalTest12!"
database:
provider: postgres
user: dbuser
host: db.example.com
port: 5432
password: secret
databaseName: iofog
controllers:
- name: alpaca-1
host: 30.40.50.3
ssh:
user: john
keyFile: ~/.ssh/id_rsa
systemAgent:
config:
arch: amd64
host: 30.40.50.3
containerEngine: edgelet
- name: alpaca-2
host: 30.40.50.4
ssh:
user: john
keyFile: ~/.ssh/id_rsa
systemAgent:
config:
arch: amd64
host: 30.40.50.4
containerEngine: edgelet
---
apiVersion: datasance.com/v3
kind: Agent
metadata:
name: hippo-1
namespace: default
spec:
host: 30.40.50.6
ssh:
user: john
keyFile: ~/.ssh/id_rsa
config:
arch: amd64
containerEngine: edgelet
---
apiVersion: datasance.com/v3
kind: Agent
metadata:
name: hippo-2
namespace: default
spec:
host: 30.40.50.7
ssh:
user: john
keyFile: ~/.ssh/id_rsa
config:
arch: amd64
containerEngine: edgelet
Field availability by kind
| Field / block | K8s | Remote | Local | Controller add-on |
|---|---|---|---|---|
config (kubeconfig) | Yes | |||
replicas | Yes | |||
images | Yes | |||
services / ingresses | Yes | |||
nats.jetStream | Yes | |||
controller.consolePort / trustProxy / secretName | Yes | |||
endpoint | Runtime | Yes | Yes | |
airgap | Yes | Yes | ||
systemMicroservices | Yes | Yes | ||
routerSiteCA / natsSiteCA / site CA blocks | Yes | Yes | ||
tls (spec level) | Yes | Yes | Per-controller | |
controllers[] | Yes | Optional | N/A (this kind) | |
systemAgent (spec level) | Yes | |||
systemAgent (per controller) | Yes | Yes | ||
Shared: iofogUser, auth, database, events, controller, vault, ca, nats.enabled | Yes | Yes | Yes | Inherits from stored CP |