# Clusters

Create and manage workload Kubernetes clusters

## List clusters

> Returns all clusters in the namespace. The namespace is scoped to a single\
> tenant (\`{du-name}-{keystone-domain}-{keystone-tenant}\`), so this effectively\
> lists all clusters owned by that tenant.<br>

```json
{"openapi":"3.0.3","info":{"title":"PCD-K Cluster API","version":"v1beta1"},"tags":[{"name":"Clusters","description":"Create and manage workload Kubernetes clusters"}],"servers":[{"url":"https://{du-name}-{region}.{du-domain}/oidc-proxy/{tenant}/{region}","variables":{"du-name":{"default":"pcd"},"region":{"default":"r1"},"du-domain":{"default":"example.com"},"tenant":{"default":"service"}}}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Dex-issued JWT token."}},"schemas":{"Cluster":{"allOf":[{"$ref":"#/components/schemas/ClusterRequest"},{"type":"object","properties":{"metadata":{"type":"object","properties":{"namespace":{"type":"string","description":"Tenant namespace the cluster belongs to."},"uid":{"type":"string","format":"uuid"},"resourceVersion":{"type":"string"},"creationTimestamp":{"type":"string","format":"date-time"},"deletionTimestamp":{"type":"string","format":"date-time","description":"Set when deletion is in progress. Present until all finalizers are removed."},"labels":{"type":"object","additionalProperties":{"type":"string"},"description":"Labels set by the webhook and controllers. Do not rely on specific values for business logic."},"finalizers":{"type":"array","items":{"type":"string"},"description":"CAPI finalizers preventing premature deletion."}}},"status":{"type":"object","properties":{"phase":{"type":"string","enum":["Provisioning","Provisioned","Deleting","Failed"]},"controlPlaneReady":{"type":"boolean"},"infrastructureReady":{"type":"boolean"},"failureMessage":{"type":"string","description":"Human-readable error message when `phase` is `Failed`."},"failureDomains":{"type":"object","description":"Map of OpenStack availability zone names to their control-plane eligibility.\nPopulated from the `OpenStackCluster` status after infrastructure is ready.\n","additionalProperties":{"type":"object","properties":{"controlPlane":{"type":"boolean"}}}},"conditions":{"type":"array","description":"Standard CAPI conditions. Key `type` values to watch:\n`Ready`, `ControlPlaneInitialized`, `ControlPlaneReady`,\n`InfrastructureReady`, `TopologyReconciled`.\nAll conditions reach `status: \"True\"` when the cluster is fully provisioned.\n","items":{"type":"object","properties":{"type":{"type":"string"},"status":{"type":"string","enum":["True","False","Unknown"]},"reason":{"type":"string"},"message":{"type":"string"},"lastTransitionTime":{"type":"string","format":"date-time"}}}}}}}}]},"ClusterRequest":{"type":"object","required":["apiVersion","kind","metadata","spec"],"properties":{"apiVersion":{"type":"string","enum":["cluster.x-k8s.io/v1beta1"]},"kind":{"type":"string","enum":["Cluster"]},"metadata":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"spec":{"type":"object","required":["topology"],"properties":{"controlPlaneEndpoint":{"type":"object","description":"API server endpoint — webhook-generated from `deploymentUnit` variables, not set by the user.\nFormat: `<cluster-name>.<keystone-domain>-<keystone-tenant>.k8s.<du-name>.<du-domain>`.\nUse this host:port to reach the workload cluster's Kubernetes API.\n","properties":{"host":{"type":"string"},"port":{"type":"integer"}}},"topology":{"type":"object","required":["version","workers","variables"],"properties":{"version":{"type":"string","description":"Kubernetes version (no `v` prefix)."},"class":{"type":"string","enum":["openstack-default-v1","byoh-default-v1"],"description":"Webhook-resolved from `infrastructure.type` and `deploymentUnit.type` — omit this field.\nSet `infrastructure.type: byoh` in variables to use `byoh-default-v1`; otherwise `openstack-default-v1` is used.\n"},"classNamespace":{"type":"string","enum":["kaapi"],"description":"Webhook-set to `kaapi` — omit this field."},"workers":{"type":"object","properties":{"machineDeployments":{"type":"array","items":{"$ref":"#/components/schemas/MachineDeployment"}}}},"variables":{"type":"array","description":"Each entry is `{ name: <variable>, value: <object> }`.\nThe webhook manages `kubeadmConfigFiles`, `customSecurityGroupRules`, and\nsystem-required `apiServerFlags` automatically — do not set these.\n\n| Variable | Schema | Required | Notes |\n|---|---|---|---|\n| `deploymentUnit` | `DeploymentUnitValue` | Always | `name`, `domain`, `region` are required fields |\n| `network` | `NetworkValue` | OpenStack only | `networkID`, `subnetID` UUIDs |\n| `infrastructure` | `InfrastructureValue` | Only for BYOH | Omit entirely for OpenStack |\n| `workerNode` | `WorkerNodeValue` | OpenStack per-pool override | `flavor`, `imageName` required |\n| `rootVolume` | `RootVolumeValue` | Optional, OpenStack | Boot from Cinder volume |\n| `apiServerFlags` | string array | Optional | Merged with system defaults |\n| `controllerManagerFlags` | string array | Optional | — |\n| `schedulerFlags` | string array | Optional | — |\n| `enableSSH` | boolean | Optional, OpenStack | Adds SSH security group rule |\n| `allowedAddressPairs` | string array | Optional, OpenStack | CIDRs for allowed address pairs |\n","items":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string"},"value":{}}}}}}}}}},"MachineDeployment":{"type":"object","required":["name","class"],"properties":{"name":{"type":"string","description":"Pool name — must be unique within the cluster."},"class":{"type":"string","enum":["ost-md","byoh-md"],"description":"`ost-md` for OpenStack worker pools; `byoh-md` for BYOH pools."},"replicas":{"type":"integer","minimum":0,"description":"Fixed replica count. Omit when enabling cluster autoscaler."},"failureDomain":{"type":"string","description":"Virtualized cluster name"},"metadata":{"type":"object","properties":{"annotations":{"type":"object","additionalProperties":{"type":"string"},"description":"Autoscaler annotations — set both to enable, null both to disable:\n- `cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size`\n- `cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size`\n"}}},"variables":{"type":"object","description":"Per-pool variable overrides. OpenStack pools use `workerNode` (and optionally\n`rootVolume`) here. BYOH pools do not use overrides.\n","properties":{"overrides":{"type":"array","items":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string","enum":["workerNode","rootVolume","network"]},"value":{}}}}}}}},"Status":{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"type":"object","description":"Always present; typically empty (`{}`)."},"status":{"type":"string","enum":["Success","Failure"]},"message":{"type":"string","description":"Human-readable description of the error."},"reason":{"type":"string","description":"Machine-readable reason. Common values: `NotFound`, `AlreadyExists`, `BadRequest`, `Unauthorized`, `Forbidden`, `Invalid`.\n"},"details":{"type":"object","description":"Additional error context. Present on `NotFound` (includes `name`, `group`, `kind`) and `Invalid` / `422` responses (includes `causes` with per-field errors).\n","properties":{"name":{"type":"string","description":"Name of the resource involved."},"group":{"type":"string","description":"API group of the resource (e.g. `cluster.x-k8s.io`)."},"kind":{"type":"string","description":"Resource kind (e.g. `clusters`)."},"causes":{"type":"array","description":"Per-field validation errors (present on `422` responses).","items":{"type":"object","properties":{"reason":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"}}}}}},"code":{"type":"integer","description":"HTTP status code."}}}},"responses":{"Unauthorized":{"description":"Missing or invalid JWT token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"Forbidden":{"description":"Token does not have permission for this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}}}},"paths":{"/apis/cluster.x-k8s.io/v1beta1/namespaces/{namespace}/clusters":{"get":{"tags":["Clusters"],"operationId":"listClusters","summary":"List clusters","description":"Returns all clusters in the namespace. The namespace is scoped to a single\ntenant (`{du-name}-{keystone-domain}-{keystone-tenant}`), so this effectively\nlists all clusters owned by that tenant.\n","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"type":"object","properties":{"resourceVersion":{"type":"string","description":"Use for efficient re-list or watch from this point."}}},"items":{"type":"array","items":{"$ref":"#/components/schemas/Cluster"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}}}}
```

## Create a cluster

> Creates a new workload Kubernetes cluster using ClusterClass topology mode.\
> \
> The cluster webhook automatically sets labels, \`clusterNetwork\` CIDRs, \`controlPlaneEndpoint\`,\
> \`topology.class\`/\`classNamespace\`, do not include these in the request. Also it merges default for \`apiServerFlags\`,\
> \`kubeadmConfigFiles\`, and \`customSecurityGroupRules\` with user provided values.\
> \
> \*\*Class selection\*\* (resolved from variables, no need to set explicitly):\
> \
> \| \`infrastructure.type\` | \`deploymentUnit.type\` | ClusterClass used |\
> \|---|---|---|\
> \| \`openstack\` (default) | \`saas\` (default) | \`openstack-default-v1\` |\
> \| \`openstack\` | \`onprem\` | \`openstack-default-v1\` |\
> \| \`byoh\` | any | \`byoh-default-v1\` |\
> \
> \*\*Node pool variables\*\*: \`workerNode\` can be set at two levels. Set it in\
> \`spec.topology.variables\` as a cluster-wide default (applies to all pools), and/or\
> in a pool's \`variables.overrides\` to override for that pool specifically.\
> Pool-level overrides take precedence. In \`GET\` responses you will see the\
> cluster-level \`workerNode\` variable alongside pool-level overrides — both are normal.<br>

```json
{"openapi":"3.0.3","info":{"title":"PCD-K Cluster API","version":"v1beta1"},"tags":[{"name":"Clusters","description":"Create and manage workload Kubernetes clusters"}],"servers":[{"url":"https://{du-name}-{region}.{du-domain}/oidc-proxy/{tenant}/{region}","variables":{"du-name":{"default":"pcd"},"region":{"default":"r1"},"du-domain":{"default":"example.com"},"tenant":{"default":"service"}}}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Dex-issued JWT token."}},"schemas":{"ClusterRequest":{"type":"object","required":["apiVersion","kind","metadata","spec"],"properties":{"apiVersion":{"type":"string","enum":["cluster.x-k8s.io/v1beta1"]},"kind":{"type":"string","enum":["Cluster"]},"metadata":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"spec":{"type":"object","required":["topology"],"properties":{"controlPlaneEndpoint":{"type":"object","description":"API server endpoint — webhook-generated from `deploymentUnit` variables, not set by the user.\nFormat: `<cluster-name>.<keystone-domain>-<keystone-tenant>.k8s.<du-name>.<du-domain>`.\nUse this host:port to reach the workload cluster's Kubernetes API.\n","properties":{"host":{"type":"string"},"port":{"type":"integer"}}},"topology":{"type":"object","required":["version","workers","variables"],"properties":{"version":{"type":"string","description":"Kubernetes version (no `v` prefix)."},"class":{"type":"string","enum":["openstack-default-v1","byoh-default-v1"],"description":"Webhook-resolved from `infrastructure.type` and `deploymentUnit.type` — omit this field.\nSet `infrastructure.type: byoh` in variables to use `byoh-default-v1`; otherwise `openstack-default-v1` is used.\n"},"classNamespace":{"type":"string","enum":["kaapi"],"description":"Webhook-set to `kaapi` — omit this field."},"workers":{"type":"object","properties":{"machineDeployments":{"type":"array","items":{"$ref":"#/components/schemas/MachineDeployment"}}}},"variables":{"type":"array","description":"Each entry is `{ name: <variable>, value: <object> }`.\nThe webhook manages `kubeadmConfigFiles`, `customSecurityGroupRules`, and\nsystem-required `apiServerFlags` automatically — do not set these.\n\n| Variable | Schema | Required | Notes |\n|---|---|---|---|\n| `deploymentUnit` | `DeploymentUnitValue` | Always | `name`, `domain`, `region` are required fields |\n| `network` | `NetworkValue` | OpenStack only | `networkID`, `subnetID` UUIDs |\n| `infrastructure` | `InfrastructureValue` | Only for BYOH | Omit entirely for OpenStack |\n| `workerNode` | `WorkerNodeValue` | OpenStack per-pool override | `flavor`, `imageName` required |\n| `rootVolume` | `RootVolumeValue` | Optional, OpenStack | Boot from Cinder volume |\n| `apiServerFlags` | string array | Optional | Merged with system defaults |\n| `controllerManagerFlags` | string array | Optional | — |\n| `schedulerFlags` | string array | Optional | — |\n| `enableSSH` | boolean | Optional, OpenStack | Adds SSH security group rule |\n| `allowedAddressPairs` | string array | Optional, OpenStack | CIDRs for allowed address pairs |\n","items":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string"},"value":{}}}}}}}}}},"MachineDeployment":{"type":"object","required":["name","class"],"properties":{"name":{"type":"string","description":"Pool name — must be unique within the cluster."},"class":{"type":"string","enum":["ost-md","byoh-md"],"description":"`ost-md` for OpenStack worker pools; `byoh-md` for BYOH pools."},"replicas":{"type":"integer","minimum":0,"description":"Fixed replica count. Omit when enabling cluster autoscaler."},"failureDomain":{"type":"string","description":"Virtualized cluster name"},"metadata":{"type":"object","properties":{"annotations":{"type":"object","additionalProperties":{"type":"string"},"description":"Autoscaler annotations — set both to enable, null both to disable:\n- `cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size`\n- `cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size`\n"}}},"variables":{"type":"object","description":"Per-pool variable overrides. OpenStack pools use `workerNode` (and optionally\n`rootVolume`) here. BYOH pools do not use overrides.\n","properties":{"overrides":{"type":"array","items":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string","enum":["workerNode","rootVolume","network"]},"value":{}}}}}}}},"Cluster":{"allOf":[{"$ref":"#/components/schemas/ClusterRequest"},{"type":"object","properties":{"metadata":{"type":"object","properties":{"namespace":{"type":"string","description":"Tenant namespace the cluster belongs to."},"uid":{"type":"string","format":"uuid"},"resourceVersion":{"type":"string"},"creationTimestamp":{"type":"string","format":"date-time"},"deletionTimestamp":{"type":"string","format":"date-time","description":"Set when deletion is in progress. Present until all finalizers are removed."},"labels":{"type":"object","additionalProperties":{"type":"string"},"description":"Labels set by the webhook and controllers. Do not rely on specific values for business logic."},"finalizers":{"type":"array","items":{"type":"string"},"description":"CAPI finalizers preventing premature deletion."}}},"status":{"type":"object","properties":{"phase":{"type":"string","enum":["Provisioning","Provisioned","Deleting","Failed"]},"controlPlaneReady":{"type":"boolean"},"infrastructureReady":{"type":"boolean"},"failureMessage":{"type":"string","description":"Human-readable error message when `phase` is `Failed`."},"failureDomains":{"type":"object","description":"Map of OpenStack availability zone names to their control-plane eligibility.\nPopulated from the `OpenStackCluster` status after infrastructure is ready.\n","additionalProperties":{"type":"object","properties":{"controlPlane":{"type":"boolean"}}}},"conditions":{"type":"array","description":"Standard CAPI conditions. Key `type` values to watch:\n`Ready`, `ControlPlaneInitialized`, `ControlPlaneReady`,\n`InfrastructureReady`, `TopologyReconciled`.\nAll conditions reach `status: \"True\"` when the cluster is fully provisioned.\n","items":{"type":"object","properties":{"type":{"type":"string"},"status":{"type":"string","enum":["True","False","Unknown"]},"reason":{"type":"string"},"message":{"type":"string"},"lastTransitionTime":{"type":"string","format":"date-time"}}}}}}}}]},"Status":{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"type":"object","description":"Always present; typically empty (`{}`)."},"status":{"type":"string","enum":["Success","Failure"]},"message":{"type":"string","description":"Human-readable description of the error."},"reason":{"type":"string","description":"Machine-readable reason. Common values: `NotFound`, `AlreadyExists`, `BadRequest`, `Unauthorized`, `Forbidden`, `Invalid`.\n"},"details":{"type":"object","description":"Additional error context. Present on `NotFound` (includes `name`, `group`, `kind`) and `Invalid` / `422` responses (includes `causes` with per-field errors).\n","properties":{"name":{"type":"string","description":"Name of the resource involved."},"group":{"type":"string","description":"API group of the resource (e.g. `cluster.x-k8s.io`)."},"kind":{"type":"string","description":"Resource kind (e.g. `clusters`)."},"causes":{"type":"array","description":"Per-field validation errors (present on `422` responses).","items":{"type":"object","properties":{"reason":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"}}}}}},"code":{"type":"integer","description":"HTTP status code."}}}},"responses":{"BadRequest":{"description":"Malformed request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"Unauthorized":{"description":"Missing or invalid JWT token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"Forbidden":{"description":"Token does not have permission for this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"Conflict":{"description":"A cluster with this name already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"UnprocessableEntity":{"description":"Admission webhook rejected the request due to a validation failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}}}},"paths":{"/apis/cluster.x-k8s.io/v1beta1/namespaces/{namespace}/clusters":{"post":{"tags":["Clusters"],"operationId":"createCluster","summary":"Create a cluster","description":"Creates a new workload Kubernetes cluster using ClusterClass topology mode.\n\nThe cluster webhook automatically sets labels, `clusterNetwork` CIDRs, `controlPlaneEndpoint`,\n`topology.class`/`classNamespace`, do not include these in the request. Also it merges default for `apiServerFlags`,\n`kubeadmConfigFiles`, and `customSecurityGroupRules` with user provided values.\n\n**Class selection** (resolved from variables, no need to set explicitly):\n\n| `infrastructure.type` | `deploymentUnit.type` | ClusterClass used |\n|---|---|---|\n| `openstack` (default) | `saas` (default) | `openstack-default-v1` |\n| `openstack` | `onprem` | `openstack-default-v1` |\n| `byoh` | any | `byoh-default-v1` |\n\n**Node pool variables**: `workerNode` can be set at two levels. Set it in\n`spec.topology.variables` as a cluster-wide default (applies to all pools), and/or\nin a pool's `variables.overrides` to override for that pool specifically.\nPool-level overrides take precedence. In `GET` responses you will see the\ncluster-level `workerNode` variable alongside pool-level overrides — both are normal.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClusterRequest"}}}},"responses":{"201":{"description":"Created — provisioning is asynchronous.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Cluster"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/UnprocessableEntity"}}}}}}
```

## Get a cluster

> Returns the full Cluster object including status.\
> \
> \| \`status.phase\` | Description |\
> \|---|---|\
> \| \`Provisioning\` | Control plane and/or workers are being created |\
> \| \`Provisioned\` | Cluster is ready — control plane and all worker pools are up |\
> \| \`Deleting\` | Delete is in progress |\
> \| \`Failed\` | Provisioning failed — check \`status.failureMessage\` |<br>

```json
{"openapi":"3.0.3","info":{"title":"PCD-K Cluster API","version":"v1beta1"},"tags":[{"name":"Clusters","description":"Create and manage workload Kubernetes clusters"}],"servers":[{"url":"https://{du-name}-{region}.{du-domain}/oidc-proxy/{tenant}/{region}","variables":{"du-name":{"default":"pcd"},"region":{"default":"r1"},"du-domain":{"default":"example.com"},"tenant":{"default":"service"}}}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Dex-issued JWT token."}},"schemas":{"Cluster":{"allOf":[{"$ref":"#/components/schemas/ClusterRequest"},{"type":"object","properties":{"metadata":{"type":"object","properties":{"namespace":{"type":"string","description":"Tenant namespace the cluster belongs to."},"uid":{"type":"string","format":"uuid"},"resourceVersion":{"type":"string"},"creationTimestamp":{"type":"string","format":"date-time"},"deletionTimestamp":{"type":"string","format":"date-time","description":"Set when deletion is in progress. Present until all finalizers are removed."},"labels":{"type":"object","additionalProperties":{"type":"string"},"description":"Labels set by the webhook and controllers. Do not rely on specific values for business logic."},"finalizers":{"type":"array","items":{"type":"string"},"description":"CAPI finalizers preventing premature deletion."}}},"status":{"type":"object","properties":{"phase":{"type":"string","enum":["Provisioning","Provisioned","Deleting","Failed"]},"controlPlaneReady":{"type":"boolean"},"infrastructureReady":{"type":"boolean"},"failureMessage":{"type":"string","description":"Human-readable error message when `phase` is `Failed`."},"failureDomains":{"type":"object","description":"Map of OpenStack availability zone names to their control-plane eligibility.\nPopulated from the `OpenStackCluster` status after infrastructure is ready.\n","additionalProperties":{"type":"object","properties":{"controlPlane":{"type":"boolean"}}}},"conditions":{"type":"array","description":"Standard CAPI conditions. Key `type` values to watch:\n`Ready`, `ControlPlaneInitialized`, `ControlPlaneReady`,\n`InfrastructureReady`, `TopologyReconciled`.\nAll conditions reach `status: \"True\"` when the cluster is fully provisioned.\n","items":{"type":"object","properties":{"type":{"type":"string"},"status":{"type":"string","enum":["True","False","Unknown"]},"reason":{"type":"string"},"message":{"type":"string"},"lastTransitionTime":{"type":"string","format":"date-time"}}}}}}}}]},"ClusterRequest":{"type":"object","required":["apiVersion","kind","metadata","spec"],"properties":{"apiVersion":{"type":"string","enum":["cluster.x-k8s.io/v1beta1"]},"kind":{"type":"string","enum":["Cluster"]},"metadata":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"spec":{"type":"object","required":["topology"],"properties":{"controlPlaneEndpoint":{"type":"object","description":"API server endpoint — webhook-generated from `deploymentUnit` variables, not set by the user.\nFormat: `<cluster-name>.<keystone-domain>-<keystone-tenant>.k8s.<du-name>.<du-domain>`.\nUse this host:port to reach the workload cluster's Kubernetes API.\n","properties":{"host":{"type":"string"},"port":{"type":"integer"}}},"topology":{"type":"object","required":["version","workers","variables"],"properties":{"version":{"type":"string","description":"Kubernetes version (no `v` prefix)."},"class":{"type":"string","enum":["openstack-default-v1","byoh-default-v1"],"description":"Webhook-resolved from `infrastructure.type` and `deploymentUnit.type` — omit this field.\nSet `infrastructure.type: byoh` in variables to use `byoh-default-v1`; otherwise `openstack-default-v1` is used.\n"},"classNamespace":{"type":"string","enum":["kaapi"],"description":"Webhook-set to `kaapi` — omit this field."},"workers":{"type":"object","properties":{"machineDeployments":{"type":"array","items":{"$ref":"#/components/schemas/MachineDeployment"}}}},"variables":{"type":"array","description":"Each entry is `{ name: <variable>, value: <object> }`.\nThe webhook manages `kubeadmConfigFiles`, `customSecurityGroupRules`, and\nsystem-required `apiServerFlags` automatically — do not set these.\n\n| Variable | Schema | Required | Notes |\n|---|---|---|---|\n| `deploymentUnit` | `DeploymentUnitValue` | Always | `name`, `domain`, `region` are required fields |\n| `network` | `NetworkValue` | OpenStack only | `networkID`, `subnetID` UUIDs |\n| `infrastructure` | `InfrastructureValue` | Only for BYOH | Omit entirely for OpenStack |\n| `workerNode` | `WorkerNodeValue` | OpenStack per-pool override | `flavor`, `imageName` required |\n| `rootVolume` | `RootVolumeValue` | Optional, OpenStack | Boot from Cinder volume |\n| `apiServerFlags` | string array | Optional | Merged with system defaults |\n| `controllerManagerFlags` | string array | Optional | — |\n| `schedulerFlags` | string array | Optional | — |\n| `enableSSH` | boolean | Optional, OpenStack | Adds SSH security group rule |\n| `allowedAddressPairs` | string array | Optional, OpenStack | CIDRs for allowed address pairs |\n","items":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string"},"value":{}}}}}}}}}},"MachineDeployment":{"type":"object","required":["name","class"],"properties":{"name":{"type":"string","description":"Pool name — must be unique within the cluster."},"class":{"type":"string","enum":["ost-md","byoh-md"],"description":"`ost-md` for OpenStack worker pools; `byoh-md` for BYOH pools."},"replicas":{"type":"integer","minimum":0,"description":"Fixed replica count. Omit when enabling cluster autoscaler."},"failureDomain":{"type":"string","description":"Virtualized cluster name"},"metadata":{"type":"object","properties":{"annotations":{"type":"object","additionalProperties":{"type":"string"},"description":"Autoscaler annotations — set both to enable, null both to disable:\n- `cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size`\n- `cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size`\n"}}},"variables":{"type":"object","description":"Per-pool variable overrides. OpenStack pools use `workerNode` (and optionally\n`rootVolume`) here. BYOH pools do not use overrides.\n","properties":{"overrides":{"type":"array","items":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string","enum":["workerNode","rootVolume","network"]},"value":{}}}}}}}},"Status":{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"type":"object","description":"Always present; typically empty (`{}`)."},"status":{"type":"string","enum":["Success","Failure"]},"message":{"type":"string","description":"Human-readable description of the error."},"reason":{"type":"string","description":"Machine-readable reason. Common values: `NotFound`, `AlreadyExists`, `BadRequest`, `Unauthorized`, `Forbidden`, `Invalid`.\n"},"details":{"type":"object","description":"Additional error context. Present on `NotFound` (includes `name`, `group`, `kind`) and `Invalid` / `422` responses (includes `causes` with per-field errors).\n","properties":{"name":{"type":"string","description":"Name of the resource involved."},"group":{"type":"string","description":"API group of the resource (e.g. `cluster.x-k8s.io`)."},"kind":{"type":"string","description":"Resource kind (e.g. `clusters`)."},"causes":{"type":"array","description":"Per-field validation errors (present on `422` responses).","items":{"type":"object","properties":{"reason":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"}}}}}},"code":{"type":"integer","description":"HTTP status code."}}}},"responses":{"Unauthorized":{"description":"Missing or invalid JWT token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"Forbidden":{"description":"Token does not have permission for this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"NotFound":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}}}},"paths":{"/apis/cluster.x-k8s.io/v1beta1/namespaces/{namespace}/clusters/{name}":{"get":{"tags":["Clusters"],"operationId":"getCluster","summary":"Get a cluster","description":"Returns the full Cluster object including status.\n\n| `status.phase` | Description |\n|---|---|\n| `Provisioning` | Control plane and/or workers are being created |\n| `Provisioned` | Cluster is ready — control plane and all worker pools are up |\n| `Deleting` | Delete is in progress |\n| `Failed` | Provisioning failed — check `status.failureMessage` |\n","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Cluster"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}}}}
```

## Delete a cluster

> Deletes the cluster and all owned resources (control plane, workers, OpenStack infrastructure).\
> Asynchronous — cluster transitions to \`status.phase == "Deleting"\` and is removed when complete.\
> Typical deletion time is 2–5 minutes.\
> \
> \*\*BYOH clusters\*\*: physical host nodes are not deprovisioned. The cluster label is removed\
> from the hosts, which return to the unallocated pool and can be reused by another cluster.<br>

```json
{"openapi":"3.0.3","info":{"title":"PCD-K Cluster API","version":"v1beta1"},"tags":[{"name":"Clusters","description":"Create and manage workload Kubernetes clusters"}],"servers":[{"url":"https://{du-name}-{region}.{du-domain}/oidc-proxy/{tenant}/{region}","variables":{"du-name":{"default":"pcd"},"region":{"default":"r1"},"du-domain":{"default":"example.com"},"tenant":{"default":"service"}}}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Dex-issued JWT token."}},"schemas":{"Cluster":{"allOf":[{"$ref":"#/components/schemas/ClusterRequest"},{"type":"object","properties":{"metadata":{"type":"object","properties":{"namespace":{"type":"string","description":"Tenant namespace the cluster belongs to."},"uid":{"type":"string","format":"uuid"},"resourceVersion":{"type":"string"},"creationTimestamp":{"type":"string","format":"date-time"},"deletionTimestamp":{"type":"string","format":"date-time","description":"Set when deletion is in progress. Present until all finalizers are removed."},"labels":{"type":"object","additionalProperties":{"type":"string"},"description":"Labels set by the webhook and controllers. Do not rely on specific values for business logic."},"finalizers":{"type":"array","items":{"type":"string"},"description":"CAPI finalizers preventing premature deletion."}}},"status":{"type":"object","properties":{"phase":{"type":"string","enum":["Provisioning","Provisioned","Deleting","Failed"]},"controlPlaneReady":{"type":"boolean"},"infrastructureReady":{"type":"boolean"},"failureMessage":{"type":"string","description":"Human-readable error message when `phase` is `Failed`."},"failureDomains":{"type":"object","description":"Map of OpenStack availability zone names to their control-plane eligibility.\nPopulated from the `OpenStackCluster` status after infrastructure is ready.\n","additionalProperties":{"type":"object","properties":{"controlPlane":{"type":"boolean"}}}},"conditions":{"type":"array","description":"Standard CAPI conditions. Key `type` values to watch:\n`Ready`, `ControlPlaneInitialized`, `ControlPlaneReady`,\n`InfrastructureReady`, `TopologyReconciled`.\nAll conditions reach `status: \"True\"` when the cluster is fully provisioned.\n","items":{"type":"object","properties":{"type":{"type":"string"},"status":{"type":"string","enum":["True","False","Unknown"]},"reason":{"type":"string"},"message":{"type":"string"},"lastTransitionTime":{"type":"string","format":"date-time"}}}}}}}}]},"ClusterRequest":{"type":"object","required":["apiVersion","kind","metadata","spec"],"properties":{"apiVersion":{"type":"string","enum":["cluster.x-k8s.io/v1beta1"]},"kind":{"type":"string","enum":["Cluster"]},"metadata":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"spec":{"type":"object","required":["topology"],"properties":{"controlPlaneEndpoint":{"type":"object","description":"API server endpoint — webhook-generated from `deploymentUnit` variables, not set by the user.\nFormat: `<cluster-name>.<keystone-domain>-<keystone-tenant>.k8s.<du-name>.<du-domain>`.\nUse this host:port to reach the workload cluster's Kubernetes API.\n","properties":{"host":{"type":"string"},"port":{"type":"integer"}}},"topology":{"type":"object","required":["version","workers","variables"],"properties":{"version":{"type":"string","description":"Kubernetes version (no `v` prefix)."},"class":{"type":"string","enum":["openstack-default-v1","byoh-default-v1"],"description":"Webhook-resolved from `infrastructure.type` and `deploymentUnit.type` — omit this field.\nSet `infrastructure.type: byoh` in variables to use `byoh-default-v1`; otherwise `openstack-default-v1` is used.\n"},"classNamespace":{"type":"string","enum":["kaapi"],"description":"Webhook-set to `kaapi` — omit this field."},"workers":{"type":"object","properties":{"machineDeployments":{"type":"array","items":{"$ref":"#/components/schemas/MachineDeployment"}}}},"variables":{"type":"array","description":"Each entry is `{ name: <variable>, value: <object> }`.\nThe webhook manages `kubeadmConfigFiles`, `customSecurityGroupRules`, and\nsystem-required `apiServerFlags` automatically — do not set these.\n\n| Variable | Schema | Required | Notes |\n|---|---|---|---|\n| `deploymentUnit` | `DeploymentUnitValue` | Always | `name`, `domain`, `region` are required fields |\n| `network` | `NetworkValue` | OpenStack only | `networkID`, `subnetID` UUIDs |\n| `infrastructure` | `InfrastructureValue` | Only for BYOH | Omit entirely for OpenStack |\n| `workerNode` | `WorkerNodeValue` | OpenStack per-pool override | `flavor`, `imageName` required |\n| `rootVolume` | `RootVolumeValue` | Optional, OpenStack | Boot from Cinder volume |\n| `apiServerFlags` | string array | Optional | Merged with system defaults |\n| `controllerManagerFlags` | string array | Optional | — |\n| `schedulerFlags` | string array | Optional | — |\n| `enableSSH` | boolean | Optional, OpenStack | Adds SSH security group rule |\n| `allowedAddressPairs` | string array | Optional, OpenStack | CIDRs for allowed address pairs |\n","items":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string"},"value":{}}}}}}}}}},"MachineDeployment":{"type":"object","required":["name","class"],"properties":{"name":{"type":"string","description":"Pool name — must be unique within the cluster."},"class":{"type":"string","enum":["ost-md","byoh-md"],"description":"`ost-md` for OpenStack worker pools; `byoh-md` for BYOH pools."},"replicas":{"type":"integer","minimum":0,"description":"Fixed replica count. Omit when enabling cluster autoscaler."},"failureDomain":{"type":"string","description":"Virtualized cluster name"},"metadata":{"type":"object","properties":{"annotations":{"type":"object","additionalProperties":{"type":"string"},"description":"Autoscaler annotations — set both to enable, null both to disable:\n- `cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size`\n- `cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size`\n"}}},"variables":{"type":"object","description":"Per-pool variable overrides. OpenStack pools use `workerNode` (and optionally\n`rootVolume`) here. BYOH pools do not use overrides.\n","properties":{"overrides":{"type":"array","items":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string","enum":["workerNode","rootVolume","network"]},"value":{}}}}}}}},"Status":{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"type":"object","description":"Always present; typically empty (`{}`)."},"status":{"type":"string","enum":["Success","Failure"]},"message":{"type":"string","description":"Human-readable description of the error."},"reason":{"type":"string","description":"Machine-readable reason. Common values: `NotFound`, `AlreadyExists`, `BadRequest`, `Unauthorized`, `Forbidden`, `Invalid`.\n"},"details":{"type":"object","description":"Additional error context. Present on `NotFound` (includes `name`, `group`, `kind`) and `Invalid` / `422` responses (includes `causes` with per-field errors).\n","properties":{"name":{"type":"string","description":"Name of the resource involved."},"group":{"type":"string","description":"API group of the resource (e.g. `cluster.x-k8s.io`)."},"kind":{"type":"string","description":"Resource kind (e.g. `clusters`)."},"causes":{"type":"array","description":"Per-field validation errors (present on `422` responses).","items":{"type":"object","properties":{"reason":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"}}}}}},"code":{"type":"integer","description":"HTTP status code."}}}},"responses":{"Unauthorized":{"description":"Missing or invalid JWT token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"Forbidden":{"description":"Token does not have permission for this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"NotFound":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}}}},"paths":{"/apis/cluster.x-k8s.io/v1beta1/namespaces/{namespace}/clusters/{name}":{"delete":{"tags":["Clusters"],"operationId":"deleteCluster","summary":"Delete a cluster","description":"Deletes the cluster and all owned resources (control plane, workers, OpenStack infrastructure).\nAsynchronous — cluster transitions to `status.phase == \"Deleting\"` and is removed when complete.\nTypical deletion time is 2–5 minutes.\n\n**BYOH clusters**: physical host nodes are not deprovisioned. The cluster label is removed\nfrom the hosts, which return to the unallocated pool and can be reused by another cluster.\n","responses":{"200":{"description":"Deletion accepted. Returns the Cluster object with `metadata.deletionTimestamp` set.\nThe cluster is fully removed once `status.phase` disappears (resource deleted).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Cluster"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}}}}
```

## Update a cluster

> Two content types are supported depending on the operation:\
> \
> \*\*\`application/json-patch+json\`\*\* — for node pool (MachineDeployment) operations.\
> \`spec.topology.workers.machineDeployments\` is an array with no server-side name-keying\
> for this patch type, so elements must be addressed by their zero-based index.\
> Do a GET first to find the position of the pool you want to modify.\
> \
> \*\*\`application/apply-patch+yaml\`\*\* (Server-Side Apply) — for named topology variables\
> such as \`apiServerFlags\` .\
> \
> \*\*Autoscaling\*\*: to enable, remove the \`replicas\` field (so the autoscaler controls it)\
> and add both min/max annotations in the same request. To disable, restore a fixed\
> \`replicas\` value and remove both annotations.\
> \
> Do not patch \`spec.topology.version\` directly.<br>

```json
{"openapi":"3.0.3","info":{"title":"PCD-K Cluster API","version":"v1beta1"},"tags":[{"name":"Clusters","description":"Create and manage workload Kubernetes clusters"}],"servers":[{"url":"https://{du-name}-{region}.{du-domain}/oidc-proxy/{tenant}/{region}","variables":{"du-name":{"default":"pcd"},"region":{"default":"r1"},"du-domain":{"default":"example.com"},"tenant":{"default":"service"}}}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Dex-issued JWT token."}},"parameters":{"clusterName":{"name":"name","in":"path","required":true,"schema":{"type":"string"}}},"schemas":{"Cluster":{"allOf":[{"$ref":"#/components/schemas/ClusterRequest"},{"type":"object","properties":{"metadata":{"type":"object","properties":{"namespace":{"type":"string","description":"Tenant namespace the cluster belongs to."},"uid":{"type":"string","format":"uuid"},"resourceVersion":{"type":"string"},"creationTimestamp":{"type":"string","format":"date-time"},"deletionTimestamp":{"type":"string","format":"date-time","description":"Set when deletion is in progress. Present until all finalizers are removed."},"labels":{"type":"object","additionalProperties":{"type":"string"},"description":"Labels set by the webhook and controllers. Do not rely on specific values for business logic."},"finalizers":{"type":"array","items":{"type":"string"},"description":"CAPI finalizers preventing premature deletion."}}},"status":{"type":"object","properties":{"phase":{"type":"string","enum":["Provisioning","Provisioned","Deleting","Failed"]},"controlPlaneReady":{"type":"boolean"},"infrastructureReady":{"type":"boolean"},"failureMessage":{"type":"string","description":"Human-readable error message when `phase` is `Failed`."},"failureDomains":{"type":"object","description":"Map of OpenStack availability zone names to their control-plane eligibility.\nPopulated from the `OpenStackCluster` status after infrastructure is ready.\n","additionalProperties":{"type":"object","properties":{"controlPlane":{"type":"boolean"}}}},"conditions":{"type":"array","description":"Standard CAPI conditions. Key `type` values to watch:\n`Ready`, `ControlPlaneInitialized`, `ControlPlaneReady`,\n`InfrastructureReady`, `TopologyReconciled`.\nAll conditions reach `status: \"True\"` when the cluster is fully provisioned.\n","items":{"type":"object","properties":{"type":{"type":"string"},"status":{"type":"string","enum":["True","False","Unknown"]},"reason":{"type":"string"},"message":{"type":"string"},"lastTransitionTime":{"type":"string","format":"date-time"}}}}}}}}]},"ClusterRequest":{"type":"object","required":["apiVersion","kind","metadata","spec"],"properties":{"apiVersion":{"type":"string","enum":["cluster.x-k8s.io/v1beta1"]},"kind":{"type":"string","enum":["Cluster"]},"metadata":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"spec":{"type":"object","required":["topology"],"properties":{"controlPlaneEndpoint":{"type":"object","description":"API server endpoint — webhook-generated from `deploymentUnit` variables, not set by the user.\nFormat: `<cluster-name>.<keystone-domain>-<keystone-tenant>.k8s.<du-name>.<du-domain>`.\nUse this host:port to reach the workload cluster's Kubernetes API.\n","properties":{"host":{"type":"string"},"port":{"type":"integer"}}},"topology":{"type":"object","required":["version","workers","variables"],"properties":{"version":{"type":"string","description":"Kubernetes version (no `v` prefix)."},"class":{"type":"string","enum":["openstack-default-v1","byoh-default-v1"],"description":"Webhook-resolved from `infrastructure.type` and `deploymentUnit.type` — omit this field.\nSet `infrastructure.type: byoh` in variables to use `byoh-default-v1`; otherwise `openstack-default-v1` is used.\n"},"classNamespace":{"type":"string","enum":["kaapi"],"description":"Webhook-set to `kaapi` — omit this field."},"workers":{"type":"object","properties":{"machineDeployments":{"type":"array","items":{"$ref":"#/components/schemas/MachineDeployment"}}}},"variables":{"type":"array","description":"Each entry is `{ name: <variable>, value: <object> }`.\nThe webhook manages `kubeadmConfigFiles`, `customSecurityGroupRules`, and\nsystem-required `apiServerFlags` automatically — do not set these.\n\n| Variable | Schema | Required | Notes |\n|---|---|---|---|\n| `deploymentUnit` | `DeploymentUnitValue` | Always | `name`, `domain`, `region` are required fields |\n| `network` | `NetworkValue` | OpenStack only | `networkID`, `subnetID` UUIDs |\n| `infrastructure` | `InfrastructureValue` | Only for BYOH | Omit entirely for OpenStack |\n| `workerNode` | `WorkerNodeValue` | OpenStack per-pool override | `flavor`, `imageName` required |\n| `rootVolume` | `RootVolumeValue` | Optional, OpenStack | Boot from Cinder volume |\n| `apiServerFlags` | string array | Optional | Merged with system defaults |\n| `controllerManagerFlags` | string array | Optional | — |\n| `schedulerFlags` | string array | Optional | — |\n| `enableSSH` | boolean | Optional, OpenStack | Adds SSH security group rule |\n| `allowedAddressPairs` | string array | Optional, OpenStack | CIDRs for allowed address pairs |\n","items":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string"},"value":{}}}}}}}}}},"MachineDeployment":{"type":"object","required":["name","class"],"properties":{"name":{"type":"string","description":"Pool name — must be unique within the cluster."},"class":{"type":"string","enum":["ost-md","byoh-md"],"description":"`ost-md` for OpenStack worker pools; `byoh-md` for BYOH pools."},"replicas":{"type":"integer","minimum":0,"description":"Fixed replica count. Omit when enabling cluster autoscaler."},"failureDomain":{"type":"string","description":"Virtualized cluster name"},"metadata":{"type":"object","properties":{"annotations":{"type":"object","additionalProperties":{"type":"string"},"description":"Autoscaler annotations — set both to enable, null both to disable:\n- `cluster.x-k8s.io/cluster-api-autoscaler-node-group-min-size`\n- `cluster.x-k8s.io/cluster-api-autoscaler-node-group-max-size`\n"}}},"variables":{"type":"object","description":"Per-pool variable overrides. OpenStack pools use `workerNode` (and optionally\n`rootVolume`) here. BYOH pools do not use overrides.\n","properties":{"overrides":{"type":"array","items":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string","enum":["workerNode","rootVolume","network"]},"value":{}}}}}}}},"Status":{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"type":"object","description":"Always present; typically empty (`{}`)."},"status":{"type":"string","enum":["Success","Failure"]},"message":{"type":"string","description":"Human-readable description of the error."},"reason":{"type":"string","description":"Machine-readable reason. Common values: `NotFound`, `AlreadyExists`, `BadRequest`, `Unauthorized`, `Forbidden`, `Invalid`.\n"},"details":{"type":"object","description":"Additional error context. Present on `NotFound` (includes `name`, `group`, `kind`) and `Invalid` / `422` responses (includes `causes` with per-field errors).\n","properties":{"name":{"type":"string","description":"Name of the resource involved."},"group":{"type":"string","description":"API group of the resource (e.g. `cluster.x-k8s.io`)."},"kind":{"type":"string","description":"Resource kind (e.g. `clusters`)."},"causes":{"type":"array","description":"Per-field validation errors (present on `422` responses).","items":{"type":"object","properties":{"reason":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"}}}}}},"code":{"type":"integer","description":"HTTP status code."}}}},"responses":{"BadRequest":{"description":"Malformed request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"Unauthorized":{"description":"Missing or invalid JWT token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"Forbidden":{"description":"Token does not have permission for this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"NotFound":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"UnprocessableEntity":{"description":"Admission webhook rejected the request due to a validation failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}}}},"paths":{"/apis/cluster.x-k8s.io/v1beta1/namespaces/{namespace}/clusters/{name}":{"patch":{"tags":["Clusters"],"operationId":"patchCluster","summary":"Update a cluster","parameters":[{"$ref":"#/components/parameters/clusterName"},{"name":"fieldManager","in":"query","required":false,"description":"Name of the field manager. Required when using `application/apply-patch+yaml` (Server-Side Apply) — any non-empty string is valid (e.g. `kubectl`, `my-app`). Not needed for `application/json-patch+json`.\n","schema":{"type":"string"}}],"description":"Two content types are supported depending on the operation:\n\n**`application/json-patch+json`** — for node pool (MachineDeployment) operations.\n`spec.topology.workers.machineDeployments` is an array with no server-side name-keying\nfor this patch type, so elements must be addressed by their zero-based index.\nDo a GET first to find the position of the pool you want to modify.\n\n**`application/apply-patch+yaml`** (Server-Side Apply) — for named topology variables\nsuch as `apiServerFlags` .\n\n**Autoscaling**: to enable, remove the `replicas` field (so the autoscaler controls it)\nand add both min/max annotations in the same request. To disable, restore a fixed\n`replicas` value and remove both annotations.\n\nDo not patch `spec.topology.version` directly.\n","requestBody":{"required":true,"content":{"application/json-patch+json":{"schema":{"type":"array","items":{"type":"object","required":["op","path"],"properties":{"op":{"type":"string","enum":["add","replace","remove"]},"path":{"type":"string"},"value":{}}}}},"application/apply-patch+yaml":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Patch applied — changes take effect asynchronously.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Cluster"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/UnprocessableEntity"}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.platform9.com/api-docs/kubernetes-service/clusters.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
