Create Cluster
Registers a cluster owned by owner_team in PENDING state with PRIVATE visibility. Nothing runs on it until an operator enrols (CreateEnrolmentToken, then the operator's first connection). A platform admin's owner_team is verified against Xeonr Auth and canonicalised to the team URN.
Access: a platform admin, or an admin of the owner_team team.
Authorization
BearerAuth A namespace-scoped API key (cpk_…) for machines, or a Xeonr Auth OIDC
token for humans. The key's namespace and role are pinned server-side.
In: header
Header Parameters
Define the version of the Connect protocol
Define the timeout, in ms
Request Body
application/json
1 <= length <= 255The owning team: a URN, or for a platform admin a slug that is verified and canonicalised.
^(urn:xeonr:auth:team:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|[a-z0-9]([a-z0-9-]{0,38}[a-z0-9])?)$properties <= 32Response Body
application/json
application/json
curl -X POST "https://containers.xeonr.io/containers.api.v1.ClusterService/CreateCluster" \ -H "Connect-Protocol-Version: 1" \ -H "Connect-Timeout-Ms: 1000" \ -H "Content-Type: application/json" \ -d '{}'{
"cluster": {
"clusterId": "string",
"displayName": "string",
"ownerTeam": "string",
"visibility": "CLUSTER_VISIBILITY_UNSPECIFIED",
"grants": [
{
"team": "string",
"quotaCpuMillis": 0,
"quotaMemoryMb": 0,
"quotaMaxPods": 0,
"quotaStorageMb": 0,
"quotaMaxVolumes": 0
}
],
"default": true,
"allowRunc": true,
"state": "CLUSTER_STATE_UNSPECIFIED",
"lastSeen": "2023-01-15T01:30:15.01Z",
"operatorVersion": "string",
"capabilities": {
"gvisor": true,
"cpCsi": true,
"previewIngress": true,
"appIngress": true,
"previewDomain": "string",
"appDomain": "string"
},
"labels": {
"property1": "string",
"property2": "string"
},
"createdAt": "2023-01-15T01:30:15.01Z",
"capacity": {
"observedAt": "2023-01-15T01:30:15.01Z",
"nodes": [
{
"name": "string",
"ready": true,
"allocatableCpuMillis": "string",
"allocatableMemoryMb": "string",
"allocatablePods": 0,
"requestedCpuMillis": "string",
"requestedMemoryMb": "string",
"pods": 0,
"volumeDiskFreeMb": "string"
}
],
"installCap": {
"cpuMillis": "string",
"memoryMb": "string",
"pods": 0,
"storageMb": "string",
"volumes": 0
},
"installRequested": {
"cpuMillis": "string",
"memoryMb": "string",
"pods": 0,
"storageMb": "string",
"volumes": 0
}
},
"conditions": [
{
"type": "TYPE_UNSPECIFIED",
"message": "string",
"since": "2023-01-15T01:30:15.01Z",
"pods": [
"string"
]
}
],
"archiveIntervalSec": 0,
"archivedBytes": "string"
}
}{
"code": "not_found",
"message": "string",
"details": [
{
"type": "string",
"value": "string",
"debug": {}
}
]
}containers.api.v1.ClusterService
ClusterService manages where namespaces run (BYOC, platform-docs container-platform/docs/BYOC.md §2). A cluster is one operator install: one enrolment, one credential, one owner team. Two teams installing on the same physical cluster produce two records, and the platform neither knows nor needs to know that they share hardware. The platform's own fleet is a cluster like any other, flagged GLOBAL and `default`, which is where a namespace lands when nothing names a cluster. A namespace is placed on exactly one cluster when it is created (Namespace.cluster_id) and everything beneath it — sandboxes, jobs, apps, environments, volumes, pools, keys — runs there. Placement is immutable: moving a namespace is a migration, not an update. Who may place a namespace on a cluster is its visibility: PRIVATE is the owner team only; SHARED adds the teams holding a grant; GLOBAL is every team, within the everyone-grant. A grant also caps how much of the cluster that team's namespaces may hold in total (BYOC.md §5.4): the sum of a team's namespace quotas on a cluster must fit its grant, and the owner team's grant is implicit and unbounded. GetCluster and ListClusters carry allow_api_keys: a namespace key reaches the cluster its namespace is placed on and nothing else. The mutations do not, for the reason CreateNamespace does not: each needs a team role, and no key holds one.
Create Enrolment Token POST
Mints a one-time enrolment token for a cluster, valid for 15 minutes, which an operator install exchanges for its cluster credential on first start. The secret is returned exactly once. Minting a new token does not revoke an unspent earlier one until it expires. **Access:** admin of the owner team, or a platform admin. Other callers get NotFound.