From 675de0239dcb8e4a6de3e29d1ebf765a54880254 Mon Sep 17 00:00:00 2001 From: rammanoj Date: Thu, 23 Nov 2023 12:45:13 -0500 Subject: [PATCH 1/7] Update values.yaml --- deploy/chart/values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/chart/values.yaml b/deploy/chart/values.yaml index 790458df..9ab888be 100644 --- a/deploy/chart/values.yaml +++ b/deploy/chart/values.yaml @@ -18,7 +18,7 @@ nodeSelector: # Image repository must be 'linode/linode-cloud-controller-manager'. The tag can be changed/set to various ccm versions. # The pullPolicy is set to Always but can be changed when it is not required to always pull the new image image: - repository: linode/linode-cloud-controller-manager + repository: rammanoj/linode-ccm:latest tag: latest pullPolicy: Always @@ -48,4 +48,4 @@ tolerations: # LINODE_HOSTNAME_ONLY_INGRESS type bool is supported # env: # - name: EXAMPLE_ENV_VAR - # value: "true" \ No newline at end of file + # value: "true" From d51ec52adbdbfebcdc58e11ad57e372d485e5b95 Mon Sep 17 00:00:00 2001 From: rpotla Date: Mon, 27 Nov 2023 20:13:33 +0000 Subject: [PATCH 2/7] Attach firewall to nodebalancer --- cloud/linode/fake_linode_test.go | 44 ++++++++++------- cloud/linode/loadbalancers.go | 14 +++++- cloud/linode/loadbalancers_test.go | 8 +-- go.mod | 32 ++++++------ go.sum | 78 ++++++++++++++++++++++-------- 5 files changed, 117 insertions(+), 59 deletions(-) diff --git a/cloud/linode/fake_linode_test.go b/cloud/linode/fake_linode_test.go index 59b326e8..283b959f 100644 --- a/cloud/linode/fake_linode_test.go +++ b/cloud/linode/fake_linode_test.go @@ -17,6 +17,8 @@ import ( "github.com/linode/linodego" ) +const apiVersion = "v4" + type fakeAPI struct { t *testing.T nb map[string]*linodego.NodeBalancer @@ -46,12 +48,12 @@ func (f *fakeAPI) ResetRequests() { f.requests = make(map[fakeRequest]struct{}) } -func (f *fakeAPI) recordRequest(r *http.Request) { +func (f *fakeAPI) recordRequest(r *http.Request, urlPath string) { bodyBytes, _ := ioutil.ReadAll(r.Body) r.Body.Close() r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) f.requests[fakeRequest{ - Path: r.URL.Path, + Path: urlPath, Method: r.Method, Body: string(bodyBytes), }] = struct{}{} @@ -67,10 +69,16 @@ func (f *fakeAPI) didRequestOccur(method, path, body string) bool { } func (f *fakeAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) { - f.recordRequest(r) - w.Header().Set("Content-Type", "application/json") urlPath := r.URL.Path + + if !strings.HasPrefix(urlPath, "/"+apiVersion) { + http.Error(w, "not found", http.StatusNotFound) + return + } + urlPath = strings.TrimPrefix(urlPath, "/"+apiVersion) + f.recordRequest(r, urlPath) + switch r.Method { case "GET": whichAPI := strings.Split(urlPath[1:], "/") @@ -99,7 +107,7 @@ func (f *fakeAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) { rx, _ = regexp.Compile("/nodebalancers/[0-9]+/configs/[0-9]+/nodes") if rx.MatchString(urlPath) { res := 0 - parts := strings.Split(r.URL.Path[1:], "/") + parts := strings.Split(urlPath[1:], "/") nbcID, err := strconv.Atoi(parts[3]) if err != nil { f.t.Fatal(err) @@ -236,7 +244,7 @@ func (f *fakeAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) { } case "POST": - tp := filepath.Base(r.URL.Path) + tp := filepath.Base(urlPath) if tp == "nodebalancers" { nbco := linodego.NodeBalancerCreateOptions{} if err := json.NewDecoder(r.Body).Decode(&nbco); err != nil { @@ -313,7 +321,7 @@ func (f *fakeAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } else if tp == "rebuild" { - parts := strings.Split(r.URL.Path[1:], "/") + parts := strings.Split(urlPath[1:], "/") nbcco := new(linodego.NodeBalancerConfigRebuildOptions) if err := json.NewDecoder(r.Body).Decode(nbcco); err != nil { f.t.Fatal(err) @@ -382,7 +390,7 @@ func (f *fakeAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) { _, _ = w.Write(resp) return } else if tp == "configs" { - parts := strings.Split(r.URL.Path[1:], "/") + parts := strings.Split(urlPath[1:], "/") nbcco := new(linodego.NodeBalancerConfigCreateOptions) if err := json.NewDecoder(r.Body).Decode(nbcco); err != nil { f.t.Fatal(err) @@ -422,7 +430,7 @@ func (f *fakeAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) { _, _ = w.Write(resp) return } else if tp == "nodes" { - parts := strings.Split(r.URL.Path[1:], "/") + parts := strings.Split(urlPath[1:], "/") nbnco := new(linodego.NodeBalancerNodeCreateOptions) if err := json.NewDecoder(r.Body).Decode(nbnco); err != nil { f.t.Fatal(err) @@ -454,14 +462,14 @@ func (f *fakeAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } case "DELETE": - idRaw := filepath.Base(r.URL.Path) + idRaw := filepath.Base(urlPath) id, err := strconv.Atoi(idRaw) if err != nil { f.t.Fatal(err) } - if strings.Contains(r.URL.Path, "nodes") { + if strings.Contains(urlPath, "nodes") { delete(f.nbn, idRaw) - } else if strings.Contains(r.URL.Path, "configs") { + } else if strings.Contains(urlPath, "configs") { delete(f.nbc, idRaw) for k, n := range f.nbn { @@ -469,7 +477,7 @@ func (f *fakeAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) { delete(f.nbn, k) } } - } else if strings.Contains(r.URL.Path, "nodebalancers") { + } else if strings.Contains(urlPath, "nodebalancers") { delete(f.nb, idRaw) for k, c := range f.nbc { @@ -485,10 +493,10 @@ func (f *fakeAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } case "PUT": - if strings.Contains(r.URL.Path, "nodes") { + if strings.Contains(urlPath, "nodes") { f.t.Fatal("PUT ...nodes is not supported by the mock API") - } else if strings.Contains(r.URL.Path, "configs") { - parts := strings.Split(r.URL.Path[1:], "/") + } else if strings.Contains(urlPath, "configs") { + parts := strings.Split(urlPath[1:], "/") nbcco := new(linodego.NodeBalancerConfigUpdateOptions) if err := json.NewDecoder(r.Body).Decode(nbcco); err != nil { f.t.Fatal(err) @@ -545,8 +553,8 @@ func (f *fakeAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) { } _, _ = w.Write(resp) return - } else if strings.Contains(r.URL.Path, "nodebalancer") { - parts := strings.Split(r.URL.Path[1:], "/") + } else if strings.Contains(urlPath, "nodebalancer") { + parts := strings.Split(urlPath[1:], "/") nbuo := new(linodego.NodeBalancerUpdateOptions) if err := json.NewDecoder(r.Body).Decode(nbuo); err != nil { f.t.Fatal(err) diff --git a/cloud/linode/loadbalancers.go b/cloud/linode/loadbalancers.go index 54dd0f26..cfc9e05f 100644 --- a/cloud/linode/loadbalancers.go +++ b/cloud/linode/loadbalancers.go @@ -50,6 +50,7 @@ const ( annLinodeHostnameOnlyIngress = "service.beta.kubernetes.io/linode-loadbalancer-hostname-only-ingress" annLinodeLoadBalancerTags = "service.beta.kubernetes.io/linode-loadbalancer-tags" + annLinodeCloudFirewallId = "service.beta.kubernetes.io/linode-loadbalancer-firewall-id" ) var ( @@ -510,7 +511,7 @@ func (l *loadbalancers) getLoadbalancerTags(ctx context.Context, service *v1.Ser return []string{} } -func (l *loadbalancers) createNodeBalancer(ctx context.Context, clusterName string, service *v1.Service, configs []*linodego.NodeBalancerConfigCreateOptions) (lb *linodego.NodeBalancer, err error) { +func (l *loadbalancers) createNodeBalancer(ctx context.Context, clusterName string, service *v1.Service, configs []*linodego.NodeBalancerConfigCreateOptions, firewallId int) (lb *linodego.NodeBalancer, err error) { connThrottle := getConnectionThrottle(service) label := l.GetLoadBalancerName(ctx, clusterName, service) @@ -521,6 +522,7 @@ func (l *loadbalancers) createNodeBalancer(ctx context.Context, clusterName stri ClientConnThrottle: &connThrottle, Configs: configs, Tags: tags, + FirewallID: firewallId, } return l.client.CreateNodeBalancer(ctx, createOpts) } @@ -639,7 +641,15 @@ func (l *loadbalancers) buildLoadBalancerRequest(ctx context.Context, clusterNam configs = append(configs, &createOpt) } - return l.createNodeBalancer(ctx, clusterName, service, configs) + + var firewallId int + var err error + if fwid, ok := service.Annotations[annLinodeCloudFirewallId]; ok { + if firewallId, err = strconv.Atoi(fwid); err != nil { + return nil, err + } + } + return l.createNodeBalancer(ctx, clusterName, service, configs, firewallId) } func (l *loadbalancers) buildNodeBalancerNodeCreateOptions(node *v1.Node, nodePort int32) linodego.NodeBalancerNodeCreateOptions { diff --git a/cloud/linode/loadbalancers_test.go b/cloud/linode/loadbalancers_test.go index 05d327f8..c5c59c59 100644 --- a/cloud/linode/loadbalancers_test.go +++ b/cloud/linode/loadbalancers_test.go @@ -1281,7 +1281,7 @@ func testEnsureLoadBalancerPreserveAnnotation(t *testing.T, client *linodego.Cli Spec: testServiceSpec, } - nb, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, []*linodego.NodeBalancerConfigCreateOptions{}) + nb, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, []*linodego.NodeBalancerConfigCreateOptions{}, 0) if err != nil { t.Fatal(err) } @@ -1363,7 +1363,7 @@ func testEnsureLoadBalancerDeleted(t *testing.T, client *linodego.Client, fake * lb := &loadbalancers{client, "us-west", nil} configs := []*linodego.NodeBalancerConfigCreateOptions{} - _, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, configs) + _, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, configs, 0) if err != nil { t.Fatal(err) } @@ -1414,7 +1414,7 @@ func testEnsureExistingLoadBalancer(t *testing.T, client *linodego.Client, _ *fa addTLSSecret(t, lb.kubeClient) configs := []*linodego.NodeBalancerConfigCreateOptions{} - nb, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, configs) + nb, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, configs, 0) if err != nil { t.Fatal(err) } @@ -1854,7 +1854,7 @@ func testGetLoadBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI) { } configs := []*linodego.NodeBalancerConfigCreateOptions{} - nb, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, configs) + nb, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, configs, 0) if err != nil { t.Fatal(err) } diff --git a/go.mod b/go.mod index 2188cfea..28de6222 100644 --- a/go.mod +++ b/go.mod @@ -6,10 +6,9 @@ require ( github.com/appscode/go v0.0.0-20200323182826-54e98e09185a github.com/getsentry/sentry-go v0.4.0 github.com/golang/mock v1.6.0 - github.com/linode/linodego v0.32.2 - github.com/pkg/errors v0.9.1 + github.com/linode/linodego v1.25.0 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.8.4 k8s.io/api v0.21.0 k8s.io/apimachinery v0.21.0 k8s.io/client-go v0.21.0 @@ -39,11 +38,11 @@ require ( github.com/go-openapi/jsonreference v0.19.3 // indirect github.com/go-openapi/spec v0.19.5 // indirect github.com/go-openapi/swag v0.19.5 // indirect - github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 // indirect + github.com/go-resty/resty/v2 v2.9.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/golang/protobuf v1.4.3 // indirect - github.com/google/go-cmp v0.5.2 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.1.0 // indirect github.com/google/uuid v1.1.2 // indirect github.com/googleapis/gnostic v0.4.1 // indirect @@ -59,6 +58,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.7.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect @@ -70,26 +70,26 @@ require ( go.uber.org/multierr v1.3.0 // indirect go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee // indirect go.uber.org/zap v1.13.0 // indirect - golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect + golang.org/x/crypto v0.14.0 // indirect golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect - golang.org/x/mod v0.4.2 // indirect - golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect + golang.org/x/mod v0.8.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect - golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect - golang.org/x/text v0.3.4 // indirect - golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect - golang.org/x/tools v0.1.1 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect + golang.org/x/tools v0.6.0 // indirect google.golang.org/appengine v1.6.5 // indirect google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a // indirect google.golang.org/grpc v1.27.1 // indirect google.golang.org/protobuf v1.25.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/tools v0.0.1-2020.1.3 // indirect k8s.io/apiserver v0.21.0 // indirect k8s.io/controller-manager v0.21.0 // indirect diff --git a/go.sum b/go.sum index b27c3260..32e47edc 100644 --- a/go.sum +++ b/go.sum @@ -164,8 +164,8 @@ github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHK github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48 h1:JVrqSeQfdhYRFk24TvhTZWU0q8lfCojxZQFi3Ou7+uY= -github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= +github.com/go-resty/resty/v2 v2.9.1 h1:PIgGx4VrHvag0juCJ4dDv3MiFRlDmP0vicBucwf+gLM= +github.com/go-resty/resty/v2 v2.9.1/go.mod h1:4/GYJVjh9nhkhGR6AUNW3XhpDYNUr+Uvy9gV/VGZIy4= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= @@ -212,8 +212,9 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= @@ -318,8 +319,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/linode/linodego v0.32.2 h1:ubQMQuQGt73N1hMzY15lx2MRdZbcGbuvEVlSpJEB+lc= -github.com/linode/linodego v0.32.2/go.mod h1:BR0gVkCJffEdIGJSl6bHR80Ty+Uvg/2jkjmrWaFectM= +github.com/linode/linodego v1.25.0 h1:zYMz0lTasD503jBu3tSRhzEmXHQN1zptCw5o71ibyyU= +github.com/linode/linodego v1.25.0/go.mod h1:BMZI0pMM/YGjBis7pIXDPbcgYfCZLH0/UvzqtsGtG1c= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -455,12 +456,16 @@ github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +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.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= @@ -488,6 +493,7 @@ github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= @@ -522,8 +528,11 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -555,8 +564,10 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 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 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -574,7 +585,6 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -587,8 +597,14 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -602,8 +618,10 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ 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 h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -644,25 +662,43 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 h1:GZokNIeuVkl3aZHJchRrr13WCsols02MLUcz1U9is6M= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -704,12 +740,13 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 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 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 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= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/version v0.1.0/go.mod h1:Y8xuV02mL/45psyPKG3NCVOwvAOy6T5Kx0l3rCjKSjU= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -783,6 +820,8 @@ gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/R gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= +gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= @@ -798,8 +837,9 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= From 628e39950e8af64004ead1b475078a3c0dbaee7e Mon Sep 17 00:00:00 2001 From: rpotla Date: Mon, 27 Nov 2023 21:58:16 +0000 Subject: [PATCH 3/7] externalize firewll creation; upgrade golint --- Makefile | 2 +- cloud/linode/loadbalancers.go | 36 +++++++++++++++++++++--------- cloud/linode/loadbalancers_test.go | 8 +++---- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 126a0a2d..44205539 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ codegen: .PHONY: lint lint: docker run --rm -v "$(shell pwd):/var/work:ro" -w /var/work \ - golangci/golangci-lint:v1.44.0 golangci-lint run -v --timeout=5m + golangci/golangci-lint:v1.46.0 golangci-lint run -v --timeout=5m .PHONY: fmt fmt: diff --git a/cloud/linode/loadbalancers.go b/cloud/linode/loadbalancers.go index cfc9e05f..d8bebb11 100644 --- a/cloud/linode/loadbalancers.go +++ b/cloud/linode/loadbalancers.go @@ -50,7 +50,7 @@ const ( annLinodeHostnameOnlyIngress = "service.beta.kubernetes.io/linode-loadbalancer-hostname-only-ingress" annLinodeLoadBalancerTags = "service.beta.kubernetes.io/linode-loadbalancer-tags" - annLinodeCloudFirewallId = "service.beta.kubernetes.io/linode-loadbalancer-firewall-id" + annLinodeCloudFirewallID = "service.beta.kubernetes.io/linode-loadbalancer-firewall-id" ) var ( @@ -511,18 +511,39 @@ func (l *loadbalancers) getLoadbalancerTags(ctx context.Context, service *v1.Ser return []string{} } -func (l *loadbalancers) createNodeBalancer(ctx context.Context, clusterName string, service *v1.Service, configs []*linodego.NodeBalancerConfigCreateOptions, firewallId int) (lb *linodego.NodeBalancer, err error) { +func (l *loadbalancers) getLoadbalancerFirewallID(service *v1.Service) (int, error) { + fwid, ok := getServiceAnnotation(service, annLinodeCloudFirewallID) + if !ok { + return -1, nil + } + + firewallID, err := strconv.Atoi(fwid) + if err != nil { + return -1, err + } + return firewallID, nil +} + +func (l *loadbalancers) createNodeBalancer(ctx context.Context, clusterName string, service *v1.Service, configs []*linodego.NodeBalancerConfigCreateOptions) (lb *linodego.NodeBalancer, err error) { connThrottle := getConnectionThrottle(service) label := l.GetLoadBalancerName(ctx, clusterName, service) tags := l.getLoadbalancerTags(ctx, service) + firewallID, err := l.getLoadbalancerFirewallID(service) + if err != nil { + return nil, err + } + createOpts := linodego.NodeBalancerCreateOptions{ Label: &label, Region: l.zone, ClientConnThrottle: &connThrottle, Configs: configs, Tags: tags, - FirewallID: firewallId, + } + + if firewallID != -1 { + createOpts.FirewallID = firewallID } return l.client.CreateNodeBalancer(ctx, createOpts) } @@ -642,14 +663,7 @@ func (l *loadbalancers) buildLoadBalancerRequest(ctx context.Context, clusterNam configs = append(configs, &createOpt) } - var firewallId int - var err error - if fwid, ok := service.Annotations[annLinodeCloudFirewallId]; ok { - if firewallId, err = strconv.Atoi(fwid); err != nil { - return nil, err - } - } - return l.createNodeBalancer(ctx, clusterName, service, configs, firewallId) + return l.createNodeBalancer(ctx, clusterName, service, configs) } func (l *loadbalancers) buildNodeBalancerNodeCreateOptions(node *v1.Node, nodePort int32) linodego.NodeBalancerNodeCreateOptions { diff --git a/cloud/linode/loadbalancers_test.go b/cloud/linode/loadbalancers_test.go index c5c59c59..05d327f8 100644 --- a/cloud/linode/loadbalancers_test.go +++ b/cloud/linode/loadbalancers_test.go @@ -1281,7 +1281,7 @@ func testEnsureLoadBalancerPreserveAnnotation(t *testing.T, client *linodego.Cli Spec: testServiceSpec, } - nb, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, []*linodego.NodeBalancerConfigCreateOptions{}, 0) + nb, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, []*linodego.NodeBalancerConfigCreateOptions{}) if err != nil { t.Fatal(err) } @@ -1363,7 +1363,7 @@ func testEnsureLoadBalancerDeleted(t *testing.T, client *linodego.Client, fake * lb := &loadbalancers{client, "us-west", nil} configs := []*linodego.NodeBalancerConfigCreateOptions{} - _, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, configs, 0) + _, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, configs) if err != nil { t.Fatal(err) } @@ -1414,7 +1414,7 @@ func testEnsureExistingLoadBalancer(t *testing.T, client *linodego.Client, _ *fa addTLSSecret(t, lb.kubeClient) configs := []*linodego.NodeBalancerConfigCreateOptions{} - nb, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, configs, 0) + nb, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, configs) if err != nil { t.Fatal(err) } @@ -1854,7 +1854,7 @@ func testGetLoadBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI) { } configs := []*linodego.NodeBalancerConfigCreateOptions{} - nb, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, configs, 0) + nb, err := lb.createNodeBalancer(context.TODO(), "linodelb", svc, configs) if err != nil { t.Fatal(err) } From 56d93e8b98f38e30c94c2820b36fcf30efaa15d8 Mon Sep 17 00:00:00 2001 From: rpotla Date: Mon, 27 Nov 2023 22:04:30 +0000 Subject: [PATCH 4/7] Add doc; remove extra line --- README.md | 1 + cloud/linode/loadbalancers.go | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 118d75f3..d70c6693 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ Annotation (Suffix) | Values | Default | Description `nodebalancer-id` | string | | The ID of the NodeBalancer to front the service. When not specified, a new NodeBalancer will be created. This can be configured on service creation or patching `hostname-only-ingress` | [bool](#annotation-bool-values) | `false` | When `true`, the LoadBalancerStatus for the service will only contain the Hostname. This is useful for bypassing kube-proxy's rerouting of in-cluster requests originally intended for the external LoadBalancer to the service's constituent pod IPs. `tags` | string | | A comma seperated list of tags to be applied to the createad NodeBalancer instance +`firewall-id` | string | | The Firewall ID that's applied to the NodeBalancer instance. #### Deprecated Annotations diff --git a/cloud/linode/loadbalancers.go b/cloud/linode/loadbalancers.go index d8bebb11..b2407a46 100644 --- a/cloud/linode/loadbalancers.go +++ b/cloud/linode/loadbalancers.go @@ -662,7 +662,6 @@ func (l *loadbalancers) buildLoadBalancerRequest(ctx context.Context, clusterNam configs = append(configs, &createOpt) } - return l.createNodeBalancer(ctx, clusterName, service, configs) } From 241de57358674f3d2fec7347e22ef4abb2d005f3 Mon Sep 17 00:00:00 2001 From: rpotla Date: Fri, 1 Dec 2023 16:29:15 +0000 Subject: [PATCH 5/7] Address Comments --- cloud/linode/loadbalancers_test.go | 51 +++++++++++++++--------------- deploy/chart/values.yaml | 2 +- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/cloud/linode/loadbalancers_test.go b/cloud/linode/loadbalancers_test.go index b59facf0..32f5c3ba 100644 --- a/cloud/linode/loadbalancers_test.go +++ b/cloud/linode/loadbalancers_test.go @@ -213,7 +213,7 @@ func stubService(fake *fake.Clientset, service *v1.Service) { fake.CoreV1().Services("").Create(context.TODO(), service, metav1.CreateOptions{}) } -func testCreateNodeBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI, firewallID *string) { +func testCreateNodeBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI, firewallID *string) error { svc := &v1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: randString(10), @@ -241,10 +241,8 @@ func testCreateNodeBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI, f }, } - var errExpected error if firewallID != nil { svc.Annotations[annLinodeCloudFirewallID] = *firewallID - _, errExpected = strconv.Atoi(*firewallID) } lb := &loadbalancers{client, "us-west", nil} @@ -252,16 +250,10 @@ func testCreateNodeBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI, f {ObjectMeta: metav1.ObjectMeta{Name: "node-1"}}, } nb, err := lb.buildLoadBalancerRequest(context.TODO(), "linodelb", svc, nodes) - if errExpected != nil { - if err == nil || err.Error() != errExpected.Error() { - t.Fatalf("expected %s got %s", errExpected.Error(), err.Error()) - } else { - return - } - } if err != nil { - t.Fatal(err) + return err } + if nb.Region != lb.zone { t.Error("unexpected nodebalancer region") t.Logf("expected: %s", lb.zone) @@ -270,7 +262,7 @@ func testCreateNodeBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI, f configs, err := client.ListNodeBalancerConfigs(context.TODO(), nb.ID, nil) if err != nil { - t.Fatal(err) + return err } if len(configs) != len(svc.Spec.Ports) { @@ -279,17 +271,9 @@ func testCreateNodeBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI, f t.Logf("actual: %v", len(configs)) } - if !reflect.DeepEqual(err, nil) { - t.Error("unexpected error") - t.Logf("expected: %v", nil) - t.Logf("actual: %v", err) - } - nb, err = client.GetNodeBalancer(context.TODO(), nb.ID) - if !reflect.DeepEqual(err, nil) { - t.Error("unexpected error") - t.Logf("expected: %v", nil) - t.Logf("actual: %v", err) + if err != nil { + return err } if nb.ClientConnThrottle != 15 { @@ -306,20 +290,37 @@ func testCreateNodeBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI, f } defer func() { _ = lb.EnsureLoadBalancerDeleted(context.TODO(), "linodelb", svc) }() + return nil } func testCreateNodeBalancerWithOutFirewall(t *testing.T, client *linodego.Client, f *fakeAPI) { - testCreateNodeBalancer(t, client, f, nil) + err := testCreateNodeBalancer(t, client, f, nil) + if !reflect.DeepEqual(err, nil) { + t.Error("unexpected error") + t.Logf("expected: %v", nil) + t.Logf("actual: %v", err) + } } func testCreateNodeBalancerWithFirewall(t *testing.T, client *linodego.Client, f *fakeAPI) { firewallID := "123" - testCreateNodeBalancer(t, client, f, &firewallID) + err := testCreateNodeBalancer(t, client, f, &firewallID) + if !reflect.DeepEqual(err, nil) { + t.Error("unexpected error") + t.Logf("expected: %v", nil) + t.Logf("actual: %v", err) + } } func testCreateNodeBalancerWithInvalidFirewall(t *testing.T, client *linodego.Client, f *fakeAPI) { firewallID := "qwerty" - testCreateNodeBalancer(t, client, f, &firewallID) + expectedError := "strconv.Atoi: parsing \"qwerty\": invalid syntax" + err := testCreateNodeBalancer(t, client, f, &firewallID) + if !reflect.DeepEqual(err.Error(), expectedError) { + t.Error("unexpected error") + t.Logf("expected: %s", expectedError) + t.Logf("actual: %v", err) + } } func testUpdateLoadBalancerAddAnnotation(t *testing.T, client *linodego.Client, _ *fakeAPI) { diff --git a/deploy/chart/values.yaml b/deploy/chart/values.yaml index 9ab888be..7b2e3804 100644 --- a/deploy/chart/values.yaml +++ b/deploy/chart/values.yaml @@ -18,7 +18,7 @@ nodeSelector: # Image repository must be 'linode/linode-cloud-controller-manager'. The tag can be changed/set to various ccm versions. # The pullPolicy is set to Always but can be changed when it is not required to always pull the new image image: - repository: rammanoj/linode-ccm:latest + repository: linode/linode-cloud-controller-manager tag: latest pullPolicy: Always From 8fb258df6050f5f6a022d1a6d10d8fcbeeef1397 Mon Sep 17 00:00:00 2001 From: rpotla Date: Fri, 1 Dec 2023 16:29:51 +0000 Subject: [PATCH 6/7] Remove extra line --- deploy/chart/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/chart/values.yaml b/deploy/chart/values.yaml index 7b2e3804..790458df 100644 --- a/deploy/chart/values.yaml +++ b/deploy/chart/values.yaml @@ -48,4 +48,4 @@ tolerations: # LINODE_HOSTNAME_ONLY_INGRESS type bool is supported # env: # - name: EXAMPLE_ENV_VAR - # value: "true" + # value: "true" \ No newline at end of file From 15e5f7a9f17f59cab9c16c4d6daa6dfde7a04c42 Mon Sep 17 00:00:00 2001 From: rpotla Date: Mon, 4 Dec 2023 15:05:58 +0000 Subject: [PATCH 7/7] Remove redundant deepequals --- cloud/linode/loadbalancers_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud/linode/loadbalancers_test.go b/cloud/linode/loadbalancers_test.go index b5d8b42a..b2250ffa 100644 --- a/cloud/linode/loadbalancers_test.go +++ b/cloud/linode/loadbalancers_test.go @@ -312,7 +312,7 @@ func testCreateNodeBalancerWithInvalidFirewall(t *testing.T, client *linodego.Cl firewallID := "qwerty" expectedError := "strconv.Atoi: parsing \"qwerty\": invalid syntax" err := testCreateNodeBalancer(t, client, f, &firewallID) - if !reflect.DeepEqual(err.Error(), expectedError) { + if err.Error() != expectedError { t.Fatalf("expected a %s error, got %v", expectedError, err) } }