From 84a6e489a6618b40f8aec211044449f5f4367aab Mon Sep 17 00:00:00 2001 From: Ingo Gottwald Date: Thu, 26 Sep 2024 14:59:46 +0200 Subject: [PATCH] doks: add custom subnets flags (#1586) This allows setting custom subnets on DOKS clusters and create vpc-native clusters. --- args.go | 4 ++ commands/kubernetes.go | 20 +++++++ commands/kubernetes_test.go | 13 ++++ go.mod | 2 +- go.sum | 4 ++ .../github.com/digitalocean/godo/CHANGELOG.md | 5 ++ .../github.com/digitalocean/godo/databases.go | 60 +++++++++++++++++++ vendor/github.com/digitalocean/godo/godo.go | 2 +- .../digitalocean/godo/kubernetes.go | 12 ++-- vendor/modules.txt | 2 +- 10 files changed, 116 insertions(+), 8 deletions(-) diff --git a/args.go b/args.go index ab5c34b57..fee162667 100644 --- a/args.go +++ b/args.go @@ -66,6 +66,10 @@ const ( ArgVPCUUID = "vpc-uuid" // ArgClusterVPCUUID is a cluster vpc-uuid argument. ArgClusterVPCUUID = "vpc-uuid" + // ArgClusterSubnet is a cluster pod CIDR argument. + ArgClusterSubnet = "cluster-subnet" + // ArgServiceSubnet is a cluster service CIDR argument. + ArgServiceSubnet = "service-subnet" // ArgClusterNodePool are a cluster's node pools arguments. ArgClusterNodePool = "node-pool" // ArgClusterUpdateKubeconfig updates the local kubeconfig. diff --git a/commands/kubernetes.go b/commands/kubernetes.go index 6b067fea9..975b59ae5 100644 --- a/commands/kubernetes.go +++ b/commands/kubernetes.go @@ -277,6 +277,10 @@ After creating a cluster, a configuration context is added to kubectl and made a "A `slug` indicating which Kubernetes version to use when creating the cluster. Use the `doctl kubernetes options versions` command for a list of options") AddStringFlag(cmdKubeClusterCreate, doctl.ArgClusterVPCUUID, "", "", "The UUID of a VPC network to create the cluster in. Must be the UUID of a valid VPC in the same region specified for the cluster. If a VPC is not specified, the cluster is placed in the default VPC network for the region.") + AddStringFlag(cmdKubeClusterCreate, doctl.ArgClusterSubnet, "", "", + "The CIDR block to use for the pod network. Must be a valid CIDR block. Defaults to `10.244.0.0/16`. If left empty/default the cluster will be created with a virtual network. If a custom one is provided, the cluster will be created as vpc-native cluster. VPC-native CIDR blocks cannot overlap within an account.") + AddStringFlag(cmdKubeClusterCreate, doctl.ArgServiceSubnet, "", "", + "The CIDR block to use for the service network. Must be a valid CIDR block. Defaults to `10.245.0.0/16`. If left empty/default the cluster will be created with a virtual network. If a custom one is provided, the cluster will be created as vpc-native cluster. VPC-native CIDR blocks cannot overlap within an account.") AddBoolFlag(cmdKubeClusterCreate, doctl.ArgAutoUpgrade, "", false, "Enables automatic upgrades to new patch releases during the cluster's maintenance window. Defaults to `false`. To enable automatic upgrade, supply `--auto-upgrade=true`.") AddBoolFlag(cmdKubeClusterCreate, doctl.ArgSurgeUpgrade, "", true, @@ -1633,6 +1637,22 @@ func buildClusterCreateRequestFromArgs(c *CmdConfig, r *godo.KubernetesClusterCr // empty "" is fine, the default region VPC will be resolved r.VPCUUID = vpcUUID + podCIDR, err := c.Doit.GetString(c.NS, doctl.ArgClusterSubnet) + if err != nil { + return err + } + r.ClusterSubnet = podCIDR + svcCIDR, err := c.Doit.GetString(c.NS, doctl.ArgServiceSubnet) + if err != nil { + return err + } + r.ServiceSubnet = svcCIDR + // empty "" is fine, the default is still to use a virtual network and not be vpc-native. + // either both have to be set (vpc-native) or none (virtual network) + if c.Doit.IsSet(doctl.ArgClusterSubnet) != c.Doit.IsSet(doctl.ArgServiceSubnet) { + return fmt.Errorf("flags %q and %q both have to be set for vpc-native clusters or both unset for virtual network clusters", doctl.ArgClusterSubnet, doctl.ArgServiceSubnet) + } + version, err := getVersionOrLatest(c) if err != nil { return err diff --git a/commands/kubernetes_test.go b/commands/kubernetes_test.go index d20b4cf01..4c3d35281 100644 --- a/commands/kubernetes_test.go +++ b/commands/kubernetes_test.go @@ -547,6 +547,19 @@ func TestKubernetesCreate(t *testing.T) { err = testK8sCmdService().RunKubernetesClusterCreate("c-8", 3)(config) assert.NoError(t, err) + // Test vpc-native + const podNetwork = "10.100.0.0/16" + const serviceNetwork = "10.101.0.0/16" + config.Doit.Set(config.NS, doctl.ArgClusterSubnet, podNetwork) + config.Doit.Set(config.NS, doctl.ArgServiceSubnet, serviceNetwork) + r.ClusterSubnet = podNetwork + r.ServiceSubnet = serviceNetwork + testCluster.ClusterSubnet = podNetwork + testCluster.ServiceSubnet = serviceNetwork + tm.kubernetes.EXPECT().Create(&r).Return(&testCluster, nil) + err = testK8sCmdService().RunKubernetesClusterCreate("c-8", 3)(config) + assert.NoError(t, err) + // Test with 1-clicks specified config.Doit.Set(config.NS, doctl.ArgOneClicks, []string{"slug1", "slug2"}) tm.kubernetes.EXPECT().Create(&r).Return(&testCluster, nil) diff --git a/go.mod b/go.mod index caae3c46d..59323d6ac 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22 require ( github.com/blang/semver v3.5.1+incompatible github.com/creack/pty v1.1.21 - github.com/digitalocean/godo v1.125.0 + github.com/digitalocean/godo v1.126.0 github.com/docker/cli v24.0.5+incompatible github.com/docker/docker v25.0.6+incompatible github.com/docker/docker-credential-helpers v0.7.0 // indirect diff --git a/go.sum b/go.sum index 1d888d85e..1b4b48721 100644 --- a/go.sum +++ b/go.sum @@ -93,6 +93,10 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/digitalocean/godo v1.125.0 h1:wGPBQRX9Wjo0qCF0o8d25mT3A84Iw8rfHnZOPyvHcMQ= github.com/digitalocean/godo v1.125.0/go.mod h1:PU8JB6I1XYkQIdHFop8lLAY9ojp6M0XcU0TWaQSxbrc= +github.com/digitalocean/godo v1.125.1-0.20240925184037-40ea734536f0 h1:hEi5W+TPrYUjq1PLt1lJmhrt+ezpzUrAvwYr9f1Xo4U= +github.com/digitalocean/godo v1.125.1-0.20240925184037-40ea734536f0/go.mod h1:PU8JB6I1XYkQIdHFop8lLAY9ojp6M0XcU0TWaQSxbrc= +github.com/digitalocean/godo v1.126.0 h1:+Znh7VMQj/E8ArbjWnc7OKGjWfzC+I8OCSRp7r1MdD8= +github.com/digitalocean/godo v1.126.0/go.mod h1:PU8JB6I1XYkQIdHFop8lLAY9ojp6M0XcU0TWaQSxbrc= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/cli v24.0.5+incompatible h1:WeBimjvS0eKdH4Ygx+ihVq1Q++xg36M/rMi4aXAvodc= diff --git a/vendor/github.com/digitalocean/godo/CHANGELOG.md b/vendor/github.com/digitalocean/godo/CHANGELOG.md index b045687a9..371272169 100644 --- a/vendor/github.com/digitalocean/godo/CHANGELOG.md +++ b/vendor/github.com/digitalocean/godo/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## [v1.126.0] - 2024-09-25 + +- #732 - @gottwald - DOKS: add custom CIDR fields +- #727 - @loosla - [databases]: add support for Kafka advanced configuration + ## [v1.125.0] - 2024-09-17 - #726 - @loosla - [databases]: add support for MongoDB advanced configuration diff --git a/vendor/github.com/digitalocean/godo/databases.go b/vendor/github.com/digitalocean/godo/databases.go index c0c91e2b4..e168186ff 100644 --- a/vendor/github.com/digitalocean/godo/databases.go +++ b/vendor/github.com/digitalocean/godo/databases.go @@ -3,6 +3,7 @@ package godo import ( "context" "fmt" + "math/big" "net/http" "strings" "time" @@ -153,10 +154,12 @@ type DatabasesService interface { GetRedisConfig(context.Context, string) (*RedisConfig, *Response, error) GetMySQLConfig(context.Context, string) (*MySQLConfig, *Response, error) GetMongoDBConfig(context.Context, string) (*MongoDBConfig, *Response, error) + GetKafkaConfig(context.Context, string) (*KafkaConfig, *Response, error) UpdatePostgreSQLConfig(context.Context, string, *PostgreSQLConfig) (*Response, error) UpdateRedisConfig(context.Context, string, *RedisConfig) (*Response, error) UpdateMySQLConfig(context.Context, string, *MySQLConfig) (*Response, error) UpdateMongoDBConfig(context.Context, string, *MongoDBConfig) (*Response, error) + UpdateKafkaConfig(context.Context, string, *KafkaConfig) (*Response, error) ListOptions(todo context.Context) (*DatabaseOptions, *Response, error) UpgradeMajorVersion(context.Context, string, *UpgradeVersionRequest) (*Response, error) ListTopics(context.Context, string, *ListOptions) ([]DatabaseTopic, *Response, error) @@ -659,6 +662,27 @@ type MongoDBConfig struct { Verbosity *int `json:"verbosity,omitempty"` } +// KafkaConfig holds advanced configurations for Kafka database clusters. +type KafkaConfig struct { + GroupInitialRebalanceDelayMs *int `json:"group_initial_rebalance_delay_ms,omitempty"` + GroupMinSessionTimeoutMs *int `json:"group_min_session_timeout_ms,omitempty"` + GroupMaxSessionTimeoutMs *int `json:"group_max_session_timeout_ms,omitempty"` + MessageMaxBytes *int `json:"message_max_bytes,omitempty"` + LogCleanerDeleteRetentionMs *int64 `json:"log_cleaner_delete_retention_ms,omitempty"` + LogCleanerMinCompactionLagMs *uint64 `json:"log_cleaner_min_compaction_lag_ms,omitempty"` + LogFlushIntervalMs *uint64 `json:"log_flush_interval_ms,omitempty"` + LogIndexIntervalBytes *int `json:"log_index_interval_bytes,omitempty"` + LogMessageDownconversionEnable *bool `json:"log_message_downconversion_enable,omitempty"` + LogMessageTimestampDifferenceMaxMs *uint64 `json:"log_message_timestamp_difference_max_ms,omitempty"` + LogPreallocate *bool `json:"log_preallocate,omitempty"` + LogRetentionBytes *big.Int `json:"log_retention_bytes,omitempty"` + LogRetentionHours *int `json:"log_retention_hours,omitempty"` + LogRetentionMs *big.Int `json:"log_retention_ms,omitempty"` + LogRollJitterMs *uint64 `json:"log_roll_jitter_ms,omitempty"` + LogSegmentDeleteDelayMs *int `json:"log_segment_delete_delay_ms,omitempty"` + AutoCreateTopicsEnable *bool `json:"auto_create_topics_enable,omitempty"` +} + type databaseUserRoot struct { User *DatabaseUser `json:"user"` } @@ -703,6 +727,10 @@ type databaseMongoDBConfigRoot struct { Config *MongoDBConfig `json:"config"` } +type databaseKafkaConfigRoot struct { + Config *KafkaConfig `json:"config"` +} + type databaseBackupsRoot struct { Backups []DatabaseBackup `json:"backups"` } @@ -1546,6 +1574,38 @@ func (svc *DatabasesServiceOp) UpdateMongoDBConfig(ctx context.Context, database return resp, nil } +// GetKafkaConfig retrieves the config for a Kafka database cluster. +func (svc *DatabasesServiceOp) GetKafkaConfig(ctx context.Context, databaseID string) (*KafkaConfig, *Response, error) { + path := fmt.Sprintf(databaseConfigPath, databaseID) + req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + root := new(databaseKafkaConfigRoot) + resp, err := svc.client.Do(ctx, req, root) + if err != nil { + return nil, resp, err + } + return root.Config, resp, nil +} + +// UpdateKafkaConfig updates the config for a Kafka database cluster. +func (svc *DatabasesServiceOp) UpdateKafkaConfig(ctx context.Context, databaseID string, config *KafkaConfig) (*Response, error) { + path := fmt.Sprintf(databaseConfigPath, databaseID) + root := &databaseKafkaConfigRoot{ + Config: config, + } + req, err := svc.client.NewRequest(ctx, http.MethodPatch, path, root) + if err != nil { + return nil, err + } + resp, err := svc.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + return resp, nil +} + // ListOptions gets the database options available. func (svc *DatabasesServiceOp) ListOptions(ctx context.Context) (*DatabaseOptions, *Response, error) { root := new(databaseOptionsRoot) diff --git a/vendor/github.com/digitalocean/godo/godo.go b/vendor/github.com/digitalocean/godo/godo.go index 45c0f115f..3702ac1f7 100644 --- a/vendor/github.com/digitalocean/godo/godo.go +++ b/vendor/github.com/digitalocean/godo/godo.go @@ -21,7 +21,7 @@ import ( ) const ( - libraryVersion = "1.125.0" + libraryVersion = "1.126.0" defaultBaseURL = "https://api.digitalocean.com/" userAgent = "godo/" + libraryVersion mediaType = "application/json" diff --git a/vendor/github.com/digitalocean/godo/kubernetes.go b/vendor/github.com/digitalocean/godo/kubernetes.go index 8ef9d241e..9b3bcfa1a 100644 --- a/vendor/github.com/digitalocean/godo/kubernetes.go +++ b/vendor/github.com/digitalocean/godo/kubernetes.go @@ -65,11 +65,13 @@ type KubernetesServiceOp struct { // KubernetesClusterCreateRequest represents a request to create a Kubernetes cluster. type KubernetesClusterCreateRequest struct { - Name string `json:"name,omitempty"` - RegionSlug string `json:"region,omitempty"` - VersionSlug string `json:"version,omitempty"` - Tags []string `json:"tags,omitempty"` - VPCUUID string `json:"vpc_uuid,omitempty"` + Name string `json:"name,omitempty"` + RegionSlug string `json:"region,omitempty"` + VersionSlug string `json:"version,omitempty"` + Tags []string `json:"tags,omitempty"` + VPCUUID string `json:"vpc_uuid,omitempty"` + ClusterSubnet string `json:"cluster_subnet,omitempty"` + ServiceSubnet string `json:"service_subnet,omitempty"` // Create cluster with highly available control plane HA bool `json:"ha"` diff --git a/vendor/modules.txt b/vendor/modules.txt index 09e25066b..051318834 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -61,7 +61,7 @@ github.com/creack/pty # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew -# github.com/digitalocean/godo v1.125.0 +# github.com/digitalocean/godo v1.126.0 ## explicit; go 1.22 github.com/digitalocean/godo github.com/digitalocean/godo/metrics