From 85c521d59a98b65e7341baf9dae4d28683d5ae2b Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Wed, 17 Dec 2025 12:10:23 -0600 Subject: [PATCH 1/7] [feat] Add support for premium_40GB NodeBalancer type --- cloud/linode/loadbalancers.go | 9 +++++++-- docs/configuration/annotations.md | 4 ++-- docs/configuration/environment.md | 2 +- go.mod | 3 ++- go.sum | 8 ++++---- main.go | 2 +- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/cloud/linode/loadbalancers.go b/cloud/linode/loadbalancers.go index 681f4b75..dbf6d694 100644 --- a/cloud/linode/loadbalancers.go +++ b/cloud/linode/loadbalancers.go @@ -761,8 +761,13 @@ func (l *loadbalancers) GetLoadBalancerTags(_ context.Context, clusterName strin // GetLinodeNBType returns the NodeBalancer type for the service. func (l *loadbalancers) GetLinodeNBType(service *v1.Service) linodego.NodeBalancerPlanType { typeStr, ok := service.GetAnnotations()[annotations.AnnLinodeNodeBalancerType] - if ok && linodego.NodeBalancerPlanType(typeStr) == linodego.NBTypePremium { - return linodego.NBTypePremium + if ok { + switch linodego.NodeBalancerPlanType(typeStr) { + case linodego.NBTypePremium: + return linodego.NBTypePremium + case linodego.NBTypePremium40GB: + return linodego.NBTypePremium40GB + } } return linodego.NodeBalancerPlanType(options.Options.DefaultNBType) diff --git a/docs/configuration/annotations.md b/docs/configuration/annotations.md index a497032b..2241a64e 100644 --- a/docs/configuration/annotations.md +++ b/docs/configuration/annotations.md @@ -38,7 +38,7 @@ The keys and the values in [annotations must be strings](https://kubernetes.io/d | `tags` | string | | A comma separated list of tags to be applied to the NodeBalancer instance | | `firewall-id` | int | | An existing Cloud Firewall ID to be attached to the NodeBalancer instance. See [Firewall Setup](firewall.md) | | `firewall-acl` | string | | The Firewall rules to be applied to the NodeBalancer. See [Firewall Configuration](#firewall-configuration) | -| `nodebalancer-type` | string | | The type of NodeBalancer to create (options: common, premium). See [NodeBalancer Types](#nodebalancer-type) | +| `nodebalancer-type` | string | | The type of NodeBalancer to create (options: common, premium, premium_40GB). See [NodeBalancer Types](#nodebalancer-type) | | `enable-ipv6-ingress` | bool | `false` | When `true`, both IPv4 and IPv6 addresses will be included in the LoadBalancerStatus ingress | | `backend-ipv4-range` | string | | The IPv4 range from VPC subnet to be applied to the NodeBalancer backend. See [Nodebalancer VPC Configuration](#nodebalancer-vpc-configuration) | | `backend-vpc-name` | string | | VPC which is connected to the NodeBalancer backend. See [Nodebalancer VPC Configuration](#nodebalancer-vpc-configuration) | @@ -123,7 +123,7 @@ metadata: ``` ### NodeBalancer Type -Linode supports nodebalancers of different types: common and premium. By default, nodebalancers of type common are provisioned. If an account is allowed to provision premium nodebalancers and one wants to use them, it can be achieved by specifying the annotation: +Linode supports nodebalancers of different types: common, premium, and premium_40GB. By default, nodebalancers of type common are provisioned. If an account is allowed to provision premium nodebalancers and one wants to use them, it can be achieved by specifying the annotation: ```yaml metadata: annotations: diff --git a/docs/configuration/environment.md b/docs/configuration/environment.md index 842fc902..39b49682 100644 --- a/docs/configuration/environment.md +++ b/docs/configuration/environment.md @@ -46,7 +46,7 @@ The CCM supports the following flags: | `--load-balancer-type` | String | `nodebalancer` | Configures which type of load-balancing to use (options: nodebalancer, cilium-bgp) | | `--bgp-node-selector` | String | `""` | Node selector to use to perform shared IP fail-over with BGP | | `--ip-holder-suffix` | String | `""` | Suffix to append to the IP holder name when using shared IP fail-over with BGP | -| `--default-nodebalancer-type` | String | `common` | Default type of NodeBalancer to create (options: common, premium) | +| `--default-nodebalancer-type` | String | `common` | Default type of NodeBalancer to create (options: common, premium, premium_40GB) | | `--nodebalancer-tags` | String (comma separated) | | Linode tags to apply to all NodeBalancers | | `--nodebalancer-backend-ipv4-subnet` | String | `""` | ipv4 subnet to use for NodeBalancer backends | | `--nodebalancer-backend-ipv4-subnet-id` | Int | `""` | ipv4 subnet id to use for NodeBalancer backends | diff --git a/go.mod b/go.mod index 3ffe33a4..b57119d1 100644 --- a/go.mod +++ b/go.mod @@ -141,7 +141,7 @@ require ( golang.org/x/crypto v0.45.0 // indirect golang.org/x/mod v0.29.0 // indirect golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/oauth2 v0.33.0 // indirect golang.org/x/sync v0.18.0 // indirect golang.org/x/sys v0.38.0 // indirect golang.org/x/term v0.37.0 // indirect @@ -171,6 +171,7 @@ require ( ) replace ( + github.com/linode/linodego => github.com/komer3/linodego v0.0.0-20251217180225-898c4f5734c3 k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.34.1 k8s.io/cri-api => k8s.io/cri-api v0.34.1 k8s.io/cri-client => k8s.io/cri-client v0.34.1 diff --git a/go.sum b/go.sum index c1d5b23e..fac13982 100644 --- a/go.sum +++ b/go.sum @@ -186,6 +186,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/komer3/linodego v0.0.0-20251217180225-898c4f5734c3 h1:3YnjeYS0UMTCsfnxn2oEpjOczt3CYNKLRkaleeUyfkU= +github.com/komer3/linodego v0.0.0-20251217180225-898c4f5734c3/go.mod h1:u+mbth1igHGsd8VasP+8LKHrxuCYsVMHbY3fOYRh/FU= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -194,8 +196,6 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/linode/linodego v1.58.0 h1:yf/tDTf5v74qcxqWWvu3bEDOmDT1ulG9NBDdivp0/oM= -github.com/linode/linodego v1.58.0/go.mod h1:ViH3Tun41yQdknbSyrdHz/iFDXsquLu+YwFdFneEZbY= github.com/mackerelio/go-osstat v0.2.6 h1:gs4U8BZeS1tjrL08tt5VUliVvSWP26Ai2Ob8Lr7f2i0= github.com/mackerelio/go-osstat v0.2.6/go.mod h1:lRy8V9ZuHpuRVZh+vyTkODeDPl3/d5MgXHtLSaqG8bA= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= @@ -393,8 +393,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= +golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/main.go b/main.go index 89c45aee..d477ea80 100644 --- a/main.go +++ b/main.go @@ -91,7 +91,7 @@ func main() { command.Flags().StringVar(&ccmOptions.Options.LoadBalancerType, "load-balancer-type", "nodebalancer", "configures which type of load-balancing to use for LoadBalancer Services (options: nodebalancer, cilium-bgp)") command.Flags().StringVar(&ccmOptions.Options.BGPNodeSelector, "bgp-node-selector", "", "node selector to use to perform shared IP fail-over with BGP (e.g. cilium-bgp-peering=true") command.Flags().StringVar(&ccmOptions.Options.IpHolderSuffix, "ip-holder-suffix", "", "suffix to append to the ip holder name when using shared IP fail-over with BGP (e.g. ip-holder-suffix=my-cluster-name") - command.Flags().StringVar(&ccmOptions.Options.DefaultNBType, "default-nodebalancer-type", string(linodego.NBTypeCommon), "default type of NodeBalancer to create (options: common, premium)") + command.Flags().StringVar(&ccmOptions.Options.DefaultNBType, "default-nodebalancer-type", string(linodego.NBTypeCommon), "default type of NodeBalancer to create (options: common, premium, premium_40GB)") command.Flags().StringVar(&ccmOptions.Options.NodeBalancerBackendIPv4Subnet, "nodebalancer-backend-ipv4-subnet", "", "ipv4 subnet to use for NodeBalancer backends") command.Flags().StringSliceVar(&ccmOptions.Options.NodeBalancerTags, "nodebalancer-tags", []string{}, "Linode tags to apply to all NodeBalancers") command.Flags().BoolVar(&ccmOptions.Options.EnableIPv6ForLoadBalancers, "enable-ipv6-for-loadbalancers", false, "set both IPv4 and IPv6 addresses for all LoadBalancer services (when disabled, only IPv4 is used)") From ef25f0b029d0bdc19c06d64967d8a29ca8baf646 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Wed, 17 Dec 2025 12:17:54 -0600 Subject: [PATCH 2/7] [fix] Use VPCInterfaceUpdateOptions for interface updates --- cloud/linode/route_controller.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cloud/linode/route_controller.go b/cloud/linode/route_controller.go index 31fc0b9d..bf785849 100644 --- a/cloud/linode/route_controller.go +++ b/cloud/linode/route_controller.go @@ -245,9 +245,8 @@ func (r *routes) DeleteRoute(ctx context.Context, clusterName string, route *clo func (r *routes) handleInterfaces(ctx context.Context, intfRoutes []string, linodeInterfaceRoutes []linodego.VPCInterfaceIPv4RangeCreateOptions, instance *linodego.Instance, intfVPCIP linodego.VPCIP, route *cloudprovider.Route) error { if instance.InterfaceGeneration == linodego.GenerationLinode { interfaceUpdateOptions := linodego.LinodeInterfaceUpdateOptions{ - VPC: &linodego.VPCInterfaceCreateOptions{ - SubnetID: intfVPCIP.SubnetID, - IPv4: &linodego.VPCInterfaceIPv4CreateOptions{Ranges: linodeInterfaceRoutes}, + VPC: &linodego.VPCInterfaceUpdateOptions{ + IPv4: &linodego.VPCInterfaceIPv4CreateOptions{Ranges: &linodeInterfaceRoutes}, }, } resp, err := r.client.UpdateInterface(ctx, instance.ID, intfVPCIP.InterfaceID, interfaceUpdateOptions) From aef73cea6b34e13ff499be3d2003daef5dfbbb7a Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Wed, 17 Dec 2025 12:26:09 -0600 Subject: [PATCH 3/7] lint fix --- cloud/linode/loadbalancers.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cloud/linode/loadbalancers.go b/cloud/linode/loadbalancers.go index dbf6d694..763c2cdb 100644 --- a/cloud/linode/loadbalancers.go +++ b/cloud/linode/loadbalancers.go @@ -763,6 +763,8 @@ func (l *loadbalancers) GetLinodeNBType(service *v1.Service) linodego.NodeBalanc typeStr, ok := service.GetAnnotations()[annotations.AnnLinodeNodeBalancerType] if ok { switch linodego.NodeBalancerPlanType(typeStr) { + case linodego.NBTypeCommon: // need to add this because of the golint check + return linodego.NBTypeCommon case linodego.NBTypePremium: return linodego.NBTypePremium case linodego.NBTypePremium40GB: From 89b82d1ca6daa7ef320b97c3e7cbcc25f4665a35 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Wed, 17 Dec 2025 13:05:44 -0600 Subject: [PATCH 4/7] update linodego dep to fix typo --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b57119d1..8f1e7683 100644 --- a/go.mod +++ b/go.mod @@ -171,7 +171,7 @@ require ( ) replace ( - github.com/linode/linodego => github.com/komer3/linodego v0.0.0-20251217180225-898c4f5734c3 + github.com/linode/linodego => github.com/komer3/linodego v0.0.0-20251217190421-39bf98dc054f k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.34.1 k8s.io/cri-api => k8s.io/cri-api v0.34.1 k8s.io/cri-client => k8s.io/cri-client v0.34.1 diff --git a/go.sum b/go.sum index fac13982..76124e33 100644 --- a/go.sum +++ b/go.sum @@ -186,8 +186,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= -github.com/komer3/linodego v0.0.0-20251217180225-898c4f5734c3 h1:3YnjeYS0UMTCsfnxn2oEpjOczt3CYNKLRkaleeUyfkU= -github.com/komer3/linodego v0.0.0-20251217180225-898c4f5734c3/go.mod h1:u+mbth1igHGsd8VasP+8LKHrxuCYsVMHbY3fOYRh/FU= +github.com/komer3/linodego v0.0.0-20251217190421-39bf98dc054f h1:nUC+FQ3WKJxOfo1Ag86LzRhXKjvBmSkazqqQXb8GaWU= +github.com/komer3/linodego v0.0.0-20251217190421-39bf98dc054f/go.mod h1:u+mbth1igHGsd8VasP+8LKHrxuCYsVMHbY3fOYRh/FU= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= From bf2b16121514b58da6b13be47dd13defffa49773 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Mon, 29 Dec 2025 10:45:03 -0600 Subject: [PATCH 5/7] Switching to linode/linodego commit for the new changes --- go.mod | 22 +++++++++++----------- go.sum | 44 ++++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/go.mod b/go.mod index 8f1e7683..51127f84 100644 --- a/go.mod +++ b/go.mod @@ -65,7 +65,7 @@ require ( github.com/go-openapi/strfmt v0.23.0 // indirect github.com/go-openapi/swag v0.23.1 // indirect github.com/go-openapi/validate v0.24.0 // indirect - github.com/go-resty/resty/v2 v2.16.5 // indirect + github.com/go-resty/resty/v2 v2.17.1 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect @@ -138,16 +138,16 @@ require ( go.yaml.in/yaml/v2 v2.4.2 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/mod v0.29.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.12.0 // indirect - golang.org/x/tools v0.38.0 // indirect + golang.org/x/tools v0.39.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250721164621-a45f3dfb1074 // indirect google.golang.org/grpc v1.74.2 // indirect @@ -171,7 +171,7 @@ require ( ) replace ( - github.com/linode/linodego => github.com/komer3/linodego v0.0.0-20251217190421-39bf98dc054f + github.com/linode/linodego => github.com/linode/linodego v1.63.1-0.20251219213351-56cd69e69d8d k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.34.1 k8s.io/cri-api => k8s.io/cri-api v0.34.1 k8s.io/cri-client => k8s.io/cri-client v0.34.1 diff --git a/go.sum b/go.sum index 76124e33..7464c83b 100644 --- a/go.sum +++ b/go.sum @@ -109,8 +109,8 @@ github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3Bum github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= github.com/go-quicktest/qt v1.101.1-0.20240301121107-c6c8733fa1e6 h1:teYtXy9B7y5lHTp8V9KPxpYRAVA7dozigQcMiBust1s= github.com/go-quicktest/qt v1.101.1-0.20240301121107-c6c8733fa1e6/go.mod h1:p4lGIVX+8Wa6ZPNDvqcxq36XpUDLh42FLetFU7odllI= -github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= -github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= +github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4= +github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= @@ -186,8 +186,6 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= -github.com/komer3/linodego v0.0.0-20251217190421-39bf98dc054f h1:nUC+FQ3WKJxOfo1Ag86LzRhXKjvBmSkazqqQXb8GaWU= -github.com/komer3/linodego v0.0.0-20251217190421-39bf98dc054f/go.mod h1:u+mbth1igHGsd8VasP+8LKHrxuCYsVMHbY3fOYRh/FU= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -196,6 +194,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/linode/linodego v1.63.1-0.20251219213351-56cd69e69d8d h1:zHGKdDYYnRswWSPbXzWvH34Dh8EqXfj2SO6I7Q8gpI8= +github.com/linode/linodego v1.63.1-0.20251219213351-56cd69e69d8d/go.mod h1:GoiwLVuLdBQcAebxAVKVL3mMYUgJZR/puOUSla04xBE= github.com/mackerelio/go-osstat v0.2.6 h1:gs4U8BZeS1tjrL08tt5VUliVvSWP26Ai2Ob8Lr7f2i0= github.com/mackerelio/go-osstat v0.2.6/go.mod h1:lRy8V9ZuHpuRVZh+vyTkODeDPl3/d5MgXHtLSaqG8bA= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= @@ -376,31 +376,31 @@ golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= -golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -411,15 +411,15 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -428,8 +428,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 5c9ac9e644f60f7d74a007ca4675f76640f44fe9 Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Mon, 29 Dec 2025 10:49:48 -0600 Subject: [PATCH 6/7] Add warning for invalid NodeBalancer type annotation but still default to `DefaultNBType` --- cloud/linode/loadbalancers.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cloud/linode/loadbalancers.go b/cloud/linode/loadbalancers.go index 763c2cdb..a4ca0019 100644 --- a/cloud/linode/loadbalancers.go +++ b/cloud/linode/loadbalancers.go @@ -769,6 +769,9 @@ func (l *loadbalancers) GetLinodeNBType(service *v1.Service) linodego.NodeBalanc return linodego.NBTypePremium case linodego.NBTypePremium40GB: return linodego.NBTypePremium40GB + default: + klog.Warningf("Invalid NodeBalancer type '%s' specified in annotation for service %s/%s. Valid types are: %s, %s, %s. Defaulting to %s.", + typeStr, service.Namespace, service.Name, linodego.NBTypeCommon, linodego.NBTypePremium, linodego.NBTypePremium40GB, options.Options.DefaultNBType) } } From 58457f3d584c12693f6bb5e9cbc266eca581ca6b Mon Sep 17 00:00:00 2001 From: Khaja Omer Date: Mon, 29 Dec 2025 11:07:16 -0600 Subject: [PATCH 7/7] Normalize NodeBalancer type annotation to lowercase for safety Add automatic lowercase conversion for NodeBalancer type annotations to prevent typos and inconsistent casing. Update documentation to reflect that NodeBalancer types should always be specified in lowercase (e.g., `premium_40gb` instead of `premium_40GB`). --- cloud/linode/loadbalancers.go | 2 ++ docs/configuration/annotations.md | 6 ++++-- docs/configuration/environment.md | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cloud/linode/loadbalancers.go b/cloud/linode/loadbalancers.go index a4ca0019..a02f03df 100644 --- a/cloud/linode/loadbalancers.go +++ b/cloud/linode/loadbalancers.go @@ -762,6 +762,8 @@ func (l *loadbalancers) GetLoadBalancerTags(_ context.Context, clusterName strin func (l *loadbalancers) GetLinodeNBType(service *v1.Service) linodego.NodeBalancerPlanType { typeStr, ok := service.GetAnnotations()[annotations.AnnLinodeNodeBalancerType] if ok { + // For Safety - avoid typos and inconsistent casing + typeStr = strings.ToLower(typeStr) switch linodego.NodeBalancerPlanType(typeStr) { case linodego.NBTypeCommon: // need to add this because of the golint check return linodego.NBTypeCommon diff --git a/docs/configuration/annotations.md b/docs/configuration/annotations.md index 2241a64e..80088d4a 100644 --- a/docs/configuration/annotations.md +++ b/docs/configuration/annotations.md @@ -38,7 +38,7 @@ The keys and the values in [annotations must be strings](https://kubernetes.io/d | `tags` | string | | A comma separated list of tags to be applied to the NodeBalancer instance | | `firewall-id` | int | | An existing Cloud Firewall ID to be attached to the NodeBalancer instance. See [Firewall Setup](firewall.md) | | `firewall-acl` | string | | The Firewall rules to be applied to the NodeBalancer. See [Firewall Configuration](#firewall-configuration) | -| `nodebalancer-type` | string | | The type of NodeBalancer to create (options: common, premium, premium_40GB). See [NodeBalancer Types](#nodebalancer-type) | +| `nodebalancer-type` | string | | The type of NodeBalancer to create (options: common, premium, premium_40gb). See [NodeBalancer Types](#nodebalancer-type). Note: NodeBalancer types should always be specified in lowercase. | | `enable-ipv6-ingress` | bool | `false` | When `true`, both IPv4 and IPv6 addresses will be included in the LoadBalancerStatus ingress | | `backend-ipv4-range` | string | | The IPv4 range from VPC subnet to be applied to the NodeBalancer backend. See [Nodebalancer VPC Configuration](#nodebalancer-vpc-configuration) | | `backend-vpc-name` | string | | VPC which is connected to the NodeBalancer backend. See [Nodebalancer VPC Configuration](#nodebalancer-vpc-configuration) | @@ -123,7 +123,9 @@ metadata: ``` ### NodeBalancer Type -Linode supports nodebalancers of different types: common, premium, and premium_40GB. By default, nodebalancers of type common are provisioned. If an account is allowed to provision premium nodebalancers and one wants to use them, it can be achieved by specifying the annotation: +Linode supports nodebalancers of different types: common, premium, and premium_40gb. By default, nodebalancers of type common are provisioned. If an account is allowed to provision premium nodebalancers and one wants to use them, it can be achieved by specifying the annotation: + +**Note:** NodeBalancer types should always be specified in lowercase. The controller will automatically convert uppercase values to lowercase for safety. ```yaml metadata: annotations: diff --git a/docs/configuration/environment.md b/docs/configuration/environment.md index 39b49682..cbed0124 100644 --- a/docs/configuration/environment.md +++ b/docs/configuration/environment.md @@ -46,7 +46,7 @@ The CCM supports the following flags: | `--load-balancer-type` | String | `nodebalancer` | Configures which type of load-balancing to use (options: nodebalancer, cilium-bgp) | | `--bgp-node-selector` | String | `""` | Node selector to use to perform shared IP fail-over with BGP | | `--ip-holder-suffix` | String | `""` | Suffix to append to the IP holder name when using shared IP fail-over with BGP | -| `--default-nodebalancer-type` | String | `common` | Default type of NodeBalancer to create (options: common, premium, premium_40GB) | +| `--default-nodebalancer-type` | String | `common` | Default type of NodeBalancer to create (options: common, premium, premium_40gb). Note: NodeBalancer types should always be specified in lowercase. | | `--nodebalancer-tags` | String (comma separated) | | Linode tags to apply to all NodeBalancers | | `--nodebalancer-backend-ipv4-subnet` | String | `""` | ipv4 subnet to use for NodeBalancer backends | | `--nodebalancer-backend-ipv4-subnet-id` | Int | `""` | ipv4 subnet id to use for NodeBalancer backends |