Repository: digitalocean/doctl
Pull request #1538 (2024-06-05 13:39:29)

Support load balancers network type

asaha2: cc @andrewsomething when you have a chance 🙏 

Patch:
diff --git a/args.go b/args.go
index 9b2b381a..7570f645 100644
--- a/args.go
+++ b/args.go
@@ -345,6 +345,8 @@ const (
 	ArgGlobalLoadBalancerCDNSettings = "glb-cdn-settings"
 	// ArgTargetLoadBalancerIDs is a list of target load balancer IDs.
 	ArgTargetLoadBalancerIDs = "target-lb-ids"
+	// ArgLoadBalancerNetwork is the type of network the load balancer is accessible from.
+	ArgLoadBalancerNetwork = "network"
 
 	// ArgFirewallName is a name of the firewall.
 	ArgFirewallName = "name"
diff --git a/commands/load_balancers.go b/commands/load_balancers.go
index 476bd3ba..6e9374bd 100644
--- a/commands/load_balancers.go
+++ b/commands/load_balancers.go
@@ -104,7 +104,10 @@ With the load-balancer command, you can list, create, or delete load balancers,
 	AddStringSliceFlag(cmdLoadBalancerCreate, doctl.ArgTargetLoadBalancerIDs, "", []string{},
 		"A comma-separated list of Load Balancer IDs to add as target to the global load balancer "+
 			"(NOTE: this is a closed beta feature, contact DigitalOcean support to review its public availability.)")
+	AddStringFlag(cmdLoadBalancerCreate, doctl.ArgLoadBalancerNetwork, "", "", "The type of network the load balancer is accessible from, e.g.: `EXTERNAL` or `INTERNAL`"+
+		"(NOTE: this is a closed beta feature, contact DigitalOcean support to review its public availability.)")
 	cmdLoadBalancerCreate.Flags().MarkHidden(doctl.ArgLoadBalancerType)
+	cmdLoadBalancerCreate.Flags().MarkHidden(doctl.ArgLoadBalancerNetwork)
 
 	cmdRecordUpdate := CmdBuilder(cmd, RunLoadBalancerUpdate, "update <id>",
 		"Update a load balancer's configuration", `Use this command to update the configuration of a specified load balancer. Using all applicable flags, the command should contain a full representation of the load balancer including existing attributes, such as the load balancer's name, region, forwarding rules, and Droplet IDs. Any attribute that is not provided is reset to its default value.`, Writer, aliasOpt("u"))
@@ -705,6 +708,12 @@ func buildRequestFromArgs(c *CmdConfig, r *godo.LoadBalancerRequest) error {
 	}
 	r.TargetLoadBalancerIDs = lbIDsList
 
+	network, err := c.Doit.GetString(c.NS, doctl.ArgLoadBalancerNetwork)
+	if err != nil {
+		return err
+	}
+	r.Network = strings.ToUpper(network)
+
 	return nil
 }
 
diff --git a/go.mod b/go.mod
index 380485ef..9cda598f 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.21
 require (
 	github.com/blang/semver v3.5.1+incompatible
 	github.com/creack/pty v1.1.11
-	github.com/digitalocean/godo v1.116.0
+	github.com/digitalocean/godo v1.117.0
 	github.com/docker/cli v24.0.5+incompatible
 	github.com/docker/docker v24.0.9+incompatible
 	github.com/docker/docker-credential-helpers v0.7.0 // indirect
diff --git a/go.sum b/go.sum
index 05424209..3de9287c 100644
--- a/go.sum
+++ b/go.sum
@@ -86,10 +86,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/digitalocean/godo v1.115.1-0.20240515191029-705fb26c5aa5 h1:bAO9uVDeZhwy1DdKmtAqgjS9+isKWnzxzxiKvNHKNtQ=
-github.com/digitalocean/godo v1.115.1-0.20240515191029-705fb26c5aa5/go.mod h1:Vk0vpCot2HOAJwc5WE8wljZGtJ3ZtWIc8MQ8rF38sdo=
-github.com/digitalocean/godo v1.116.0 h1:SuF/Imd1/dE/nYrUFVkJ2itesQNnJQE1a/vmtHknxeE=
-github.com/digitalocean/godo v1.116.0/go.mod h1:Vk0vpCot2HOAJwc5WE8wljZGtJ3ZtWIc8MQ8rF38sdo=
+github.com/digitalocean/godo v1.117.0 h1:WVlTe09melDYTd7VCVyvHcNWbgB+uI1O115+5LOtdSw=
+github.com/digitalocean/godo v1.117.0/go.mod h1:Vk0vpCot2HOAJwc5WE8wljZGtJ3ZtWIc8MQ8rF38sdo=
 github.com/docker/cli v24.0.5+incompatible h1:WeBimjvS0eKdH4Ygx+ihVq1Q++xg36M/rMi4aXAvodc=
 github.com/docker/cli v24.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
diff --git a/vendor/github.com/digitalocean/godo/CHANGELOG.md b/vendor/github.com/digitalocean/godo/CHANGELOG.md
index 1d3102b2..ce940ccb 100644
--- a/vendor/github.com/digitalocean/godo/CHANGELOG.md
+++ b/vendor/github.com/digitalocean/godo/CHANGELOG.md
@@ -1,5 +1,12 @@
 # Change Log
 
+## [v1.117.0] - 2024-06-04
+
+- #696 - @llDrLove - Support specifying control plane firewall rules when creating or updating DOKS clusters
+- #697 - @asaha2 - Add support for lb internal network type
+- #695 - @ElanHasson - APPS-8732 - Update documentation on App Platform OpenSearch endpoint structure.
+- #692 - @ElanHasson - APPS-8732 - Add OpenSearch as a Log Destination for App Platform.
+
 ## [v1.116.0] - 2024-05-16
 
 - #693 - @guptado - Introduce VPC peering methods
diff --git a/vendor/github.com/digitalocean/godo/apps.gen.go b/vendor/github.com/digitalocean/godo/apps.gen.go
index f734ab02..f5be2992 100644
--- a/vendor/github.com/digitalocean/godo/apps.gen.go
+++ b/vendor/github.com/digitalocean/godo/apps.gen.go
@@ -221,6 +221,7 @@ const (
 	AppDatabaseSpecEngine_PG      AppDatabaseSpecEngine = "PG"
 	AppDatabaseSpecEngine_Redis   AppDatabaseSpecEngine = "REDIS"
 	AppDatabaseSpecEngine_MongoDB AppDatabaseSpecEngine = "MONGODB"
+	AppDatabaseSpecEngine_Kafka   AppDatabaseSpecEngine = "KAFKA"
 )
 
 // AppDedicatedIp Represents a dedicated egress ip.
@@ -415,6 +416,7 @@ type AppLogDestinationSpec struct {
 	Papertrail  *AppLogDestinationSpecPapertrail `json:"papertrail,omitempty"`
 	Datadog     *AppLogDestinationSpecDataDog    `json:"datadog,omitempty"`
 	Logtail     *AppLogDestinationSpecLogtail    `json:"logtail,omitempty"`
+	OpenSearch  *AppLogDestinationSpecOpenSearch `json:"open_search,omitempty"`
 	Endpoint    string                           `json:"endpoint,omitempty"`
 	TLSInsecure bool                             `json:"tls_insecure,omitempty"`
 	Headers     []*AppLogDestinationSpecHeader   `json:"headers,omitempty"`
@@ -442,6 +444,15 @@ type AppLogDestinationSpecLogtail struct {
 	Token string `json:"token"`
 }
 
+// AppLogDestinationSpecOpenSearch OpenSearch configuration.
+type AppLogDestinationSpecOpenSearch struct {
+	// OpenSearch API Endpoint. Only HTTPS is supported. Format: https://<host>:<port>.
+	Endpoint  string               `json:"endpoint"`
+	BasicAuth *OpenSearchBasicAuth `json:"basic_auth,omitempty"`
+	// The index name to use for the logs. If not set, the default index name is \"logs\".
+	IndexName string `json:"index_name,omitempty"`
+}
+
 // AppLogDestinationSpecPapertrail Papertrail configuration.
 type AppLogDestinationSpecPapertrail struct {
 	// Papertrail syslog endpoint.
@@ -1171,6 +1182,14 @@ type ListBuildpacksResponse struct {
 	Buildpacks []*Buildpack `json:"buildpacks,omitempty"`
 }
 
+// OpenSearchBasicAuth Configure Username and/or Password for Basic authentication.
+type OpenSearchBasicAuth struct {
+	// Username to authenticate with.
+	User string `json:"user"`
+	// Password for user defined in User.
+	Password string `json:"password"`
+}
+
 // AppProposeRequest struct for AppProposeRequest
 type AppProposeRequest struct {
 	Spec *AppSpec `json:"spec"`
diff --git a/vendor/github.com/digitalocean/godo/apps_accessors.go b/vendor/github.com/digitalocean/godo/apps_accessors.go
index 734c27ea..0bbba2dd 100644
--- a/vendor/github.com/digitalocean/godo/apps_accessors.go
+++ b/vendor/github.com/digitalocean/godo/apps_accessors.go
@@ -1317,6 +1317,14 @@ func (a *AppLogDestinationSpec) GetName() string {
 	return a.Name
 }
 
+// GetOpenSearch returns the OpenSearch field.
+func (a *AppLogDestinationSpec) GetOpenSearch() *AppLogDestinationSpecOpenSearch {
+	if a == nil {
+		return nil
+	}
+	return a.OpenSearch
+}
+
 // GetPapertrail returns the Papertrail field.
 func (a *AppLogDestinationSpec) GetPapertrail() *AppLogDestinationSpecPapertrail {
 	if a == nil {
@@ -1373,6 +1381,30 @@ func (a *AppLogDestinationSpecLogtail) GetToken() string {
 	return a.Token
 }
 
+// GetBasicAuth returns the BasicAuth field.
+func (a *AppLogDestinationSpecOpenSearch) GetBasicAuth() *OpenSearchBasicAuth {
+	if a == nil {
+		return nil
+	}
+	return a.BasicAuth
+}
+
+// GetEndpoint returns the Endpoint field.
+func (a *AppLogDestinationSpecOpenSearch) GetEndpoint() string {
+	if a == nil {
+		return ""
+	}
+	return a.Endpoint
+}
+
+// GetIndexName returns the IndexName field.
+func (a *AppLogDestinationSpecOpenSearch) GetIndexName() string {
+	if a == nil {
+		return ""
+	}
+	return a.IndexName
+}
+
 // GetEndpoint returns the Endpoint field.
 func (a *AppLogDestinationSpecPapertrail) GetEndpoint() string {
 	if a == nil {
@@ -3533,6 +3565,22 @@ func (l *ListBuildpacksResponse) GetBuildpacks() []*Buildpack {
 	return l.Buildpacks
 }
 
+// GetPassword returns the Password field.
+func (o *OpenSearchBasicAuth) GetPassword() string {
+	if o == nil {
+		return ""
+	}
+	return o.Password
+}
+
+// GetUser returns the User field.
+func (o *OpenSearchBasicAuth) GetUser() string {
+	if o == nil {
+		return ""
+	}
+	return o.User
+}
+
 // GetAppID returns the AppID field.
 func (r *ResetDatabasePasswordRequest) GetAppID() string {
 	if r == nil {
diff --git a/vendor/github.com/digitalocean/godo/godo.go b/vendor/github.com/digitalocean/godo/godo.go
index 1ec4df20..c16aac43 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.116.0"
+	libraryVersion = "1.117.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 38c380a5..e275fa10 100644
--- a/vendor/github.com/digitalocean/godo/kubernetes.go
+++ b/vendor/github.com/digitalocean/godo/kubernetes.go
@@ -76,18 +76,20 @@ type KubernetesClusterCreateRequest struct {
 
 	NodePools []*KubernetesNodePoolCreateRequest `json:"node_pools,omitempty"`
 
-	MaintenancePolicy *KubernetesMaintenancePolicy `json:"maintenance_policy"`
-	AutoUpgrade       bool                         `json:"auto_upgrade"`
-	SurgeUpgrade      bool                         `json:"surge_upgrade"`
+	MaintenancePolicy      *KubernetesMaintenancePolicy      `json:"maintenance_policy"`
+	AutoUpgrade            bool                              `json:"auto_upgrade"`
+	SurgeUpgrade           bool                              `json:"surge_upgrade"`
+	ControlPlanePermission *KubernetesControlPlanePermission `json:"control_plane_permission,omitempty"`
 }
 
 // KubernetesClusterUpdateRequest represents a request to update a Kubernetes cluster.
 type KubernetesClusterUpdateRequest struct {
-	Name              string                       `json:"name,omitempty"`
-	Tags              []string                     `json:"tags,omitempty"`
-	MaintenancePolicy *KubernetesMaintenancePolicy `json:"maintenance_policy,omitempty"`
-	AutoUpgrade       *bool                        `json:"auto_upgrade,omitempty"`
-	SurgeUpgrade      bool                         `json:"surge_upgrade,omitempty"`
+	Name                   string                            `json:"name,omitempty"`
+	Tags                   []string                          `json:"tags,omitempty"`
+	MaintenancePolicy      *KubernetesMaintenancePolicy      `json:"maintenance_policy,omitempty"`
+	AutoUpgrade            *bool                             `json:"auto_upgrade,omitempty"`
+	SurgeUpgrade           bool                              `json:"surge_upgrade,omitempty"`
+	ControlPlanePermission *KubernetesControlPlanePermission `json:"control_plane_permission,omitempty"`
 
 	// Convert cluster to run highly available control plane
 	HA *bool `json:"ha,omitempty"`
@@ -201,10 +203,11 @@ type KubernetesCluster struct {
 
 	NodePools []*KubernetesNodePool `json:"node_pools,omitempty"`
 
-	MaintenancePolicy *KubernetesMaintenancePolicy `json:"maintenance_policy,omitempty"`
-	AutoUpgrade       bool                         `json:"auto_upgrade,omitempty"`
-	SurgeUpgrade      bool                         `json:"surge_upgrade,omitempty"`
-	RegistryEnabled   bool                         `json:"registry_enabled,omitempty"`
+	MaintenancePolicy      *KubernetesMaintenancePolicy      `json:"maintenance_policy,omitempty"`
+	AutoUpgrade            bool                              `json:"auto_upgrade,omitempty"`
+	SurgeUpgrade           bool                              `json:"surge_upgrade,omitempty"`
+	RegistryEnabled        bool                              `json:"registry_enabled,omitempty"`
+	ControlPlanePermission *KubernetesControlPlanePermission `json:"control_plane_permission,omitempty"`
 
 	Status    *KubernetesClusterStatus `json:"status,omitempty"`
 	CreatedAt time.Time                `json:"created_at,omitempty"`
@@ -240,6 +243,12 @@ type KubernetesMaintenancePolicy struct {
 	Day       KubernetesMaintenancePolicyDay `json:"day"`
 }
 
+// KubernetesControlPlanePermission represents Kubernetes cluster control plane permission.
+type KubernetesControlPlanePermission struct {
+	Enabled          *bool    `json:"enabled"`
+	AllowedAddresses []string `json:"allowed_addresses"`
+}
+
 // KubernetesMaintenancePolicyDay represents the possible days of a maintenance
 // window
 type KubernetesMaintenancePolicyDay int
diff --git a/vendor/github.com/digitalocean/godo/load_balancers.go b/vendor/github.com/digitalocean/godo/load_balancers.go
index 39679053..703aa842 100644
--- a/vendor/github.com/digitalocean/godo/load_balancers.go
+++ b/vendor/github.com/digitalocean/godo/load_balancers.go
@@ -13,11 +13,15 @@ const (
 	loadBalancersBasePath = "/v2/load_balancers"
 )
 
-// Load Balancer types.
 const (
+	// Load Balancer types
 	LoadBalancerTypeGlobal          = "GLOBAL"
 	LoadBalancerTypeRegional        = "REGIONAL"
 	LoadBalancerTypeRegionalNetwork = "REGIONAL_NETWORK"
+
+	// Load Balancer network types
+	LoadBalancerNetworkTypeExternal = "EXTERNAL"
+	LoadBalancerNetworkTypeInternal = "INTERNAL"
 )
 
 // LoadBalancersService is an interface for managing load balancers with the DigitalOcean API.
@@ -68,6 +72,7 @@ type LoadBalancer struct {
 	Domains                      []*LBDomain      `json:"domains,omitempty"`
 	GLBSettings                  *GLBSettings     `json:"glb_settings,omitempty"`
 	TargetLoadBalancerIDs        []string         `json:"target_load_balancer_ids,omitempty"`
+	Network                      string           `json:"network,omitempty"`
 }
 
 // String creates a human-readable description of a LoadBalancer.
@@ -101,6 +106,7 @@ func (l LoadBalancer) AsRequest() *LoadBalancerRequest {
 		ProjectID:                    l.ProjectID,
 		HTTPIdleTimeoutSeconds:       l.HTTPIdleTimeoutSeconds,
 		TargetLoadBalancerIDs:        append([]string(nil), l.TargetLoadBalancerIDs...),
+		Network:                      l.Network,
 	}
 
 	if l.DisableLetsEncryptDNSRecords != nil {
@@ -238,6 +244,7 @@ type LoadBalancerRequest struct {
 	Domains                      []*LBDomain      `json:"domains,omitempty"`
 	GLBSettings                  *GLBSettings     `json:"glb_settings,omitempty"`
 	TargetLoadBalancerIDs        []string         `json:"target_load_balancer_ids,omitempty"`
+	Network                      string           `json:"network,omitempty"`
 }
 
 // String creates a human-readable description of a LoadBalancerRequest.
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 3f9b348a..484c604f 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -58,7 +58,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.116.0
+# github.com/digitalocean/godo v1.117.0
 ## explicit; go 1.20
 github.com/digitalocean/godo
 github.com/digitalocean/godo/metrics


Test patch:
diff --git a/commands/load_balancers_test.go b/commands/load_balancers_test.go
index 3d0a1d63..dd74405a 100644
--- a/commands/load_balancers_test.go
+++ b/commands/load_balancers_test.go
@@ -116,6 +116,7 @@ func TestLoadBalancerCreate(t *testing.T) {
 				Deny:  []string{"cidr:1.2.0.0/16"},
 				Allow: []string{"ip:1.2.3.4", "ip:1.2.3.5"},
 			},
+			Network: "EXTERNAL",
 		}
 		disableLetsEncryptDNSRecords := true
 		r.DisableLetsEncryptDNSRecords = &disableLetsEncryptDNSRecords
@@ -135,6 +136,7 @@ func TestLoadBalancerCreate(t *testing.T) {
 		config.Doit.Set(config.NS, doctl.ArgHTTPIdleTimeoutSeconds, 120)
 		config.Doit.Set(config.NS, doctl.ArgDenyList, []string{"cidr:1.2.0.0/16"})
 		config.Doit.Set(config.NS, doctl.ArgAllowList, []string{"ip:1.2.3.4", "ip:1.2.3.5"})
+		config.Doit.Set(config.NS, doctl.ArgLoadBalancerNetwork, "EXTERNAL")
 
 		err := RunLoadBalancerCreate(config)
 		assert.NoError(t, err)
@@ -182,6 +184,7 @@ func TestLoadBalancerCreateGLB(t *testing.T) {
 				"019cb059-603f-4828-8be4-641a20f25006",
 				"023da268-bc81-468f-aa4d-9abdc4f69935",
 			},
+			Network: "EXTERNAL",
 		}
 		disableLetsEncryptDNSRecords := true
 		r.DisableLetsEncryptDNSRecords = &disableLetsEncryptDNSRecords
@@ -203,6 +206,7 @@ func TestLoadBalancerCreateGLB(t *testing.T) {
 			"019cb059-603f-4828-8be4-641a20f25006",
 			"023da268-bc81-468f-aa4d-9abdc4f69935",
 		})
+		config.Doit.Set(config.NS, doctl.ArgLoadBalancerNetwork, "EXTERNAL")
 
 		err := RunLoadBalancerCreate(config)
 		assert.NoError(t, err)