diff --git a/Dockerfile b/Dockerfile index de8fbec..3bb1de8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ -FROM alpine:3.22 +FROM alpine:3.23 RUN apk add --no-cache curl tini COPY cloud-controller-manager /usr/local/bin/ ENTRYPOINT ["/sbin/tini", "--"] -CMD ["cloud-controller-manager"] \ No newline at end of file +CMD ["cloud-controller-manager"] diff --git a/Dockerfile.builder b/Dockerfile.builder new file mode 100644 index 0000000..fc52209 --- /dev/null +++ b/Dockerfile.builder @@ -0,0 +1,24 @@ +FROM golang:1.25-alpine AS builder + +WORKDIR /workspace +COPY go.mod go.mod +COPY go.sum go.sum +RUN go mod download +COPY ./ ./ +ARG GOPROXY +ARG OS +ARG ARCH +ARG ARM +ARG LDFLAGS +RUN CGO_ENABLED=0 GOOS=${OS} GOARCH=${ARCH} GOARM=${ARM} GOPROXY=${GOPROXY} \ + go build \ + -ldflags="-extldflags '-static' ${LDFLAGS}" \ + -o=cloud-controller-manager \ + github.com/UpCloudLtd/upcloud-cloud-controller-manager/cmd/upcloud-cloud-controller-manager + +FROM alpine:3.23 +RUN apk add --no-cache curl tini +WORKDIR / +COPY --from=builder /workspace/cloud-controller-manager /usr/local/bin/ +ENTRYPOINT ["/sbin/tini", "--"] +CMD ["cloud-controller-manager"] \ No newline at end of file diff --git a/Makefile b/Makefile index 419929d..2f725f9 100644 --- a/Makefile +++ b/Makefile @@ -9,8 +9,7 @@ ifeq ($(GOPROXY),) GOPROXY := https://proxy.golang.org endif export GOPROXY - -export LDFLAGS := "-w -s -X 'k8s.io/component-base/version/verflag.programName=UpCloud cloud controller manager' $(shell scripts/version.sh "ldflags")" +LDFLAGS ?= "" ## -------------------------------------- ## Binaries ## -------------------------------------- @@ -18,3 +17,7 @@ export LDFLAGS := "-w -s -X 'k8s.io/component-base/version/verflag.programName=U .PHONY: manager manager: ## Build cloud controller manager binary in local environment CGO_ENABLED=0 GOPROXY=$(GOPROXY) go build -ldflags $(LDFLAGS) -o $(BIN_DIR)/cloud-controller-manager github.com/UpCloudLtd/upcloud-cloud-controller-manager/cmd/upcloud-cloud-controller-manager + +.PHONY: test +test: + go test -race ./... diff --git a/go.mod b/go.mod index 98c439a..b41a3cd 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module github.com/UpCloudLtd/upcloud-cloud-controller-manager -go 1.24.6 +go 1.25 require ( - github.com/UpCloudLtd/upcloud-go-api/v8 v8.20.0 + github.com/UpCloudLtd/upcloud-go-api/v8 v8.35.0 github.com/google/uuid v1.6.0 - github.com/stretchr/testify v1.10.0 + github.com/stretchr/testify v1.11.1 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.31.10 k8s.io/apimachinery v0.31.10 diff --git a/go.sum b/go.sum index c702092..a0e138c 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOEl github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/UpCloudLtd/upcloud-go-api/v8 v8.20.0 h1:nx1lbPwbqRPTNCZx437a7PrmyQkVXkgnK3hYZi9QgPc= -github.com/UpCloudLtd/upcloud-go-api/v8 v8.20.0/go.mod h1:ImDdnWfVVM6WCRTrskGhAw2W1cRwu5IEkBw+9UCzAv8= +github.com/UpCloudLtd/upcloud-go-api/v8 v8.35.0 h1:AIt07ExXzCaC9YVszkVPT+CteoyXldw0C8DGUMxtjD4= +github.com/UpCloudLtd/upcloud-go-api/v8 v8.35.0/go.mod h1:sxG94uNhC31OQH+zK0RhZjVj+PdkhObsNAt5bvq2J8c= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= @@ -162,8 +162,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= diff --git a/internal/loadbalancer/compare.go b/internal/loadbalancer/compare.go index 86ded8b..ad379f0 100644 --- a/internal/loadbalancer/compare.go +++ b/internal/loadbalancer/compare.go @@ -72,6 +72,9 @@ func createLoadBalancerRequestsEqual(r1, r2 *request.CreateLoadBalancerRequest) if !reflect.DeepEqual(r1.Backends, r2.Backends) { return fieldValueNotEqualError("backends") } + if !reflect.DeepEqual(r1.IPAddresses, r2.IPAddresses) { + return fieldValueNotEqualError("IP addresses") + } return nil } @@ -120,6 +123,9 @@ func sortCreateLoadBalancerRequestSlices(r *request.CreateLoadBalancerRequest) { slices.SortFunc(r.Backends, func(a, b request.LoadBalancerBackend) int { return strings.Compare(a.Name, b.Name) }) + slices.SortFunc(r.IPAddresses, func(a, b request.LoadBalancerIPAddress) int { + return strings.Compare(a.NetworkName, b.NetworkName) + }) } func lengthNotEqualError(field string) error { diff --git a/internal/loadbalancer/compare_internal_test.go b/internal/loadbalancer/compare_internal_test.go index b17658e..63de6c5 100644 --- a/internal/loadbalancer/compare_internal_test.go +++ b/internal/loadbalancer/compare_internal_test.go @@ -52,6 +52,13 @@ func TestCreateLoadBalancerRequestsEqual(t *testing.T) { r2.Name = "test-1" require.Equal(t, fieldValueNotEqualError("name"), createLoadBalancerRequestsEqual(&r1, &r2)) }) + t.Run("IPAddresses", func(t *testing.T) { + t.Parallel() + r1 := createRequest(id) + r2 := createRequest(id) + r2.IPAddresses[0].Address = "0.0.0.1" + require.Equal(t, fieldValueNotEqualError("IP addresses"), createLoadBalancerRequestsEqual(&r1, &r2)) + }) } func createRequest(id uuid.UUID) request.CreateLoadBalancerRequest { @@ -68,6 +75,7 @@ func createRequest(id uuid.UUID) request.CreateLoadBalancerRequest { Backends: backends(id), Resolvers: resolvers(), Labels: upcloudLabels(id), + IPAddresses: ipAddresses(), } } @@ -192,3 +200,12 @@ func upcloudLabels(id uuid.UUID) []upcloud.Label { }, } } + +func ipAddresses() []request.LoadBalancerIPAddress { + return []request.LoadBalancerIPAddress{ + { + NetworkName: networkNamePublic, + Address: "0.0.0.0", + }, + } +} diff --git a/internal/loadbalancer/const.go b/internal/loadbalancer/const.go index d508e8f..0fa292a 100644 --- a/internal/loadbalancer/const.go +++ b/internal/loadbalancer/const.go @@ -32,12 +32,10 @@ const ( // ServiceExternalTrafficPolicyLabelKey is a key for label that should store external traffic policy type as a value. serviceExternalTrafficPolicyLabel string = "ccm_external_traffic_policy" - changesDetectedEventType string = "ChangesDetected" - noChangesDetectedEventType string = "NoChangesDetected" - newLoadBalancerEventType string = "NewLoadBalancer" - updateLoadBalancerEventType string = "UpdateLoadBalancer" - deleteLoadBalancerEventType string = "DeleteLoadBalancer" - nodeCountLimitReached string = "NodeCountLimitReached" + changesDetectedEventType string = "ChangesDetected" + noChangesDetectedEventType string = "NoChangesDetected" + newLoadBalancerEventType string = "NewLoadBalancer" + nodeCountLimitReached string = "NodeCountLimitReached" loadBalancerNameMaxLength int = 64 loadBalancerIDMaxLength int = 36 diff --git a/internal/loadbalancer/loadbalancer.go b/internal/loadbalancer/loadbalancer.go index ee4f71a..2aa096a 100644 --- a/internal/loadbalancer/loadbalancer.go +++ b/internal/loadbalancer/loadbalancer.go @@ -138,7 +138,7 @@ func (m *manager) ensureNewLoadBalancer(ctx context.Context, clusterName string, m.eventRecorder.Event(service, v1.EventTypeNormal, newLoadBalancerEventType, "Creating load balancer") lb, err := m.svc.CreateLoadBalancer(ctx, service, nodes, clusterName) // Patch service object as soon as we have LB UUID so that we don't loose reference. - if lb.UUID != "" && !serviceHasAnnotation(service, loadBalancerIDAnnotation) { + if lb != nil && lb.UUID != "" && !serviceHasAnnotation(service, loadBalancerIDAnnotation) { modifiedService := service.DeepCopy() updateServiceAnnotations(modifiedService, lb) if perr := m.patchService(ctx, service, modifiedService); perr != nil { diff --git a/internal/loadbalancer/loadbalancer_request.go b/internal/loadbalancer/loadbalancer_request.go index d883749..eb25ec3 100644 --- a/internal/loadbalancer/loadbalancer_request.go +++ b/internal/loadbalancer/loadbalancer_request.go @@ -28,6 +28,7 @@ type replaceLoadBalancerRequest struct { Labels []upcloud.Label `json:"labels,omitempty"` MaintenanceDOW upcloud.LoadBalancerMaintenanceDOW `json:"maintenance_dow,omitempty"` MaintenanceTime string `json:"maintenance_time,omitempty"` + IPAddresses []request.LoadBalancerIPAddress `json:"ip_addresses"` } func (r *replaceLoadBalancerRequest) RequestURL() string { @@ -60,7 +61,8 @@ func createLoadBalancerRequest(service *v1.Service, nodes []*v1.Node, plan upclo }, }, ConfiguredStatus: upcloud.LoadBalancerConfiguredStatusStarted, - Resolvers: []request.LoadBalancerResolver{}, + Resolvers: make([]request.LoadBalancerResolver, 0), + IPAddresses: make([]request.LoadBalancerIPAddress, 0), } r.Frontends = make([]request.LoadBalancerFrontend, len(service.Spec.Ports)) r.Backends = make([]request.LoadBalancerBackend, len(service.Spec.Ports)) @@ -220,6 +222,13 @@ func loadBalancerToCreateRequest(lb *upcloud.LoadBalancer) *request.CreateLoadBa CacheInvalid: lb.Resolvers[i].CacheInvalid, } } + ipAddresses := make([]request.LoadBalancerIPAddress, len(lb.IPAddresses)) + for i := range ipAddresses { + ipAddresses[i] = request.LoadBalancerIPAddress{ + NetworkName: lb.IPAddresses[i].NetworkName, + Address: lb.IPAddresses[i].Address, + } + } return &request.CreateLoadBalancerRequest{ Name: lb.Name, Plan: lb.Plan, @@ -233,5 +242,6 @@ func loadBalancerToCreateRequest(lb *upcloud.LoadBalancer) *request.CreateLoadBa Labels: lb.Labels, MaintenanceDOW: lb.MaintenanceDOW, MaintenanceTime: lb.MaintenanceTime, + IPAddresses: ipAddresses, } } diff --git a/internal/loadbalancer/loadbalancer_test.go b/internal/loadbalancer/loadbalancer_test.go index d2ba96e..90f8c0e 100644 --- a/internal/loadbalancer/loadbalancer_test.go +++ b/internal/loadbalancer/loadbalancer_test.go @@ -2,6 +2,7 @@ package loadbalancer_test import ( "context" + "encoding/json" "strings" "testing" "time" @@ -11,6 +12,7 @@ import ( "github.com/UpCloudLtd/upcloud-cloud-controller-manager/internal/mock" "github.com/UpCloudLtd/upcloud-cloud-controller-manager/internal/utils" "github.com/UpCloudLtd/upcloud-go-api/v8/upcloud" + "github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request" "github.com/google/uuid" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" @@ -29,23 +31,13 @@ func TestLoadBalancer(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - m, err := initManager(ctx) + m, err := newManager(ctx) require.NoError(t, err) service := v1.Service{ ObjectMeta: metav1.ObjectMeta{Name: "test-service", Namespace: "default"}, } - nodes := []*v1.Node{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "node-1", - Annotations: map[string]string{ - utils.PrivateNetworkUUIDAnnotation: uuid.NewString(), - }, - }, - Spec: v1.NodeSpec{ProviderID: serverUUID}, - }, - } + nodes := newNodes() t.Run("EnsureLoadBalancer", func(t *testing.T) { status, err := m.EnsureLoadBalancer(ctx, "", &service, nodes) @@ -90,23 +82,56 @@ func TestLoadBalancer(t *testing.T) { }) } -func initManager(ctx context.Context) (cloudprovider.LoadBalancer, error) { - client := mock.NewControllerClientBuilder().ClientOrDie("test-client") - upcs := mock.NewUpCloudService( - upcloud.ServerDetails{Server: upcloud.Server{UUID: uuid.NewString()}}, - upcloud.ServerDetails{Server: upcloud.Server{UUID: uuid.NewString()}}, - upcloud.ServerDetails{ - Server: upcloud.Server{UUID: serverUUID, State: upcloud.ServerStateStopped}, - Networking: upcloud.ServerNetworking{ - Interfaces: upcloud.ServerInterfaceSlice{ - { - Type: upcloud.NetworkTypePrivate, - IPAddresses: upcloud.IPAddressSlice{{Address: "10.0.0.10"}}, - }, - }, +func TestLoadBalancerCustomConfig(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + upcs := newUpCloudMockService() + + m, err := newManagerWithService(ctx, upcs) + require.NoError(t, err) + + config := &request.CreateLoadBalancerRequest{ + IPAddresses: []request.LoadBalancerIPAddress{ + { + NetworkName: "public-IPv4", + Address: "0.0.0.0", }, }, - ) + } + service := v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-service", + Namespace: "default", + Annotations: map[string]string{ + "service.beta.kubernetes.io/upcloud-load-balancer-config": loadBalancerRequestToJSON(t, config), + }, + }, + } + nodes := newNodes() + + t.Run("IPAddresses", func(t *testing.T) { + _, err := m.EnsureLoadBalancer(ctx, "", &service, nodes) + require.NoError(t, err) + lbs, err := upcs.GetLoadBalancers(ctx, &request.GetLoadBalancersRequest{}) + require.NoError(t, err) + require.Len(t, lbs, 1) + lb := lbs[0] + require.Len(t, lb.IPAddresses, 1) + require.Equal(t, config.IPAddresses[0].NetworkName, lb.IPAddresses[0].NetworkName) + require.Equal(t, config.IPAddresses[0].Address, lb.IPAddresses[0].Address) + }) +} + +func newManager(ctx context.Context) (cloudprovider.LoadBalancer, error) { + upcs := newUpCloudMockService() + return newManagerWithService(ctx, upcs) +} + +func newManagerWithService(ctx context.Context, upcs loadbalancer.UpCloudService) (cloudprovider.LoadBalancer, error) { + client := mock.NewControllerClientBuilder().ClientOrDie("test-client") if _, err := client.CoreV1().Services("default").Create(ctx, &v1.Service{ ObjectMeta: metav1.ObjectMeta{Name: "test-service"}, Spec: v1.ServiceSpec{ @@ -125,3 +150,42 @@ func initManager(ctx context.Context) (cloudprovider.LoadBalancer, error) { log := logger.NewKlog() return loadbalancer.NewLoadBalancerManager(loadBalancerService, config, client.CoreV1(), eventRecorder, log), nil } + +func newUpCloudMockService() *mock.UpCloudService { + return mock.NewUpCloudService( + upcloud.ServerDetails{Server: upcloud.Server{UUID: uuid.NewString()}}, + upcloud.ServerDetails{Server: upcloud.Server{UUID: uuid.NewString()}}, + upcloud.ServerDetails{ + Server: upcloud.Server{UUID: serverUUID, State: upcloud.ServerStateStopped}, + Networking: upcloud.ServerNetworking{ + Interfaces: upcloud.ServerInterfaceSlice{ + { + Type: upcloud.NetworkTypePrivate, + IPAddresses: upcloud.IPAddressSlice{{Address: "10.0.0.10"}}, + }, + }, + }, + }, + ) +} + +func newNodes() []*v1.Node { + return []*v1.Node{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "node-1", + Annotations: map[string]string{ + utils.PrivateNetworkUUIDAnnotation: uuid.NewString(), + }, + }, + Spec: v1.NodeSpec{ProviderID: serverUUID}, + }, + } +} + +func loadBalancerRequestToJSON(t *testing.T, r *request.CreateLoadBalancerRequest) string { + t.Helper() + b, err := json.MarshalIndent(r, "", "\t") + require.NoError(t, err) + return string(b) +} diff --git a/internal/loadbalancer/upcloud_service.go b/internal/loadbalancer/upcloud_service.go index d380ef2..fb611d1 100644 --- a/internal/loadbalancer/upcloud_service.go +++ b/internal/loadbalancer/upcloud_service.go @@ -178,6 +178,7 @@ func (u *upCloudLoadBalancer) UpdateLoadBalancer(ctx context.Context, lb *upclou Resolvers: config.Resolvers, MaintenanceDOW: config.MaintenanceDOW, MaintenanceTime: config.MaintenanceTime, + IPAddresses: config.IPAddresses, } b, err := json.Marshal(r) if err != nil { diff --git a/internal/loadbalancer/utils.go b/internal/loadbalancer/utils.go index 09e7f54..61e5dab 100644 --- a/internal/loadbalancer/utils.go +++ b/internal/loadbalancer/utils.go @@ -123,15 +123,17 @@ func loadBalancerFrontendFromServicePort(p *v1.ServicePort) request.LoadBalancer InboundProxyProtocol: nil, HTTP2Enabled: &f, }, + TLSConfigs: make([]request.LoadBalancerFrontendTLSConfig, 0), } } func loadBalancerBackendFromServicePort(p *v1.ServicePort, nodes []*v1.Node, plan upcloud.LoadBalancerPlan) request.LoadBalancerBackend { portName := servicePortName(p) b := request.LoadBalancerBackend{ - Name: portName, - Resolver: "", - Members: make([]request.LoadBalancerBackendMember, 0, len(nodes)), + Name: portName, + Resolver: "", + Members: make([]request.LoadBalancerBackendMember, 0, len(nodes)), + TLSConfigs: make([]request.LoadBalancerBackendTLSConfig, 0), } for _, node := range nodes { m := request.LoadBalancerBackendMember{ @@ -230,6 +232,7 @@ func mergeLoadBalancerConfigFromServiceAnnotations(service *v1.Service, r *reque r.Frontends = make([]request.LoadBalancerFrontend, 0) r.Labels = make([]upcloud.Label, 0, len(defaults.Labels)) r.Networks = make([]request.LoadBalancerNetwork, 0) + r.IPAddresses = make([]request.LoadBalancerIPAddress, 0) if err := json.Unmarshal([]byte(config), &r); err != nil { return fmt.Errorf("%w: can't parse annotations[%s], got error: '%v'", errUnsupportedConfiguration, loadBalancerConfigAnnotation, err) } @@ -281,6 +284,9 @@ func mergeLoadBalancerBackends(backends, defaults []request.LoadBalancerBackend, if backend.Properties == nil { backends[i].Properties = defaultBackend.Properties } + if len(backend.TLSConfigs) == 0 { + backends[i].TLSConfigs = defaultBackend.TLSConfigs + } break } } @@ -314,7 +320,7 @@ func mergeLoadBalancerFrontends(frontends, defaults []request.LoadBalancerFronte if len(frontend.Rules) == 0 { frontends[i].Rules = defaultFrontend.Rules } - if frontend.TLSConfigs == nil && frontend.Mode == upcloud.LoadBalancerModeHTTP { + if len(frontend.TLSConfigs) == 0 { frontends[i].TLSConfigs = defaultFrontend.TLSConfigs } if frontend.Properties == nil { diff --git a/internal/mock/upcloud_service.go b/internal/mock/upcloud_service.go index e7dfaaa..9d3b4fe 100644 --- a/internal/mock/upcloud_service.go +++ b/internal/mock/upcloud_service.go @@ -65,6 +65,14 @@ func (u *UpCloudService) CreateLoadBalancer(_ context.Context, r *request.Create for i := range r.Backends { backends[i] = upcloud.LoadBalancerBackend{Name: r.Backends[i].Name} } + ipAddresses := make([]upcloud.LoadBalancerFloatingIPAddress, len(r.IPAddresses)) + for i := range ipAddresses { + ipAddresses[i] = upcloud.LoadBalancerFloatingIPAddress{ + NetworkName: r.IPAddresses[i].NetworkName, + Address: r.IPAddresses[i].Address, + } + } + lb := upcloud.LoadBalancer{ UUID: uuid.NewString(), Name: r.Name, @@ -81,6 +89,7 @@ func (u *UpCloudService) CreateLoadBalancer(_ context.Context, r *request.Create MaintenanceTime: r.MaintenanceTime, DNSName: fmt.Sprintf("%s.example.com", r.Name), OperationalState: upcloud.LoadBalancerOperationalStateRunning, + IPAddresses: ipAddresses, } u.loadBalancers = append(u.loadBalancers, lb) return &lb, nil diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 735cbc1..29af06c 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -1,5 +1,5 @@ // Package utils contains common utility functions that are used by multiple internal packages. -package utils //nolint:revive +package utils import ( "encoding/json"