Clusters API
The ClusterService (pivirt.cluster.v1) manages multi-node cluster topology, node lifecycle operations (adding, draining, cordoning, and removing nodes), health telemetry, and cluster-wide rolling upgrades.
Service Definition
Section titled “Service Definition”package pivirt.cluster.v1;
service ClusterService { // Cluster operations rpc CreateCluster(CreateClusterRequest) returns (Cluster); rpc GetCluster(GetClusterRequest) returns (Cluster); rpc ListClusters(ListClustersRequest) returns (stream Cluster); rpc DeleteCluster(DeleteClusterRequest) returns (Operation); rpc UpdateCluster(UpdateClusterRequest) returns (Cluster);
// Node operations rpc AddNode(AddNodeRequest) returns (Node); rpc RemoveNode(RemoveNodeRequest) returns (Operation); rpc GetNode(GetNodeRequest) returns (Node); rpc ListNodes(ListNodesRequest) returns (stream Node); rpc DrainNode(DrainNodeRequest) returns (Operation); rpc CordonNode(CordonNodeRequest) returns (Operation); rpc UncordonNode(UncordonNodeRequest) returns (Operation);
// Cluster health rpc GetHealth(GetHealthRequest) returns (ClusterHealth); rpc GetMetrics(GetMetricsRequest) returns (ClusterMetrics);
// Cluster upgrade rpc UpgradeCluster(UpgradeClusterRequest) returns (Operation); rpc GetUpgradeStatus(GetUpgradeStatusRequest) returns (UpgradeStatus);}Messages
Section titled “Messages”Cluster
Section titled “Cluster”message Cluster { string id = 1; string name = 2; ClusterStatus status = 3; string version = 4; ClusterTopology topology = 5; map<string, string> labels = 6; map<string, string> annotations = 7; google.protobuf.Timestamp created_at = 8; google.protobuf.Timestamp updated_at = 9;}
enum ClusterStatus { CLUSTER_STATUS_UNSPECIFIED = 0; CLUSTER_STATUS_CREATING = 1; CLUSTER_STATUS_RUNNING = 2; CLUSTER_STATUS_DEGRADED = 3; CLUSTER_STATUS_ERROR = 4; CLUSTER_STATUS_UPGRADING = 5;}
message ClusterTopology { int32 control_plane_count = 1; int32 worker_count = 2; repeated string control_plane_nodes = 3; repeated string worker_nodes = 4;}message Node { string id = 1; string name = 2; string cluster_id = 3; NodeRole role = 4; NodeStatus status = 5; string ip = 6; NodeResources resources = 7; NodeConditions conditions = 8; map<string, string> labels = 9; map<string, string> annotations = 10; google.protobuf.Timestamp created_at = 11; google.protobuf.Timestamp updated_at = 12;}
enum NodeRole { NODE_ROLE_UNSPECIFIED = 0; NODE_ROLE_CONTROL_PLANE = 1; NODE_ROLE_WORKER = 2;}
enum NodeStatus { NODE_STATUS_UNSPECIFIED = 0; NODE_STATUS_READY = 1; NODE_STATUS_NOT_READY = 2; NODE_STATUS_DRAINING = 3; NODE_STATUS_CORDONED = 4; NODE_STATUS_ERROR = 5;}
message NodeResources { int32 cpu_cores = 1; int64 memory_bytes = 2; int64 storage_bytes = 3; int32 cpu_used_cores = 4; int64 memory_used_bytes = 5; int64 storage_used_bytes = 6;}
message NodeConditions { bool memory_pressure = 1; bool disk_pressure = 2; bool pid_pressure = 3; bool network_unavailable = 4;}ClusterHealth
Section titled “ClusterHealth”message ClusterHealth { string cluster_id = 1; HealthStatus status = 2; repeated ComponentHealth components = 3; repeated NodeHealth nodes = 4; string message = 5;}
enum HealthStatus { HEALTH_STATUS_UNSPECIFIED = 0; HEALTH_STATUS_HEALTHY = 1; HEALTH_STATUS_DEGRADED = 2; HEALTH_STATUS_UNHEALTHY = 3;}
message ComponentHealth { string name = 1; HealthStatus status = 2; string message = 3; google.protobuf.Timestamp last_check = 4;}
message NodeHealth { string node_id = 1; string node_name = 2; HealthStatus status = 3; string message = 4; google.protobuf.Timestamp last_check = 5;}Methods
Section titled “Methods”CreateCluster
Section titled “CreateCluster”message CreateClusterRequest { string name = 1; ClusterTopology topology = 2; string version = 3; map<string, string> labels = 4; map<string, string> annotations = 5;}Example:
grpcurl -plaintext -d '{ "name": "prod-cluster", "topology": { "control_plane_count": 3, "worker_count": 5 }, "version": "v0.0.89"}' localhost:8443 pivirt.cluster.v1.ClusterService/CreateClusterAddNode
Section titled “AddNode”message AddNodeRequest { string cluster_id = 1; string name = 2; NodeRole role = 3; string ip = 4; map<string, string> labels = 5;}Example:
grpcurl -plaintext -d '{ "cluster_id": "cluster-abc123", "name": "worker-04", "role": "NODE_ROLE_WORKER", "ip": "10.0.1.24"}' localhost:8443 pivirt.cluster.v1.ClusterService/AddNodeDrainNode
Section titled “DrainNode”message DrainNodeRequest { string cluster_id = 1; string node_id = 2; bool force = 3; bool ignore_daemonsets = 4; int32 grace_period_seconds = 5;}Example:
grpcurl -plaintext -d '{ "cluster_id": "cluster-abc123", "node_id": "node-01", "force": false, "grace_period_seconds": 300}' localhost:8443 pivirt.cluster.v1.ClusterService/DrainNodeUpgradeCluster
Section titled “UpgradeCluster”message UpgradeClusterRequest { string cluster_id = 1; string target_version = 2; UpgradeStrategy strategy = 3;}
message UpgradeStrategy { UpgradeType type = 1; int32 max_surge = 2; int32 max_unavailable = 3; int32 partition = 4;}
enum UpgradeType { UPGRADE_TYPE_UNSPECIFIED = 0; UPGRADE_TYPE_ROLLING = 1; UPGRADE_TYPE_BLUE_GREEN = 2; UPGRADE_TYPE_CANARY = 3;}Example:
grpcurl -plaintext -d '{ "cluster_id": "cluster-abc123", "target_version": "v0.0.90", "strategy": { "type": "UPGRADE_TYPE_ROLLING", "max_surge": 1, "max_unavailable": 0 }}' localhost:8443 pivirt.cluster.v1.ClusterService/UpgradeClusterGetHealth
Section titled “GetHealth”message GetHealthRequest { string cluster_id = 1;}Example:
grpcurl -plaintext -d '{ "cluster_id": "cluster-abc123"}' localhost:8443 pivirt.cluster.v1.ClusterService/GetHealthError Codes
Section titled “Error Codes”| Code | Description |
|---|---|
NOT_FOUND |
Cluster or node not found |
ALREADY_EXISTS |
Cluster or node with same name exists |
INVALID_ARGUMENT |
Invalid cluster/node configuration |
FAILED_PRECONDITION |
Cluster in wrong state for operation |
RESOURCE_EXHAUSTED |
Insufficient resources for operation |