How to expand or delete a cluster without GUI

Deployment and removal of client clusters is performed through the platform’s REST API: requests are sent with an authentication token in the Authorization: Bearer $token header. The $BACKENDPOINT variable is the platform’s backend API address.

Authorization

Before managing client clusters, log in to the platform and receive a token.

In the examples below:

  • $BACKENDPOINT — base address of the backend API of the platform;
  • $token — authorized user token;
  • $CLUSTERNAME — name of the cluster to be created or deleted;
  • $PROVIDERTEMPLATENAME is the name of a pre-created provider configuration.

Prepare provider

It is impossible to create a cluster without a provider. Before a request to create a cluster, a provider instance must be created in the platform: its name is passed in the body of the request as identityName, providerName or name, depending on the type of provider.

Get a list of available providers and their configurations:

curl -k -s -L --request GET $BACKENDPOINT/api/v1/platform/providers \
  --header "Authorization: Bearer $token" | jq -r

Example response fragment:

[
  {
    "providerType": "capov",
    "configs": [
      {
        "name": "capov-name",
        "kubeVers": ["v1.34.1"],
        "allowEditCSI": false,
        "IPAddressPoolName": "",
        "IPAddressPoolAvailableCount": 0
      }
    ]
  },
  {
    "providerType": "capvs",
    "configs": [
      {
        "name": "capvs",
        "kubeVers": ["v1.34.1"],
        "allowEditCSI": false,
        "IPAddressPoolName": "name-pool",
        "IPAddressPoolAvailableCount": 1
      }
    ]
  }
]

If there is no suitable configuration, create it through the provider’s API.

VMware vSphere (capvs)

Command to create VMware vSphere provider (capvs):

curl -k -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/capvs \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "IPAddressPoolName": "name-pool",
  "allowEditCSI": false,
  "cloneMode": "linkedClone",
  "connectInfo": {
    "passwd": "mypassword",
    "url": "stendcloud.aaaaaaa.bb:443",
    "user": "myusername"
  },
  "datacenter": "/StendCloud",
  "datastore": "StendCloud_Name",
  "folder": "/StendCloud/vm/StendCloud/Name/",
  "identityName": "identityname",
  "network": "/StendCloud/network/data",
  "resourcePool": "/StendCloud/host/StendCloud/Resources/Name",
  "storagePolicyName": "",
  "template": [
    { "key": "ED OS-7.3.2-shturval", "value": "v1.34.1" }
  ],
  "templateNetInterface": "enp1s0"
}
EOF
) | jq -r

Sample answer:

{
  "identityName": "identityname",
  "provider": {
    "vCenterAddress": "stendcloud.aaaaaaa.aa:443",
    "user": "",
    "passwd": "",
    "thumbprint": "A1:F1:C8:9F:04:E8:13:7A:87:39:D0:EA:10:96:40:57:FE:D0:77:3E",
    "datacenter": "/StendCloud",
    "datastore": "StendCloud_Name",
    "storagePolicyName": "",
    "cloneMode": "",
    "folder": "/StendCloud/vm/StendCloud/Name/",
    "network": "/StendCloud/network/data",
    "template": [
      { "key": "ED OS-7.3.2-shturval", "value": "v1.34.1" }
    ],
    "templateNetInterface": "enp1s0",
    "resourcePool": "/StendCloud/host/StendCloud/Resources/Name",
    "allowEditCSI": false,
    "IPAddressPoolName": "name-pool"
  },
  "ready": false
}

oVirt, zVirt, HostVM, ED Virtualization, ROSA Virtualization (capov)

Command to create a provider oVirt, zVirt, HostVM, ED Virtualization, ROSA Virtualization (capov):

curl -k -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/capov \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "name": "identityname",
  "VNICProfile": "VNI",
  "allowEditCSI": false,
  "cluster": "RHVLab",
  "connection": {
    "passwd": "password",
    "tls": {
      "cert": true,
      "certs": "",
      "insecure": true
    },
    "url": "https://rhv-mg.aaaaa.bbb.cc/ovirt-engine/api",
    "user": "name"
  },
  "datacenter": "datacenter",
  "templates": [
    { "template": "AstraLinux", "kubeVersion": "v1.34.1" }
  ],
  "templateNetInterface": "eth0",
  "csistorageDomainName": "hosted_storage",
  "IPAddressPoolName": "",
  "providerSubtype": "rosavirt",
  "infraProviderName": ""
}
EOF
) | jq -r

Sample answer:

{
  "name": "identityname",
  "cluster": "RHVLab",
  "VNICProfile": "VNI",
  "allowEditCSI": false,
  "VMType": "server",
  "templateNetInterface": "eth0",
  "connection": {
    "url": "https://rhv-mg.aaaaa.bbb.cc/ovirt-engine/api",
    "user": "name",
    "passwd": "password",
    "tls": {
      "cert": true,
      "insecure": true
    }
  },
  "templates": [
    { "template": "AstraLinux", "kubeVersion": "v1.34.1" }
  ],
  "datacenter": "datacenter",
  "csistorageDomainName": "hosted_storage",
  "IPAddressPoolName": "",
  "providerSubtype": "rosavirt",
  "infraProviderName": ""
}

Basis Dynamix (capbd)

Basis Dynamix provider creation command (capbd):

curl -k -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/capbd \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "name": "name",
  "accountName": "Shturval",
  "rgName": "dev-2.6",
  "templateNetInterface": "eth0",
  "connection": {
    "decordUrl": "https://mr4.digitalenergy.online/",
    "ssoUrl": "https://sso.digitalenergy.online",
    "appId": "xxxxxxx",
    "appSecret": "dddddd",
    "skipSSLVerification": true
  },
  "templates": [
    { "template": "pfSASE", "kubeVersion": "v1.34.1" }
  ],
  "extNetName": "NAME",
  "vinsName": "res_group_internal",
  "haLoadBalancer": true
}
EOF
) | jq -r

Sample answer:

{
  "name": "name",
  "accountName": "Shturval",
  "rgName": "dev-2.6",
  "templateNetInterface": "eth0",
  "connection": {
    "decordUrl": "https://mr4.digitalenergy.online/",
    "ssoUrl": "https://sso.digitalenergy.online",
    "appId": "xxxxxxx",
    "appSecret": "dddddd",
    "skipSSLVerification": true
  },
  "templates": [
    { "template": "pfSASE", "kubeVersion": "v1.34.1" }
  ],
  "extNetName": "NAME",
  "vinsName": "res_group_internal",
  "haLoadBalancer": true
}

OpenStack, Selectel, VK Cloud (capos)

OpenStack provider creation command (capos):

curl -k -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/capos \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "name": "identityname",
  "cloudconfig": {
    "config": {
      "auth": {
        "auth_url": "https://xxxxxx:1111/v3/",
        "project_domain_id": "36d4ecf",
        "project_id": "c3cf4f8101",
        "username": "username@example.ru",
        "user_domain_name": "users",
        "password": "mypassword"
      },
      "auth_type": "password",
      "verify": false,
      "identity_api_version": "3",
      "interface": "public",
      "region_name": "RegionOne"
    }
  },
  "nodeCIDR": "10.0.0.0/24",
  "sshKeyName": "sshKeyName",
  "cloudName": "vkcloud",
  "templateNetInterface": "eth0",
  "externalNetworkID": "ec8c6",
  "flavors": ["STD2-16-32", "STD2-8-20"],
  "templates": [
    { "template": "ubuntu24", "kubeVersion": "v1.33.1" }
  ],
  "volumeTypes": ["high-iops"],
  "managedSecurityGroups": "true",
  "enableCSI": false,
  "disablePortSecurity": "false",
  "dns": [""],
  "allowEditCSI": false,
  "availabilityZones": ["GZ1", "PA2"],
  "providerSubtype": "vkcloud"
}
EOF
) | jq -r

Sample answer:

{
  "name": "identityname",
  "allowEditCSI": false,
  "cloudName": "vkcloud",
  "templateNetInterface": "eth0",
  "cloudconfig": {
    "config": {
      "auth": {
        "auth_url": "https://xxxxxx:1111/v3/",
        "project_domain_id": "36d4ecf",
        "project_id": "c3cf4f8101",
        "username": "username@example.ru",
        "user_domain_name": "users",
        "password": "mypassword"
      },
      "auth_type": "password",
      "identity_api_version": "3",
      "verify": false
    }
  },
  "templates": [
    { "template": "ubuntu24", "kubeVersion": "v1.33.1" }
  ],
  "externalNetworkID": "ec8c6",
  "sshKeyName": "sshKeyName",
  "flavors": ["STD2-16-32", "STD2-8-20"],
  "volumeTypes": ["high-iops"],
  "nodeCIDR": "10.0.0.0/24",
  "nodeSubnetDNS": null,
  "managedSecurityGroups": "true",
  "disablePortSecurity": "false",
  "rootVolumeAvailabilityZone": "",
  "availabilityZones": ["GZ1", "PA2"],
  "providerSubtype": "vkcloud"
}

Shturval v2 (capsmv2)

Command to create Shturval v2 provider (capsmv2):

curl -k -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/capsmv2 \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "name": "identityname",
  "IPAddressPoolName": "",
  "credentials": {
    "SSH": {
      "privateKey": "privateKey",
      "userName": "username"
    }
  },
  "hosts": [
    {
      "address": "10.10.10.10",
      "labelsSelector": {
        "role": "controlplane"
      },
      "credentials": null
    }
  ]
}
EOF
) | jq -r

Sample answer:

{
  "name": "identityname",
  "hosts": [
    {
      "address": "10.10.10.10",
      "labelsSelector": {
        "role": "controlplane"
      },
      "credentials": null
    }
  ],
  "credentials": {
    "SSH": {
      "userName": "username",
      "privateKey": "privateKey"
    }
  },
  "IPAddressPoolName": "",
  "infraProviderName": ""
}

Yandex Cloud (capyc)

Yandex Cloud provider creation command (capyc):

curl -k -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/capyc \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "allowedPlatformIDs": ["standard"],
  "connectInfo": {
    "folderId": "b1gcffn",
    "key": "{\n  \"id\": \"aj2u\",\n  \"service_account_id\": \"e49pbe\",\n  \"created_at\": \"2024-12-13T13:28:15.261795772Z\",\n  \"key_algorithm\": \"RSA_2048\",\n  \"public_key\": \"-----BEGIN PUBLIC KEY-----\\nMIIUEyYcDkOn\\nqTrn6lh52A\\nfQIDB\\n-----END PUBLIC KEY-----\\n\",\n  \"private_key\": \"PLEASE DO NOT REMOVE THIS LINE! Yandex.Cloud SA Key ID <aje76qbj2u>\\n-----BEGIN PRIVATE KEY-----\\nM58VMZ0=\\n-----END PRIVATE KEY-----\\n\"\n}"
  },
  "folderID": "b1gcffn",
  "identityName": "provideryandexname",
  "loadBalancerInternal": false,
  "loadBalancerType": "ALB",
  "networkID": "en5tl",
  "subnetID": "be2",
  "templates": [
    { "template": "fd82", "kubeVersion": "v1.33.1" }
  ],
  "zoneID": "zone-c",
  "volumeTypes": ["network-ssd"],
  "allowEditCSI": false
}
EOF
) | jq -r

Sample answer:

{
  "identityName": "provideryandexname",
  "connectInfo": {
    "key": ""
  },
  "templateNetInterface": "",
  "templates": [
    { "template": "fd82", "kubeVersion": "v1.33.1" }
  ],
  "folderID": "b1gcffn",
  "networkID": "en5tl",
  "subnetID": "be2",
  "zoneID": "zone-c",
  "volumeTypes": ["network-ssd"],
  "loadBalancerType": "ALB",
  "loadBalancerInternal": false,
  "allowedPlatformIDs": ["standard"],
  "allowEditCSI": false
}

VMware vCloud Director (capcd)

Command to create VMware vCloud Director provider (capcd):

curl -k -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/capcd \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "connectInfo": {
    "username": "username",
    "password": "mypassword",
    "refreshToken": "",
    "org": "Shturval-Client-Cluster",
    "connectType": "login",
    "site": "https://example.ru"
  },
  "name": "identityname",
  "catalog": "shturval",
  "templates": [
    { "template": "Ubuntu_sthurvalv2.11.0", "kubeVersion": "v1.33.1" }
  ],
  "sizingPolicies": ["TKG"],
  "ovdc": "Shturval-Client-Cluster-v1cl4-vdc",
  "vipSubnetName": "",
  "network": "Network",
  "providerType": "vCloud Director"
}
EOF
) | jq -r

Sample answer:

{
  "name": "identityname",
  "connectInfo": {
    "site": "https://example.ru",
    "org": "Shturval-Client-Cluster",
    "username": "username",
    "password": "mypassword",
    "refreshToken": ""
  },
  "ovdc": "Shturval-Client-Cluster-v1cl4-vdc",
  "network": "Network",
  "vipSubnet": "",
  "catalog": "shturval",
  "templates": [
    { "template": "Ubuntu_sthurvalv2.11.0", "kubeVersion": "v1.33.1" }
  ],
  "placementPolicy": "",
  "sizingPolicies": ["TKG"],
  "allowEditCSI": false,
  "IPAddressPoolName": ""
}

The provider can be removed with the command:

export PROVIDERNAME="provider-name"

curl -k -L --request DELETE $BACKENDPOINT/api/v1/platform/providers/{provider}/$PROVIDERNAME \
  --header "Authorization: Bearer $token"

Get a list of clusters

curl -k -s -L --request GET $BACKENDPOINT/api/v1/clusters --header "Authorization: Bearer $token" | jq -r

Example response fragment:

{
  "items": [
    {
      "id": "shturval-new-cluster",
      "clusterName": "shturval-new-cluster",
      "clusterType": "platform",
      "annotations": [
        { "key": "shturval.tech/clustername", "value": "shturval-new-cluster" }
      ],
      "providerType": "capov",
      "providerConfigID": "capov-test",
      "apiEndpoint": "10.20.10.20:5555",
      "networks": [
        { "type": "Service CIDR", "network": "10.96.0.0/12", "netmask": "" },
        { "type": "Pod CIDR", "network": "172.16.0.0/16", "netmask": "" }
      ],
      "ingress": "*.shturval-new-cluster.ip-10-20-10-21.shturval.link",
      "argoCdIngress": "",
      "secure": false,
      "phase": "Provisioned",
      "conditions": [
        { "type": "Ready", "status": "True", "lastTransitionTime": "2024-05-27T07:44:37Z" },
        { "type": "ControlPlaneInitialized", "status": "True", "lastTransitionTime": "2024-05-27T07:44:37Z" },
        { "type": "ControlPlaneReady", "status": "True", "lastTransitionTime": "2024-05-27T07:44:37Z" },
        { "type": "InfrastructureReady", "status": "True", "lastTransitionTime": "2024-05-27T07:41:26Z" }
      ],
      "controlplaneNodesCount": 1,
      "controlplaneHealthyNodesCount": 3,
      "workersGroups": [
        { "groupName": "shturval-new-cluster-default", "workersScale": null, "workersCount": 3 },
        { "groupName": "shturval-new-cluster-infra", "workersScale": null, "workersCount": 0 }
      ],
      "UpdateReady": true
    }
  ],
  "count": 1
}

Creating a cluster

Before creating a cluster, make sure that a provider has already been created for the selected infrastructure type. The cluster creation request references an existing provider configuration; Without it, you cannot create a cluster.

Method and path: POST $BACKENDPOINT/api/v1/platform/providers/clusters/{provider}

{provider}Provider
capvsVMware vSphere
capovoVirt, zVirt, HostVM, ED Virtualization and ROSA Virtualization
capsmv2Shturval v2
caposOpenStack, Selectel, VK Cloud
capbdBasis Dynamix
capycYandex Cloud
capcdVMware vCloud Director

The body of the request is JSON with sections cluster and provider. The name of the provider template is specified in the field identityName (vSphere, vCloud Director), providerName (oVirt, zVirt, HostVM, ED Virtualization, ROSA Virtualization, OpenStack, Selectel, VK Cloud, Basis Dynamix, Yandex Cloud) or name (Shturval v2).

Cluster section fields

FieldPurpose
clusterNameCluster name
apiEndpointKubernetes API server IP (for capvs, capov, capsmv2, capbd; for capos, capyc, capcd can be empty with an external load balancer)
controlPlaneNodesCountNumber of Control Plane Nodes
ingressvipVIP for Ingress at externalingresslb: false
ingressWildcard FQDN Ingress at externalingresslb: true (for example, cluster.shturval.link)
podSubnet, serviceSubnetPod subnets andservices (example: 172.16.0.0/16, 10.96.0.0/12)
shturvalVersionPlatform version on the cluster (for example, 2.14.0)
enabledServicesList of included services (charts)
disabledServicesList of disabled services or ["all"] - only critical ones
ingressControllerTypeController for external HTTP traffic. nginx is the external connections module (shturval-ingress-controller). gateway is Gateway API on Cilium. The default is nginx. If the field is left empty in the request, the platform writes nginx. With gateway, shturval-ingress-controller is installed in absent mode
externalKubeAPILB, externalingresslbExternal load balancer for API and Ingress
securefalse - Ingress self-signed certificate
acmeRootCert, ACMEURLACME certificate parameters (oVirt, zVirt, HostVM, ED Virtualization, ROSA Virtualization, Shturval v2)
cacert, cakeyIntermediate certificate (OpenStack, Selectel, VK Cloud, Yandex Cloud - in the version with critical services)
mgmtClusterfalse for client cluster
deletePersistentVolumesFor oVirt, vSphere, OpenStack, Selectel, VK Cloud, vCloud Director, Yandex Cloud. true — delete PVs before deleting the cluster, false — keep them. If omitted, the cluster profile policy is used. Details: PV cleanup when deleting a cluster

Service management

  • Explicit set of services: disabledServices: [] and list in enabledServices.
  • Critical services only: for any provider, specify disabledServices: ["all"] and do not pass enabledServices; Fill out the remaining sections cluster and provider following the example of the selected provider.

If created successfully, the response may contain the recalculated lists enabledServices and disabledServices, as well as the field CreatedByUser / createdByUser. The platform also aligns the service lists with ingressControllerType: with gateway, shturval-ingress-controller is installed in absent mode.

Provider section fields

  • controlplaneNodeConfig / controlPlaneNodeConfig — Control Plane configuration (nodeConfig with groupName and roles);
  • workerNodeConfigs — groups default and infra with workersCount and roles node-role.kubernetes.io/workers, node-role.kubernetes.io/infra;
  • enableCSI — for VMware vSphere, oVirt, zVirt, HostVM, ED Virtualization, ROSA Virtualization, OpenStack, Selectel, VK Cloud, vCloud Director, Yandex Cloud (in the examples, false). The field is available when the provider instance has allowEditCSI set to true.

The node configuration depends on the provider: capvsNodeConfig, capovNodeConfig, caposNodeConfig, capbdNodeConfig, capycNodeConfig, capcdNodeConfig; for Shturval v2 - selectors controlPlaneSelector and workerSelector with labels role.

VMware vSphere (capvs)

Variables and request with a full set of services and a self-signed certificate (secure: false):

export CLUSTERNAME="capvs-new-cluster"
export PROVIDERTEMPLATENAME="capvs-template-name"

curl -k -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/clusters/capvs \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "cluster": {
    "apiEndpoint": "10.20.30.40",
    "clusterName": "$CLUSTERNAME",
    "controlPlaneNodesCount": 1,
    "disabledServices": [],
    "enabledServices": ["shturval-cert-manager-crds","shturval-vip-provider","shturval-update-crds","shturval-monitoring-crds","shturval-local-csi","shturval-policy-manager-crds","shturval-vip","shturval-node-config-crds","shturval-services","shturval-services-crds","shturval-caching-dns","shturval-cert-manager","shturval-update","shturval-networking","shturval-node-config"],
    "externalKubeAPILB": false,
    "externalingresslb": false,
    "ingress": "",
    "ingressvip": "10.20.30.42",
    "podSubnet": "172.16.0.0/16",
    "secure": false,
    "serviceSubnet": "10.96.0.0/12",
    "shturvalVersion": "2.14.0",
    "mgmtCluster": false
  },
  "provider": {
    "controlplaneNodeConfig": {
      "capvsNodeConfig": { "diskGiB": 60, "memoryMiB": 1200, "numCPUs": 4 },
      "nodeConfig": {
        "groupName": "control-plane",
        "roles": [{ "name": "node-role.kubernetes.io/control-plane" }]
      }
    },
    "enableCSI": false,
    "identityName": "$PROVIDERTEMPLATENAME",
    "workerNodeConfigs": [
      {
        "capvsNodeConfig": { "diskGiB": 60, "memoryMiB": 1200, "numCPUs": 4 },
        "nodeConfig": {
          "groupName": "default",
          "roles": [{ "name": "node-role.kubernetes.io/workers" }]
        },
        "workersCount": 3
      },
      {
        "capvsNodeConfig": { "diskGiB": 60, "memoryMiB": 1200, "numCPUs": 4 },
        "nodeConfig": {
          "groupName": "infra",
          "roles": [{ "name": "node-role.kubernetes.io/infra" }]
        },
        "workersCount": 3
      }
    ]
  }
EOF
) | jq -r

For the option with only critical services, use the general rule from the Service Management section; for group infra you can set "workersCount": 0.

oVirt, zVirt, HostVM, ED Virtualization, ROSA Virtualization (capov)

The ACME certificate is specified by the acmeRootCert and ACMEURL fields in the cluster section. The provider template is providerName. Node configuration - capovNodeConfig (cpu, memory.sizeMB, osDiskSizeGB).

export CLUSTERNAME="capov-new-cluster"
export PROVIDERTEMPLATENAME="capov-template-name"

curl -k -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/clusters/capov \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "cluster": {
    "apiEndpoint": "10.20.30.40",
    "clusterName": "$CLUSTERNAME",
    "controlPlaneNodesCount": 1,
    "disabledServices": [],
    "enabledServices": ["shturval-cert-manager-crds","shturval-vip-provider","shturval-update-crds","shturval-monitoring-crds","shturval-local-csi","shturval-policy-manager-crds","shturval-vip","shturval-node-config-crds","shturval-services","shturval-services-crds","shturval-caching-dns","shturval-cert-manager","shturval-update","shturval-networking","shturval-node-config"],
    "externalKubeAPILB": false,
    "externalingresslb": false,
    "ingress": "",
    "ingressvip": "10.20.30.42",
    "podSubnet": "172.16.0.0/16",
    "secure": false,
    "serviceSubnet": "10.96.0.0/12",
    "shturvalVersion": "2.14.0",
    "acmeRootCert": "acmeRootCert",
    "ACMEURL": "https://issuer.ip-xx-xx-xx-xx.shturval.link:9443/acme/acme/directory",
    "mgmtCluster": false
  },
  "provider": {
    "controlplaneNodeConfig": {
      "capovNodeConfig": {
        "cpu": { "cores": 4, "sockets": 1, "threads": 1 },
        "memory": { "sizeMB": 1200 },
        "osDiskSizeGB": 60
      },
      "nodeConfig": {
        "groupName": "control-plane",
        "roles": [{ "name": "node-role.kubernetes.io/control-plane" }]
      }
    },
    "enableCSI": false,
    "providerName": "$PROVIDERTEMPLATENAME",
    "workerNodeConfigs": [
      {
        "capovNodeConfig": {
          "cpu": { "cores": 4, "sockets": 1, "threads": 1 },
          "memory": { "sizeMB": 1200 },
          "osDiskSizeGB": 60
        },
        "nodeConfig": {
          "groupName": "default",
          "roles": [{ "name": "node-role.kubernetes.io/workers" }]
        },
        "workersCount": 3
      },
      {
        "capovNodeConfig": {
          "cpu": { "cores": 4, "sockets": 1, "threads": 1 },
          "memory": { "sizeMB": 1200 },
          "osDiskSizeGB": 60
        },
        "nodeConfig": {
          "groupName": "infra",
          "roles": [{ "name": "node-role.kubernetes.io/infra" }]
        },
        "workersCount": 3
      }
    ]
  }
EOF
) | jq -r

Shturval v2 (capsmv2)

Request without the -k flag for curl. Template - field name. Nodes are selected using the matchLabels.role selectors: controlplane, workers, infra.

export CLUSTERNAME="capsmv2-new-cluster"
export PROVIDERTEMPLATENAME="capsmv2-template-name"

curl -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/clusters/capsmv2 \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "cluster": {
    "apiEndpoint": "10.20.30.40",
    "clusterName": "$CLUSTERNAME",
    "disabledServices": [],
    "enabledServices": ["shturval-local-csi","shturval-services","shturval-update","shturval-vip","shturval-monitoring-crds","shturval-caching-dns","shturval-node-config","shturval-services-crds","shturval-cert-manager-crds","shturval-cert-manager","shturval-node-config-crds","shturval-policy-manager-crds","shturval-networking","shturval-vip-provider","shturval-update-crds"],
    "externalKubeAPILB": false,
    "externalingresslb": false,
    "ingress": "",
    "controlPlaneNodesCount": 1,
    "ingressvip": "10.20.30.42",
    "podSubnet": "172.16.0.0/16",
    "secure": false,
    "serviceSubnet": "10.96.0.0/12",
    "shturvalVersion": "2.14.0",
    "acmeRootCert": "acmeRootCert",
    "ACMEURL": "https://issuer.ip-xx-xx-xx-xx.shturval.link:9443/acme/acme/directory",
    "mgmtCluster": false
  },
  "provider": {
    "controlPlaneNodeConfig": {
      "controlPlaneSelector": {
        "matchExpressions": [],
        "matchLabels": { "role": "controlplane" }
      },
      "nodeConfig": {
        "groupName": "control-plane",
        "roles": [{ "name": "node-role.kubernetes.io/control-plane" }]
      }
    },
    "name": "$PROVIDERTEMPLATENAME",
    "workerNodeConfigs": [
      {
        "nodeConfig": {
          "groupName": "default",
          "roles": [{ "name": "node-role.kubernetes.io/workers" }]
        },
        "workersCount": 3,
        "workerSelector": {
          "matchExpressions": [],
          "matchLabels": { "role": "workers" }
        }
      },
      {
        "nodeConfig": {
          "groupName": "infra",
          "roles": [{ "name": "node-role.kubernetes.io/infra" }]
        },
        "workersCount": 0,
        "workerSelector": {
          "matchExpressions": [],
          "matchLabels": { "role": "infra" }
        }
    ]
  }
EOF
) | jq -r

OpenStack, Selectel, VK Cloud (capos)

externalKubeAPILB and externalingresslb - true, ingressvip - empty string. Intermediate certificate: cacert, cakey. Nodes - caposNodeConfig (openstackFlavorName, volumeType, volumeSize, availabilityZone). For worker groups, flavor is set by the $OPENSTACKFLAVORNAME variable.

export CLUSTERNAME="capos-new-cluster"
export PROVIDERTEMPLATENAME="capos-template-name"

curl -k -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/clusters/capos \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "cluster": {
    "clusterName": "$CLUSTERNAME",
    "disabledServices": [],
    "enabledServices": ["shturval-monitoring-crds","shturval-vip","shturval-services-crds","shturval-caching-dns","shturval-cert-manager","shturval-update-crds","shturval-services","shturval-update","shturval-networking","shturval-node-config-crds","shturval-node-config","shturval-cert-manager-crds","shturval-vip-provider","shturval-local-csi","shturval-policy-manager-crds"],
    "externalKubeAPILB": true,
    "externalingresslb": true,
    "ingress": "",
    "controlPlaneNodesCount": 1,
    "ingressvip": "",
    "podSubnet": "172.16.0.0/16",
    "secure": false,
    "serviceSubnet": "10.96.0.0/12",
    "shturvalVersion": "2.14.0",
    "cacert": "cacert",
    "cakey": "cakey",
    "mgmtCluster": false
  },
  "provider": {
    "controlplaneNodeConfig": {
      "caposNodeConfig": {
        "openstackFlavorName": "STD3-4-8",
        "volumeType": "ceph-hdd",
        "volumeSize": 60,
        "availabilityZone": "ME1"
      },
      "nodeConfig": {
        "groupName": "control-plane",
        "roles": [{ "name": "node-role.kubernetes.io/control-plane" }]
      }
    },
    "providerName": "$PROVIDERTEMPLATENAME",
    "enableCSI": false,
    "workerNodeConfigs": [
      {
        "nodeConfig": {
          "groupName": "default",
          "roles": [{ "name": "node-role.kubernetes.io/workers" }]
        },
        "workersCount": 3,
        "caposNodeConfig": {
          "openstackFlavorName": "$OPENSTACKFLAVORNAME",
          "volumeSize": 60,
          "volumeType": "ceph-hdd",
          "availabilityZone": "ME1"
        }
      },
      {
        "nodeConfig": {
          "groupName": "infra",
          "roles": [{ "name": "node-role.kubernetes.io/infra" }]
        },
        "workersCount": 0,
        "caposNodeConfig": {
          "openstackFlavorName": "$OPENSTACKFLAVORNAME",
          "volumeSize": 60,
          "volumeType": "ceph-hdd",
          "availabilityZone": "ME1"
        }
    ]
  }
EOF
) | jq -r

Basis Dynamix (capbd)

For Control Plane in capbdNodeConfig.networkInterfaces netType and networkName are specified (variables $NETTYPE, $NETWORKNAME). externalingresslb: true, ingressvip is different from VMware vSphere (example: 10.20.30.41).

export CLUSTERNAME="capbd-new-cluster"
export PROVIDERTEMPLATENAME="capbd-template-name"
export NETTYPE="net-type"
export NETWORKNAME="networkname"

curl -k -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/clusters/capbd \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "cluster": {
    "apiEndpoint": "10.20.30.40",
    "clusterName": "$CLUSTERNAME",
    "disabledServices": [],
    "enabledServices": ["shturval-node-config-crds","shturval-backup","shturval-services-crds","shturval-services","shturval-rollouts-crds","shturval-descheduler","shturval-vip-provider","shturval-ingress-controller","shturval-policy-manager-crds","shturval-networking","shturval-metrics-collector","shturval-monitoring-crds","shturval-scanner","shturval-caching-dns","shturval-vip","shturval-node-config","shturval-cert-expiration","shturval-update-crds","shturval-backup-crds","shturval-cd-crds","shturval-cert-manager-crds","shturval-cert-manager","shturval-local-csi","shturval-update","shturval-scanner-crds","shturval-policy-manager"],
    "externalKubeAPILB": false,
    "externalingresslb": true,
    "ingress": "",
    "controlPlaneNodesCount": 1,
    "ingressvip": "10.20.30.41",
    "podSubnet": "172.16.0.0/16",
    "secure": false,
    "serviceSubnet": "10.96.0.0/12",
    "shturvalVersion": "2.14.0",
    "mgmtCluster": false
  },
  "provider": {
    "controlplaneNodeConfig": {
      "capbdNodeConfig": {
        "cpu": 4,
        "memory": 12000,
        "networkInterfaces": [{ "netType": "$NETTYPE", "networkName": "$NETWORKNAME" }],
        "osDiskSizeGB": 60
      },
      "nodeConfig": {
        "groupName": "control-plane",
        "roles": [{ "name": "node-role.kubernetes.io/control-plane" }]
      }
    },
    "providerName": "$PROVIDERTEMPLATENAME",
    "workerNodeConfigs": [
      {
        "nodeConfig": {
          "groupName": "default",
          "roles": [{ "name": "node-role.kubernetes.io/workers" }]
        },
        "workersCount": 3,
        "capbdNodeConfig": { "cpu": 4, "memory": 12000, "osDiskSizeGB": 60 }
      },
      {
        "nodeConfig": {
          "groupName": "infra",
          "roles": [{ "name": "node-role.kubernetes.io/infra" }]
        },
        "workersCount": 3,
        "capbdNodeConfig": { "cpu": 4, "memory": 12000, "osDiskSizeGB": 60 }
      }
    ]
  }
EOF
) | jq -r

The creation response may return a short description of the cluster with phase: "Pending" and a generated ingress of the form *.capbd-new-cluster.ip-10-20-30-41.shturval.link.

Yandex Cloud (capyc)

externalKubeAPILB and externalingresslb are true, ingress is an FQDN (for example, cluster.shturval.link), and ingressvip is an empty string. Nodes use capycNodeConfig (cpuCores, memorySize, platformID, volumeType, volumeSize). enableCSI installs shturval-capy-csi; true is rejected when the instance has allowEditCSI: false. deletePersistentVolumes deletes PVs when the cluster is deleted; if the field is omitted, the cluster profile policy is used.

export CLUSTERNAME="capyc-new-cluster"
export PROVIDERTEMPLATENAME="capyc-template-name"

curl -k -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/clusters/capyc \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "cluster": {
    "clusterName": "$CLUSTERNAME",
    "disabledServices": [],
    "enabledServices": ["shturval-cert-manager-crds","shturval-vip-provider","shturval-update-crds","shturval-monitoring-crds","shturval-local-csi","shturval-policy-manager-crds","shturval-vip","shturval-node-config-crds","shturval-services","shturval-services-crds","shturval-caching-dns","shturval-cert-manager","shturval-update","shturval-networking","shturval-node-config"],
    "externalKubeAPILB": true,
    "externalingresslb": true,
    "ingress": "cluster.shturval.link",
    "controlPlaneNodesCount": 1,
    "ingressvip": "",
    "podSubnet": "172.16.0.0/16",
    "secure": false,
    "serviceSubnet": "10.96.0.0/12",
    "shturvalVersion": "2.14.0",
    "deletePersistentVolumes": false,
    "mgmtCluster": false
  },
  "provider": {
    "controlplaneNodeConfig": {
      "capycNodeConfig": {
        "cpuCores": 4,
        "memorySize": "800Mi",
        "platformID": "standard",
        "volumeType": "network-ssd",
        "volumeSize": "40Gi"
      },
      "nodeConfig": {
        "groupName": "control-plane",
        "roles": [{ "name": "node-role.kubernetes.io/control-plane" }]
      }
    },
    "providerName": "$PROVIDERTEMPLATENAME",
    "enableCSI": false,
    "workerNodeConfigs": [
      {
        "nodeConfig": {
          "groupName": "default",
          "roles": [{ "name": "node-role.kubernetes.io/workers" }]
        },
        "workersCount": 1,
        "capycNodeConfig": {
          "platformID": "standard",
          "volumeType": "network-ssd",
          "volumeSize": "40Gi",
          "memorySize": "800Mi",
          "cpuCores": 4
        }
      },
      {
        "nodeConfig": {
          "groupName": "infra",
          "roles": [{ "name": "node-role.kubernetes.io/infra" }]
        },
        "workersCount": 0,
        "capycNodeConfig": {
          "platformID": "standard",
          "volumeType": "network-ssd",
          "volumeSize": "40Gi",
          "memorySize": "800Mi",
          "cpuCores": 4
        }
    ]
  }
EOF
) | jq -r

VMware vCloud Director (capcd)

The API path is capcd. Template - identityName. Nodes - capcdNodeConfig (diskSize, sizingPolicy). Will complementProvider specific fields: kubeAPIVIPSubnet, serviceVIPSubnet.

export CLUSTERNAME="capvcd-new-cluster"
export PROVIDERTEMPLATENAME="capvcd-template-name"

curl -k -s -L --request POST $BACKENDPOINT/api/v1/platform/providers/clusters/capcd \
  --header "Authorization: Bearer $token" \
  --data @<(cat <<EOF
{
  "cluster": {
    "apiEndpoint": "",
    "clusterName": "$CLUSTERNAME",
    "disabledServices": [],
    "enabledServices": ["shturval-cert-manager-crds","shturval-vip-provider","shturval-update-crds","shturval-monitoring-crds","shturval-local-csi","shturval-policy-manager-crds","shturval-vip","shturval-node-config-crds","shturval-services","shturval-services-crds","shturval-caching-dns","shturval-cert-manager","shturval-update","shturval-networking","shturval-node-config"],
    "externalKubeAPILB": true,
    "externalingresslb": true,
    "ingress": "cluster.shturval.link",
    "controlPlaneNodesCount": 1,
    "ingressvip": "",
    "podSubnet": "172.16.0.0/16",
    "secure": false,
    "serviceSubnet": "10.96.0.0/12",
    "shturvalVersion": "2.14.0",
    "clusterConfigProfileName": "",
    "mgmtCluster": false
  },
  "provider": {
    "enableCSI": false,
    "identityName": "$PROVIDERTEMPLATENAME",
    "kubeAPIVIPSubnet": "",
    "serviceVIPSubnet": "",
    "controlplaneNodeConfig": {
      "capcdNodeConfig": { "diskSize": "50Gi", "sizingPolicy": "TKG" },
      "nodeConfig": {
        "groupName": "control-plane",
        "roles": [{ "name": "node-role.kubernetes.io/control-plane" }]
      }
    },
    "workerNodeConfigs": [
      {
        "nodeConfig": {
          "groupName": "default",
          "roles": [{ "name": "node-role.kubernetes.io/workers" }]
        },
        "workersCount": 2,
        "capcdNodeConfig": { "diskSize": "50Gi", "sizingPolicy": "TKG" }
      },
      {
        "nodeConfig": {
          "groupName": "infra",
          "roles": [{ "name": "node-role.kubernetes.io/infra" }]
        },
        "workersCount": 0,
        "capcdNodeConfig": { "diskSize": "50Gi", "sizingPolicy": "TKG" }
      }
    ]
  }
EOF
) | jq -r

Delete a cluster

export CLUSTERNAME="clustername"

curl -k -L --request DELETE $BACKENDPOINT/api/v1/clusters/$CLUSTERNAME --header "Authorization: Bearer $token"