Xeonr Developer Docs
API SpecificationNamespaces

Create Namespace

POST
/containers.api.v1.NamespaceService/CreateNamespace

Creates a namespace owned by owner_team (a team URN, or transitionally a bare slug; platform admins' values are verified against Xeonr Auth and canonicalised to the URN), places it on cluster_id (empty: the team's default cluster, else the platform's) and provisions its dedicated runner namespace cp-rn-<namespace>. namespace must be a DNS-label slug of at most 40 characters. Team admins may not set internal targets or image pull secrets (PermissionDenied). Quotas left at zero default to 4000 mCPU, 8192 MB memory, 16 pods, 50 GiB storage and 20 volumes; a team admin may set them within the team's grant on the cluster (ResourceExhausted beyond it), and a platform admin without limit. Returns AlreadyExists for a taken name.

Access: a platform admin, or an admin of the owner_team team.

Authorization

BearerAuth
AuthorizationBearer <token>

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

Connect-Protocol-Version?number

Define the version of the Connect protocol

Connect-Timeout-Ms?number

Define the timeout, in ms

Request Body

application/json

namespace?string

DNS-label slug: lowercase alphanumeric and hyphens, 1-40 chars.

Match^[a-z0-9]([a-z0-9-]{0,38}[a-z0-9])?$
displayName?string
Lengthlength <= 4096
groups?Deprecated

validate:skip deprecated and ignored by the server

defaultLimits?
quotaCpuMillis?integer

validate:skip 0 = server default (team admins must send 0) / unlimited; no ceiling

quotaMemoryMb?integer

validate:skip as quota_cpu_millis

quotaMaxPods?integer

validate:skip as quota_cpu_millis

internalTargets?
Itemsitems <= 1000
imagePullSecrets?image_pull_secrets
Itemsitems <= 1000
ownerTeam?string

Owning team: a team URN (urn:xeonr:auth:team:<uuid>) or, transitionally, a bare team slug. Required. The caller must be a platform admin or hold the team's admin role.

Match^(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])?)$
quotaStorageMb?integer

validate:skip as quota_cpu_millis

quotaMaxVolumes?integer

validate:skip as quota_cpu_millis

clusterId?string

Where the namespace runs. Empty resolves to the owner team's default cluster (TeamSettingsService), else the platform's default cluster. The team must be able to place on it: it owns the cluster, holds a grant on it, or the cluster is GLOBAL. A cluster the caller cannot see is NotFound; one it can see but not place on is PermissionDenied; one that is PENDING is FailedPrecondition. The quotas must fit the team's grant on the cluster (ResourceExhausted otherwise).

Match^(cl-[0-9a-f]{16})?$
[key: string]?never

Response Body

application/json

application/json

curl -X POST "https://containers.xeonr.io/containers.api.v1.NamespaceService/CreateNamespace" \  -H "Connect-Protocol-Version: 1" \  -H "Connect-Timeout-Ms: 1000" \  -H "Content-Type: application/json" \  -d '{}'
{
  "namespace": {
    "namespace": "string",
    "displayName": "string",
    "k8sRunnerNamespace": "string",
    "groups": [
      {
        "oidcGroup": "string",
        "role": "ROLE_UNSPECIFIED"
      }
    ],
    "defaultLimits": {
      "cpuMillis": 0,
      "memoryMb": 0,
      "ephemeralMb": 0,
      "pids": 0
    },
    "quotaCpuMillis": 0,
    "quotaMemoryMb": 0,
    "quotaMaxPods": 0,
    "quotaStorageMb": 0,
    "quotaMaxVolumes": 0,
    "internalTargets": [
      {
        "host": "string",
        "port": 1
      }
    ],
    "imagePullSecrets": [
      "string"
    ],
    "ownerTeam": "string",
    "clusterId": "string",
    "move": {
      "state": "STATE_UNSPECIFIED",
      "sourceClusterId": "string",
      "targetClusterId": "string",
      "startedAt": "2023-01-15T01:30:15.01Z",
      "updatedAt": "2023-01-15T01:30:15.01Z",
      "finishedAt": "2023-01-15T01:30:15.01Z",
      "message": "string",
      "rolledBack": true,
      "estimatedDowntimeSec": 0,
      "volumes": [
        {
          "volumeId": "string",
          "archiveSnapshotId": "string",
          "sourceNode": "string",
          "sourceState": "VOLUME_STATE_UNSPECIFIED",
          "reseeded": true
        }
      ],
      "startedBy": "string"
    }
  }
}
{
  "code": "not_found",
  "message": "string",
  "details": [
    {
      "type": "string",
      "value": "string",
      "debug": {}
    }
  ]
}