From 99a959e094514e41a9034a10d6dd6ab4cca15b97 Mon Sep 17 00:00:00 2001 From: liaochuntao Date: Sun, 24 Dec 2023 13:27:03 +0800 Subject: [PATCH] feat:support sync polaris config to k8s configmap (#150) --- cmd/polaris-controller/app/config.go | 81 ++++ cmd/polaris-controller/app/options/polaris.go | 45 +- .../app/polaris-controller-manager.go | 65 +-- cmd/polaris-controller/main.go | 1 + common/log/type.go | 19 +- deploy/kubernetes_v1.21/configmap.yaml | 6 + .../templates/controller-statefulset.yaml | 6 +- deploy/kubernetes_v1.21/helm/values.yaml | 3 + .../kubernetes_v1.21/polaris-controller.yaml | 2 - .../templates/controller-statefulset.yaml | 6 +- deploy/kubernetes_v1.22/helm/values.yaml | 3 + go.mod | 42 +- go.sum | 100 ++--- pkg/controller/configmap.go | 402 +++++++++++++++++- pkg/controller/controller.go | 32 +- pkg/controller/namespace.go | 2 +- pkg/controller/rsync.go | 4 +- pkg/polarisapi/config_api.go | 14 +- pkg/util/map.go | 400 +++++++++++++++++ pkg/util/scheduler.go | 223 ++++++++++ pkg/util/types.go | 21 + version | 2 +- 22 files changed, 1317 insertions(+), 162 deletions(-) create mode 100644 cmd/polaris-controller/app/config.go create mode 100644 pkg/util/map.go create mode 100644 pkg/util/scheduler.go diff --git a/cmd/polaris-controller/app/config.go b/cmd/polaris-controller/app/config.go new file mode 100644 index 00000000..1640433e --- /dev/null +++ b/cmd/polaris-controller/app/config.go @@ -0,0 +1,81 @@ +// Tencent is pleased to support the open source community by making Polaris available. +// +// Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// 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 app + +import ( + "io/ioutil" + + "gopkg.in/yaml.v2" + + "github.com/polarismesh/polaris-controller/cmd/polaris-controller/app/options" + "github.com/polarismesh/polaris-controller/common/log" +) + +// ServiceSync controller 用到的配置 +type ProxyMetadata struct { + ServerAddress string `yaml:"serverAddress"` + ClusterName string `yaml:"clusterName"` + CAAddress string `yaml:"caAddress"` +} + +// DefaultConfig controller 用到的配置 +type DefaultConfig struct { + ProxyMetadata ProxyMetadata `yaml:"serviceSync"` +} + +// SidecarInject sidecar 注入相关 +type SidecarInject struct { + Mode string `yaml:"mode"` + Ignores []IgnorePod `yaml:"ignorePods"` +} + +type IgnorePod struct { + Namespace string `yaml:"namespace"` + PodName string `yaml:"podName"` +} + +type Server struct { + // 健康探测时间间隔 + HealthCheckDuration string `yaml:"healthCheckDuration"` + // 定时对账时间间隔 + ResyncDuration string `yaml:"resyncDuration"` +} + +type controllerConfig struct { + Logger map[string]*log.Options `yaml:"logger"` + ClusterName string `yaml:"clusterName"` + Server Server `yaml:"server"` + ServiceSync *options.ServiceSync `yaml:"serviceSync"` + ConfigSync *options.ConfigSync `yaml:"configSync"` + SidecarInject SidecarInject `yaml:"sidecarInject"` +} + +func readConfFromFile() (*controllerConfig, error) { + buf, err := ioutil.ReadFile(MeshFile) + if err != nil { + log.Errorf("read file error, %v", err) + return nil, err + } + + c := &controllerConfig{} + err = yaml.Unmarshal(buf, c) + if err != nil { + log.Errorf("unmarshal config error, %v", err) + return nil, err + } + + return c, nil +} diff --git a/cmd/polaris-controller/app/options/polaris.go b/cmd/polaris-controller/app/options/polaris.go index d0bfe28a..1cf8a2f1 100644 --- a/cmd/polaris-controller/app/options/polaris.go +++ b/cmd/polaris-controller/app/options/polaris.go @@ -27,6 +27,45 @@ type PolarisControllerOptions struct { *PolarisControllerConfiguration } +// ServiceSync 服务同步相关配置 +type ServiceSync struct { + Mode string `yaml:"mode"` + ServerAddress string `yaml:"serverAddress"` + // 以下配置仅 polaris-server 开启 console auth + // 调用 polaris-server OpenAPI 的凭据 + PolarisAccessToken string `yaml:"accessToken"` + // Operator 用于数据同步的帐户ID + Operator string `yaml:"operator"` + // Enable 开启同步 + Enable bool `yaml:"enable"` +} + +// ConfigSync 服务同步相关配置 +type ConfigSync struct { + Mode string `yaml:"mode"` + ServerAddress string `yaml:"serverAddress"` + // 以下配置仅 polaris-server 开启 console auth + // 调用 polaris-server OpenAPI 的凭据 + PolarisAccessToken string `yaml:"accessToken"` + // Operator 用于数据同步的帐户ID + Operator string `yaml:"operator"` + // AllowDelete 允许向 Polaris 发起删除操作 + AllowDelete bool `yaml:"allowDelete"` + // SyncDirection 配置同步方向, kubernetesToPolaris/polarisToKubernetes/both + // kubernetesToPolaris: 配置数据只能从 kubernetes 同步到 polaris + // polarisToKubernetes: 配置数据只能从 polaris 同步到 kubernetes + // both: 配置数据能从 kubernetes 同步到 polaris, 也能从 polaris 同步到 kubernetes, 但是不会出现循环同步 + SyncDirection string `yaml:"syncDirection"` + // ConflictMode 同步冲突策略 + ConflictMode string `yaml:"conflictMode"` + // Enable 开启同步 + Enable bool `yaml:"enable"` + // IgnoreNamespaces 忽略同步的命名空间,默认不忽略 + IgnoreNamespaces []string `yaml:"ignoreNamespaces"` + // DefaultGroup 配置分组同步默认分组名称 + DefaultGroup string `yaml:"defaultGroup"` +} + // PolarisControllerConfiguration holds configuration for a polaris controller type PolarisControllerConfiguration struct { // port is the port that the controller-manager's http service runs on. @@ -45,8 +84,8 @@ type PolarisControllerConfiguration struct { HealthCheckDuration time.Duration // ResyncDuration 对账任务执行时间 ResyncDuration time.Duration - // SyncConfigMap 是否开启 ConfigMap 同步 - SyncConfigMap bool + // ConfigSync 配置中心同步配置 + ConfigSync *ConfigSync } // AddFlags adds flags related to generic for controller manager to the specified FlagSet. @@ -66,7 +105,6 @@ func (o *PolarisControllerOptions) AddFlags(fs *pflag.FlagSet) { fs.DurationVar(&o.HealthCheckDuration, "healthcheck-duration", time.Second, "The health checking duration of the polaris server (eg. 5h30m2s).") fs.DurationVar(&o.ResyncDuration, "resync-duration", time.Second*30, "The resync duration (eg. 5h30m2s).") - fs.BoolVar(&o.SyncConfigMap, "sync-configmap", false, "is open sync configmap to polaris (eg. true/false, default is false).") } // ApplyTo fills up generic config with options. @@ -86,6 +124,5 @@ func (o *PolarisControllerOptions) ApplyTo(cfg *PolarisControllerConfiguration) cfg.SidecarMode = o.SidecarMode cfg.HealthCheckDuration = o.HealthCheckDuration cfg.ResyncDuration = o.ResyncDuration - cfg.SyncConfigMap = o.SyncConfigMap return nil } diff --git a/cmd/polaris-controller/app/polaris-controller-manager.go b/cmd/polaris-controller/app/polaris-controller-manager.go index 1f283631..1a32a617 100644 --- a/cmd/polaris-controller/app/polaris-controller-manager.go +++ b/cmd/polaris-controller/app/polaris-controller-manager.go @@ -30,7 +30,6 @@ import ( "github.com/polarismesh/polaris-go/api" "github.com/spf13/cobra" "google.golang.org/grpc/grpclog" - "gopkg.in/yaml.v2" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apiserver/pkg/server/healthz" @@ -211,11 +210,11 @@ func initControllerConfig(s *options.KubeControllerManagerOptions) { // 4. 配置 polaris-sidecar 注入模式的 s.PolarisController.SidecarMode = config.SidecarInject.Mode // 设置是否开启同步 ConfigMap - s.PolarisController.SyncConfigMap = config.ServiceSync.EnableSyncConfigMap + s.PolarisController.ConfigSync = config.ConfigSync // 5.设置健康检查时间以及定时对账时间 - s.PolarisController.HealthCheckDuration, _ = time.ParseDuration(config.ServiceSync.HealthCheckDuration) - s.PolarisController.ResyncDuration, _ = time.ParseDuration(config.ServiceSync.ResyncDuration) + s.PolarisController.HealthCheckDuration, _ = time.ParseDuration(config.Server.HealthCheckDuration) + s.PolarisController.ResyncDuration, _ = time.ParseDuration(config.Server.ResyncDuration) common.PolarisServerAddress = polarisServerAddress common.PolarisServerGrpcAddress = polarisapi.PolarisGrpc @@ -541,64 +540,6 @@ func startPolarisController(ctx ControllerContext) (http.Handler, error) { return nil, nil } -// ServiceSync controller 用到的配置 -type ProxyMetadata struct { - ServerAddress string `yaml:"serverAddress"` - ClusterName string `yaml:"clusterName"` - CAAddress string `yaml:"caAddress"` -} - -// DefaultConfig controller 用到的配置 -type DefaultConfig struct { - ProxyMetadata ProxyMetadata `yaml:"serviceSync"` -} - -// ResourceSync 服务同步相关配置 -type ResourceSync struct { - Mode string `yaml:"mode"` - ServerAddress string `yaml:"serverAddress"` - // 健康探测时间间隔 - HealthCheckDuration string `yaml:"healthCheckDuration"` - // 定时对账时间间隔 - ResyncDuration string `yaml:"resyncDuration"` - // 以下配置仅 polaris-server 开启 console auth - // 调用 polaris-server OpenAPI 的凭据 - PolarisAccessToken string `yaml:"accessToken"` - // Operator 用于数据同步的帐户ID - Operator string `yaml:"operator"` - // EnableSyncConfigMap 开启同步 ConfigMap - EnableSyncConfigMap bool `yaml:"enableSyncConfigMap"` -} - -// SidecarInject sidecar 注入相关 -type SidecarInject struct { - Mode string `yaml:"mode"` -} - -type controllerConfig struct { - Logger map[string]*log.Options `yaml:"logger"` - ClusterName string `yaml:"clusterName"` - ServiceSync *ResourceSync `yaml:"serviceSync"` - SidecarInject SidecarInject `yaml:"sidecarInject"` -} - -func readConfFromFile() (*controllerConfig, error) { - buf, err := ioutil.ReadFile(MeshFile) - if err != nil { - log.Errorf("read file error, %v", err) - return nil, err - } - - c := &controllerConfig{} - err = yaml.Unmarshal(buf, c) - if err != nil { - log.Errorf("unmarshal config error, %v", err) - return nil, err - } - - return c, nil -} - // startPolarisAccountController 启用反对账逻辑,定时从北极星侧拉取通过TKEx注册的服务,对比一下是否在集群中还存在 //func startPolarisAccountController(ctx ControllerContext) (http.Handler, error) { // go accounting_controller.NewPolarisAccountingController( diff --git a/cmd/polaris-controller/main.go b/cmd/polaris-controller/main.go index 310b325a..f2993b51 100644 --- a/cmd/polaris-controller/main.go +++ b/cmd/polaris-controller/main.go @@ -21,6 +21,7 @@ import ( "os" "time" + _ "go.uber.org/automaxprocs" "k8s.io/component-base/logs" "github.com/polarismesh/polaris-controller/cmd/polaris-controller/app" diff --git a/common/log/type.go b/common/log/type.go index 4f6ad943..a45b1a4b 100644 --- a/common/log/type.go +++ b/common/log/type.go @@ -25,6 +25,10 @@ const ( SyncNamingLoggerName = "syncnaming" // SyncConfigLoggerName config sync logger name, can use FindScope function to get the logger SyncConfigLoggerName = "syncconfig" + // SyncConfigLoggerName config map sync logger name, can use FindScope function to get the logger + SyncConfigMapLoggerName = "synccm" + // TraceLoggerName trace logger name, can use FindScope function to get the logger + TraceLoggerName = "trace" ) var ( @@ -32,10 +36,13 @@ var ( injectScope = RegisterScope(InjectLoggerName, "pod inject logging messages.", 0) syncNamingScope = RegisterScope(SyncNamingLoggerName, "naming sync logging messages.", 0) syncConfigScope = RegisterScope(SyncConfigLoggerName, "config sync logging messages.", 0) + syncCmScope = RegisterScope(SyncConfigMapLoggerName, "configmap sync logging messages.", 0) + traceScope = RegisterScope(TraceLoggerName, "trace logging messages.", 0) ) func allLoggerTypes() []string { - return []string{SyncLoggerName, InjectLoggerName, DefaultLoggerName} + return []string{SyncLoggerName, SyncNamingLoggerName, SyncConfigLoggerName, + SyncConfigMapLoggerName, InjectLoggerName, DefaultLoggerName} } // DefaultScope default logging scope handler @@ -58,7 +65,17 @@ func SyncConfigScope() *Scope { return syncConfigScope } +// SyncConfigMapScope naming logging scope handler +func SyncConfigMapScope() *Scope { + return syncCmScope +} + // InjectScope func InjectScope() *Scope { return injectScope } + +// TraceScope +func TraceScope() *Scope { + return traceScope +} diff --git a/deploy/kubernetes_v1.21/configmap.yaml b/deploy/kubernetes_v1.21/configmap.yaml index 33827b67..82ac48b9 100644 --- a/deploy/kubernetes_v1.21/configmap.yaml +++ b/deploy/kubernetes_v1.21/configmap.yaml @@ -68,10 +68,16 @@ data: mode: "mesh" # service sync serviceSync: + enable: true mode: "all" serverAddress: #POLARIS_HOST# # 北极星开启鉴权时需要配置 accessToken: #POLARIS_TOKEN# + configSync: + enable: true + serverAddress: #POLARIS_HOST# + # 北极星开启鉴权时需要配置 + accessToken: #POLARIS_TOKEN# defaultConfig: proxyMetadata: serverAddress: #POLARIS_HOST# \ No newline at end of file diff --git a/deploy/kubernetes_v1.21/helm/templates/controller-statefulset.yaml b/deploy/kubernetes_v1.21/helm/templates/controller-statefulset.yaml index a5151ed3..d84debf3 100644 --- a/deploy/kubernetes_v1.21/helm/templates/controller-statefulset.yaml +++ b/deploy/kubernetes_v1.21/helm/templates/controller-statefulset.yaml @@ -35,6 +35,10 @@ spec: fieldRef: fieldPath: metadata.namespace imagePullPolicy: {{ .Values.controller.image.pullPolicy }} + resources: + limits: + cpu: {{ .Values.controller.limit.cpu }} + memory: {{ .Values.controller.limit.memory }} volumeMounts: - mountPath: /polaris-controller/log name: log @@ -48,8 +52,6 @@ spec: mountPath: /etc/polaris-inject/config readOnly: true dnsPolicy: ClusterFirst - imagePullSecrets: - - name: qcloudregistrykey restartPolicy: Always schedulerName: default-scheduler terminationGracePeriodSeconds: 30 diff --git a/deploy/kubernetes_v1.21/helm/values.yaml b/deploy/kubernetes_v1.21/helm/values.yaml index 275d5a65..772c168f 100644 --- a/deploy/kubernetes_v1.21/helm/values.yaml +++ b/deploy/kubernetes_v1.21/helm/values.yaml @@ -48,6 +48,9 @@ controller: repo: polarismesh/polaris-controller tag: #CONTROLLER_VERSION# pullPolicy: IfNotPresent + limit: + cpu: 2 + memory: 2Gi metrics: port: 80 type: ClusterIP diff --git a/deploy/kubernetes_v1.21/polaris-controller.yaml b/deploy/kubernetes_v1.21/polaris-controller.yaml index b230e2de..523e2060 100644 --- a/deploy/kubernetes_v1.21/polaris-controller.yaml +++ b/deploy/kubernetes_v1.21/polaris-controller.yaml @@ -50,8 +50,6 @@ spec: mountPath: /etc/polaris-inject/config readOnly: true dnsPolicy: ClusterFirst - imagePullSecrets: - - name: qcloudregistrykey restartPolicy: Always schedulerName: default-scheduler terminationGracePeriodSeconds: 30 diff --git a/deploy/kubernetes_v1.22/helm/templates/controller-statefulset.yaml b/deploy/kubernetes_v1.22/helm/templates/controller-statefulset.yaml index a5151ed3..d84debf3 100644 --- a/deploy/kubernetes_v1.22/helm/templates/controller-statefulset.yaml +++ b/deploy/kubernetes_v1.22/helm/templates/controller-statefulset.yaml @@ -35,6 +35,10 @@ spec: fieldRef: fieldPath: metadata.namespace imagePullPolicy: {{ .Values.controller.image.pullPolicy }} + resources: + limits: + cpu: {{ .Values.controller.limit.cpu }} + memory: {{ .Values.controller.limit.memory }} volumeMounts: - mountPath: /polaris-controller/log name: log @@ -48,8 +52,6 @@ spec: mountPath: /etc/polaris-inject/config readOnly: true dnsPolicy: ClusterFirst - imagePullSecrets: - - name: qcloudregistrykey restartPolicy: Always schedulerName: default-scheduler terminationGracePeriodSeconds: 30 diff --git a/deploy/kubernetes_v1.22/helm/values.yaml b/deploy/kubernetes_v1.22/helm/values.yaml index 275d5a65..772c168f 100644 --- a/deploy/kubernetes_v1.22/helm/values.yaml +++ b/deploy/kubernetes_v1.22/helm/values.yaml @@ -48,6 +48,9 @@ controller: repo: polarismesh/polaris-controller tag: #CONTROLLER_VERSION# pullPolicy: IfNotPresent + limit: + cpu: 2 + memory: 2Gi metrics: port: 80 type: ClusterIP diff --git a/go.mod b/go.mod index 07fdc18c..99002723 100644 --- a/go.mod +++ b/go.mod @@ -1,27 +1,27 @@ module github.com/polarismesh/polaris-controller -go 1.20 +go 1.21 require ( github.com/ghodss/yaml v1.0.0 github.com/gogo/protobuf v1.3.2 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.4.0 github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 github.com/howeyc/fsnotify v0.9.0 github.com/natefinch/lumberjack v2.0.0+incompatible github.com/openshift/api v3.9.1-0.20191008181517-e4fd21196097+incompatible - github.com/polarismesh/polaris-go v1.5.3 - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/common v0.44.0 // indirect + github.com/polarismesh/polaris-go v1.6.0-beta.2 + github.com/prometheus/client_golang v1.17.0 // indirect + github.com/prometheus/common v0.45.0 // indirect github.com/spf13/cobra v1.6.0 github.com/spf13/pflag v1.0.5 go.uber.org/atomic v1.11.0 go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect - google.golang.org/grpc v1.56.3 + golang.org/x/sys v0.14.0 // indirect + google.golang.org/grpc v1.59.0 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.27.3 k8s.io/apimachinery v0.27.3 @@ -30,6 +30,11 @@ require ( k8s.io/component-base v0.27.3 ) +require ( + github.com/polarismesh/specification v1.4.2-alpha.6 + google.golang.org/protobuf v1.31.0 +) + require ( github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -57,15 +62,14 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/polarismesh/specification v1.4.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/procfs v0.11.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.1 // indirect go.opentelemetry.io/otel v1.10.0 // indirect @@ -76,16 +80,16 @@ require ( go.opentelemetry.io/otel/sdk v1.10.0 // indirect go.opentelemetry.io/otel/trace v1.10.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect - golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sync v0.2.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + go.uber.org/automaxprocs v1.5.3 + golang.org/x/oauth2 v0.12.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/term v0.14.0 // indirect + golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230525234025-438c736192d0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231030173426-d783a09b4405 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.90.1 // indirect diff --git a/go.sum b/go.sum index 7298cdd9..d21c3ab7 100644 --- a/go.sum +++ b/go.sum @@ -173,7 +173,6 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw= github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -232,6 +231,7 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -247,7 +247,6 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb 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 v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= @@ -255,6 +254,7 @@ github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= +github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= @@ -263,12 +263,14 @@ github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/ github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -354,8 +356,9 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJY github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -367,7 +370,6 @@ github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99 github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= @@ -397,7 +399,6 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= @@ -410,6 +411,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN 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/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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= @@ -417,8 +419,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -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/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -435,7 +437,9 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= github.com/openshift/api v3.9.1-0.20191008181517-e4fd21196097+incompatible h1:CIa+Zv6vIPhJl5OHmKxVpnekHC54YYe49L9GLr7IxGI= github.com/openshift/api v3.9.1-0.20191008181517-e4fd21196097+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -444,46 +448,48 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polarismesh/polaris-go v1.5.3 h1:RL1m6FThsYCzKYGOLp5HXNCnzeqa5NEsgO0h5kxZXRM= -github.com/polarismesh/polaris-go v1.5.3/go.mod h1:KVMjcp6P2R8MFPKfBPX3kzykyzH0iX8fHCiITcqKda8= -github.com/polarismesh/specification v1.4.0 h1:fm7sUtFZC2g9+lLmRCtjGrUow47CY5JDFoZXwwCQGGY= -github.com/polarismesh/specification v1.4.0/go.mod h1:rDvMMtl5qebPmqiBLNa5Ps0XtwkP31ZLirbH4kXA0YU= +github.com/polarismesh/polaris-go v1.6.0-beta.2 h1:BIOg1J4w/saH4mYvjedZKKNTZDnZuE7RPn4sTepDX+4= +github.com/polarismesh/polaris-go v1.6.0-beta.2/go.mod h1:CuXO9bhHGjSoOIMWr4NXf3bJAkRBp5YoM7ibBzENC+c= +github.com/polarismesh/specification v1.4.1/go.mod h1:rDvMMtl5qebPmqiBLNa5Ps0XtwkP31ZLirbH4kXA0YU= +github.com/polarismesh/specification v1.4.2-alpha.6 h1:EUhATwFjb4lGIrI/UEoaVdyLWpjZrOuDTQn4S12QE10= +github.com/polarismesh/specification v1.4.2-alpha.6/go.mod h1:rDvMMtl5qebPmqiBLNa5Ps0XtwkP31ZLirbH4kXA0YU= +github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 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.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -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_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= 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.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= 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.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/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.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= -github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= 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/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= @@ -543,8 +549,11 @@ go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= +go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= 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= @@ -643,8 +652,6 @@ golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -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= @@ -670,8 +677,8 @@ golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7Lm golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -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/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= +golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= 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= @@ -685,8 +692,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -760,17 +767,13 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.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/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -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/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= +golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= 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= @@ -781,10 +784,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 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.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -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/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-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= @@ -846,6 +847,7 @@ golang.org/x/tools v0.1.4/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.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= 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= @@ -1006,12 +1008,12 @@ google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20230525234025-438c736192d0 h1:x1vNwUhVOcsYoKyEGCZBH694SBmmBjA2EfauFVEI2+M= -google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a h1:HiYVD+FGJkTo+9zj1gqz0anapsa1JxjiSrN+BJKyUmE= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529 h1:DEH99RbiLZhMxrpEJCZ0A+wdTe0EOgou/poSLx9vWf4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= +google.golang.org/genproto/googleapis/api v0.0.0-20231030173426-d783a09b4405 h1:HJMDndgxest5n2y77fnErkM62iUsptE/H8p0dC2Huo4= +google.golang.org/genproto/googleapis/api v0.0.0-20231030173426-d783a09b4405/go.mod h1:oT32Z4o8Zv2xPQTg0pbVaPr0MPOH6f14RgXt7zfIpwg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1048,10 +1050,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= -google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= -google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= -google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= -google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/pkg/controller/configmap.go b/pkg/controller/configmap.go index c7f4c574..a8120751 100644 --- a/pkg/controller/configmap.go +++ b/pkg/controller/configmap.go @@ -16,13 +16,29 @@ package controller import ( + "context" "fmt" + "runtime" + "strconv" + "sync" + "sync/atomic" "time" + "github.com/polarismesh/polaris-go/api" + "github.com/polarismesh/polaris-go/pkg/model" + "github.com/polarismesh/specification/source/go/api/v1/config_manage" + apimodel "github.com/polarismesh/specification/source/go/api/v1/model" + "go.uber.org/zap" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/protobuf/types/known/wrapperspb" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/watch" + clientset "k8s.io/client-go/kubernetes" + "github.com/polarismesh/polaris-controller/cmd/polaris-controller/app/options" "github.com/polarismesh/polaris-controller/common/log" "github.com/polarismesh/polaris-controller/pkg/metrics" "github.com/polarismesh/polaris-controller/pkg/polarisapi" @@ -45,9 +61,10 @@ func (p *PolarisController) syncConfigMap(task *Task) error { op := task.Operation configMap, err := p.configMapLister.ConfigMaps(namespaces).Get(name) + switch { case errors.IsNotFound(err): - // 发现对应的service不存在,即已经被删除了,那么需要从cache中查询之前注册的北极星是什么,然后把它从实例中删除 + // 发现对应的 ConfigMap 不存在,即已经被删除了,那么需要从 cache 中查询之前注册的北极星是什么,然后把它从实例中删除 cachedConfigMap, ok := p.configFileCache.Load(task.Key()) if !ok { // 如果之前的数据也已经不存在那么就跳过不在处理 @@ -79,9 +96,14 @@ func (p *PolarisController) syncConfigMap(task *Task) error { metav1.SetMetaDataAnnotation(&operationConfigMap.ObjectMeta, util.PolarisSync, util.IsEnableSync) } if _, ok := operationConfigMap.Annotations[util.PolarisConfigGroup]; !ok { - metav1.SetMetaDataAnnotation(&operationConfigMap.ObjectMeta, util.PolarisConfigGroup, - p.config.PolarisController.ClusterName) + groupName := p.config.PolarisController.ClusterName + if p.config.PolarisController.ConfigSync.DefaultGroup != "" { + groupName = p.config.PolarisController.ConfigSync.DefaultGroup + } + metav1.SetMetaDataAnnotation(&operationConfigMap.ObjectMeta, util.PolarisConfigGroup, groupName) } + // 记录ConfigMap 的 sync 来源 kubernetes 集群 + metav1.SetMetaDataLabel(&operationConfigMap.ObjectMeta, util.InternalConfigFileSyncSourceClusterKey, p.config.PolarisController.ClusterName) cachedConfigMap, ok := p.configFileCache.Load(task.Key()) if !ok { @@ -139,20 +161,25 @@ func (p *PolarisController) processSyncNamespaceAndConfigMap(configmap *v1.Confi func (p *PolarisController) processUpdateConfigMap(old, cur *v1.ConfigMap) error { log.SyncConfigScope().Infof("Update ConfigMap %s/%s", cur.GetNamespace(), cur.GetName()) if !p.IsPolarisConfigMap(cur) { - return polarisapi.DeleteConfigMap(cur) + log.SyncConfigScope().Infof("user cancel sync ConfigMap %s/%s, delete(%v)", cur.GetNamespace(), cur.GetName(), p.allowDeleteConfig()) + return p.processDeleteConfigMap(cur) } _, err := polarisapi.UpdateConfigMap(cur) return err } func (p *PolarisController) processDeleteConfigMap(configmap *v1.ConfigMap) error { - log.SyncConfigScope().Infof("Delete ConfigMap %s/%s", configmap.GetNamespace(), configmap.GetName()) + if !p.allowDeleteConfig() { + return nil + } + log.SyncConfigScope().Infof("delete ConfigMap %s/%s", configmap.GetNamespace(), configmap.GetName()) + // 平台接口 return polarisapi.DeleteConfigMap(configmap) } func (p *PolarisController) onConfigMapAdd(cur interface{}) { - if !p.OpenSyncConfigMap() { + if !p.AllowSyncFromConfigMap() { return } configMap, ok := cur.(*v1.ConfigMap) @@ -176,7 +203,7 @@ func (p *PolarisController) onConfigMapAdd(cur interface{}) { } func (p *PolarisController) onConfigMapUpdate(old, cur interface{}) { - if !p.OpenSyncConfigMap() { + if !p.AllowSyncFromConfigMap() { return } @@ -225,7 +252,7 @@ func (p *PolarisController) onConfigMapUpdate(old, cur interface{}) { } func (p *PolarisController) onConfigMapDelete(cur interface{}) { - if !p.OpenSyncConfigMap() { + if !p.AllowSyncFromConfigMap() { return } @@ -248,3 +275,362 @@ func (p *PolarisController) onConfigMapDelete(cur interface{}) { p.enqueueConfigMap(task, configmap, "Delete") p.resyncConfigFileCache.Delete(task.Key()) } + +func (p *PolarisController) watchPolarisConfig() error { + conn, err := grpc.Dial(polarisapi.PolarisGrpc, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + return err + } + + discoverClient, err := config_manage.NewPolarisConfigGRPCClient(conn).Discover(context.Background()) + if err != nil { + return err + } + + ctx, cancel := context.WithCancel(context.Background()) + + // + watcher := &PolarisConfigWatcher{ + controller: p, + k8sClient: p.client, + config: p.config, + conn: conn, + configAPI: api.NewConfigFileAPIBySDKContext(p.consumer.SDKContext()), + discoverClient: discoverClient, + namespaces: util.NewSyncSet[string](), + needSyncFiles: util.NewSyncMap[string, *util.SyncMap[string, *util.SyncMap[string, *configFileRefrence]]](), + filesRevisions: util.NewSyncMap[string, string](), + groups: util.NewSyncMap[string, *util.SyncSet[string]](), + groupRevisions: util.NewSyncMap[string, string](), + cancel: cancel, + } + + p.polarisConfigWatcher = watcher + return watcher.Start(ctx) +} + +type configFileRefrence struct { + Revision uint64 + Data *config_manage.ClientConfigFileInfo +} + +type PolarisConfigWatcher struct { + // + controller *PolarisController + // config provides access to init options for a given controller + config options.KubeControllerManagerConfiguration + // nsWatcher + nsWatcher watch.Interface + // k8sClient + k8sClient clientset.Interface + // configAPI + configAPI api.ConfigFileAPI + // conn + conn *grpc.ClientConn + // discoverClient + discoverClient config_manage.PolarisConfigGRPC_DiscoverClient + // namespaces + namespaces *util.SyncSet[string] + // needSyncFiles 需要同步到 k8s ConfigMap 的配置文件 + needSyncFiles *util.SyncMap[string, *util.SyncMap[string, *util.SyncMap[string, *configFileRefrence]]] + // filesRevisions 文件列表版本 + filesRevisions *util.SyncMap[string, string] + // groups + groups *util.SyncMap[string, *util.SyncSet[string]] + // groupRevisions + groupRevisions *util.SyncMap[string, string] + // + cancel context.CancelFunc + // + executor *util.TaskExecutor +} + +func (p *PolarisConfigWatcher) Start(ctx context.Context) error { + p.executor = util.NewExecutor(runtime.NumCPU()) + nsList, err := p.k8sClient.CoreV1().Namespaces().List(context.Background(), metav1.ListOptions{}) + if err != nil { + return err + } + for i := range nsList.Items { + p.namespaces.Add(nsList.Items[i].Name) + } + watcher, err := p.k8sClient.CoreV1().Namespaces().Watch(context.Background(), metav1.ListOptions{}) + if err != nil { + return err + } + p.nsWatcher = watcher + + go p.watchNamespaces(ctx) + go p.fetchResources(ctx) + go p.doRecv(ctx) + + return nil +} + +func (p *PolarisConfigWatcher) Destroy() error { + p.cancel() + p.nsWatcher.Stop() + _ = p.conn.Close() + return nil +} + +func (p *PolarisConfigWatcher) doRecv(ctx context.Context) { + discoverClient := p.discoverClient + for { + select { + case <-ctx.Done(): + return + default: + msg, err := discoverClient.Recv() + if err != nil { + continue + } + + if msg.Code == uint32(apimodel.Code_DataNoChange) { + continue + } + + switch msg.Type { + case config_manage.ConfigDiscoverResponse_CONFIG_FILE_GROUPS: + p.receiveGroups(msg) + case config_manage.ConfigDiscoverResponse_CONFIG_FILE_Names: + p.receiveConfigFiles(msg) + case config_manage.ConfigDiscoverResponse_CONFIG_FILE: + // + } + } + } +} + +func (p *PolarisConfigWatcher) watchNamespaces(ctx context.Context) { + for { + select { + case e := <-p.nsWatcher.ResultChan(): + event := e.Object.(*v1.Namespace) + switch e.Type { + case watch.Added, watch.Modified: + p.namespaces.Add(event.Name) + case watch.Deleted: + p.namespaces.Remove(event.Name) + } + case <-ctx.Done(): + return + } + } +} + +func (p *PolarisConfigWatcher) fetchResources(ctx context.Context) { + ticker := time.NewTicker(2 * time.Second) + for { + select { + case <-ticker.C: + p.namespaces.Range(func(nsName string) { + p.fetchGroups(nsName) + }) + case <-ctx.Done(): + return + } + } +} + +func (p *PolarisConfigWatcher) fetchGroups(ns string) { + p.groups.ComputeIfAbsent(ns, func(k string) *util.SyncSet[string] { + return util.NewSyncSet[string]() + }) + p.needSyncFiles.ComputeIfAbsent(ns, func(k string) *util.SyncMap[string, *util.SyncMap[string, *configFileRefrence]] { + return util.NewSyncMap[string, *util.SyncMap[string, *configFileRefrence]]() + }) + + preRevision, _ := p.groupRevisions.Load(ns) + discoverClient := p.discoverClient + if err := discoverClient.Send(&config_manage.ConfigDiscoverRequest{ + Type: config_manage.ConfigDiscoverRequest_CONFIG_FILE_GROUPS, + ConfigFile: &config_manage.ClientConfigFileInfo{ + Namespace: wrapperspb.String(ns), + }, + Revision: preRevision, + }); err != nil { + log.SyncConfigMapScope().Errorf("fetch config groups failed, %v", err) + } +} + +func (p *PolarisConfigWatcher) receiveGroups(resp *config_manage.ConfigDiscoverResponse) { + groups := resp.ConfigFileGroups + if len(groups) == 0 { + return + } + + p.groupRevisions.Store(resp.GetConfigFile().GetNamespace().GetValue(), resp.GetRevision()) + for i := range groups { + item := groups[i] + nsName := item.GetNamespace().GetValue() + groupName := item.GetName().GetValue() + groups, _ := p.groups.Load(nsName) + groups.Add(groupName) + + nsBucket, _ := p.needSyncFiles.Load(nsName) + nsBucket.ComputeIfAbsent(groupName, func(k string) *util.SyncMap[string, *configFileRefrence] { + return util.NewSyncMap[string, *configFileRefrence]() + }) + } +} + +func (p *PolarisConfigWatcher) fetchConfigFiles(namespace, group string) { + key := namespace + "/" + group + preRevision, _ := p.filesRevisions.Load(key) + discoverClient := p.discoverClient + // 只要 namespace/group 下任意一个文件发生变动,revision 都会变化,因此不需要在单独监听每个配置文件 + if err := discoverClient.Send(&config_manage.ConfigDiscoverRequest{ + Type: config_manage.ConfigDiscoverRequest_CONFIG_FILE_Names, + ConfigFile: &config_manage.ClientConfigFileInfo{ + Namespace: wrapperspb.String(namespace), + Group: wrapperspb.String(group), + }, + Revision: preRevision, + }); err != nil { + log.SyncConfigMapScope().Errorf("fetch config files failed, %v", err) + } +} + +func (p *PolarisConfigWatcher) receiveConfigFiles(resp *config_manage.ConfigDiscoverResponse) { + files := resp.ConfigFileNames + if len(files) == 0 { + return + } + + var ( + start = time.Now() + wait = &sync.WaitGroup{} + syncCnt = &atomic.Int32{} + delCnt = &atomic.Int32{} + ) + + for i := range files { + item := files[i] + nsName := item.GetNamespace().GetValue() + groupName := item.GetGroup().Value + fileName := item.GetFileName().GetValue() + nsBucket, _ := p.needSyncFiles.Load(nsName) + groupBucket, _ := nsBucket.Load(groupName) + if p.allowSyncToConfigMap(item) { + val, isOld := groupBucket.ComputeIfAbsent(fileName, func(k string) *configFileRefrence { + return &configFileRefrence{ + Revision: 0, + } + }) + if isOld && val.Revision <= item.GetVersion().GetValue() { + val.Revision = item.GetVersion().Value + groupBucket.Store(fileName, val) + wait.Add(1) + log.SyncConfigMapScope().Info("begin fetch config file", zap.String("namespace", nsName), + zap.String("group", groupName), zap.String("file", fileName), zap.Uint64("cur-version", val.Revision)) + // 异步任务进行任务处理 + p.executor.Execute(func() { + defer wait.Done() + p.fetchConfigFile(val.Data) + syncCnt.Add(1) + }) + } + } else { + delCnt.Add(1) + groupBucket.Delete(fileName) + err := p.k8sClient.CoreV1().ConfigMaps(nsName).Delete(context.Background(), + fmt.Sprintf("%s/%s", groupName, fileName), metav1.DeleteOptions{}) + if err != nil { + log.SyncConfigMapScope().Errorf("delete config map failed, %v", err) + } + } + } + + wait.Wait() + log.SyncConfigMapScope().Info("finish config map sync", zap.Duration("cost", time.Since(start)), + zap.Int32("add", syncCnt.Load()), zap.Int32("del", delCnt.Load())) +} + +func (p *PolarisConfigWatcher) fetchConfigFile(req *config_manage.ClientConfigFileInfo) { + + file, err := p.configAPI.FetchConfigFile(&api.GetConfigFileRequest{ + GetConfigFileRequest: &model.GetConfigFileRequest{ + Namespace: req.GetNamespace().GetValue(), + FileGroup: req.GetGroup().GetValue(), + FileName: req.GetFileName().GetValue(), + }, + }) + if err != nil { + log.SyncConfigMapScope().Errorf("fetch config file failed, %v", err) + return + } + log.SyncConfigMapScope().Info("finish fetch config file", zap.String("namespace", file.GetNamespace()), + zap.String("group", file.GetFileGroup()), zap.String("file", file.GetFileName())) + namespace := file.GetNamespace() + + cm := &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s/%s", file.GetFileGroup(), file.GetFileName()), + Namespace: namespace, + Labels: file.GetLabels(), + }, + Data: map[string]string{ + file.GetFileName(): file.GetContent(), + }, + } + + _, err = p.k8sClient.CoreV1().ConfigMaps(namespace).Create(context.Background(), cm, metav1.CreateOptions{}) + if err == nil { + return + } + if errors.IsAlreadyExists(err) { + _, err = p.k8sClient.CoreV1().ConfigMaps(namespace).Update(context.Background(), cm, metav1.UpdateOptions{}) + } + if err != nil { + log.SyncConfigMapScope().Errorf("update config file failed, %v", err) + } +} + +const ( + MetaKeyConfigFileSyncToKubernetes = "internal-sync-to-kubernetes" +) + +func (p *PolarisConfigWatcher) allowSyncToConfigMap(file *config_manage.ClientConfigFileInfo) bool { + // 如果是加密配置,目前不支持,跳过同步 + if file.GetEncrypted().GetValue() { + return false + } + var ( + allowSync bool + isSourceFromK8s bool + isCycleSync bool + ) + + tags := file.GetTags() + for i := range tags { + if tags[i].GetKey().GetValue() == MetaKeyConfigFileSyncToKubernetes { + if tags[i].GetValue().GetValue() == "true" { + allowSync = true + } + } + if tags[i].GetKey().GetValue() == util.InternalConfigFileSyncSourceKey { + if tags[i].GetValue().GetValue() == util.SourceFromKubernetes { + isSourceFromK8s = true + } + } + if tags[i].GetKey().GetValue() == util.InternalConfigFileSyncSourceClusterKey { + if tags[i].GetValue().GetValue() == p.config.PolarisController.ClusterName { + isCycleSync = true + } + } + } + return allowSync && (!isSourceFromK8s && !isCycleSync) +} + +func ToTagMap(file *config_manage.ClientConfigFileInfo) map[string]string { + tags := file.GetTags() + kvs := map[string]string{ + "version": strconv.Itoa(int(file.GetVersion().GetValue())), + } + for i := range tags { + kvs[tags[i].GetKey().GetValue()] = tags[i].GetValue().GetValue() + } + + return kvs +} diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 38ea544e..d96eefaf 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -105,6 +105,9 @@ type PolarisController struct { // polarisServerFailedTimes record the failed time of polaris server which is used to trigger full resync polarisServerFailedTimes int + + // polarisConfigWatcher 负责将北极星上的配置同步到 kubernetes ConfigMap + polarisConfigWatcher *PolarisConfigWatcher } const ( @@ -199,8 +202,18 @@ func NewPolarisController( return p, nil } -func (p *PolarisController) OpenSyncConfigMap() bool { - return p.config.PolarisController.SyncConfigMap +// AllowSyncFromConfigMap 是否开启配置同步从 ConfigMap 到 Polaris +func (p *PolarisController) AllowSyncFromConfigMap() bool { + return p.config.PolarisController.ConfigSync.Enable && p.config.PolarisController.ConfigSync.SyncDirection != util.SyncDirectionPolarisKubernetes +} + +// AllowSyncToConfigMap 是否开启配置同步从 Polaris 到 Kubernetes +func (p *PolarisController) AllowSyncToConfigMap() bool { + return p.config.PolarisController.ConfigSync.Enable && p.config.PolarisController.ConfigSync.SyncDirection != util.SyncDirectionKubernetesToPolaris +} + +func (p *PolarisController) allowDeleteConfig() bool { + return p.config.PolarisController.ConfigSync.AllowDelete } // Run will not return until stopCh is closed. workers determines how many @@ -347,13 +360,19 @@ func (p *PolarisController) CompareServiceChange(old, new *v1.Service) util.Serv // IsPolarisConfigMap 用于判断是是否满足创建 PolarisConfigMap 的要求字段,这块逻辑应该在webhook中也增加 func (p *PolarisController) IsPolarisConfigMap(svc *v1.ConfigMap) bool { - // 过滤一些不合法的 service + // 过滤一些不合法的对象 if util.IgnoreObject(svc) { return false } + if val, ok := svc.Annotations[util.InternalConfigFileSyncSourceKey]; ok { + // 如果同步来源是 polaris, 则不能在认为是需要同步回 polaris 的 ConfigMap + if val == util.SourceFromPolaris { + return false + } + } sync, ok := svc.Annotations[util.PolarisSync] - // 优先看服务的 annotation 中是否携带 polarismesh.cn/sync 注解 + // 优先看 ConfigMap 的 annotation 中是否携带 polarismesh.cn/sync 注解 if ok { return sync == util.IsEnableSync } @@ -375,6 +394,7 @@ func (p *PolarisController) insertTask(t *Task) { case KubernetesNamespace: log.Infof("insert task: %s", t.String()) } + log.TraceScope().Info("INSERT-TASK|" + t.String()) p.queue.Add(t) } @@ -385,19 +405,23 @@ func (p *PolarisController) handleTask(f func(t *Task) error) bool { } defer p.queue.Done(val) task := val.(*Task) + log.TraceScope().Info("HANDLE-TASK|" + task.String()) err := f(task) if err == nil { + log.TraceScope().Info("REMOVE-TASK|" + task.String()) p.queue.Forget(val) return true } if p.queue.NumRequeues(val) < maxRetries { + log.TraceScope().Warn("RETRY-TASK|" + task.String()) log.Infof("syncing service %v, retrying. Error: %v", task, err) p.queue.AddRateLimited(val) return true } log.Errorf("Dropping service %v out of the queue: %v", task, err) + log.TraceScope().Error("DROP-TASK|" + task.String()) p.queue.Forget(val) runtime.HandleError(err) return true diff --git a/pkg/controller/namespace.go b/pkg/controller/namespace.go index fdd48d7a..008426b0 100644 --- a/pkg/controller/namespace.go +++ b/pkg/controller/namespace.go @@ -126,7 +126,7 @@ func (p *PolarisController) syncServiceOnNamespaceUpdate(oldNs, curNs *v1.Namesp } func (p *PolarisController) syncConfigMapOnNamespaceUpdate(oldNs, curNs *v1.Namespace, operation Operation) { - if !p.OpenSyncConfigMap() { + if !p.AllowSyncFromConfigMap() { return } diff --git a/pkg/controller/rsync.go b/pkg/controller/rsync.go index 3009de2a..aa277300 100644 --- a/pkg/controller/rsync.go +++ b/pkg/controller/rsync.go @@ -50,9 +50,9 @@ func (p *PolarisController) resyncWorker() { }) // 只有开启了 SyncConfigMap 才会触发相关任务 - if p.OpenSyncConfigMap() { + if p.AllowSyncFromConfigMap() { p.resyncConfigFileCache.Range(func(key string, value *v1.ConfigMap) bool { - v, ok := p.serviceCache.Load(util.GetOriginKeyWithResyncQueueKey(key)) + v, ok := p.configFileCache.Load(util.GetOriginKeyWithResyncQueueKey(key)) if !ok { task := &Task{ Namespace: value.GetNamespace(), diff --git a/pkg/polarisapi/config_api.go b/pkg/polarisapi/config_api.go index ac664770..0b99a9df 100644 --- a/pkg/polarisapi/config_api.go +++ b/pkg/polarisapi/config_api.go @@ -218,6 +218,7 @@ func parseConfigFileRequest(configMap *v1.ConfigMap) *ConfigFile { Tags: []*ConfigFileTag{}, } + existSourceKey := false for k, v := range configMap.Annotations { if k == util.PolarisConfigEncrypt && v == "true" { createRequest.Encrypted = true @@ -231,6 +232,9 @@ func parseConfigFileRequest(configMap *v1.ConfigMap) *ConfigFile { createRequest.Group = v continue } + if k == util.InternalConfigFileSyncSourceKey { + existSourceKey = true + } createRequest.Tags = append(createRequest.Tags, &ConfigFileTag{ Key: k, Value: v, @@ -242,9 +246,11 @@ func parseConfigFileRequest(configMap *v1.ConfigMap) *ConfigFile { Value: v, }) } - createRequest.Tags = append(createRequest.Tags, &ConfigFileTag{ - Key: "internal-sync-source", - Value: "kubernetes", - }) + if !existSourceKey { + createRequest.Tags = append(createRequest.Tags, &ConfigFileTag{ + Key: util.InternalConfigFileSyncSourceKey, + Value: util.SourceFromKubernetes, + }) + } return &createRequest } diff --git a/pkg/util/map.go b/pkg/util/map.go new file mode 100644 index 00000000..648bf207 --- /dev/null +++ b/pkg/util/map.go @@ -0,0 +1,400 @@ +// Tencent is pleased to support the open source community by making Polaris available. +// +// Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// 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 utils contains common utility functions +package util + +import ( + "encoding/json" + "sync" +) + +// NewSet returns a new Set +func NewSet[K comparable]() *Set[K] { + return &Set[K]{ + container: make(map[K]struct{}), + } +} + +type Set[K comparable] struct { + container map[K]struct{} +} + +// Add adds a string to the set +func (set *Set[K]) Add(val K) { + set.container[val] = struct{}{} +} + +// Remove removes a string from the set +func (set *Set[K]) Remove(val K) { + delete(set.container, val) +} + +func (set *Set[K]) ToSlice() []K { + ret := make([]K, 0, len(set.container)) + for k := range set.container { + ret = append(ret, k) + } + return ret +} + +func (set *Set[K]) Range(fn func(val K)) { + for k := range set.container { + fn(k) + } +} + +// NewSyncSet returns a new Set +func NewSyncSet[K comparable]() *SyncSet[K] { + return &SyncSet[K]{ + container: make(map[K]struct{}), + } +} + +type SyncSet[K comparable] struct { + container map[K]struct{} + lock sync.RWMutex +} + +// Add adds a string to the set +func (set *SyncSet[K]) Add(val K) { + set.lock.Lock() + defer set.lock.Unlock() + + set.container[val] = struct{}{} +} + +// Remove removes a string from the set +func (set *SyncSet[K]) Remove(val K) { + set.lock.Lock() + defer set.lock.Unlock() + + delete(set.container, val) +} + +func (set *SyncSet[K]) ToSlice() []K { + set.lock.RLock() + defer set.lock.RUnlock() + + ret := make([]K, 0, len(set.container)) + for k := range set.container { + ret = append(ret, k) + } + return ret +} + +func (set *SyncSet[K]) Range(fn func(val K)) { + set.lock.RLock() + snapshot := map[K]struct{}{} + for k := range set.container { + snapshot[k] = struct{}{} + } + set.lock.RUnlock() + + for k := range snapshot { + fn(k) + } +} + +func (set *SyncSet[K]) Len() int { + set.lock.RLock() + defer set.lock.RUnlock() + + return len(set.container) +} + +// Contains contains target value +func (set *SyncSet[K]) Contains(val K) bool { + set.lock.Lock() + defer set.lock.Unlock() + + _, exist := set.container[val] + return exist +} + +func (set *SyncSet[K]) String() string { + ret := set.ToSlice() + data, _ := json.Marshal(ret) + return string(data) +} + +func NewSegmentMap[K comparable, V any](soltNum int, hashFunc func(k K) int) *SegmentMap[K, V] { + locks := make([]*sync.RWMutex, 0, soltNum) + solts := make([]map[K]V, 0, soltNum) + for i := 0; i < int(soltNum); i++ { + locks = append(locks, &sync.RWMutex{}) + solts = append(solts, map[K]V{}) + } + return &SegmentMap[K, V]{ + soltNum: soltNum, + locks: locks, + solts: solts, + hashFunc: hashFunc, + } +} + +type SegmentMap[K comparable, V any] struct { + soltNum int + locks []*sync.RWMutex + solts []map[K]V + hashFunc func(k K) int +} + +func (s *SegmentMap[K, V]) Put(k K, v V) { + lock, solt := s.caulIndex(k) + lock.Lock() + defer lock.Unlock() + solt[k] = v +} + +func (s *SegmentMap[K, V]) ComputeIfAbsent(k K, supplier func(k K) V) (V, bool) { + lock, solt := s.caulIndex(k) + lock.Lock() + defer lock.Unlock() + oldVal, ok := solt[k] + if !ok { + v := supplier(k) + solt[k] = v + return v, true + } + return oldVal, false +} + +func (s *SegmentMap[K, V]) PutIfAbsent(k K, v V) (V, bool) { + lock, solt := s.caulIndex(k) + lock.Lock() + defer lock.Unlock() + oldVal, ok := solt[k] + if !ok { + solt[k] = v + return oldVal, true + } + return oldVal, false +} + +func (s *SegmentMap[K, V]) Get(k K) (V, bool) { + lock, solt := s.caulIndex(k) + lock.RLock() + defer lock.RUnlock() + + v, ok := solt[k] + return v, ok +} + +func (s *SegmentMap[K, V]) Del(k K) bool { + lock, solt := s.caulIndex(k) + lock.Lock() + defer lock.Unlock() + + _, ok := solt[k] + delete(solt, k) + return ok +} + +func (s *SegmentMap[K, V]) Range(f func(k K, v V)) { + for i := 0; i < s.soltNum; i++ { + lock := s.locks[i] + solt := s.solts[i] + func() { + lock.RLock() + defer lock.RUnlock() + for k, v := range solt { + f(k, v) + } + }() + } +} + +func (s *SegmentMap[K, V]) Count() uint64 { + count := uint64(0) + for i := 0; i < s.soltNum; i++ { + lock := s.locks[i] + solt := s.solts[i] + func() { + lock.RLock() + defer lock.RUnlock() + count += uint64(len(solt)) + }() + } + return count +} + +func (s *SegmentMap[K, V]) caulIndex(k K) (*sync.RWMutex, map[K]V) { + index := s.hashFunc(k) % s.soltNum + lock := s.locks[index] + solt := s.solts[index] + return lock, solt +} + +// NewSyncMap +func NewSyncMap[K comparable, V any]() *SyncMap[K, V] { + return &SyncMap[K, V]{ + m: make(map[K]V, 16), + } +} + +// SyncMap +type SyncMap[K comparable, V any] struct { + lock sync.RWMutex + m map[K]V +} + +// ComputeIfAbsent +func (s *SyncMap[K, V]) ComputeIfAbsent(k K, supplier func(k K) V) (V, bool) { + s.lock.Lock() + defer s.lock.Unlock() + + actual, exist := s.m[k] + if exist { + return actual, false + } + val := supplier(k) + s.m[k] = val + return val, true +} + +// Load +func (s *SyncMap[K, V]) Load(key K) (V, bool) { + s.lock.RLock() + defer s.lock.RUnlock() + + v, ok := s.m[key] + if ok { + return v, ok + } + var empty V + return empty, false +} + +// Store +func (s *SyncMap[K, V]) Store(key K, val V) { + s.lock.Lock() + defer s.lock.Unlock() + + s.m[key] = val +} + +// Values +func (s *SyncMap[K, V]) Values() []V { + s.lock.RLock() + defer s.lock.RUnlock() + + ret := make([]V, 0, len(s.m)) + for _, v := range s.m { + ret = append(ret, v) + } + return ret +} + +// Range +func (s *SyncMap[K, V]) Range(f func(key K, val V)) { + s.lock.RLock() + snapshot := map[K]V{} + for k, v := range s.m { + snapshot[k] = v + } + s.lock.RUnlock() + + for k, v := range snapshot { + f(k, v) + } +} + +// ReadRange . +func (s *SyncMap[K, V]) ReadRange(f func(key K, val V)) { + s.lock.RLock() + defer s.lock.RUnlock() + for k, v := range s.m { + f(k, v) + } +} + +// Delete +func (s *SyncMap[K, V]) Delete(key K) (V, bool) { + s.lock.Lock() + defer s.lock.Unlock() + + v, exist := s.m[key] + delete(s.m, key) + return v, exist +} + +// Len +func (s *SyncMap[K, V]) Len() int { + s.lock.RLock() + defer s.lock.RUnlock() + + return len(s.m) +} + +func (s *SyncMap[K, V]) ToMap() map[K]V { + s.lock.RLock() + defer s.lock.RUnlock() + + m := map[K]V{} + for k, v := range s.m { + m[k] = v + } + return m +} + +// NewMap +func NewMap[K comparable, V any]() *Map[K, V] { + return &Map[K, V]{ + m: map[K]V{}, + } +} + +// Map +type Map[K comparable, V any] struct { + m map[K]V +} + +// Load +func (s *Map[K, V]) Load(key K) (V, bool) { + v, ok := s.m[key] + return v, ok +} + +// Store +func (s *Map[K, V]) Store(key K, val V) { + s.m[key] = val +} + +// Range +func (s *Map[K, V]) Range(f func(key K, val V)) { + for k, v := range s.m { + f(k, v) + } +} + +// Delete +func (s *Map[K, V]) Delete(key K) { + delete(s.m, key) +} + +// Len +func (s *Map[K, V]) Len() int { + return len(s.m) +} + +// Values . +func (s *Map[K, V]) Values() []V { + ret := make([]V, 0, s.Len()) + for _, v := range s.m { + ret = append(ret, v) + } + return ret +} diff --git a/pkg/util/scheduler.go b/pkg/util/scheduler.go new file mode 100644 index 00000000..c65bc02f --- /dev/null +++ b/pkg/util/scheduler.go @@ -0,0 +1,223 @@ +// Tencent is pleased to support the open source community by making Polaris available. +// +// Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// 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 util + +import ( + "context" + "hash/fnv" + "math/rand" + "sync" + "sync/atomic" + "time" +) + +func NewExecutor(size int) *TaskExecutor { + workers := make([]*worker, 0, size) + for i := 0; i < size; i++ { + workers = append(workers, &worker{ + close: 0, + queue: make(chan func(), 128), + delayQueue: sync.Map{}, + }) + } + + ctx, cancel := context.WithCancel(context.Background()) + + e := &TaskExecutor{ + cancel: cancel, + workers: workers, + r: rand.New(rand.NewSource(time.Now().Unix())), + } + + for i := range workers { + workers[i].mainLoop(ctx) + } + return e +} + +type TaskExecutor struct { + cancel context.CancelFunc + workers []*worker + r *rand.Rand +} + +func (e *TaskExecutor) Stop() { + e.cancel() +} + +func (e *TaskExecutor) Execute(f func()) { + e.workers[e.randIndex()].add(f) +} + +func (e *TaskExecutor) IntervalExecute(interval time.Duration, f func()) { + e.workers[e.randIndex()].addDelay(interval, f, true) +} + +func (e *TaskExecutor) DelayExecute(delay time.Duration, f func()) { + e.workers[e.randIndex()].addDelay(delay, f, false) +} + +func (e *TaskExecutor) AffinityExecute(key string, f func()) { + h := fnv.New64a() + h.Write([]byte(key)) + ret := h.Sum64() + + index := int(ret % uint64(len(e.workers)-1)) + e.workers[index].add(f) +} + +func (e *TaskExecutor) AffinityDelayExecute(key string, delay time.Duration, f func()) { + h := fnv.New64a() + h.Write([]byte(key)) + ret := h.Sum64() + + index := int(ret % uint64(len(e.workers)-1)) + e.workers[index].addDelay(delay, f, false) +} + +func (e *TaskExecutor) randIndex() int32 { + return e.r.Int31n(int32(len(e.workers))) +} + +type worker struct { + lock sync.RWMutex + close int8 + queue chan func() + id int64 + delayQueue sync.Map +} + +func (w *worker) add(f func()) { + w.lock.RLock() + defer w.lock.RUnlock() + + if w.close == 1 { + return + } + + w.queue <- func() { + defer func() { + if err := recover(); err != nil { + panic(err) + } + }() + f() + } +} + +func (w *worker) addDelay(delay time.Duration, f func(), isInterval bool) { + w.lock.RLock() + defer w.lock.RUnlock() + + if w.close == 1 { + return + } + + wf := func() { + defer func() { + if err := recover(); err != nil { + // do nothing + } + }() + f() + } + + id := atomic.AddInt64(&w.id, 1) + if isInterval { + w.delayQueue.Store(id, &tickTask{ + ticker: time.NewTicker(delay), + f: wf, + }) + } else { + w.delayQueue.Store(id, &delayTask{ + timer: time.NewTimer(delay), + f: wf, + }) + } +} + +func (w *worker) mainLoop(ctx context.Context) { + go func() { + for { + select { + case <-ctx.Done(): + w.lock.Lock() + w.close = 1 + close(w.queue) + w.lock.Unlock() + return + case f := <-w.queue: + f() + } + } + }() + go func() { + ticker := time.NewTicker(100 * time.Millisecond) + for { + select { + case <-ctx.Done(): + ticker.Stop() + w.delayQueue.Range(func(key, value interface{}) bool { + switch t := value.(type) { + case *delayTask: + t.timer.Stop() + case *tickTask: + t.ticker.Stop() + } + return true + }) + return + case <-ticker.C: + waitDel := make([]interface{}, 0, 8) + w.delayQueue.Range(func(key, value interface{}) bool { + switch t := value.(type) { + case *delayTask: + select { + case <-t.timer.C: + t.timer.Stop() + t.f() + waitDel = append(waitDel, key) + default: + } + case *tickTask: + select { + case <-t.ticker.C: + t.ticker.Stop() + t.f() + waitDel = append(waitDel, key) + default: + } + } + return true + }) + + for i := range waitDel { + w.delayQueue.Delete(waitDel[i]) + } + } + } + }() +} + +type delayTask struct { + timer *time.Timer + f func() +} + +type tickTask struct { + ticker *time.Ticker + f func() +} diff --git a/pkg/util/types.go b/pkg/util/types.go index 13382657..7e5c4fd3 100644 --- a/pkg/util/types.go +++ b/pkg/util/types.go @@ -65,12 +65,33 @@ const ( IsDisableSync = "false" ) +const ( + SyncDirectionKubernetesToPolaris = "kubernetesToPolaris" + SyncDirectionPolarisKubernetes = "polarisToKubernetes" + SyncDirectionBoth = "both" +) + +const ( + SourceFromKubernetes = "kubernetes" + SourceFromPolaris = "polaris" +) + +const ( + ConflictModeIgnore = "ignore" + ConflictModeReplace = "replace" +) + const ( MTLSModeNone = "none" MTLSModeStrict = "strict" MTLSModePermissive = "permissive" ) +const ( + InternalConfigFileSyncSourceKey = "internal-sync-source" + InternalConfigFileSyncSourceClusterKey = "internal-sync-sourcecluster" +) + // PolarisSystemMetaSet 由 polaris controller 决定的 meta,用户如果在 custom meta 中设置了,不会生效 var PolarisSystemMetaSet = map[string]struct{}{PolarisClusterName: {}, PolarisSource: {}} diff --git a/version b/version index 67a687b5..03ce661d 100644 --- a/version +++ b/version @@ -1 +1 @@ -v1.6.0-alpha.0 \ No newline at end of file +v1.6.0-alpha.1 \ No newline at end of file