From 72241ad5dadef41988873db7a2c54dff8977fad9 Mon Sep 17 00:00:00 2001 From: tytv2 Date: Tue, 7 Jul 2026 15:03:19 +0700 Subject: [PATCH] fix(vks): make update-cluster fields optional per spec UpdateClusterDto no longer marks any field required. Drop the forced --k8s-version and --whitelist-node-cidrs requirements, send each body field only when its flag is set (partial update), and reject a call that changes nothing. Docs updated to match. --- docs/commands/vks/update-cluster.md | 20 +++++++--------- go/cmd/vks/update_cluster.go | 36 ++++++++++++++--------------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/docs/commands/vks/update-cluster.md b/docs/commands/vks/update-cluster.md index 655e017..4f2a920 100644 --- a/docs/commands/vks/update-cluster.md +++ b/docs/commands/vks/update-cluster.md @@ -2,9 +2,7 @@ ## Description -Update a VKS cluster's Kubernetes version, node CIDR whitelist, and plugin configuration. The cluster ID, target Kubernetes version, and at least one whitelist CIDR are always required by the API, even when the intent is only to toggle a plugin. - -Plugin flags (`--load-balancer-plugin`, `--block-store-csi-plugin`) are only sent when explicitly provided; omitting them leaves the current plugin state unchanged. +Update a VKS cluster's Kubernetes version, node CIDR whitelist, and plugin configuration. Only the cluster ID is required; every other field is a partial update. Provide at least one of `--k8s-version`, `--whitelist-node-cidrs`, `--load-balancer-plugin`, or `--block-store-csi-plugin` — any flag you omit is left unchanged. Use `--dry-run` to preview the update payload without executing the request. @@ -13,8 +11,8 @@ Use `--dry-run` to preview the update payload without executing the request. ``` grn vks update-cluster --cluster-id - --k8s-version - --whitelist-node-cidrs + [--k8s-version ] + [--whitelist-node-cidrs ] [--load-balancer-plugin ] [--block-store-csi-plugin ] [--dry-run] @@ -30,17 +28,17 @@ ID of the cluster to update. **`--k8s-version`** (string) -Target Kubernetes version (e.g. `v1.29.1`). Must be the same or a higher version than the cluster's current version. +Target Kubernetes version (e.g. `v1.29.1`). Must be the same or a higher version than the cluster's current version. When omitted, the version is left unchanged. -- Required: Yes +- Required: No - Constraints: 1–50 characters. - See available versions with [list-cluster-versions](list-cluster-versions.md). **`--whitelist-node-cidrs`** (list<string>) -CIDRs allowed to communicate with cluster nodes, comma-separated. At least one value is required. +CIDRs allowed to communicate with cluster nodes, comma-separated. When omitted, the whitelist is left unchanged. -- Required: Yes +- Required: No - Constraints: 1–30 entries. - Syntax: `10.0.0.0/8,192.168.0.0/16` @@ -80,13 +78,11 @@ grn vks update-cluster \ --whitelist-node-cidrs 10.0.0.0/8,192.168.0.0/16 ``` -Update cluster and disable the load balancer plugin: +Disable only the load balancer plugin, leaving version and whitelist unchanged: ```bash grn vks update-cluster \ --cluster-id cls-abc12345-6789-def0-1234-abcdef012345 \ - --k8s-version v1.29.1 \ - --whitelist-node-cidrs 10.0.0.0/8 \ --load-balancer-plugin disabled ``` diff --git a/go/cmd/vks/update_cluster.go b/go/cmd/vks/update_cluster.go index 616c999..ae36943 100644 --- a/go/cmd/vks/update_cluster.go +++ b/go/cmd/vks/update_cluster.go @@ -17,33 +17,34 @@ var updateClusterCmd = &cobra.Command{ func init() { f := updateClusterCmd.Flags() f.String("cluster-id", "", "Cluster ID (required)") - f.String("k8s-version", "", "Kubernetes version (required)") - f.String("whitelist-node-cidrs", "", "Whitelist CIDRs, comma-separated (required)") + f.String("k8s-version", "", "New Kubernetes version; unset = unchanged") + f.String("whitelist-node-cidrs", "", "Whitelist CIDRs, comma-separated; unset = unchanged") f.String("load-balancer-plugin", "", "Load balancer plugin (enabled, disabled); unset = unchanged") f.String("block-store-csi-plugin", "", "Block store CSI plugin (enabled, disabled); unset = unchanged") f.Bool("dry-run", false, "Validate parameters without updating") updateClusterCmd.MarkFlagRequired("cluster-id") - updateClusterCmd.MarkFlagRequired("k8s-version") - updateClusterCmd.MarkFlagRequired("whitelist-node-cidrs") } func runUpdateCluster(cmd *cobra.Command, args []string) error { clusterID, _ := cmd.Flags().GetString("cluster-id") - k8sVersion, _ := cmd.Flags().GetString("k8s-version") - whitelistCIDRs, _ := cmd.Flags().GetString("whitelist-node-cidrs") dryRun, _ := cmd.Flags().GetBool("dry-run") if err := validator.ValidateID(clusterID, "cluster-id"); err != nil { return err } - body := map[string]interface{}{ - "version": k8sVersion, - "whitelistNodeCIDRs": parseCommaSeparated(whitelistCIDRs), - } + // All body fields are optional (partial update) — send only what the user set. + body := map[string]any{} - // Plugin toggles are only sent when explicitly provided (unset = unchanged). + if cmd.Flags().Changed("k8s-version") { + v, _ := cmd.Flags().GetString("k8s-version") + body["version"] = v + } + if cmd.Flags().Changed("whitelist-node-cidrs") { + v, _ := cmd.Flags().GetString("whitelist-node-cidrs") + body["whitelistNodeCIDRs"] = parseCommaSeparated(v) + } if cmd.Flags().Changed("load-balancer-plugin") { v, _ := cmd.Flags().GetString("load-balancer-plugin") enabled, err := parseToggle("load-balancer-plugin", v) @@ -61,17 +62,16 @@ func runUpdateCluster(cmd *cobra.Command, args []string) error { body["enabledBlockStoreCsiPlugin"] = enabled } + if len(body) == 0 { + return fmt.Errorf("nothing to update: provide at least one of --k8s-version, --whitelist-node-cidrs, --load-balancer-plugin, or --block-store-csi-plugin") + } + if dryRun { fmt.Println("=== DRY RUN: Update cluster ===") fmt.Println() fmt.Printf("Cluster ID: %s\n", clusterID) - fmt.Printf("New version: %s\n", k8sVersion) - fmt.Printf("Whitelist CIDRs: %s\n", whitelistCIDRs) - if v, ok := body["enabledLoadBalancerPlugin"]; ok { - fmt.Printf("Load balancer plugin: %v\n", v) - } - if v, ok := body["enabledBlockStoreCsiPlugin"]; ok { - fmt.Printf("Block store CSI plugin: %v\n", v) + for key, value := range body { + fmt.Printf(" %s: %v\n", key, value) } fmt.Println("\nRun without --dry-run to update.") return nil