From 599088dd72c6de79095c731a190043fd1205465d Mon Sep 17 00:00:00 2001 From: WeichengWang Date: Fri, 3 Nov 2023 23:10:55 +0800 Subject: [PATCH 1/5] feat: remove resourconsist and start alibaba_cloud_slb controller by import kusionstack.io/resourceconsist --- go.mod | 77 +- go.sum | 123 ++- pkg/controllers/add_alibaba_cloud_slb.go | 10 +- .../alibabacloudslb/alibabacloudslb_client.go | 90 -- .../alibabacloudslb_controller.go | 202 ---- pkg/controllers/alibabacloudslb/types.go | 66 -- pkg/controllers/resourceconsist/consister.go | 664 ------------ .../resourceconsist/event_handler.go | 227 ----- .../resourceconsist_controller.go | 226 ----- .../resourceconsist_controller_suite_test.go | 503 ---------- .../resourceconsist_controller_test.go | 949 ------------------ pkg/controllers/resourceconsist/types.go | 124 --- pkg/controllers/resourceconsist/utils.go | 104 -- .../add_alibaba_cloud_slb.go} | 11 +- .../alibaba_cloud_slb/alibaba_cloud_slb.go} | 15 +- 15 files changed, 128 insertions(+), 3263 deletions(-) delete mode 100644 pkg/controllers/alibabacloudslb/alibabacloudslb_client.go delete mode 100644 pkg/controllers/alibabacloudslb/alibabacloudslb_controller.go delete mode 100644 pkg/controllers/alibabacloudslb/types.go delete mode 100644 pkg/controllers/resourceconsist/consister.go delete mode 100644 pkg/controllers/resourceconsist/event_handler.go delete mode 100644 pkg/controllers/resourceconsist/resourceconsist_controller.go delete mode 100644 pkg/controllers/resourceconsist/resourceconsist_controller_suite_test.go delete mode 100644 pkg/controllers/resourceconsist/resourceconsist_controller_test.go delete mode 100644 pkg/controllers/resourceconsist/types.go delete mode 100644 pkg/controllers/resourceconsist/utils.go rename pkg/{controllers/alibabacloudslb/consts.go => webhook/add_alibaba_cloud_slb.go} (67%) rename pkg/{controllers/resourceconsist/consts.go => webhook/alibaba_cloud_slb/alibaba_cloud_slb.go} (61%) diff --git a/go.mod b/go.mod index 65a6840f..0b34f299 100644 --- a/go.mod +++ b/go.mod @@ -3,31 +3,28 @@ module kusionstack.io/operating go 1.19 require ( - github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.4 - github.com/alibabacloud-go/slb-20140515/v4 v4.0.3 - github.com/alibabacloud-go/tea v1.2.1 - github.com/alibabacloud-go/tea-utils/v2 v2.0.4 github.com/davecgh/go-spew v1.1.1 - github.com/docker/distribution v2.8.1+incompatible - github.com/go-logr/logr v1.2.3 + github.com/docker/distribution v2.8.2+incompatible + github.com/go-logr/logr v1.2.4 github.com/google/uuid v1.3.0 github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.26.0 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/client_golang v1.16.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.1 - golang.org/x/net v0.11.0 - k8s.io/api v0.22.6 - k8s.io/apimachinery v0.22.6 + golang.org/x/net v0.17.0 + k8s.io/api v0.27.2 + k8s.io/apimachinery v0.27.2 k8s.io/client-go v0.22.6 - k8s.io/component-base v0.22.6 + k8s.io/component-base v0.28.3 k8s.io/component-helpers v0.22.6 k8s.io/klog v1.0.0 - k8s.io/klog/v2 v2.80.1 + k8s.io/klog/v2 v2.100.1 k8s.io/kubernetes v0.0.0-00010101000000-000000000000 k8s.io/utils v0.0.0-20230726121419-3b25d923346b - sigs.k8s.io/controller-runtime v0.10.3 + kusionstack.io/resourceconsist v0.0.1 + sigs.k8s.io/controller-runtime v0.15.1 ) require ( @@ -39,62 +36,66 @@ require ( github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect + github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.4 // indirect github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // indirect github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect github.com/alibabacloud-go/openapi-util v0.1.0 // indirect + github.com/alibabacloud-go/slb-20140515/v4 v4.0.4 // indirect + github.com/alibabacloud-go/tea v1.2.1 // indirect github.com/alibabacloud-go/tea-utils v1.3.1 // indirect + github.com/alibabacloud-go/tea-utils/v2 v2.0.4 // indirect github.com/alibabacloud-go/tea-xml v1.1.2 // indirect github.com/aliyun/credentials-go v1.1.2 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/clbanning/mxj/v2 v2.5.5 // indirect github.com/cyphar/filepath-securejoin v0.2.2 // indirect github.com/evanphx/json-patch v4.11.0+incompatible // indirect github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect - github.com/fsnotify/fsnotify v1.4.9 // indirect - github.com/go-logr/zapr v0.4.0 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-logr/zapr v1.2.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.8 // indirect - github.com/google/gofuzz v1.1.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect github.com/googleapis/gnostic v0.5.5 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/runc v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect - github.com/stretchr/objx v0.5.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.10.1 // indirect github.com/tjfoc/gmsm v1.3.2 // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.19.0 // indirect - golang.org/x/crypto v0.10.0 // indirect - golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/term v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.25.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/oauth2 v0.8.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.56.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.22.2 // indirect + k8s.io/apiextensions-apiserver v0.28.3 // indirect k8s.io/apiserver v0.22.6 // indirect - k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect - sigs.k8s.io/yaml v1.2.0 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + kusionstack.io/kube-api v0.0.27 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) replace ( diff --git a/go.sum b/go.sum index 159a31bd..a7f21d32 100644 --- a/go.sum +++ b/go.sum @@ -87,8 +87,8 @@ github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudH github.com/alibabacloud-go/openapi-util v0.0.11/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= github.com/alibabacloud-go/openapi-util v0.1.0 h1:0z75cIULkDrdEhkLWgi9tnLe+KhAFE/r5Pb3312/eAY= github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= -github.com/alibabacloud-go/slb-20140515/v4 v4.0.3 h1:APnIynL2oCgfvoZEu39mGivvLWNckxinQuq7+vFdzEg= -github.com/alibabacloud-go/slb-20140515/v4 v4.0.3/go.mod h1:Jb7cFsl5dVaotLAn//nzAbhfBPaPhHbWnsgNyfOdzd4= +github.com/alibabacloud-go/slb-20140515/v4 v4.0.4 h1:aYYiyFIxKCOfA65tDubIz0HTx0Ns/U9tZg0zCnztQ74= +github.com/alibabacloud-go/slb-20140515/v4 v4.0.4/go.mod h1:SY8uSRmAW6856BCs+ap5ZMFyjBIuKRvGDA8fQ9Kb0mg= github.com/alibabacloud-go/tea v1.1.0/go.mod h1:IkGyUSX4Ba1V+k4pCtJUc6jDpZLFph9QMy2VUPTwukg= github.com/alibabacloud-go/tea v1.1.7/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= @@ -99,7 +99,6 @@ github.com/alibabacloud-go/tea v1.2.1/go.mod h1:qbzof29bM/IFhLMtJPrgTGK3eauV5J2w github.com/alibabacloud-go/tea-utils v1.3.1 h1:iWQeRzRheqCMuiF3+XkfybB3kTgUXkXX+JMrqfLeB2I= github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE= github.com/alibabacloud-go/tea-utils/v2 v2.0.0/go.mod h1:U5MTY10WwlquGPS34DOeomUGBB0gXbLueiq5Trwu0C4= -github.com/alibabacloud-go/tea-utils/v2 v2.0.3/go.mod h1:sj1PbjPodAVTqGTA3olprfeeqqmwD0A5OQz94o9EuXQ= github.com/alibabacloud-go/tea-utils/v2 v2.0.4 h1:SoFgjJuO7pze88j9RBJNbKb7AgTS52O+J5ITxc00lCs= github.com/alibabacloud-go/tea-utils/v2 v2.0.4/go.mod h1:sj1PbjPodAVTqGTA3olprfeeqqmwD0A5OQz94o9EuXQ= github.com/alibabacloud-go/tea-xml v1.1.2 h1:oLxa7JUXm2EDFzMg+7oRsYc+kutgCVwm+bZlhhmvW5M= @@ -116,8 +115,8 @@ github.com/auth0/go-jwt-middleware v1.0.1/go.mod h1:YSeUX3z6+TF2H+7padiEqNJ73Zy9 github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= github.com/aws/aws-sdk-go v1.38.49/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -133,8 +132,8 @@ github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6 github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -194,8 +193,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= -github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -225,8 +224,9 @@ github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNy github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -237,15 +237,14 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/zapr v0.4.0 h1:uc1uML3hRYL9/ZZPdgHS/n8Nzo+eaYL/Efxkkamf7OM= github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= +github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= @@ -294,13 +293,16 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/cadvisor v0.39.3/go.mod h1:kN93gpdevu+bpS227TyHVZyCU5bbqCzTj5T9drl34MI= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -311,11 +313,12 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -409,6 +412,7 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -427,8 +431,9 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= @@ -463,7 +468,6 @@ github.com/mvdan/xurls v1.1.0/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq4 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= @@ -475,6 +479,7 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU= github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -506,23 +511,21 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -531,9 +534,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= +github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/quobyte/api v0.1.8/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= @@ -541,6 +543,7 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -646,17 +649,20 @@ go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16g go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= +go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -670,8 +676,9 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +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-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -701,7 +708,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -758,24 +764,21 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v 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-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 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.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +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= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -853,22 +856,23 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/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.0.0-20220908164124-27713097b956/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.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= golang.org/x/sys v0.9.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/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.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +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= @@ -880,8 +884,9 @@ golang.org/x/text v0.3.6/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.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 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= @@ -945,15 +950,16 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/gonum v0.6.2/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= @@ -1050,14 +1056,14 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= @@ -1126,8 +1132,9 @@ k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/kube-aggregator v0.22.6/go.mod h1:0RSTzxqiwsj5HUlov195Z72ZKyE4qgedKXCl6sLKAjM= k8s.io/kube-controller-manager v0.22.6/go.mod h1:RkYKr813YbQhuOBK+12gikPvK/AXy80qovB6YmHfzW8= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c h1:jvamsI1tn9V0S8jicyX82qaFC0H/NKxv2e5mbqsgR80= k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= k8s.io/kube-proxy v0.22.6/go.mod h1:xLxEZ3sHyz11XaRyxqI4Z4F3I/Wtt+Jlep8w5yxQPAY= k8s.io/kube-scheduler v0.22.6/go.mod h1:DcHj6ixvb0M1PvWFbg133a1pz/vv7OSCgZUDU/UUhlU= k8s.io/kubectl v0.22.6/go.mod h1:9ktAgMwUsd2w12Yhj/xhMZhNna1t9rfExJg9j9jCIYk= @@ -1144,6 +1151,10 @@ k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +kusionstack.io/kube-api v0.0.27 h1:7umLyoMmOdse0A8nXGccNpOdYu7B5sNPLoPxc/hmBIY= +kusionstack.io/kube-api v0.0.27/go.mod h1:QIQrH+MK9xuV+mXCAkk6DN8z6b8oyf4XN0VRccmHH/k= +kusionstack.io/resourceconsist v0.0.1 h1:+k/jriq5Ld7fQUYfWSMGynz/FesHtl3Rk2fmQPjBe0g= +kusionstack.io/resourceconsist v0.0.1/go.mod h1:816xS/fY6EOUbPFjXIWW/TGs8/YE46qP4ElKeIiwFdU= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= @@ -1161,7 +1172,9 @@ sigs.k8s.io/kustomize/cmd/config v0.9.13/go.mod h1:7547FLF8W/lTaDf0BDqFTbZxM9zqw sigs.k8s.io/kustomize/kustomize/v4 v4.2.0/go.mod h1:MOkR6fmhwG7hEDRXBYELTi5GSFcLwfqwzTRHW3kv5go= sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y= sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/pkg/controllers/add_alibaba_cloud_slb.go b/pkg/controllers/add_alibaba_cloud_slb.go index 934e6d1c..03d8ca60 100644 --- a/pkg/controllers/add_alibaba_cloud_slb.go +++ b/pkg/controllers/add_alibaba_cloud_slb.go @@ -19,10 +19,9 @@ package controllers import ( "sigs.k8s.io/controller-runtime/pkg/manager" - "kusionstack.io/operating/pkg/controllers/alibabacloudslb" - "kusionstack.io/operating/pkg/controllers/resourceconsist" "kusionstack.io/operating/pkg/features" "kusionstack.io/operating/pkg/utils/feature" + "kusionstack.io/resourceconsist/pkg/adapters" ) func init() { @@ -33,9 +32,6 @@ func Add(manager manager.Manager) error { if !feature.DefaultFeatureGate.Enabled(features.AlibabaCloudSlb) { return nil } - reconcileAdapter, err := alibabacloudslb.NewReconcileAdapter(manager.GetClient()) - if err != nil { - return err - } - return resourceconsist.Add(manager, reconcileAdapter) + + return adapters.AddBuiltinControllerAdaptersToMgr(manager, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb}) } diff --git a/pkg/controllers/alibabacloudslb/alibabacloudslb_client.go b/pkg/controllers/alibabacloudslb/alibabacloudslb_client.go deleted file mode 100644 index e79e9bf0..00000000 --- a/pkg/controllers/alibabacloudslb/alibabacloudslb_client.go +++ /dev/null @@ -1,90 +0,0 @@ -/* -Copyright 2023 The KusionStack Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package alibabacloudslb - -import ( - "fmt" - "os" - - openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client" - slb20140515 "github.com/alibabacloud-go/slb-20140515/v4/client" - util "github.com/alibabacloud-go/tea-utils/v2/service" - "github.com/alibabacloud-go/tea/tea" -) - -var ( - slbAccessKeyID string - slbAccessKeySecret string - slbEndpoint string -) - -type AlibabaCloudSlbClient struct { - *slb20140515.Client -} - -func NewAlibabaCloudSlbClient() (*AlibabaCloudSlbClient, error) { - if slbAccessKeyID == "" || slbAccessKeySecret == "" { - return nil, fmt.Errorf("slbAccessKeyID or slbAccessKeySecret is empty") - } - config := &openapi.Config{ - AccessKeyId: tea.String(slbAccessKeyID), - AccessKeySecret: tea.String(slbAccessKeySecret), - // Endpoint, refer: https://api.aliyun.com/product/Slb - Endpoint: tea.String(slbEndpoint), - } - - slbClient, err := slb20140515.NewClient(config) - if err != nil { - return nil, err - } - return &AlibabaCloudSlbClient{ - slbClient, - }, nil -} - -func (c *AlibabaCloudSlbClient) GetBackendServers(lbID string) ([]string, error) { - describeHealthStatusRequest := &slb20140515.DescribeHealthStatusRequest{ - LoadBalancerId: tea.String(lbID), - } - runtime := &util.RuntimeOptions{} - - resp, err := c.DescribeHealthStatusWithOptions(describeHealthStatusRequest, runtime) - if err != nil { - return nil, err - } - if resp == nil || resp.Body == nil || resp.Body.BackendServers == nil { - return nil, fmt.Errorf("get backend servers list faield, resp is nil") - } - - backendServers := make([]string, len(resp.Body.BackendServers.BackendServer)) - for idx, bs := range resp.Body.BackendServers.BackendServer { - backendServers[idx] = *bs.ServerIp - } - return backendServers, nil -} - -func init() { - if os.Getenv("ALIYUN_SLB_AK_KEY") != "" { - slbAccessKeyID = os.Getenv("ALIYUN_SLB_AK_KEY") - } - if os.Getenv("ALIYUN_SLB_AK_SECRET") != "" { - slbAccessKeySecret = os.Getenv("ALIYUN_SLB_AK_SECRET") - } - if os.Getenv("ALIYUN_SLB_ENDPOINT") != "" { - slbEndpoint = os.Getenv("ALIYUN_SLB_ENDPOINT") - } -} diff --git a/pkg/controllers/alibabacloudslb/alibabacloudslb_controller.go b/pkg/controllers/alibabacloudslb/alibabacloudslb_controller.go deleted file mode 100644 index d2aeaec8..00000000 --- a/pkg/controllers/alibabacloudslb/alibabacloudslb_controller.go +++ /dev/null @@ -1,202 +0,0 @@ -/* -Copyright 2023 The KusionStack Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package alibabacloudslb - -import ( - "context" - "fmt" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/labels" - "sigs.k8s.io/controller-runtime/pkg/client" - - "kusionstack.io/operating/pkg/controllers/resourceconsist" -) - -var _ resourceconsist.ReconcileAdapter = &ReconcileAdapter{} -var _ resourceconsist.ReconcileLifecycleOptions = &ReconcileAdapter{} - -type ReconcileAdapter struct { - client.Client - slbClient *AlibabaCloudSlbClient -} - -func NewReconcileAdapter(c client.Client) (*ReconcileAdapter, error) { - slbClient, err := NewAlibabaCloudSlbClient() - if err != nil { - return nil, err - } - if slbClient == nil { - return nil, fmt.Errorf("alibaba cloud slb client is nil") - } - - return &ReconcileAdapter{ - Client: c, - slbClient: slbClient, - }, nil -} - -func (r *ReconcileAdapter) FollowPodOpsLifeCycle() bool { - return true -} - -func (r *ReconcileAdapter) NeedRecordEmployees() bool { - return true -} - -func (r *ReconcileAdapter) GetControllerName() string { - return "alibaba-cloud-slb-controller" -} - -func (r *ReconcileAdapter) GetExpectedEmployer(ctx context.Context, employer client.Object) ([]resourceconsist.IEmployer, error) { - return nil, nil -} - -func (r *ReconcileAdapter) GetSelectedEmployeeNames(ctx context.Context, employer client.Object) ([]string, error) { - svc, ok := employer.(*corev1.Service) - if !ok { - return nil, fmt.Errorf("expect employer kind is Service") - } - selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated() - var podList corev1.PodList - err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector}) - if err != nil { - return nil, err - } - - selected := make([]string, len(podList.Items)) - for idx, pod := range podList.Items { - selected[idx] = pod.Name - } - - return selected, nil -} - -func (r *ReconcileAdapter) GetCurrentEmployer(ctx context.Context, employer client.Object) ([]resourceconsist.IEmployer, error) { - return nil, nil -} - -func (r *ReconcileAdapter) CreateEmployer(ctx context.Context, employer client.Object, toCreates []resourceconsist.IEmployer) ([]resourceconsist.IEmployer, []resourceconsist.IEmployer, error) { - return nil, nil, nil -} - -func (r *ReconcileAdapter) UpdateEmployer(ctx context.Context, employer client.Object, toUpdates []resourceconsist.IEmployer) ([]resourceconsist.IEmployer, []resourceconsist.IEmployer, error) { - return nil, nil, nil -} - -func (r *ReconcileAdapter) DeleteEmployer(ctx context.Context, employer client.Object, toDeletes []resourceconsist.IEmployer) ([]resourceconsist.IEmployer, []resourceconsist.IEmployer, error) { - return nil, nil, nil -} - -func (r *ReconcileAdapter) GetExpectedEmployee(ctx context.Context, employer client.Object) ([]resourceconsist.IEmployee, error) { - svc, ok := employer.(*corev1.Service) - if !ok { - return nil, fmt.Errorf("expect employer kind is Service") - } - selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated() - var podList corev1.PodList - err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector}) - if err != nil { - return nil, err - } - - expected := make([]resourceconsist.IEmployee, len(podList.Items)) - for idx, pod := range podList.Items { - status := AlibabaSlbPodStatus{ - EmployeeID: pod.Status.PodIP, - EmployeeName: pod.Name, - } - employeeStatuses, err := resourceconsist.GetCommonPodEmployeeStatus(&pod) - if err != nil { - return nil, err - } - extraStatus := PodExtraStatus{} - if employeeStatuses.LifecycleReady { - extraStatus.TrafficOn = true - } else { - extraStatus.TrafficOn = false - } - employeeStatuses.ExtraStatus = extraStatus - status.EmployeeStatuses = employeeStatuses - expected[idx] = status - } - - return expected, nil -} - -func (r *ReconcileAdapter) GetCurrentEmployee(ctx context.Context, employer client.Object) ([]resourceconsist.IEmployee, error) { - svc, ok := employer.(*corev1.Service) - if !ok { - return nil, fmt.Errorf("expect employer kind is Service") - } - selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated() - var podList corev1.PodList - err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector}) - if err != nil { - return nil, err - } - - lbID := svc.GetLabels()[alibabaCloudSlbLbIdLabelKey] - bsExistUnderSlb := make(map[string]bool) - if lbID != "" { - backendServers, err := r.slbClient.GetBackendServers(lbID) - if err != nil { - return nil, fmt.Errorf("get backend servers of slb failed, err: %s", err.Error()) - } - for _, bs := range backendServers { - bsExistUnderSlb[bs] = true - } - } - - current := make([]resourceconsist.IEmployee, len(podList.Items)) - for idx, pod := range podList.Items { - status := AlibabaSlbPodStatus{ - EmployeeID: pod.Status.PodIP, - EmployeeName: pod.Name, - } - employeeStatuses, err := resourceconsist.GetCommonPodEmployeeStatus(&pod) - if err != nil { - return nil, err - } - extraStatus := PodExtraStatus{} - if !bsExistUnderSlb[status.EmployeeID] { - extraStatus.TrafficOn = false - } else { - extraStatus.TrafficOn = true - } - employeeStatuses.ExtraStatus = extraStatus - status.EmployeeStatuses = employeeStatuses - current[idx] = status - } - - return current, nil -} - -// CreateEmployees returns (nil, toCreate, nil) since CCM of ACK will sync bs of slb -func (r *ReconcileAdapter) CreateEmployees(ctx context.Context, employer client.Object, toCreates []resourceconsist.IEmployee) ([]resourceconsist.IEmployee, []resourceconsist.IEmployee, error) { - return nil, toCreates, nil -} - -// UpdateEmployees returns (nil, toUpdate, nil) since CCM of ACK will sync bs of slb -func (r *ReconcileAdapter) UpdateEmployees(ctx context.Context, employer client.Object, toUpdates []resourceconsist.IEmployee) ([]resourceconsist.IEmployee, []resourceconsist.IEmployee, error) { - return nil, toUpdates, nil -} - -// DeleteEmployees returns (nil, toDelete, nil) since CCM of ACK will sync bs of slb -func (r *ReconcileAdapter) DeleteEmployees(ctx context.Context, employer client.Object, toDeletes []resourceconsist.IEmployee) ([]resourceconsist.IEmployee, []resourceconsist.IEmployee, error) { - return nil, toDeletes, nil -} diff --git a/pkg/controllers/alibabacloudslb/types.go b/pkg/controllers/alibabacloudslb/types.go deleted file mode 100644 index 1359a557..00000000 --- a/pkg/controllers/alibabacloudslb/types.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -Copyright 2023 The KusionStack Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package alibabacloudslb - -import ( - "fmt" - "reflect" - - "kusionstack.io/operating/pkg/controllers/resourceconsist" -) - -var _ resourceconsist.IEmployee = AlibabaSlbPodStatus{} - -type AlibabaSlbPodStatus struct { - EmployeeID string - EmployeeName string - EmployeeStatuses resourceconsist.PodEmployeeStatuses -} - -type PodExtraStatus struct { - TrafficOn bool -} - -func (a AlibabaSlbPodStatus) GetEmployeeId() string { - return a.EmployeeID -} - -func (a AlibabaSlbPodStatus) GetEmployeeName() string { - return a.EmployeeName -} - -func (a AlibabaSlbPodStatus) GetEmployeeStatuses() interface{} { - return a.EmployeeStatuses -} - -func (a AlibabaSlbPodStatus) EmployeeEqual(employeeStatus resourceconsist.IEmployee) (bool, error) { - if a.EmployeeName != employeeStatus.GetEmployeeName() { - return false, nil - } - - podEmployeeStatuses, ok := employeeStatus.GetEmployeeStatuses().(resourceconsist.PodEmployeeStatuses) - if !ok { - return false, fmt.Errorf("employee to diff is not Pod Employee status") - } - - if a.EmployeeStatuses.Ip != podEmployeeStatuses.Ip || a.EmployeeStatuses.LifecycleReady != podEmployeeStatuses.LifecycleReady || - a.EmployeeStatuses.Ipv6 != podEmployeeStatuses.Ipv6 { - return false, nil - } - - return reflect.DeepEqual(a.EmployeeStatuses.ExtraStatus, podEmployeeStatuses.ExtraStatus), nil -} diff --git a/pkg/controllers/resourceconsist/consister.go b/pkg/controllers/resourceconsist/consister.go deleted file mode 100644 index f31f5bf2..00000000 --- a/pkg/controllers/resourceconsist/consister.go +++ /dev/null @@ -1,664 +0,0 @@ -/* -Copyright 2023 The KusionStack Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resourceconsist - -import ( - "context" - "encoding/json" - "fmt" - "reflect" - "sort" - "strings" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - errors2 "k8s.io/apimachinery/pkg/util/errors" - "k8s.io/apimachinery/pkg/util/sets" - "kusionstack.io/operating/apis/apps/v1alpha1" - "sigs.k8s.io/controller-runtime/pkg/client" - - "kusionstack.io/operating/pkg/controllers/utils" -) - -func (r *Consist) syncEmployer(ctx context.Context, employer client.Object, expectEmployerStatus, currentEmployerStatus []IEmployer) (bool, bool, error) { - toCudEmployer, err := r.diffEmployer(expectEmployerStatus, currentEmployerStatus) - if err != nil { - return false, false, fmt.Errorf("diff employer failed, err: %s", err.Error()) - } - _, failCreate, err := r.adapter.CreateEmployer(ctx, employer, toCudEmployer.ToCreate) - if err != nil { - return false, false, fmt.Errorf("syncCreate failed, err: %s", err.Error()) - } - _, failUpdate, err := r.adapter.UpdateEmployer(ctx, employer, toCudEmployer.ToUpdate) - if err != nil { - return false, false, fmt.Errorf("syncUpdate failed, err: %s", err.Error()) - } - _, failDelete, err := r.adapter.DeleteEmployer(ctx, employer, toCudEmployer.ToDelete) - if err != nil { - return false, false, fmt.Errorf("syncDelete failed, err: %s", err.Error()) - } - - isClean := len(toCudEmployer.Unchanged) == 0 && len(toCudEmployer.ToCreate) == 0 && len(toCudEmployer.ToUpdate) == 0 && len(failDelete) == 0 - cudFailedExist := len(failCreate) > 0 || len(failUpdate) > 0 || len(failDelete) > 0 - return isClean, cudFailedExist, nil -} - -func (r *Consist) diffEmployer(expectEmployer, currentEmployer []IEmployer) (ToCUDEmployer, error) { - expectEmployerMap := make(map[string]IEmployer) - currentEmployerMap := make(map[string]IEmployer) - - for _, expect := range expectEmployer { - expectEmployerMap[expect.GetEmployerId()] = expect - } - for _, current := range currentEmployer { - currentEmployerMap[current.GetEmployerId()] = current - } - - toCreate := make([]IEmployer, len(expectEmployer)) - toUpdate := make([]IEmployer, len(currentEmployer)) - toDelete := make([]IEmployer, len(currentEmployer)) - unchanged := make([]IEmployer, len(currentEmployer)) - toCreateIdx, toUpdateIdx, toDeleteIdx, unchangedIdx := 0, 0, 0, 0 - - for expectId, expect := range expectEmployerMap { - current, exist := currentEmployerMap[expectId] - if !exist { - toCreate[toCreateIdx] = expect - toCreateIdx++ - continue - } - equal, err := expect.EmployerEqual(current) - if err != nil { - return ToCUDEmployer{}, err - } - if !equal { - toUpdate[toUpdateIdx] = expect - toUpdateIdx++ - continue - } - unchanged[unchangedIdx] = expect - unchangedIdx++ - } - - for currentId, current := range currentEmployerMap { - _, exist := expectEmployerMap[currentId] - if !exist { - toDelete[toDeleteIdx] = current - toDeleteIdx++ - } - } - - // todo, log level - r.Logger.Info("employer info", - "toCreate", toCreate[:toCreateIdx], - "toUpdate", toUpdate[:toUpdateIdx], - "toDelete", toDelete[:toDeleteIdx], - "unchanged", unchanged[:unchangedIdx], - ) - - return ToCUDEmployer{ - ToCreate: toCreate[:toCreateIdx], - ToUpdate: toUpdate[:toUpdateIdx], - ToDelete: toDelete[:toDeleteIdx], - Unchanged: unchanged[:unchangedIdx], - }, nil -} - -func (r *Consist) diffEmployees(expectEmployees, currentEmployees []IEmployee) (ToCUDEmployees, error) { - expectEmployeesMap := make(map[string]IEmployee) - currentEmployeesMap := make(map[string]IEmployee) - - for _, expect := range expectEmployees { - expectEmployeesMap[expect.GetEmployeeId()] = expect - } - for _, current := range currentEmployees { - currentEmployeesMap[current.GetEmployeeId()] = current - } - - toCreate := make([]IEmployee, len(expectEmployees)) - toUpdate := make([]IEmployee, len(currentEmployees)) - toDelete := make([]IEmployee, len(currentEmployees)) - unchanged := make([]IEmployee, len(currentEmployees)) - toCreateIdx, toUpdateIdx, toDeleteIdx, unchangedIdx := 0, 0, 0, 0 - - for expectId, expect := range expectEmployeesMap { - current, exist := currentEmployeesMap[expectId] - if !exist { - toCreate[toCreateIdx] = expect - toCreateIdx++ - continue - } - equal, err := expect.EmployeeEqual(current) - if err != nil { - return ToCUDEmployees{}, err - } - if !equal { - toUpdate[toUpdateIdx] = expect - toUpdateIdx++ - continue - } - unchanged[unchangedIdx] = expect - unchangedIdx++ - } - - for currentId, current := range currentEmployeesMap { - _, exist := expectEmployeesMap[currentId] - if !exist { - toDelete[toDeleteIdx] = current - toDeleteIdx++ - } - } - - // todo, log level - r.Logger.Info("employee info", - "toCreate", toCreate[:toCreateIdx], - "toUpdate", toUpdate[:toUpdateIdx], - "toDelete", toDelete[:toDeleteIdx], - "unchanged", unchanged[:unchangedIdx], - ) - - return ToCUDEmployees{ - ToCreate: toCreate[:toCreateIdx], - ToUpdate: toUpdate[:toUpdateIdx], - ToDelete: toDelete[:toDeleteIdx], - Unchanged: unchanged[:unchangedIdx], - }, nil -} - -func (r *Consist) syncEmployees(ctx context.Context, employer client.Object, expectEmployees, currentEmployees []IEmployee) (bool, bool, error) { - // get expect/current employees diffEmployees - toCudEmployees, err := r.diffEmployees(expectEmployees, currentEmployees) - if err != nil { - return false, false, err - } - - succCreate, failCreate, err := r.adapter.CreateEmployees(ctx, employer, toCudEmployees.ToCreate) - if err != nil { - return false, false, fmt.Errorf("syncCreate failed, err: %s", err.Error()) - } - succUpdate, failUpdate, err := r.adapter.UpdateEmployees(ctx, employer, toCudEmployees.ToUpdate) - if err != nil { - return false, false, fmt.Errorf("syncUpdate failed, err: %s", err.Error()) - } - succDelete, failDelete, err := r.adapter.DeleteEmployees(ctx, employer, toCudEmployees.ToDelete) - if err != nil { - return false, false, fmt.Errorf("syncDelete failed, err: %s", err.Error()) - } - - toAddLifecycleFlzEmployees, toDeleteLifecycleFlzEmployees := r.getToAddDeleteLifecycleFlzEmployees( - succCreate, succDelete, succUpdate, toCudEmployees.Unchanged) - - lifecycleOptions, lifecycleOptionsImplemented := r.adapter.(ReconcileLifecycleOptions) - needRecordEmployees := lifecycleOptionsImplemented && lifecycleOptions.FollowPodOpsLifeCycle() && lifecycleOptions.NeedRecordEmployees() - if needRecordEmployees { - if employer.GetAnnotations()[lifecycleFinalizerRecordedAnnoKey] != "" { - selectedEmployees, err := r.adapter.GetSelectedEmployeeNames(ctx, employer) - if err != nil { - return false, false, fmt.Errorf("GetSelectedEmployeeNames failed, err: %s", err.Error()) - } - recordedEmployees := strings.Split(employer.GetAnnotations()[lifecycleFinalizerRecordedAnnoKey], ",") - selectedSet := sets.NewString(selectedEmployees...) - for _, recordedEmployee := range recordedEmployees { - if !selectedSet.Has(recordedEmployee) { - toDeleteLifecycleFlzEmployees = append(toDeleteLifecycleFlzEmployees, recordedEmployee) - } - } - } - } - - ns := employer.GetNamespace() - lifecycleFlz := GenerateLifecycleFinalizer(employer.GetName()) - err = r.ensureLifecycleFinalizer(ctx, ns, lifecycleFlz, toAddLifecycleFlzEmployees, toDeleteLifecycleFlzEmployees) - if err != nil { - return false, false, fmt.Errorf("ensureLifecycleFinalizer failed, err: %s", err.Error()) - } - - if needRecordEmployees { - needUpdate := false - if employer.GetAnnotations()[lifecycleFinalizerRecordedAnnoKey] == "" { - if len(toAddLifecycleFlzEmployees) != 0 { - needUpdate = true - } - } else { - recordedEmployees := strings.Split(employer.GetAnnotations()[lifecycleFinalizerRecordedAnnoKey], ",") - if len(recordedEmployees) != len(toAddLifecycleFlzEmployees) { - needUpdate = true - } else { - sort.Strings(recordedEmployees) - sort.Strings(toAddLifecycleFlzEmployees) - if !reflect.DeepEqual(recordedEmployees, toAddLifecycleFlzEmployees) { - needUpdate = true - } - } - } - if needUpdate { - patch := client.MergeFrom(employer.DeepCopyObject().(client.Object)) - annos := employer.GetAnnotations() - if annos == nil { - annos = make(map[string]string) - } - annos[lifecycleFinalizerRecordedAnnoKey] = strings.Join(toAddLifecycleFlzEmployees, ",") - employer.SetAnnotations(annos) - err = r.Client.Patch(ctx, employer, patch) - if err != nil { - return false, false, fmt.Errorf("patch lifecycleFinalizerRecordedAnno failed, err: %s", err.Error()) - } - } - } - - isClean := len(toCudEmployees.ToCreate) == 0 && len(toCudEmployees.ToUpdate) == 0 && len(toCudEmployees.Unchanged) == 0 && len(failDelete) == 0 - cudFailedExist := len(failCreate) > 0 || len(failUpdate) > 0 || len(failDelete) > 0 - return isClean, cudFailedExist, nil -} - -// ensureExpectFinalizer add expected finalizer to employee's available condition anno -func (r *Consist) ensureExpectedFinalizer(ctx context.Context, employer client.Object) (bool, error) { - // employee is not pod or not follow PodOpsLifecycle - watchOptions, watchOptionsImplemented := r.adapter.(ReconcileWatchOptions) - lifecycleOptions, lifecycleOptionsImplemented := r.adapter.(ReconcileLifecycleOptions) - if (lifecycleOptionsImplemented && !lifecycleOptions.FollowPodOpsLifeCycle()) || (watchOptionsImplemented && !isPod(watchOptions.NewEmployee())) { - return true, nil - } - - selectedEmployeeNames, err := r.adapter.GetSelectedEmployeeNames(ctx, employer) - if err != nil { - return false, fmt.Errorf("get selected employees' names failed, err: %s", err.Error()) - } - - addedExpectedFinalizerPodNames := strings.Split(employer.GetAnnotations()[expectedFinalizerAddedAnnoKey], ",") - - var toAdd, toDelete []PodExpectedFinalizerOps - if !employer.GetDeletionTimestamp().IsZero() { - toDeleteNames := sets.NewString(addedExpectedFinalizerPodNames...).Insert(selectedEmployeeNames...).List() - for _, podName := range toDeleteNames { - toDelete = append(toDelete, PodExpectedFinalizerOps{ - Name: podName, - Succeed: false, - }) - } - _ = r.patchPodExpectedFinalizer(ctx, employer, toAdd, toDelete) - var notDeletedPodNames []string - for _, deleteExpectedFinalizerOps := range toDelete { - if !deleteExpectedFinalizerOps.Succeed { - notDeletedPodNames = append(notDeletedPodNames, deleteExpectedFinalizerOps.Name) - } - } - patch := client.MergeFrom(employer.DeepCopyObject().(client.Object)) - annos := employer.GetAnnotations() - if annos == nil { - annos = make(map[string]string) - } - if annos[expectedFinalizerAddedAnnoKey] == strings.Join(notDeletedPodNames, ",") { - return len(notDeletedPodNames) == 0, nil - } - annos[expectedFinalizerAddedAnnoKey] = strings.Join(notDeletedPodNames, ",") - employer.SetAnnotations(annos) - return len(notDeletedPodNames) == 0, r.Client.Patch(ctx, employer, patch) - } - - selectedSet := sets.NewString(selectedEmployeeNames...) - for _, podName := range addedExpectedFinalizerPodNames { - if !selectedSet.Has(podName) { - toDelete = append(toDelete, PodExpectedFinalizerOps{ - Name: podName, - Succeed: false, - }) - } - } - - addedSet := sets.NewString(addedExpectedFinalizerPodNames...) - for _, podName := range selectedEmployeeNames { - if !addedSet.Has(podName) { - toAdd = append(toAdd, PodExpectedFinalizerOps{ - Name: podName, - Succeed: false, - }) - } - } - - _ = r.patchPodExpectedFinalizer(ctx, employer, toAdd, toDelete) - var succDeletedNames []string - for _, deleteExpectFinalizerOps := range toDelete { - if deleteExpectFinalizerOps.Succeed { - succDeletedNames = append(succDeletedNames, deleteExpectFinalizerOps.Name) - } - } - succDeletedNamesSet := sets.NewString(succDeletedNames...) - var addedNames []string - for _, added := range addedExpectedFinalizerPodNames { - if !succDeletedNamesSet.Has(added) { - addedNames = append(addedNames, added) - } - } - for _, addExpectedFinalizerOps := range toAdd { - if addExpectedFinalizerOps.Succeed { - addedNames = append(addedNames, addExpectedFinalizerOps.Name) - } - } - - patch := client.MergeFrom(employer.DeepCopyObject().(client.Object)) - annos := employer.GetAnnotations() - if annos == nil { - annos = make(map[string]string) - } - if annos[expectedFinalizerAddedAnnoKey] == strings.Join(addedNames, ",") { - return len(addedNames) == 0, nil - } - annos[expectedFinalizerAddedAnnoKey] = strings.Join(addedNames, ",") - employer.SetAnnotations(annos) - return len(addedNames) == 0, r.Client.Patch(ctx, employer, patch) -} - -func (r *Consist) patchPodExpectedFinalizer(ctx context.Context, employer client.Object, toAdd, toDelete []PodExpectedFinalizerOps) error { - expectedFlzKey := GenerateLifecycleFinalizerKey(employer) - expectedFlz := GenerateLifecycleFinalizer(employer.GetName()) - - errAdd := r.patchAddPodExpectedFinalizer(ctx, employer, toAdd, expectedFlzKey, expectedFlz) - errDelete := r.patchDeletePodExpectedFinalizer(ctx, employer, toDelete, expectedFlzKey) - - return errors2.NewAggregate([]error{errAdd, errDelete}) -} - -func (r *Consist) patchAddPodExpectedFinalizer(ctx context.Context, employer client.Object, toAdd []PodExpectedFinalizerOps, - expectedFlzKey, expectedFlz string) error { - _, err := utils.SlowStartBatch(len(toAdd), 1, false, func(i int, _ error) error { - podExpectedFinalizerOps := &toAdd[i] - var pod corev1.Pod - err := r.Client.Get(ctx, types.NamespacedName{ - Namespace: employer.GetNamespace(), - Name: podExpectedFinalizerOps.Name, - }, &pod) - if err != nil { - if errors.IsNotFound(err) { - return nil - } - return err - } - - if !pod.GetDeletionTimestamp().IsZero() { - return nil - } - - patch := client.MergeFrom(pod.DeepCopy()) - - var availableExpectedFlzs v1alpha1.PodAvailableConditions - if pod.Annotations == nil { - pod.Annotations = make(map[string]string) - } - if pod.Annotations[v1alpha1.PodAvailableConditionsAnnotation] == "" { - availableExpectedFlzs.ExpectedFinalizers = map[string]string{expectedFlzKey: expectedFlz} - annoAvailableExpectedFlzs, errMarshal := json.Marshal(availableExpectedFlzs) - if errMarshal != nil { - return errMarshal - } - pod.Annotations[v1alpha1.PodAvailableConditionsAnnotation] = string(annoAvailableExpectedFlzs) - errPatch := r.Client.Patch(ctx, &pod, patch) - if errPatch != nil { - return errPatch - } - } else { - errUnmarshal := json.Unmarshal([]byte(pod.Annotations[v1alpha1.PodAvailableConditionsAnnotation]), &availableExpectedFlzs) - if errUnmarshal != nil { - return errUnmarshal - } - if availableExpectedFlzs.ExpectedFinalizers == nil { - availableExpectedFlzs.ExpectedFinalizers = make(map[string]string) - } - if availableExpectedFlzs.ExpectedFinalizers[expectedFlzKey] != expectedFlz { - availableExpectedFlzs.ExpectedFinalizers[expectedFlzKey] = expectedFlz - annoAvailableExpectedFlzs, errMarshal := json.Marshal(availableExpectedFlzs) - if errMarshal != nil { - return errMarshal - } - pod.Annotations[v1alpha1.PodAvailableConditionsAnnotation] = string(annoAvailableExpectedFlzs) - errPatch := r.Client.Patch(ctx, &pod, patch) - if errPatch != nil { - return errPatch - } - } - } - podExpectedFinalizerOps.Succeed = true - return nil - }) - - return err -} - -func (r *Consist) patchDeletePodExpectedFinalizer(ctx context.Context, employer client.Object, toDelete []PodExpectedFinalizerOps, - expectedFlzKey string) error { - _, err := utils.SlowStartBatch(len(toDelete), 1, false, func(i int, _ error) error { - podExpectedFinalizerOps := &toDelete[i] - var pod corev1.Pod - err := r.Client.Get(ctx, types.NamespacedName{ - Namespace: employer.GetNamespace(), - Name: podExpectedFinalizerOps.Name, - }, &pod) - if err != nil { - if errors.IsNotFound(err) { - podExpectedFinalizerOps.Succeed = true - return nil - } - return err - } - - patch := client.MergeFrom(pod.DeepCopy()) - - var availableExpectedFlzs v1alpha1.PodAvailableConditions - if pod.Annotations == nil || pod.Annotations[v1alpha1.PodAvailableConditionsAnnotation] == "" { - podExpectedFinalizerOps.Succeed = true - return nil - } - - errUnmarshal := json.Unmarshal([]byte(pod.Annotations[v1alpha1.PodAvailableConditionsAnnotation]), &availableExpectedFlzs) - if errUnmarshal != nil { - return errUnmarshal - } - if _, exist := availableExpectedFlzs.ExpectedFinalizers[expectedFlzKey]; exist { - delete(availableExpectedFlzs.ExpectedFinalizers, expectedFlzKey) - annoAvailableExpectedFlzs, errMarshal := json.Marshal(availableExpectedFlzs) - if errMarshal != nil { - return errMarshal - } - pod.Annotations[v1alpha1.PodAvailableConditionsAnnotation] = string(annoAvailableExpectedFlzs) - errPatch := r.Client.Patch(ctx, &pod, patch) - if errPatch != nil { - return errPatch - } - } - podExpectedFinalizerOps.Succeed = true - return nil - }) - - return err -} - -func (r *Consist) cleanEmployerCleanFinalizer(ctx context.Context, employer client.Object) error { - var employerLatest client.Object - if watchOptions, ok := r.adapter.(ReconcileWatchOptions); ok { - employerLatest = watchOptions.NewEmployer() - } else { - employerLatest = &corev1.Service{} - } - - err := r.Client.Get(ctx, types.NamespacedName{ - Namespace: employer.GetNamespace(), - Name: employer.GetName(), - }, employerLatest) - if err != nil { - if errors.IsNotFound(err) { - return nil - } - return err - } - - alreadyDeleted := true - var finalizers []string - cleanFlz := cleanFinalizerPrefix + employer.GetName() - for _, flz := range employer.GetFinalizers() { - if flz == cleanFlz { - alreadyDeleted = false - continue - } - finalizers = append(finalizers, flz) - } - if alreadyDeleted { - return nil - } - employerLatest.SetFinalizers(finalizers) - return r.Client.Update(ctx, employerLatest) -} - -func (r *Consist) ensureLifecycleFinalizer(ctx context.Context, ns, lifecycleFlz string, toAdd, toDelete []string) error { - watchOptions, watchOptionsImplemented := r.adapter.(ReconcileWatchOptions) - - _, err := utils.SlowStartBatch(len(toAdd), 1, false, func(i int, _ error) error { - employeeName := toAdd[i] - var employee client.Object - if watchOptionsImplemented { - employee = watchOptions.NewEmployee() - } else { - employee = &corev1.Pod{} - } - err := r.Client.Get(ctx, types.NamespacedName{ - Namespace: ns, - Name: employeeName, - }, employee) - if err != nil { - if errors.IsNotFound(err) { - return nil - } - return err - } - alreadyAdd := false - for _, flz := range employee.GetFinalizers() { - if flz == lifecycleFlz { - alreadyAdd = true - break - } - } - if alreadyAdd { - return nil - } - employee.SetFinalizers(append(employee.GetFinalizers(), lifecycleFlz)) - return r.Client.Update(ctx, employee) - }) - if err != nil { - return err - } - - _, err = utils.SlowStartBatch(len(toDelete), 1, false, func(i int, _ error) error { - employeeName := toDelete[i] - var employee client.Object - if watchOptionsImplemented { - employee = watchOptions.NewEmployee() - } else { - employee = &corev1.Pod{} - } - err := r.Client.Get(ctx, types.NamespacedName{ - Namespace: ns, - Name: employeeName, - }, employee) - if err != nil { - if errors.IsNotFound(err) { - return nil - } - return err - } - alreadyDeleted := true - var finalizers []string - for _, flz := range employee.GetFinalizers() { - if flz == lifecycleFlz { - alreadyDeleted = false - continue - } - finalizers = append(finalizers, flz) - } - if alreadyDeleted { - return nil - } - employee.SetFinalizers(finalizers) - return r.Client.Update(ctx, employee) - }) - return err -} - -func (r *Consist) getToAddDeleteLifecycleFlzEmployees(succCreate, succDelete, succUpdate, unchanged []IEmployee) ([]string, []string) { - toAddLifecycleFlz := make([]string, len(succCreate)+len(succUpdate)+len(unchanged)) - toDeleteLifecycleFlz := make([]string, len(succDelete)+len(succUpdate)+len(unchanged)) - toAddIdx, toDeleteIdx := 0, 0 - - watchOptions, watchOptionsImplemented := r.adapter.(ReconcileWatchOptions) - - lifecycleOptions, lifecycleOptionsImplemented := r.adapter.(ReconcileLifecycleOptions) - if (lifecycleOptionsImplemented && !lifecycleOptions.FollowPodOpsLifeCycle()) || (watchOptionsImplemented && !isPod(watchOptions.NewEmployee())) { - return toAddLifecycleFlz[:toAddIdx], toDeleteLifecycleFlz[:toDeleteIdx] - } - - for _, employee := range succCreate { - toAddLifecycleFlz[toAddIdx] = employee.GetEmployeeName() - toAddIdx++ - } - - for _, employee := range succUpdate { - podEmployeeStatus, ok := employee.GetEmployeeStatuses().(PodEmployeeStatuses) - if !ok { - continue - } - if podEmployeeStatus.LifecycleReady { - toAddLifecycleFlz[toAddIdx] = employee.GetEmployeeName() - toAddIdx++ - continue - } - toDeleteLifecycleFlz[toDeleteIdx] = employee.GetEmployeeName() - toDeleteIdx++ - } - - for _, employee := range succDelete { - toDeleteLifecycleFlz[toDeleteIdx] = employee.GetEmployeeName() - toDeleteIdx++ - } - - for _, employee := range unchanged { - podEmployeeStatus, ok := employee.GetEmployeeStatuses().(PodEmployeeStatuses) - if !ok { - continue - } - if podEmployeeStatus.LifecycleReady { - toAddLifecycleFlz[toAddIdx] = employee.GetEmployeeName() - toAddIdx++ - continue - } - toDeleteLifecycleFlz[toDeleteIdx] = employee.GetEmployeeName() - toDeleteIdx++ - } - - return toAddLifecycleFlz[:toAddIdx], toDeleteLifecycleFlz[:toDeleteIdx] -} - -func (r *Consist) ensureEmployerCleanFlz(ctx context.Context, employer client.Object) (bool, error) { - if !employer.GetDeletionTimestamp().IsZero() { - return false, nil - } - for _, flz := range employer.GetFinalizers() { - if flz == cleanFinalizerPrefix+employer.GetName() { - return false, nil - } - } - employer.SetFinalizers(append(employer.GetFinalizers(), cleanFinalizerPrefix+employer.GetName())) - return true, r.Client.Update(ctx, employer) -} diff --git a/pkg/controllers/resourceconsist/event_handler.go b/pkg/controllers/resourceconsist/event_handler.go deleted file mode 100644 index 2ada0f36..00000000 --- a/pkg/controllers/resourceconsist/event_handler.go +++ /dev/null @@ -1,227 +0,0 @@ -/* -Copyright 2023 The KusionStack Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resourceconsist - -import ( - "context" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/util/workqueue" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/predicate" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - "kusionstack.io/operating/apis/apps/v1alpha1" -) - -var _ handler.EventHandler = &EnqueueServiceWithRateLimit{} - -var _ handler.EventHandler = &EnqueueServiceByPod{} - -type EnqueueServiceWithRateLimit struct{} - -type EnqueueServiceByPod struct { - c client.Client -} - -func (e *EnqueueServiceWithRateLimit) Create(evt event.CreateEvent, q workqueue.RateLimitingInterface) { - if evt.Object == nil { - return - } - - q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ - Name: evt.Object.GetName(), - Namespace: evt.Object.GetNamespace(), - }}) -} - -func (e *EnqueueServiceWithRateLimit) Update(evt event.UpdateEvent, q workqueue.RateLimitingInterface) { - if evt.ObjectOld != nil { - q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ - Name: evt.ObjectOld.GetName(), - Namespace: evt.ObjectOld.GetNamespace(), - }}) - } - - if evt.ObjectNew != nil { - q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ - Name: evt.ObjectNew.GetName(), - Namespace: evt.ObjectNew.GetNamespace(), - }}) - } -} - -func (e *EnqueueServiceWithRateLimit) Delete(evt event.DeleteEvent, q workqueue.RateLimitingInterface) { - if evt.Object == nil { - return - } - - q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ - Name: evt.Object.GetName(), - Namespace: evt.Object.GetNamespace(), - }}) -} - -func (e *EnqueueServiceWithRateLimit) Generic(evt event.GenericEvent, q workqueue.RateLimitingInterface) { - if evt.Object == nil { - return - } - - q.Add(reconcile.Request{NamespacedName: types.NamespacedName{ - Name: evt.Object.GetName(), - Namespace: evt.Object.GetNamespace(), - }}) -} - -func (e *EnqueueServiceByPod) Create(evt event.CreateEvent, q workqueue.RateLimitingInterface) { - serviceNames, err := GetEmployerByEmployee(context.Background(), e.c, evt.Object) - if err != nil { - return - } - for _, obj := range serviceNames { - svc := &corev1.Service{} - err = e.c.Get(context.Background(), types.NamespacedName{Name: obj, Namespace: evt.Object.GetNamespace()}, svc) - if err != nil { - continue - } - if doPredicate(svc) { - q.Add(reconcile.Request{NamespacedName: types.NamespacedName{Namespace: evt.Object.GetNamespace(), Name: obj}}) - } - } -} - -func (e *EnqueueServiceByPod) Update(evt event.UpdateEvent, q workqueue.RateLimitingInterface) { - serviceNamesOld, err := GetEmployerByEmployee(context.Background(), e.c, evt.ObjectOld) - if err != nil { - return - } - for _, obj := range serviceNamesOld { - svc := &corev1.Service{} - err = e.c.Get(context.Background(), types.NamespacedName{Name: obj, Namespace: evt.ObjectOld.GetNamespace()}, svc) - if err != nil { - continue - } - if doPredicate(svc) { - q.Add(reconcile.Request{NamespacedName: types.NamespacedName{Namespace: evt.ObjectOld.GetNamespace(), Name: obj}}) - } - } - - serviceNamesNew, err := GetEmployerByEmployee(context.Background(), e.c, evt.ObjectNew) - if err != nil { - return - } - for _, obj := range serviceNamesNew { - svc := &corev1.Service{} - err = e.c.Get(context.Background(), types.NamespacedName{Name: obj, Namespace: evt.ObjectNew.GetNamespace()}, svc) - if err != nil { - continue - } - if doPredicate(svc) { - q.Add(reconcile.Request{NamespacedName: types.NamespacedName{Namespace: evt.ObjectNew.GetNamespace(), Name: obj}}) - } - } -} - -func (e *EnqueueServiceByPod) Delete(evt event.DeleteEvent, q workqueue.RateLimitingInterface) { - serviceNames, err := GetEmployerByEmployee(context.Background(), e.c, evt.Object) - if err != nil { - return - } - for _, obj := range serviceNames { - svc := &corev1.Service{} - err = e.c.Get(context.Background(), types.NamespacedName{Name: obj, Namespace: evt.Object.GetNamespace()}, svc) - if err != nil { - continue - } - if doPredicate(svc) { - q.Add(reconcile.Request{NamespacedName: types.NamespacedName{Namespace: evt.Object.GetNamespace(), Name: obj}}) - } - } -} - -func (e *EnqueueServiceByPod) Generic(evt event.GenericEvent, q workqueue.RateLimitingInterface) { - serviceNames, err := GetEmployerByEmployee(context.Background(), e.c, evt.Object) - if err != nil { - return - } - for _, obj := range serviceNames { - svc := &corev1.Service{} - err = e.c.Get(context.Background(), types.NamespacedName{Name: obj, Namespace: evt.Object.GetNamespace()}, svc) - if err != nil { - continue - } - if doPredicate(svc) { - q.Add(reconcile.Request{NamespacedName: types.NamespacedName{Namespace: evt.Object.GetNamespace(), Name: obj}}) - } - } -} - -func GetEmployerByEmployee(ctx context.Context, client client.Client, employee client.Object) ([]string, error) { - if employee.GetLabels() == nil { - return nil, nil - } - - services := &corev1.ServiceList{} - if err := client.List(ctx, services); err != nil { - return nil, err - } - - employeeLabels := labels.Set(employee.GetLabels()) - var names []string - for _, svc := range services.Items { - selector := labels.Set(svc.Spec.Selector).AsSelector() - if selector.Matches(employeeLabels) { - names = append(names, svc.GetName()) - } - } - - return names, nil -} - -func doPredicate(obj client.Object) bool { - if obj == nil { - return false - } - if obj.GetLabels() != nil { - value, exist := obj.GetLabels()[v1alpha1.ControlledByKusionStackLabelKey] - if exist && value == "true" { - return true - } - } - return false -} - -var employerPredicates = predicate.Funcs{ - CreateFunc: func(event event.CreateEvent) bool { - return doPredicate(event.Object) - }, - DeleteFunc: func(event event.DeleteEvent) bool { - return doPredicate(event.Object) - }, - UpdateFunc: func(event event.UpdateEvent) bool { - return doPredicate(event.ObjectNew) - }, - GenericFunc: func(event event.GenericEvent) bool { - return doPredicate(event.Object) - }, -} - -var employeePredicates = predicate.Funcs{} diff --git a/pkg/controllers/resourceconsist/resourceconsist_controller.go b/pkg/controllers/resourceconsist/resourceconsist_controller.go deleted file mode 100644 index 85dc03e4..00000000 --- a/pkg/controllers/resourceconsist/resourceconsist_controller.go +++ /dev/null @@ -1,226 +0,0 @@ -/* -Copyright 2023 The KusionStack Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resourceconsist - -import ( - "context" - "fmt" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/util/workqueue" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/source" - - "kusionstack.io/operating/pkg/utils/mixin" -) - -// Add creates a new Controller of specified reconcileAdapter and adds it to the Manager with default RBAC. -// The Manager will set fields on the Controller and Start it when the Manager is Started. -func Add(mgr manager.Manager, reconcileAdapter ReconcileAdapter) error { - return AddToMgr(mgr, reconcileAdapter) -} - -func AddToMgr(mgr manager.Manager, adapter ReconcileAdapter) error { - r := NewReconcile(mgr, adapter) - - // CreateEmployees a new controller - maxConcurrentReconciles := defaultMaxConcurrentReconciles - rateLimiter := workqueue.DefaultControllerRateLimiter() - if reconcileOptions, ok := adapter.(ReconcileOptions); ok { - maxConcurrentReconciles = reconcileOptions.GetMaxConcurrentReconciles() - rateLimiter = reconcileOptions.GetRateLimiter() - } - c, err := controller.New(adapter.GetControllerName(), mgr, controller.Options{ - MaxConcurrentReconciles: maxConcurrentReconciles, - Reconciler: r, - RateLimiter: rateLimiter}) - if err != nil { - return err - } - - if watchOptions, ok := adapter.(ReconcileWatchOptions); ok { - // Watch for changes to EmployerResources - err = c.Watch(&source.Kind{ - Type: watchOptions.NewEmployer()}, - watchOptions.EmployerEventHandler(), - watchOptions.EmployerPredicates()) - if err != nil { - return err - } - - // Watch for changes to EmployeeResources - err = c.Watch(&source.Kind{ - Type: watchOptions.NewEmployee()}, - watchOptions.EmployeeEventHandler(), - watchOptions.EmployeePredicates()) - if err != nil { - return err - } - - return nil - } - - // Watch for changes to EmployerResources - err = c.Watch(&source.Kind{ - Type: &corev1.Service{}}, - &EnqueueServiceWithRateLimit{}, - employerPredicates) - if err != nil { - return err - } - - // Watch for changes to EmployeeResources - err = c.Watch(&source.Kind{ - Type: &corev1.Pod{}}, - &EnqueueServiceByPod{ - c: mgr.GetClient(), - }, - employeePredicates) - if err != nil { - return err - } - - return nil -} - -func NewReconcile(mgr manager.Manager, reconcileAdapter ReconcileAdapter) *Consist { - mixin := mixin.NewReconcilerMixin(reconcileAdapter.GetControllerName(), mgr) - return &Consist{ - ReconcilerMixin: mixin, - adapter: reconcileAdapter, - } -} - -type Consist struct { - *mixin.ReconcilerMixin - - adapter ReconcileAdapter -} - -// +kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=core,resources=pods/status,verbs=get;update;patch - -func (r *Consist) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { - var employer client.Object - if watchOptions, ok := r.adapter.(ReconcileWatchOptions); ok { - employer = watchOptions.NewEmployer() - } else { - employer = &corev1.Service{} - } - err := r.Client.Get(ctx, types.NamespacedName{ - Namespace: request.Namespace, - Name: request.Name, - }, employer) - if err != nil { - if errors.IsNotFound(err) { - return reconcile.Result{}, nil - } - r.Logger.Error(err, "get employer failed") - return reconcile.Result{}, err - } - - // ensure employer-clean finalizer firstly, employer-clean finalizer should be cleaned at the end - updated, err := r.ensureEmployerCleanFlz(ctx, employer) - if err != nil { - r.Logger.Error(err, "add employer clean finalizer failed") - r.Recorder.Eventf(employer, corev1.EventTypeWarning, "ensureEmployerCleanFlzFailed", - "add employer clean finalizer failed: %s", err.Error()) - return reconcile.Result{}, err - } - if updated { - r.Logger.Info("add employer clean finalizer") - r.Recorder.Eventf(employer, corev1.EventTypeNormal, "ensureEmployerCleanFlzSucceed", - "add employer clean finalizer") - return reconcile.Result{}, nil - } - - isExpectedClean, err := r.ensureExpectedFinalizer(ctx, employer) - if err != nil { - r.Logger.Error(err, "ensure employees expected finalizer failed") - r.Recorder.Eventf(employer, corev1.EventTypeWarning, "ensureExpectedFinalizerFailed", - "ensure employees expected finalizer failed: %s", err.Error()) - return reconcile.Result{}, err - } - - expectEmployer, err := r.adapter.GetExpectedEmployer(ctx, employer) - if err != nil { - r.Logger.Error(err, "get expect employer failed") - r.Recorder.Eventf(employer, corev1.EventTypeWarning, "GetExpectEmployerFailed", - "get expect employer status failed: %s", err.Error()) - return reconcile.Result{}, err - } - currentEmployer, err := r.adapter.GetCurrentEmployer(ctx, employer) - if err != nil { - r.Logger.Error(err, "get current employer failed") - r.Recorder.Eventf(employer, corev1.EventTypeWarning, "GetCurrentEmployerFailed", - "get current employer status failed: %s", err.Error()) - return reconcile.Result{}, err - } - isCleanEmployer, syncEmployerFailedExist, err := r.syncEmployer(ctx, employer, expectEmployer, currentEmployer) - if err != nil { - r.Logger.Error(err, "sync employer status failed") - r.Recorder.Eventf(employer, corev1.EventTypeWarning, "syncEmployerFailed", - "sync employer status failed: %s", err.Error()) - return reconcile.Result{}, err - } - - expectEmployees, err := r.adapter.GetExpectedEmployee(ctx, employer) - if err != nil { - r.Logger.Error(err, "get expect employees failed") - r.Recorder.Eventf(employer, corev1.EventTypeWarning, "GetExpectEmployeeFailed", - "get expect employees status failed: %s", err.Error()) - return reconcile.Result{}, err - } - currentEmployees, err := r.adapter.GetCurrentEmployee(ctx, employer) - if err != nil { - r.Logger.Error(err, "get current employees failed") - r.Recorder.Eventf(employer, corev1.EventTypeWarning, "GetCurrentEmployeeFailed", - "get current employees status failed: %s", err.Error()) - return reconcile.Result{}, err - } - isCleanEmployee, syncEmployeeFailedExist, err := r.syncEmployees(ctx, employer, expectEmployees, currentEmployees) - if err != nil { - r.Logger.Error(err, "sync employees status failed") - r.Recorder.Eventf(employer, corev1.EventTypeWarning, "syncEmployeesFailed", - "sync employees status failed: %s", err.Error()) - return reconcile.Result{}, err - } - - if isCleanEmployer && isCleanEmployee && isExpectedClean && !employer.GetDeletionTimestamp().IsZero() { - err = r.cleanEmployerCleanFinalizer(ctx, employer) - if err != nil { - r.Logger.Error(err, "clean employer clean-finalizer failed") - r.Recorder.Eventf(employer, corev1.EventTypeWarning, "cleanEmployerCleanFinalizerFailed", - "clean employer clean-finalizer failed: %s", err.Error()) - return reconcile.Result{}, err - } - } - - if syncEmployerFailedExist || syncEmployeeFailedExist { - r.Recorder.Eventf(employer, corev1.EventTypeNormal, "ReconcileFailed", "employer or employees synced failed exist") - return reconcile.Result{}, fmt.Errorf("employer or employees synced failed exist") - } - - r.Recorder.Eventf(employer, corev1.EventTypeNormal, "ReconcileSucceed", "") - return reconcile.Result{}, nil -} diff --git a/pkg/controllers/resourceconsist/resourceconsist_controller_suite_test.go b/pkg/controllers/resourceconsist/resourceconsist_controller_suite_test.go deleted file mode 100644 index e93f6184..00000000 --- a/pkg/controllers/resourceconsist/resourceconsist_controller_suite_test.go +++ /dev/null @@ -1,503 +0,0 @@ -/* -Copyright 2023 The KusionStack Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resourceconsist - -import ( - "context" - "fmt" - "reflect" - "sync" - - "github.com/stretchr/testify/mock" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/labels" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -type DemoReconcile struct { - client.Client - resourceProviderClient *DemoResourceProviderClient -} - -var _ ReconcileAdapter = &DemoReconcile{} -var _ ReconcileLifecycleOptions = &DemoReconcile{} - -var needRecordEmployees = false - -func NewDemoReconcileAdapter(c client.Client, rc *DemoResourceProviderClient) *DemoReconcile { - return &DemoReconcile{ - Client: c, - resourceProviderClient: rc, - } -} - -func (r *DemoReconcile) FollowPodOpsLifeCycle() bool { - return true -} - -func (r *DemoReconcile) NeedRecordEmployees() bool { - return needRecordEmployees -} - -func (r *DemoReconcile) GetSelectedEmployeeNames(ctx context.Context, employer client.Object) ([]string, error) { - svc, ok := employer.(*corev1.Service) - if !ok { - return nil, fmt.Errorf("expect employer kind is Service") - } - selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated() - var podList corev1.PodList - err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector}) - if err != nil { - return nil, err - } - - selected := make([]string, len(podList.Items)) - for idx, pod := range podList.Items { - selected[idx] = pod.Name - } - - return selected, nil -} - -func (r *DemoReconcile) GetControllerName() string { - return "demo-controller" -} - -func (r *DemoReconcile) GetExpectedEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) { - if !employer.GetDeletionTimestamp().IsZero() { - return nil, nil - } - var expect []IEmployer - expect = append(expect, DemoServiceStatus{ - EmployerId: employer.GetName(), - EmployerStatuses: DemoServiceDetails{ - RemoteVIP: "demo-remote-VIP", - RemoteVIPQPS: 100, - }, - }) - return expect, nil -} - -func (r *DemoReconcile) GetCurrentEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) { - var current []IEmployer - - req := &DemoResourceVipOps{} - resp, err := r.resourceProviderClient.QueryVip(req) - if err != nil { - return current, err - } - if resp == nil { - return current, fmt.Errorf("demo resource vip query resp is nil") - } - - for _, employerStatus := range resp.VipStatuses { - current = append(current, employerStatus) - } - return current, nil -} - -func (r *DemoReconcile) CreateEmployer(ctx context.Context, employer client.Object, toCreates []IEmployer) ([]IEmployer, []IEmployer, error) { - if toCreates == nil || len(toCreates) == 0 { - return toCreates, nil, nil - } - - toCreateDemoServiceStatus := make([]DemoServiceStatus, len(toCreates)) - for idx, create := range toCreates { - createDemoServiceStatus, ok := create.(DemoServiceStatus) - if !ok { - return nil, toCreates, fmt.Errorf("toCreates employer is not DemoServiceStatus") - } - toCreateDemoServiceStatus[idx] = createDemoServiceStatus - } - - _, err := r.resourceProviderClient.CreateVip(&DemoResourceVipOps{ - VipStatuses: toCreateDemoServiceStatus, - }) - if err != nil { - return nil, toCreates, err - } - return toCreates, nil, nil -} - -func (r *DemoReconcile) UpdateEmployer(ctx context.Context, employer client.Object, toUpdates []IEmployer) ([]IEmployer, []IEmployer, error) { - if toUpdates == nil || len(toUpdates) == 0 { - return toUpdates, nil, nil - } - - toUpdateDemoServiceStatus := make([]DemoServiceStatus, len(toUpdates)) - for idx, update := range toUpdates { - updateDemoServiceStatus, ok := update.(DemoServiceStatus) - if !ok { - return nil, toUpdates, fmt.Errorf("toUpdates employer is not DemoServiceStatus") - } - toUpdateDemoServiceStatus[idx] = updateDemoServiceStatus - } - - _, err := r.resourceProviderClient.UpdateVip(&DemoResourceVipOps{ - VipStatuses: toUpdateDemoServiceStatus, - }) - if err != nil { - return nil, toUpdates, err - } - return toUpdates, nil, nil -} - -func (r *DemoReconcile) DeleteEmployer(ctx context.Context, employer client.Object, toDeletes []IEmployer) ([]IEmployer, []IEmployer, error) { - if toDeletes == nil || len(toDeletes) == 0 { - return toDeletes, nil, nil - } - - toDeleteDemoServiceStatus := make([]DemoServiceStatus, len(toDeletes)) - for idx, update := range toDeletes { - deleteDemoServiceStatus, ok := update.(DemoServiceStatus) - if !ok { - return nil, toDeletes, fmt.Errorf("toDeletes employer is not DemoServiceStatus") - } - toDeleteDemoServiceStatus[idx] = deleteDemoServiceStatus - } - - _, err := r.resourceProviderClient.DeleteVip(&DemoResourceVipOps{ - VipStatuses: toDeleteDemoServiceStatus, - }) - if err != nil { - return nil, toDeletes, err - } - return toDeletes, nil, nil -} - -// GetExpectEmployeeStatus return expect employee status -func (r *DemoReconcile) GetExpectedEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) { - if !employer.GetDeletionTimestamp().IsZero() { - return []IEmployee{}, nil - } - - svc, ok := employer.(*corev1.Service) - if !ok { - return nil, fmt.Errorf("expect employer kind is Service") - } - selector := labels.Set(svc.Spec.Selector).AsSelectorPreValidated() - - var podList corev1.PodList - err := r.List(ctx, &podList, &client.ListOptions{Namespace: svc.Namespace, LabelSelector: selector}) - if err != nil { - return nil, err - } - - expected := make([]IEmployee, len(podList.Items)) - expectIdx := 0 - for _, pod := range podList.Items { - if !pod.DeletionTimestamp.IsZero() { - continue - } - status := DemoPodStatus{ - EmployeeId: pod.Name, - EmployeeName: pod.Name, - } - employeeStatuses, err := GetCommonPodEmployeeStatus(&pod) - if err != nil { - return nil, err - } - extraStatus := PodExtraStatus{} - if employeeStatuses.LifecycleReady { - extraStatus.TrafficOn = true - extraStatus.TrafficWeight = 100 - } else { - extraStatus.TrafficOn = false - extraStatus.TrafficWeight = 0 - } - employeeStatuses.ExtraStatus = extraStatus - status.EmployeeStatuses = employeeStatuses - expected[expectIdx] = status - expectIdx++ - } - - return expected[:expectIdx], nil -} - -func (r *DemoReconcile) GetCurrentEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) { - var current []IEmployee - req := &DemoResourceRsOps{} - resp, err := r.resourceProviderClient.QueryRealServer(req) - if err != nil { - return current, err - } - if resp == nil { - return current, fmt.Errorf("demo resource rs query resp is nil") - } - - for _, rsStatus := range resp.RsStatuses { - current = append(current, rsStatus) - } - return current, nil -} - -func (r *DemoReconcile) CreateEmployees(ctx context.Context, employer client.Object, toCreates []IEmployee) ([]IEmployee, []IEmployee, error) { - if toCreates == nil || len(toCreates) == 0 { - return toCreates, nil, nil - } - toCreateDemoPodStatuses := make([]DemoPodStatus, len(toCreates)) - - for idx, toCreate := range toCreates { - podStatus, ok := toCreate.(DemoPodStatus) - if !ok { - return nil, toCreates, fmt.Errorf("toCreate is not DemoPodStatus") - } - toCreateDemoPodStatuses[idx] = podStatus - } - - _, err := r.resourceProviderClient.CreateRealServer(&DemoResourceRsOps{ - RsStatuses: toCreateDemoPodStatuses, - }) - if err != nil { - return nil, toCreates, err - } - - return toCreates, nil, nil -} - -func (r *DemoReconcile) UpdateEmployees(ctx context.Context, employer client.Object, toUpdates []IEmployee) ([]IEmployee, []IEmployee, error) { - if toUpdates == nil || len(toUpdates) == 0 { - return toUpdates, nil, nil - } - - toUpdateDemoPodStatuses := make([]DemoPodStatus, len(toUpdates)) - - for idx, toUpdate := range toUpdates { - podStatus, ok := toUpdate.(DemoPodStatus) - if !ok { - return nil, toUpdates, fmt.Errorf("toUpdate is not DemoPodStatus") - } - toUpdateDemoPodStatuses[idx] = podStatus - } - - _, err := r.resourceProviderClient.UpdateRealServer(&DemoResourceRsOps{ - RsStatuses: toUpdateDemoPodStatuses, - }) - if err != nil { - return nil, toUpdates, err - } - - return toUpdates, nil, nil -} - -func (r *DemoReconcile) DeleteEmployees(ctx context.Context, employer client.Object, toDeletes []IEmployee) ([]IEmployee, []IEmployee, error) { - if toDeletes == nil || len(toDeletes) == 0 { - return toDeletes, nil, nil - } - - toDeleteDemoPodStatuses := make([]DemoPodStatus, len(toDeletes)) - - for idx, toDelete := range toDeletes { - podStatus, ok := toDelete.(DemoPodStatus) - if !ok { - return nil, toDeletes, fmt.Errorf("toDelete is not DemoPodStatus") - } - toDeleteDemoPodStatuses[idx] = podStatus - } - - _, err := r.resourceProviderClient.DeleteRealServer(&DemoResourceRsOps{ - RsStatuses: toDeleteDemoPodStatuses, - }) - if err != nil { - return nil, toDeletes, err - } - - return toDeletes, nil, nil -} - -var _ IEmployer = DemoServiceStatus{} -var _ IEmployee = DemoPodStatus{} - -type DemoServiceStatus struct { - EmployerId string - EmployerStatuses DemoServiceDetails -} - -type DemoServiceDetails struct { - RemoteVIP string - RemoteVIPQPS int -} - -func (d DemoServiceStatus) GetEmployerId() string { - return d.EmployerId -} - -func (d DemoServiceStatus) GetEmployerStatuses() interface{} { - return d.EmployerStatuses -} - -func (d DemoServiceStatus) EmployerEqual(employer IEmployer) (bool, error) { - if d.EmployerId != employer.GetEmployerId() { - return false, nil - } - employerStatus, ok := employer.GetEmployerStatuses().(DemoServiceDetails) - if !ok { - return false, fmt.Errorf("employer to diff is not Demo Service Details") - } - return reflect.DeepEqual(d.EmployerStatuses, employerStatus), nil -} - -type DemoPodStatus struct { - EmployeeId string - EmployeeName string - EmployeeStatuses PodEmployeeStatuses -} - -func (d DemoPodStatus) GetEmployeeId() string { - return d.EmployeeId -} - -func (d DemoPodStatus) GetEmployeeName() string { - return d.EmployeeName -} - -func (d DemoPodStatus) GetEmployeeStatuses() interface{} { - return d.EmployeeStatuses -} - -func (d DemoPodStatus) EmployeeEqual(employeeStatus IEmployee) (bool, error) { - if d.EmployeeName != employeeStatus.GetEmployeeName() { - return false, nil - } - - podEmployeeStatuses, ok := employeeStatus.GetEmployeeStatuses().(PodEmployeeStatuses) - if !ok { - return false, fmt.Errorf("employee to diff is not Pod Employee status") - } - - if d.EmployeeStatuses.Ip != podEmployeeStatuses.Ip || d.EmployeeStatuses.LifecycleReady != podEmployeeStatuses.LifecycleReady || - d.EmployeeStatuses.Ipv6 != podEmployeeStatuses.Ipv6 { - return false, nil - } - - return reflect.DeepEqual(d.EmployeeStatuses.ExtraStatus, podEmployeeStatuses.ExtraStatus), nil -} - -type PodExtraStatus struct { - TrafficOn bool - TrafficWeight int -} - -var demoResourceVipStatusInProvider sync.Map -var demoResourceRsStatusInProvider sync.Map - -type DemoResourceProviderClient struct { - mock.Mock -} - -type DemoResourceVipOps struct { - VipStatuses []DemoServiceStatus - MockData bool -} - -type DemoResourceRsOps struct { - RsStatuses []DemoPodStatus - MockData bool -} - -func (d *DemoResourceProviderClient) CreateVip(req *DemoResourceVipOps) (*DemoResourceVipOps, error) { - args := d.Called(req) - if !args.Get(0).(*DemoResourceVipOps).MockData { - for _, vipStatus := range req.VipStatuses { - demoResourceVipStatusInProvider.Store(vipStatus.EmployerId, vipStatus.EmployerStatuses) - } - } - return args.Get(0).(*DemoResourceVipOps), args.Error(1) -} - -func (d *DemoResourceProviderClient) UpdateVip(req *DemoResourceVipOps) (*DemoResourceVipOps, error) { - args := d.Called(req) - if !args.Get(0).(*DemoResourceVipOps).MockData { - for _, vipStatus := range req.VipStatuses { - demoResourceVipStatusInProvider.Store(vipStatus.EmployerId, vipStatus.EmployerStatuses) - } - } - return args.Get(0).(*DemoResourceVipOps), args.Error(1) -} - -func (d *DemoResourceProviderClient) DeleteVip(req *DemoResourceVipOps) (*DemoResourceVipOps, error) { - args := d.Called(req) - if !args.Get(0).(*DemoResourceVipOps).MockData { - for _, vipStatus := range req.VipStatuses { - demoResourceVipStatusInProvider.Delete(vipStatus.EmployerId) - } - } - return args.Get(0).(*DemoResourceVipOps), args.Error(1) -} - -func (d *DemoResourceProviderClient) QueryVip(req *DemoResourceVipOps) (*DemoResourceVipOps, error) { - args := d.Called(req) - if !args.Get(0).(*DemoResourceVipOps).MockData { - vipStatuses := make([]DemoServiceStatus, 0) - demoResourceVipStatusInProvider.Range(func(key, value any) bool { - vipStatuses = append(vipStatuses, DemoServiceStatus{ - EmployerId: key.(string), - EmployerStatuses: value.(DemoServiceDetails), - }) - return true - }) - return &DemoResourceVipOps{ - VipStatuses: vipStatuses, - }, args.Error(1) - } - return args.Get(0).(*DemoResourceVipOps), args.Error(1) -} - -func (d *DemoResourceProviderClient) CreateRealServer(req *DemoResourceRsOps) (*DemoResourceRsOps, error) { - args := d.Called(req) - if !args.Get(0).(*DemoResourceRsOps).MockData { - for _, employeeStatus := range req.RsStatuses { - demoResourceRsStatusInProvider.Store(employeeStatus.GetEmployeeId(), employeeStatus) - } - } - return args.Get(0).(*DemoResourceRsOps), args.Error(1) -} - -func (d *DemoResourceProviderClient) UpdateRealServer(req *DemoResourceRsOps) (*DemoResourceRsOps, error) { - args := d.Called(req) - if !args.Get(0).(*DemoResourceRsOps).MockData { - for _, employeeStatus := range req.RsStatuses { - demoResourceRsStatusInProvider.Store(employeeStatus.GetEmployeeId(), employeeStatus) - } - } - return args.Get(0).(*DemoResourceRsOps), args.Error(1) -} - -func (d *DemoResourceProviderClient) DeleteRealServer(req *DemoResourceRsOps) (*DemoResourceRsOps, error) { - args := d.Called(req) - if !args.Get(0).(*DemoResourceRsOps).MockData { - for _, employeeStatus := range req.RsStatuses { - demoResourceRsStatusInProvider.Delete(employeeStatus.GetEmployeeId()) - } - } - return args.Get(0).(*DemoResourceRsOps), args.Error(1) -} - -func (d *DemoResourceProviderClient) QueryRealServer(req *DemoResourceRsOps) (*DemoResourceRsOps, error) { - args := d.Called(req) - if !args.Get(0).(*DemoResourceRsOps).MockData { - rsStatuses := make([]DemoPodStatus, 0) - demoResourceRsStatusInProvider.Range(func(key, value any) bool { - rsStatuses = append(rsStatuses, value.(DemoPodStatus)) - return true - }) - return &DemoResourceRsOps{ - RsStatuses: rsStatuses, - }, args.Error(1) - } - return args.Get(0).(*DemoResourceRsOps), args.Error(1) -} diff --git a/pkg/controllers/resourceconsist/resourceconsist_controller_test.go b/pkg/controllers/resourceconsist/resourceconsist_controller_test.go deleted file mode 100644 index 74005b70..00000000 --- a/pkg/controllers/resourceconsist/resourceconsist_controller_test.go +++ /dev/null @@ -1,949 +0,0 @@ -/* -Copyright 2023 The KusionStack Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resourceconsist - -import ( - "context" - "fmt" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes" - "os" - "path/filepath" - "strings" - "testing" - "time" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/stretchr/testify/mock" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - "sigs.k8s.io/controller-runtime/pkg/manager" - - "kusionstack.io/operating/apis" - "kusionstack.io/operating/apis/apps/v1alpha1" - "kusionstack.io/operating/pkg/utils/inject" -) - -var ( - env *envtest.Environment - mgr manager.Manager - clientSet *kubernetes.Clientset - - ctx context.Context - cancel context.CancelFunc - - rc = &DemoResourceProviderClient{} -) - -var _ = Describe("resource-consist-controller", func() { - - Context("employer synced", func() { - svc0 := corev1.Service{ - ObjectMeta: v1.ObjectMeta{ - Name: "resource-consist-ut-svc", - Namespace: "default", - Labels: map[string]string{ - v1alpha1.ControlledByKusionStackLabelKey: "true", - }, - }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "tcp-80", - Port: 80, - Protocol: corev1.ProtocolTCP, - }, - }, - Selector: map[string]string{ - "resource-consist-ut": "resource-consist-ut", - }, - }, - } - - It("clean finalizer added if svc0 not deleting", func() { - err := mgr.GetClient().Create(context.Background(), &svc0) - Expect(err).NotTo(HaveOccurred()) - Eventually(func() bool { - svcTmp := corev1.Service{} - err = mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: svc0.Name, - Namespace: svc0.Namespace, - }, &svcTmp) - if err != nil { - return false - } - for _, flz := range svcTmp.GetFinalizers() { - if flz == cleanFinalizerPrefix+svc0.GetName() { - return true - } - } - return false - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - - rc.On("QueryVip", mock.Anything).Return(&DemoResourceVipOps{}, nil) - rc.On("CreateVip", mock.Anything).Return(&DemoResourceVipOps{}, nil) - rc.On("UpdateVip", mock.Anything).Return(&DemoResourceVipOps{}, nil) - rc.On("DeleteVip", mock.Anything).Return(&DemoResourceVipOps{}, nil) - It("employer created", func() { - Eventually(func() bool { - details, exist := demoResourceVipStatusInProvider.Load(svc0.Name) - return exist && details.(DemoServiceDetails).RemoteVIP == "demo-remote-VIP" && details.(DemoServiceDetails).RemoteVIPQPS == 100 - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - - It("employer updated", func() { - demoResourceVipStatusInProvider.Store(svc0.Name, DemoServiceDetails{ - RemoteVIP: "demo-remote-VIP", - RemoteVIPQPS: 200, - }) - - // trigger reconcile - svcTmp := corev1.Service{} - Expect(mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: svc0.Name, - Namespace: svc0.Namespace, - }, &svcTmp)).Should(BeNil()) - if svcTmp.Labels == nil { - svcTmp.Labels = make(map[string]string) - } - svcTmp.Labels["demo-controller-trigger-reconcile"] = fmt.Sprintf("%d", time.Now().Unix()) - Expect(mgr.GetClient().Update(context.TODO(), &svcTmp)).Should(BeNil()) - - Eventually(func() bool { - details, exist := demoResourceVipStatusInProvider.Load(svc0.Name) - return exist && details.(DemoServiceDetails).RemoteVIP == "demo-remote-VIP" && details.(DemoServiceDetails).RemoteVIPQPS == 100 - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - - It("employer deleted", func() { - Eventually(func() bool { - svcTmp := corev1.Service{} - Expect(mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: svc0.Name, - Namespace: svc0.Namespace, - }, &svcTmp)).Should(BeNil()) - flzs := svcTmp.GetFinalizers() - flzs = append(flzs, "kusionstack.io/ut-block-finalizer") - svcTmp.SetFinalizers(flzs) - return mgr.GetClient().Update(context.TODO(), &svcTmp) == nil - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Expect(mgr.GetClient().Delete(context.TODO(), &svc0)).Should(BeNil()) - Eventually(func() bool { - svcTmp := corev1.Service{} - Expect(mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: svc0.Name, - Namespace: svc0.Namespace, - }, &svcTmp)).Should(BeNil()) - return !svcTmp.GetDeletionTimestamp().IsZero() - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - Eventually(func() bool { - _, exist := demoResourceVipStatusInProvider.Load(svc0.Name) - return !exist - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - svcTmp := corev1.Service{} - Expect(mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: svc0.Name, - Namespace: svc0.Namespace, - }, &svcTmp)).Should(BeNil()) - var flzs []string - for _, flz := range svcTmp.GetFinalizers() { - if flz == "kusionstack.io/ut-block-finalizer" { - continue - } - flzs = append(flzs, flz) - } - svcTmp.SetFinalizers(flzs) - return mgr.GetClient().Update(context.TODO(), &svcTmp) == nil - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - svcTmp := corev1.Service{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: svc0.Name, - Namespace: svc0.Namespace, - }, &svcTmp) - return errors.IsNotFound(err) - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - }) - - Context("employee synced", func() { - rc.On("QueryRealServer", mock.Anything).Return(&DemoResourceRsOps{}, nil) - rc.On("CreateRealServer", mock.Anything).Return(&DemoResourceRsOps{}, nil) - rc.On("UpdateRealServer", mock.Anything).Return(&DemoResourceRsOps{}, nil) - rc.On("DeleteRealServer", mock.Anything).Return(&DemoResourceRsOps{}, nil) - - svc1 := corev1.Service{ - ObjectMeta: v1.ObjectMeta{ - Name: "resource-consist-ut-svc-1", - Namespace: "default", - Labels: map[string]string{ - v1alpha1.ControlledByKusionStackLabelKey: "true", - }, - }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "tcp-80", - Port: 80, - Protocol: corev1.ProtocolTCP, - }, - }, - Selector: map[string]string{ - "resource-consist-ut": "resource-consist-ut-1", - }, - }, - } - - pod := corev1.Pod{ - ObjectMeta: v1.ObjectMeta{ - Name: "resource-consist-ut-pod", - Namespace: "default", - Labels: map[string]string{ - v1alpha1.ControlledByKusionStackLabelKey: "true", - "resource-consist-ut": "resource-consist-ut-1", - }, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "nginx", - Image: "nginx:latest", - }, - }, - ReadinessGates: []corev1.PodReadinessGate{ - { - ConditionType: v1alpha1.ReadinessGatePodServiceReady, - }, - }, - }, - } - - It("employee synced, employer created", func() { - Expect(mgr.GetClient().Create(context.Background(), &svc1)).Should(BeNil()) - Eventually(func() bool { - details, exist := demoResourceVipStatusInProvider.Load(svc1.Name) - return exist && details.(DemoServiceDetails).RemoteVIP == "demo-remote-VIP" && details.(DemoServiceDetails).RemoteVIPQPS == 100 - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - - It("employee synced, employees created", func() { - Expect(mgr.GetClient().Create(context.TODO(), &pod)).Should(BeNil()) - Eventually(func() bool { - podTmp := corev1.Pod{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod.Name, - Namespace: pod.Namespace, - }, &podTmp) - if err != nil { - return false - } - podTmp.Status = corev1.PodStatus{ - PodIP: "1.2.3.4", - Conditions: []corev1.PodCondition{ - { - Type: corev1.PodReady, - Status: corev1.ConditionTrue, - }, - { - Type: v1alpha1.ReadinessGatePodServiceReady, - Status: corev1.ConditionTrue, - }, - }, - } - return mgr.GetClient().Status().Update(context.TODO(), &podTmp) == nil - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - details, exist := demoResourceRsStatusInProvider.Load(pod.Name) - return exist && details.(DemoPodStatus).GetEmployeeName() == pod.Name && - details.(DemoPodStatus).GetEmployeeStatuses().(PodEmployeeStatuses).ExtraStatus.(PodExtraStatus).TrafficWeight == 100 && - details.(DemoPodStatus).GetEmployeeStatuses().(PodEmployeeStatuses).ExtraStatus.(PodExtraStatus).TrafficOn == true - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - podTmp := corev1.Pod{} - _ = mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod.Name, - Namespace: pod.Namespace, - }, &podTmp) - containsLifecycleFlz := false - for _, flz := range podTmp.GetFinalizers() { - if flz == GenerateLifecycleFinalizer(svc1.Name) { - containsLifecycleFlz = true - break - } - } - return containsLifecycleFlz - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - svcTmp := corev1.Service{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: svc1.Name, - Namespace: svc1.Namespace, - }, &svcTmp) - if err != nil { - return false - } - return svcTmp.GetAnnotations()[expectedFinalizerAddedAnnoKey] == pod.Name - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - - It("employee synced, employees updated", func() { - Eventually(func() bool { - podTmp := corev1.Pod{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod.Name, - Namespace: pod.Namespace, - }, &podTmp) - if err != nil { - return false - } - podTmp.Status.Conditions = []corev1.PodCondition{ - { - Type: corev1.PodReady, - Status: corev1.ConditionTrue, - }, - { - Type: v1alpha1.ReadinessGatePodServiceReady, - Status: corev1.ConditionFalse, - }, - } - return mgr.GetClient().Status().Update(context.TODO(), &podTmp) == nil - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - details, exist := demoResourceRsStatusInProvider.Load(pod.Name) - return exist && details.(DemoPodStatus).GetEmployeeName() == pod.Name && - details.(DemoPodStatus).GetEmployeeStatuses().(PodEmployeeStatuses).ExtraStatus.(PodExtraStatus).TrafficWeight == 0 && - details.(DemoPodStatus).GetEmployeeStatuses().(PodEmployeeStatuses).ExtraStatus.(PodExtraStatus).TrafficOn == false - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - podTmp := corev1.Pod{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod.Name, - Namespace: pod.Namespace, - }, &podTmp) - if err != nil { - return false - } - podTmp.Status.Conditions = []corev1.PodCondition{ - { - Type: corev1.PodReady, - Status: corev1.ConditionTrue, - }, - { - Type: v1alpha1.ReadinessGatePodServiceReady, - Status: corev1.ConditionTrue, - }, - } - return mgr.GetClient().Status().Update(context.TODO(), &podTmp) == nil - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - details, exist := demoResourceRsStatusInProvider.Load(pod.Name) - return exist && details.(DemoPodStatus).GetEmployeeName() == pod.Name && - details.(DemoPodStatus).GetEmployeeStatuses().(PodEmployeeStatuses).ExtraStatus.(PodExtraStatus).TrafficWeight == 100 && - details.(DemoPodStatus).GetEmployeeStatuses().(PodEmployeeStatuses).ExtraStatus.(PodExtraStatus).TrafficOn == true - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - - It("employee synced, employees deleted", func() { - podTmp := corev1.Pod{} - Expect(mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod.Name, - Namespace: pod.Namespace, - }, &podTmp)).Should(BeNil()) - - Expect(mgr.GetClient().Delete(context.TODO(), &podTmp)).Should(BeNil()) - - Eventually(func() bool { - podTmp := corev1.Pod{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod.Name, - Namespace: pod.Namespace, - }, &podTmp) - return errors.IsNotFound(err) - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - _, exist := demoResourceRsStatusInProvider.Load(pod.Name) - return !exist - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Expect(mgr.GetClient().Delete(context.TODO(), &svc1)).Should(BeNil()) - - Eventually(func() bool { - svcTmp := corev1.Service{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: svc1.Name, - Namespace: svc1.Namespace, - }, &svcTmp) - return errors.IsNotFound(err) - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - _, exist := demoResourceVipStatusInProvider.Load(svc1.Name) - return !exist - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - }) - - Context("cases with unexpected err", func() { - svc2 := corev1.Service{ - ObjectMeta: v1.ObjectMeta{ - Name: "resource-consist-ut-svc-2", - Namespace: "default", - Labels: map[string]string{ - v1alpha1.ControlledByKusionStackLabelKey: "true", - }, - }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "tcp-80", - Port: 80, - Protocol: corev1.ProtocolTCP, - }, - }, - Selector: map[string]string{ - "resource-consist-ut": "resource-consist-ut-2", - }, - }, - } - - pod2 := corev1.Pod{ - ObjectMeta: v1.ObjectMeta{ - Name: "resource-consist-ut-pod", - Namespace: "default", - Labels: map[string]string{ - v1alpha1.ControlledByKusionStackLabelKey: "true", - "resource-consist-ut": "resource-consist-ut-2", - }, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "nginx", - Image: "nginx:latest", - }, - }, - ReadinessGates: []corev1.PodReadinessGate{ - { - ConditionType: v1alpha1.ReadinessGatePodServiceReady, - }, - }, - }, - } - - It("create vip resp failed, but actually created in backend provider", func() { - rc.ExpectedCalls = nil - rc.On("CreateVip", mock.Anything).Return(&DemoResourceVipOps{ - MockData: true, - }, fmt.Errorf("fake err")) - rc.On("QueryVip", mock.Anything).Return(&DemoResourceVipOps{}, nil) - rc.On("QueryRealServer", mock.Anything).Return(&DemoResourceRsOps{}, nil) - - Expect(mgr.GetClient().Create(context.Background(), &svc2)).Should(BeNil()) - - Eventually(func() bool { - events, err := clientSet.CoreV1().Events("default").List(context.TODO(), v1.ListOptions{ - FieldSelector: "involvedObject.name=resource-consist-ut-svc-2", - TypeMeta: v1.TypeMeta{Kind: "Service"}}) - if err != nil { - return false - } - for _, evt := range events.Items { - if evt.Reason == "syncEmployerFailed" && - evt.Message == "sync employer status failed: syncCreate failed, err: fake err" { - return true - } - } - return false - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - demoResourceVipStatusInProvider.Store(svc2.Name, DemoServiceDetails{ - RemoteVIP: "demo-remote-VIP", - RemoteVIPQPS: 100, - }) - - Eventually(func() bool { - events, err := clientSet.CoreV1().Events("default").List(context.TODO(), v1.ListOptions{ - FieldSelector: "involvedObject.name=resource-consist-ut-svc-2", - TypeMeta: v1.TypeMeta{Kind: "Service"}}) - if err != nil { - return false - } - for _, evt := range events.Items { - if evt.Reason == "ReconcileSucceed" && evt.Message == "" { - return true - } - } - return false - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - details, exist := demoResourceVipStatusInProvider.Load(svc2.Name) - return exist && details.(DemoServiceDetails).RemoteVIP == "demo-remote-VIP" && details.(DemoServiceDetails).RemoteVIPQPS == 100 - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - - It("create rs resp failed, but actually created in backend provider", func() { - rc.On("CreateRealServer", mock.Anything).Return(&DemoResourceRsOps{ - MockData: true, - }, fmt.Errorf("fake err")) - - Expect(mgr.GetClient().Create(context.Background(), &pod2)).Should(BeNil()) - - Eventually(func() bool { - events, err := clientSet.CoreV1().Events("default").List(context.TODO(), v1.ListOptions{ - FieldSelector: "involvedObject.name=resource-consist-ut-svc-2", - TypeMeta: v1.TypeMeta{Kind: "Service"}}) - if err != nil { - return false - } - for _, evt := range events.Items { - if evt.Reason == "syncEmployeesFailed" && - evt.Message == "sync employees status failed: syncCreate failed, err: fake err" { - return true - } - } - return false - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - demoResourceRsStatusInProvider.Store(pod2.Name, DemoPodStatus{ - EmployeeId: pod2.Name, - EmployeeName: pod2.Name, - EmployeeStatuses: PodEmployeeStatuses{ - Ip: "", - Ipv6: "", - LifecycleReady: false, - ExtraStatus: PodExtraStatus{ - TrafficOn: false, - TrafficWeight: 0, - }, - }, - }) - - Eventually(func() bool { - events, err := clientSet.CoreV1().Events("default").List(context.TODO(), v1.ListOptions{ - FieldSelector: "involvedObject.name=resource-consist-ut-svc-2", - TypeMeta: v1.TypeMeta{Kind: "Service"}}) - if err != nil { - return false - } - for _, evt := range events.Items { - if evt.Reason == "ReconcileSucceed" && evt.Message == "" { - return true - } - } - return false - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - details, exist := demoResourceRsStatusInProvider.Load(pod2.Name) - return exist && details.(DemoPodStatus).GetEmployeeName() == pod2.Name && - details.(DemoPodStatus).GetEmployeeStatuses().(PodEmployeeStatuses).ExtraStatus.(PodExtraStatus).TrafficWeight == 0 && - details.(DemoPodStatus).GetEmployeeStatuses().(PodEmployeeStatuses).ExtraStatus.(PodExtraStatus).TrafficOn == false - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - - It("delete vip & rs", func() { - rc.ExpectedCalls = nil - rc.On("QueryVip", mock.Anything).Return(&DemoResourceVipOps{}, nil) - rc.On("DeleteVip", mock.Anything).Return(&DemoResourceVipOps{}, nil) - rc.On("QueryRealServer", mock.Anything).Return(&DemoResourceRsOps{}, nil) - rc.On("DeleteRealServer", mock.Anything).Return(&DemoResourceRsOps{}, nil) - - Expect(mgr.GetClient().Delete(context.TODO(), &svc2)).Should(BeNil()) - - Eventually(func() bool { - _, exist := demoResourceVipStatusInProvider.Load(svc2.Name) - return !exist - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - _, exist := demoResourceRsStatusInProvider.Load(pod2.Name) - return !exist - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - service1 := corev1.Service{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: svc2.Name, - Namespace: svc2.Namespace, - }, &service1) - return errors.IsNotFound(err) - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Expect(mgr.GetClient().Delete(context.TODO(), &pod2)).Should(BeNil()) - - Eventually(func() bool { - pod22 := corev1.Pod{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod2.Name, - Namespace: pod2.Namespace, - }, &pod22) - return errors.IsNotFound(err) - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - }) - - Context("label/selector change", func() { - svc3 := corev1.Service{ - ObjectMeta: v1.ObjectMeta{ - Name: "resource-consist-ut-svc-3", - Namespace: "default", - Labels: map[string]string{ - v1alpha1.ControlledByKusionStackLabelKey: "true", - }, - }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "tcp-80", - Port: 80, - Protocol: corev1.ProtocolTCP, - }, - }, - Selector: map[string]string{ - "resource-consist-ut": "resource-consist-ut-3", - }, - }, - } - - pod3 := corev1.Pod{ - ObjectMeta: v1.ObjectMeta{ - Name: "resource-consist-ut-pod", - Namespace: "default", - Labels: map[string]string{ - v1alpha1.ControlledByKusionStackLabelKey: "true", - "resource-consist-ut": "resource-consist-ut-3", - }, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "nginx", - Image: "nginx:latest", - }, - }, - ReadinessGates: []corev1.PodReadinessGate{ - { - ConditionType: v1alpha1.ReadinessGatePodServiceReady, - }, - }, - }, - } - - It("employee synced, employer created", func() { - rc.ExpectedCalls = nil - rc.On("QueryVip", mock.Anything).Return(&DemoResourceVipOps{}, nil) - rc.On("CreateVip", mock.Anything).Return(&DemoResourceVipOps{}, nil) - rc.On("UpdateVip", mock.Anything).Return(&DemoResourceVipOps{}, nil) - rc.On("DeleteVip", mock.Anything).Return(&DemoResourceVipOps{}, nil) - rc.On("QueryRealServer", mock.Anything).Return(&DemoResourceRsOps{}, nil) - rc.On("CreateRealServer", mock.Anything).Return(&DemoResourceRsOps{}, nil) - rc.On("UpdateRealServer", mock.Anything).Return(&DemoResourceRsOps{}, nil) - rc.On("DeleteRealServer", mock.Anything).Return(&DemoResourceRsOps{}, nil) - - Expect(mgr.GetClient().Create(context.Background(), &svc3)).Should(BeNil()) - Eventually(func() bool { - details, exist := demoResourceVipStatusInProvider.Load(svc3.Name) - return exist && details.(DemoServiceDetails).RemoteVIP == "demo-remote-VIP" && details.(DemoServiceDetails).RemoteVIPQPS == 100 - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - - It("employee synced, employees created", func() { - Expect(mgr.GetClient().Create(context.TODO(), &pod3)).Should(BeNil()) - Eventually(func() bool { - podTmp := corev1.Pod{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod3.Name, - Namespace: pod3.Namespace, - }, &podTmp) - if err != nil { - return false - } - podTmp.Status = corev1.PodStatus{ - PodIP: "1.2.3.4", - Conditions: []corev1.PodCondition{ - { - Type: corev1.PodReady, - Status: corev1.ConditionTrue, - }, - { - Type: v1alpha1.ReadinessGatePodServiceReady, - Status: corev1.ConditionTrue, - }, - }, - } - return mgr.GetClient().Status().Update(context.TODO(), &podTmp) == nil - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - details, exist := demoResourceRsStatusInProvider.Load(pod3.Name) - return exist && details.(DemoPodStatus).GetEmployeeName() == pod3.Name && - details.(DemoPodStatus).GetEmployeeStatuses().(PodEmployeeStatuses).ExtraStatus.(PodExtraStatus).TrafficWeight == 100 && - details.(DemoPodStatus).GetEmployeeStatuses().(PodEmployeeStatuses).ExtraStatus.(PodExtraStatus).TrafficOn == true - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - podTmp := corev1.Pod{} - _ = mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod3.Name, - Namespace: pod3.Namespace, - }, &podTmp) - containsLifecycleFlz := false - for _, flz := range podTmp.GetFinalizers() { - if flz == GenerateLifecycleFinalizer(svc3.Name) { - containsLifecycleFlz = true - break - } - } - return containsLifecycleFlz - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - svcTmp := corev1.Service{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: svc3.Name, - Namespace: svc3.Namespace, - }, &svcTmp) - if err != nil { - return false - } - return svcTmp.GetAnnotations()[expectedFinalizerAddedAnnoKey] == pod3.Name - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - - It("label/selector change and resources in backend provider might changed by others", func() { - // make pod not selected, resource in backend provider not changed by others - podTmp := corev1.Pod{} - Expect(mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod3.Name, - Namespace: pod3.Namespace, - }, &podTmp)).Should(BeNil()) - podTmp.Labels["resource-consist-ut"] = "not-selected" - Expect(mgr.GetClient().Update(context.TODO(), &podTmp)).Should(BeNil()) - - Eventually(func() bool { - podTmp := corev1.Pod{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod3.Name, - Namespace: pod3.Namespace, - }, &podTmp) - if err != nil { - return false - } - - lifecycleFlzExist := false - for _, flz := range podTmp.Finalizers { - if flz == GenerateLifecycleFinalizer(svc3.Name) { - lifecycleFlzExist = true - break - } - } - - _, pod3RsExist := demoResourceRsStatusInProvider.Load(pod3.Name) - return !strings.Contains(podTmp.GetAnnotations()[v1alpha1.PodAvailableConditionsAnnotation], - "Service/default/resource-consist-ut-svc-3") && !lifecycleFlzExist && !pod3RsExist - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - // make demo controller need record employees - needRecordEmployees = true - // make pod selected again - Expect(mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod3.Name, - Namespace: pod3.Namespace, - }, &podTmp)).Should(BeNil()) - podTmp.Labels["resource-consist-ut"] = "resource-consist-ut-3" - Expect(mgr.GetClient().Update(context.TODO(), &podTmp)).Should(BeNil()) - - Eventually(func() bool { - podTmp := corev1.Pod{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod3.Name, - Namespace: pod3.Namespace, - }, &podTmp) - if err != nil { - return false - } - - lifecycleFlzExist := false - for _, flz := range podTmp.Finalizers { - if flz == GenerateLifecycleFinalizer(svc3.Name) { - lifecycleFlzExist = true - break - } - } - - _, pod3RsExist := demoResourceRsStatusInProvider.Load(pod3.Name) - return strings.Contains(podTmp.GetAnnotations()[v1alpha1.PodAvailableConditionsAnnotation], - "Service/default/resource-consist-ut-svc-3") && lifecycleFlzExist && pod3RsExist - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - // delete pod3 rs - demoResourceRsStatusInProvider.Delete(pod3.Name) - // make pod not selected - Expect(mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod3.Name, - Namespace: pod3.Namespace, - }, &podTmp)).Should(BeNil()) - podTmp.Labels["resource-consist-ut"] = "not-selected" - Expect(mgr.GetClient().Update(context.TODO(), &podTmp)).Should(BeNil()) - - Eventually(func() bool { - podTmp := corev1.Pod{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod3.Name, - Namespace: pod3.Namespace, - }, &podTmp) - if err != nil { - return false - } - - lifecycleFlzExist := false - for _, flz := range podTmp.Finalizers { - if flz == GenerateLifecycleFinalizer(svc3.Name) { - lifecycleFlzExist = true - break - } - } - - _, pod3RsExist := demoResourceRsStatusInProvider.Load(pod3.Name) - - svcTmp := corev1.Service{} - err = mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: svc3.Name, - Namespace: svc3.Namespace, - }, &svcTmp) - if err != nil { - return false - } - - return !strings.Contains(podTmp.GetAnnotations()[v1alpha1.PodAvailableConditionsAnnotation], - "Service/default/resource-consist-ut-svc-3") && !lifecycleFlzExist && !pod3RsExist && - !strings.Contains(svcTmp.GetAnnotations()[lifecycleFinalizerRecordedAnnoKey], pod3.Name) - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - - It("employee synced, employees deleted", func() { - podTmp := corev1.Pod{} - Expect(mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod3.Name, - Namespace: pod3.Namespace, - }, &podTmp)).Should(BeNil()) - - Expect(mgr.GetClient().Delete(context.TODO(), &podTmp)).Should(BeNil()) - - Eventually(func() bool { - podTmp := corev1.Pod{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: pod3.Name, - Namespace: pod3.Namespace, - }, &podTmp) - return errors.IsNotFound(err) - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - _, exist := demoResourceRsStatusInProvider.Load(pod3.Name) - return !exist - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Expect(mgr.GetClient().Delete(context.TODO(), &svc3)).Should(BeNil()) - - Eventually(func() bool { - svcTmp := corev1.Service{} - err := mgr.GetClient().Get(context.TODO(), types.NamespacedName{ - Name: svc3.Name, - Namespace: svc3.Namespace, - }, &svcTmp) - return errors.IsNotFound(err) - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - - Eventually(func() bool { - _, exist := demoResourceVipStatusInProvider.Load(svc3.Name) - return !exist - }, 3*time.Second, 100*time.Millisecond).Should(BeTrue()) - }) - - }) -}) - -var _ = BeforeSuite(func() { - By("bootstrapping test environment") - - ctx, cancel = context.WithCancel(context.TODO()) - logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - - env = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, - } - - config, err := env.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(config).NotTo(BeNil()) - - clientSet, _ = kubernetes.NewForConfig(config) - - mgr, err = manager.New(config, manager.Options{ - MetricsBindAddress: "0", - NewCache: inject.NewCacheWithFieldIndex, - }) - Expect(err).NotTo(HaveOccurred()) - - scheme := mgr.GetScheme() - err = appsv1.SchemeBuilder.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - err = apis.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - err = AddToMgr(mgr, NewDemoReconcileAdapter(mgr.GetClient(), rc)) - Expect(err).NotTo(HaveOccurred()) - - go func() { - err = mgr.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - - cancel() - - err := env.Stop() - Expect(err).NotTo(HaveOccurred()) -}) - -func TestResourceConsistController(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "resource consist controller test") -} diff --git a/pkg/controllers/resourceconsist/types.go b/pkg/controllers/resourceconsist/types.go deleted file mode 100644 index 00c53ece..00000000 --- a/pkg/controllers/resourceconsist/types.go +++ /dev/null @@ -1,124 +0,0 @@ -/* -Copyright 2023 The KusionStack Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resourceconsist - -import ( - "context" - - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/predicate" - "sigs.k8s.io/controller-runtime/pkg/ratelimiter" -) - -// ReconcileOptions includes max concurrent reconciles and rate limiter, -// max concurrent reconcile: 5 and DefaultControllerRateLimiter() will be used if ReconcileOptions not implemented. -type ReconcileOptions interface { - GetRateLimiter() ratelimiter.RateLimiter - GetMaxConcurrentReconciles() int -} - -// ReconcileWatchOptions defines what employer and employee is and how controller watch -// default employer: Service, default employee: Pod -// Recommend: -// implement ReconcileWatchOptions if Employer resource might be reconciled by other controller, -// different Predicates make an employer won't be reconciled by more than one controller so that LifecycleFinalizer won't -// be solved incorrectly. -type ReconcileWatchOptions interface { - NewEmployer() client.Object - NewEmployee() client.Object - EmployerEventHandler() handler.EventHandler - EmployeeEventHandler() handler.EventHandler - EmployerPredicates() predicate.Funcs - EmployeePredicates() predicate.Funcs -} - -// ReconcileLifecycleOptions defines whether PodOpsLifecycle followed and -// whether employees' LifecycleFinalizer conditions need to be Record/Erase to employer's anno -// actually NeedRecordEmployees only needed for those adapters that follow PodOpsLifecycle, -// in the case of employment relationship might change and resources in backend provider might be changed by others. -// if not implemented, the two options would be FollowPodOpsLifeCycle: true and NeedRecordEmployees: false -type ReconcileLifecycleOptions interface { - FollowPodOpsLifeCycle() bool - NeedRecordEmployees() bool -} - -// ReconcileAdapter is the interface that customized controllers should implement. -type ReconcileAdapter interface { - GetControllerName() string - - GetSelectedEmployeeNames(ctx context.Context, employer client.Object) ([]string, error) - - // GetExpectedEmployer and GetCurrentEmployer return expect/current status of employer from related backend provider - GetExpectedEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) - GetCurrentEmployer(ctx context.Context, employer client.Object) ([]IEmployer, error) - - // CreateEmployer/UpdateEmployer/DeleteEmployer handles creation/update/deletion of resources related to employer on related backend provider - CreateEmployer(ctx context.Context, employer client.Object, toCreates []IEmployer) ([]IEmployer, []IEmployer, error) - UpdateEmployer(ctx context.Context, employer client.Object, toUpdates []IEmployer) ([]IEmployer, []IEmployer, error) - DeleteEmployer(ctx context.Context, employer client.Object, toDeletes []IEmployer) ([]IEmployer, []IEmployer, error) - - // GetExpectedEmployee and GetCurrentEmployee return expect/current status of employees from related backend provider - GetExpectedEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) - GetCurrentEmployee(ctx context.Context, employer client.Object) ([]IEmployee, error) - - // CreateEmployees/UpdateEmployees/DeleteEmployees handles creation/update/deletion of resources related to employee on related backend provider - CreateEmployees(ctx context.Context, employer client.Object, toCreates []IEmployee) ([]IEmployee, []IEmployee, error) - UpdateEmployees(ctx context.Context, employer client.Object, toUpdates []IEmployee) ([]IEmployee, []IEmployee, error) - DeleteEmployees(ctx context.Context, employer client.Object, toDeletes []IEmployee) ([]IEmployee, []IEmployee, error) -} - -type IEmployer interface { - GetEmployerId() string - GetEmployerStatuses() interface{} - EmployerEqual(employer IEmployer) (bool, error) -} - -type IEmployee interface { - GetEmployeeId() string - GetEmployeeName() string - GetEmployeeStatuses() interface{} - EmployeeEqual(employee IEmployee) (bool, error) -} - -type ToCUDEmployer struct { - ToCreate []IEmployer - ToUpdate []IEmployer - ToDelete []IEmployer - Unchanged []IEmployer -} - -type ToCUDEmployees struct { - ToCreate []IEmployee - ToUpdate []IEmployee - ToDelete []IEmployee - Unchanged []IEmployee -} - -type PodEmployeeStatuses struct { - // can be set by calling SetCommonPodEmployeeStatus - Ip string `json:"ip,omitempty"` - Ipv6 string `json:"ipv6,omitempty"` - LifecycleReady bool `json:"lifecycleReady,omitempty"` - // extra info related to backend provider - ExtraStatus interface{} `json:"extraStatus,omitempty"` -} - -type PodExpectedFinalizerOps struct { - Name string - Succeed bool -} diff --git a/pkg/controllers/resourceconsist/utils.go b/pkg/controllers/resourceconsist/utils.go deleted file mode 100644 index 132df5fc..00000000 --- a/pkg/controllers/resourceconsist/utils.go +++ /dev/null @@ -1,104 +0,0 @@ -/* -Copyright 2023 The KusionStack Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resourceconsist - -import ( - "crypto/md5" - "encoding/hex" - "errors" - "fmt" - "net" - "strings" - - corev1 "k8s.io/api/core/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - - "kusionstack.io/operating/apis/apps/v1alpha1" -) - -func isPod(obj client.Object) bool { - _, ok := obj.(*corev1.Pod) - return ok -} - -// isPodLifecycleReady check both ReadinessGatePodServiceReady and PodReady to avoid effects that PodReady not set to false -// even ReadinessGatePodServiceReady is false caused by evict machine -func isPodLifecycleReady(pod *corev1.Pod) bool { - if !pod.DeletionTimestamp.IsZero() { - return false - } - - podReady := false - readinessGateReady := true - var podReadyChecked, readinessGateReadyChecked bool - for _, condition := range pod.Status.Conditions { - if podReadyChecked && readinessGateReadyChecked { - break - } - if condition.Type == corev1.PodReady { - podReadyChecked = true - if condition.Status == corev1.ConditionTrue { - podReady = true - continue - } - break - } - if condition.Type == v1alpha1.ReadinessGatePodServiceReady { - readinessGateReadyChecked = true - if condition.Status != corev1.ConditionTrue { - readinessGateReady = false - break - } - } - } - return podReady && readinessGateReady -} - -func getPodIpv6Address(pod *corev1.Pod) string { - if pod == nil { - return "" - } - for _, ip := range pod.Status.PodIPs { - if net.ParseIP(ip.IP) != nil && strings.Contains(ip.IP, ":") { - return ip.IP - } - } - return "" -} - -// GetCommonPodEmployeeStatus called by ReconcileAdapter's GetExpectedEmployee/GetCurrentEmployee -func GetCommonPodEmployeeStatus(pod *corev1.Pod) (PodEmployeeStatuses, error) { - if pod == nil { - return PodEmployeeStatuses{}, errors.New("SetCommonPodEmployeeStatus failed, pod is nil") - } - - return PodEmployeeStatuses{ - Ip: pod.Status.PodIP, - Ipv6: getPodIpv6Address(pod), - LifecycleReady: isPodLifecycleReady(pod), - }, nil -} - -func GenerateLifecycleFinalizerKey(employer client.Object) string { - return fmt.Sprintf("%s/%s/%s", employer.GetObjectKind().GroupVersionKind().Kind, - employer.GetNamespace(), employer.GetName()) -} - -func GenerateLifecycleFinalizer(employerName string) string { - b := md5.Sum([]byte(employerName)) - return v1alpha1.PodOperationProtectionFinalizerPrefix + "/" + hex.EncodeToString(b[:])[8:24] -} diff --git a/pkg/controllers/alibabacloudslb/consts.go b/pkg/webhook/add_alibaba_cloud_slb.go similarity index 67% rename from pkg/controllers/alibabacloudslb/consts.go rename to pkg/webhook/add_alibaba_cloud_slb.go index 0ffa6f3d..ad63642f 100644 --- a/pkg/controllers/alibabacloudslb/consts.go +++ b/pkg/webhook/add_alibaba_cloud_slb.go @@ -14,6 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -package alibabacloudslb +package webhook -const alibabaCloudSlbLbIdLabelKey = "service.k8s.alibaba/loadbalancer-id" +import ( + "kusionstack.io/operating/pkg/webhook/alibaba_cloud_slb" +) + +func init() { + // AddToManagerFuncs is a list of functions to create webhook servers and add them to a manager. + AddToManagerFuncs = append(AddToManagerFuncs, alibaba_cloud_slb.Add) +} diff --git a/pkg/controllers/resourceconsist/consts.go b/pkg/webhook/alibaba_cloud_slb/alibaba_cloud_slb.go similarity index 61% rename from pkg/controllers/resourceconsist/consts.go rename to pkg/webhook/alibaba_cloud_slb/alibaba_cloud_slb.go index 8d341b96..a6459997 100644 --- a/pkg/controllers/resourceconsist/consts.go +++ b/pkg/webhook/alibaba_cloud_slb/alibaba_cloud_slb.go @@ -14,11 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -package resourceconsist +package alibaba_cloud_slb -const ( - defaultMaxConcurrentReconciles = 5 - expectedFinalizerAddedAnnoKey = "resource-consist.kusionstack.io/employees-expected-finalizer-added" - lifecycleFinalizerRecordedAnnoKey = "resource-consist.kusionstack.io/employees-lifecycle-finalizer-recorded" - cleanFinalizerPrefix = "resource-consist.kusionstack.io/clean-" +import ( + "sigs.k8s.io/controller-runtime/pkg/manager" + + "kusionstack.io/resourceconsist/pkg/adapters" ) + +func Add(mgr manager.Manager) error { + return adapters.AddBuiltinWebhookAdaptersToMgr(mgr, []adapters.AdapterName{adapters.AdapterAlibabaCloudSlb}) +} From 5bcd5df5afff76d3ad604c123964de0edd810aa9 Mon Sep 17 00:00:00 2001 From: WeichengWang Date: Fri, 3 Nov 2023 23:20:16 +0800 Subject: [PATCH 2/5] fix golint, replace github.com/go-logr/zapr version --- go.mod | 2 +- go.sum | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 0b34f299..b5dddfc4 100644 --- a/go.mod +++ b/go.mod @@ -99,8 +99,8 @@ require ( ) replace ( - github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.6.3 github.com/go-logr/logr => github.com/go-logr/logr v0.4.0 + github.com/go-logr/zapr => github.com/go-logr/zapr v0.4.0 github.com/onsi/gomega => github.com/onsi/gomega v1.15.0 k8s.io/api => k8s.io/api v0.22.6 k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.22.6 diff --git a/go.sum b/go.sum index a7f21d32..e0a60bea 100644 --- a/go.sum +++ b/go.sum @@ -242,9 +242,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/zapr v0.4.0 h1:uc1uML3hRYL9/ZZPdgHS/n8Nzo+eaYL/Efxkkamf7OM= github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= -github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= @@ -651,7 +650,6 @@ go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0H go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -660,7 +658,6 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -950,7 +947,6 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/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/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 13687941a79447aad009b721318fef3345d375cc Mon Sep 17 00:00:00 2001 From: WeichengWang Date: Fri, 3 Nov 2023 23:26:05 +0800 Subject: [PATCH 3/5] fix ut, replace k8s.io/kube-openapi version --- go.mod | 2 +- go.sum | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index b5dddfc4..d443f3ff 100644 --- a/go.mod +++ b/go.mod @@ -57,7 +57,6 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/googleapis/gnostic v0.5.5 // indirect @@ -119,6 +118,7 @@ replace ( k8s.io/klog/v2 => k8s.io/klog/v2 v2.9.0 k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.22.6 k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.22.6 + k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c k8s.io/kube-proxy => k8s.io/kube-proxy v0.22.6 k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.22.6 k8s.io/kubectl => k8s.io/kubectl v0.22.6 diff --git a/go.sum b/go.sum index e0a60bea..79646c52 100644 --- a/go.sum +++ b/go.sum @@ -300,8 +300,6 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/cadvisor v0.39.3/go.mod h1:kN93gpdevu+bpS227TyHVZyCU5bbqCzTj5T9drl34MI= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -478,7 +476,6 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU= github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1127,10 +1124,8 @@ k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/kube-aggregator v0.22.6/go.mod h1:0RSTzxqiwsj5HUlov195Z72ZKyE4qgedKXCl6sLKAjM= k8s.io/kube-controller-manager v0.22.6/go.mod h1:RkYKr813YbQhuOBK+12gikPvK/AXy80qovB6YmHfzW8= -k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c h1:jvamsI1tn9V0S8jicyX82qaFC0H/NKxv2e5mbqsgR80= k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= k8s.io/kube-proxy v0.22.6/go.mod h1:xLxEZ3sHyz11XaRyxqI4Z4F3I/Wtt+Jlep8w5yxQPAY= k8s.io/kube-scheduler v0.22.6/go.mod h1:DcHj6ixvb0M1PvWFbg133a1pz/vv7OSCgZUDU/UUhlU= k8s.io/kubectl v0.22.6/go.mod h1:9ktAgMwUsd2w12Yhj/xhMZhNna1t9rfExJg9j9jCIYk= From 2e9ac4ad9c7be7c8929b8053f75768399a7ff1b7 Mon Sep 17 00:00:00 2001 From: WeichengWang Date: Fri, 3 Nov 2023 23:30:34 +0800 Subject: [PATCH 4/5] fix ci, make generate manifests fmt vet --- config/rbac/role.yaml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 2ed40b53..e2949efa 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -123,15 +123,3 @@ rules: - get - patch - update -- apiGroups: - - "" - resources: - - services - verbs: - - create - - delete - - get - - list - - patch - - update - - watch From 98bb564332aa995b1e500255acf2ae0c0feecc2f Mon Sep 17 00:00:00 2001 From: WeichengWang Date: Sat, 4 Nov 2023 00:32:58 +0800 Subject: [PATCH 5/5] add rbac --- config/rbac/role.yaml | 12 ++++++++++++ pkg/controllers/add_alibaba_cloud_slb.go | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index e2949efa..2ed40b53 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -123,3 +123,15 @@ rules: - get - patch - update +- apiGroups: + - "" + resources: + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch diff --git a/pkg/controllers/add_alibaba_cloud_slb.go b/pkg/controllers/add_alibaba_cloud_slb.go index 03d8ca60..586d21b4 100644 --- a/pkg/controllers/add_alibaba_cloud_slb.go +++ b/pkg/controllers/add_alibaba_cloud_slb.go @@ -28,6 +28,10 @@ func init() { AddToManagerFuncs = append(AddToManagerFuncs, Add) } +// +kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=core,resources=pods/status,verbs=get;update;patch + func Add(manager manager.Manager) error { if !feature.DefaultFeatureGate.Enabled(features.AlibabaCloudSlb) { return nil