diff --git a/go/boss/boss.go b/go/boss/boss.go index 0aae3cc61..f6c5b1f07 100644 --- a/go/boss/boss.go +++ b/go/boss/boss.go @@ -1,6 +1,7 @@ package boss import ( + "context" "encoding/json" "fmt" "io" @@ -11,10 +12,12 @@ import ( "strconv" "strings" "syscall" + "time" "github.com/open-lambda/open-lambda/go/boss/autoscaling" "github.com/open-lambda/open-lambda/go/boss/cloudvm" "github.com/open-lambda/open-lambda/go/boss/config" + "github.com/open-lambda/open-lambda/go/boss/etcd" "github.com/open-lambda/open-lambda/go/boss/lambdastore" ) @@ -144,15 +147,81 @@ func (b *Boss) RegistryHandler(w http.ResponseWriter, r *http.Request) { } } +// leaderOrRedirect wraps a handler so that follower bosses redirect mutating +// requests to the current leader. read-only GET requests are served locally on every replica. +func leaderOrRedirect(le *etcd.LeaderElection, next http.HandlerFunc) http.HandlerFunc { + if le == nil { + return next + } + return func(w http.ResponseWriter, r *http.Request) { + if le.IsLeader() || r.Method == http.MethodGet { + next(w, r) + return + } + ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second) + defer cancel() + addr, err := le.LeaderAddr(ctx) + if err != nil { + http.Error(w, "no leader available", http.StatusServiceUnavailable) + return + } + http.Redirect(w, r, fmt.Sprintf("http://%s%s", addr, r.URL.RequestURI()), http.StatusTemporaryRedirect) + } +} + // BossMain is the main function for the boss. func BossMain() (err error) { fmt.Printf("WARNING! Boss incomplete (only use this as part of development process).\n") - pool, err := cloudvm.NewWorkerPool(config.BossConf.Platform, config.BossConf.Worker_Cap) + var etcdClient *etcd.Client + if len(config.BossConf.Etcd.Endpoints) > 0 { + timeout := time.Duration(config.BossConf.Etcd.Dial_timeout_sec) * time.Second + etcdClient, err = etcd.NewClient(config.BossConf.Etcd.Endpoints, config.BossConf.Etcd.Prefix, timeout) + if err != nil { + return fmt.Errorf("etcd connect failed: %w", err) + } + defer etcdClient.Close() + slog.Info("etcd connected", "endpoints", config.BossConf.Etcd.Endpoints) + } + + var le *etcd.LeaderElection + var selfAddr string + if etcdClient != nil && config.BossConf.Etcd.Enable_HA { + le, err = etcdClient.NewLeaderElection(context.Background()) + if err != nil { + return fmt.Errorf("leader election init failed: %w", err) + } + + selfHost := config.BossConf.Boss_host + if selfHost == "" { + if h, e := os.Hostname(); e == nil { + selfHost = h + } else { + selfHost = "localhost" + } + } + selfAddr = fmt.Sprintf("%s:%s", selfHost, config.BossConf.Boss_port) + } + + pool, err := cloudvm.NewWorkerPool(config.BossConf.Platform, config.BossConf.Worker_Cap, etcdClient) if err != nil { return err } + if le != nil { + go func() { + slog.Info("campaigning for leadership", "self", selfAddr) + if err := le.Campaign(context.Background(), selfAddr); err != nil { + slog.Error("leader election campaign failed", "err", err) + return + } + if err := pool.ResyncFromEtcd(); err != nil { + slog.Error("etcd resync on election win failed", "err", err) + } + slog.Info("elected leader", "addr", selfAddr) + }() + } + store, err := lambdastore.NewLambdaStore(config.BossConf.GetLambdaStoreURL(), pool) if err != nil { return err @@ -168,16 +237,24 @@ func BossMain() (err error) { boss.autoScaler.Launch(boss.workerPool) } - // Launch 1 worker by default when boss starts - slog.Info("Launching 1 worker by default") - boss.workerPool.SetTarget(1) + // restore a prior target, else default to 1. + if pool.GetTarget() == 0 { + slog.Info("Launching 1 worker by default") + boss.workerPool.SetTarget(1) + } else { + slog.Info("resuming from etcd", "target", pool.GetTarget()) + boss.workerPool.SetTarget(pool.GetTarget()) + } + + wrap := func(h http.HandlerFunc) http.HandlerFunc { + return leaderOrRedirect(le, h) + } http.HandleFunc(BOSS_STATUS_PATH, boss.BossStatus) - http.HandleFunc(SCALING_PATH, boss.ScalingWorker) - http.HandleFunc(RUN_PATH, boss.workerPool.RunLambda) + http.HandleFunc(SCALING_PATH, wrap(boss.ScalingWorker)) + http.HandleFunc(RUN_PATH, wrap(boss.workerPool.RunLambda)) http.HandleFunc(SHUTDOWN_PATH, boss.Close) - - http.HandleFunc(REGISTRY_BASE_PATH, boss.RegistryHandler) + http.HandleFunc(REGISTRY_BASE_PATH, wrap(boss.RegistryHandler)) // clean up if signal hits us c := make(chan os.Signal, 1) @@ -186,6 +263,12 @@ func BossMain() (err error) { go func() { <-c slog.Info("received kill signal, cleaning up") + if le != nil { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + le.Resign(ctx) + le.Close() + cancel() + } boss.Close(nil, nil) os.Exit(0) }() diff --git a/go/boss/cloudvm/api.go b/go/boss/cloudvm/api.go index a9fed8ba8..a007fcb06 100644 --- a/go/boss/cloudvm/api.go +++ b/go/boss/cloudvm/api.go @@ -5,6 +5,8 @@ import ( "net/http" "os" "sync" + + "github.com/open-lambda/open-lambda/go/boss/etcd" ) // The WorkerState integer @@ -51,6 +53,8 @@ type WorkerPool struct { totalTask int32 sumLatency int64 nLatency int64 + + etcd *etcd.Client } /* diff --git a/go/boss/cloudvm/worker_pool.go b/go/boss/cloudvm/worker_pool.go index 0be0e03b3..16cf189d1 100644 --- a/go/boss/cloudvm/worker_pool.go +++ b/go/boss/cloudvm/worker_pool.go @@ -1,6 +1,7 @@ package cloudvm import ( + "context" "fmt" "io" "log/slog" @@ -10,9 +11,11 @@ import ( "os/user" "sync/atomic" "time" + + "github.com/open-lambda/open-lambda/go/boss/etcd" ) -func NewWorkerPool(platform string, worker_cap int) (*WorkerPool, error) { +func NewWorkerPool(platform string, worker_cap int, etcdClient *etcd.Client) (*WorkerPool, error) { clusterLogFile, _ := os.Create("cluster.log") taskLogFile, _ := os.Create("tasks.log") @@ -50,6 +53,13 @@ func NewWorkerPool(platform string, worker_cap int) (*WorkerPool, error) { pool.platform = platform pool.worker_cap = worker_cap + if etcdClient != nil { + pool.etcd = etcdClient + if err := pool.restoreFromEtcd(); err != nil { + return nil, fmt.Errorf("etcd restore failed: %w", err) + } + } + slog.Info(fmt.Sprintf("READY: worker pool of type %s", platform)) // log total outstanding tasks @@ -87,6 +97,7 @@ func (pool *WorkerPool) SetTarget(target int) { pool.Lock() pool.target = target + pool.persistMeta() pool.clusterLog.Info("set target", "target", pool.target) pool.Unlock() @@ -112,6 +123,8 @@ func (pool *WorkerPool) startNewWorker() { worker := pool.NewWorker(fmt.Sprintf("worker-%d", nextId)) worker.state = STARTING pool.workers[STARTING][worker.workerId] = worker + pool.persistWorker(worker) + pool.persistMeta() pool.clusterLog.Info("worker starting", "worker_id", worker.workerId, "target", pool.target, @@ -136,6 +149,7 @@ func (pool *WorkerPool) startNewWorker() { worker.state = RUNNING delete(pool.workers[STARTING], worker.workerId) pool.workers[RUNNING][worker.workerId] = worker + pool.persistWorker(worker) pool.clusterLog.Info("worker running", "worker_id", worker.workerId, @@ -162,6 +176,7 @@ func (pool *WorkerPool) recoverWorker(worker *Worker) { worker.state = RUNNING delete(pool.workers[CLEANING], worker.workerId) pool.workers[RUNNING][worker.workerId] = worker + pool.persistWorker(worker) pool.clusterLog.Info("worker running", "worker_id", worker.workerId, @@ -184,6 +199,7 @@ func (pool *WorkerPool) cleanWorker(worker *Worker) { worker.state = CLEANING delete(pool.workers[RUNNING], worker.workerId) pool.workers[CLEANING][worker.workerId] = worker + pool.persistWorker(worker) pool.clusterLog.Info("worker cleaning", "worker_id", worker.workerId, @@ -200,23 +216,25 @@ func (pool *WorkerPool) cleanWorker(worker *Worker) { slog.Info("worker cleaning progress", "worker_id", worker.workerId, "num_tasks", worker.numTask) pool.Lock() if _, ok := pool.workers[CLEANING][worker.workerId]; !ok { - return // stop if the worker is recovered + pool.Unlock() + return } pool.Unlock() time.Sleep(time.Second) } - pool.detroyWorker(worker) + pool.destroyWorker(worker) }(worker) } // destroy a worker from the cluster -func (pool *WorkerPool) detroyWorker(worker *Worker) { +func (pool *WorkerPool) destroyWorker(worker *Worker) { pool.Lock() worker.state = DESTROYING delete(pool.workers[CLEANING], worker.workerId) pool.workers[DESTROYING][worker.workerId] = worker + pool.persistWorker(worker) pool.clusterLog.Info("worker destroying", "worker_id", worker.workerId, @@ -240,6 +258,7 @@ func (pool *WorkerPool) detroyWorker(worker *Worker) { pool.Lock() delete(pool.workers[DESTROYING], worker.workerId) + pool.evictWorker(worker.workerId) slog.Info(fmt.Sprintf("%s destroyed", worker.workerId)) pool.clusterLog.Info("worker destroyed", @@ -377,6 +396,9 @@ func (w *Worker) runCmd(command string) { // return wokers' id and number of tasks func (pool *WorkerPool) StatusTasks() map[string]int { + pool.Lock() + defer pool.Unlock() + var output = map[string]int{} output["task/worker"] = 0 @@ -401,6 +423,9 @@ func (pool *WorkerPool) StatusTasks() map[string]int { // return status of cluster func (pool *WorkerPool) StatusCluster() map[string]int { + pool.Lock() + defer pool.Unlock() + var output = map[string]int{} output["starting"] = len(pool.workers[STARTING]) @@ -454,3 +479,155 @@ func GetWorkerAddress(worker *Worker) (string, error) { } return fmt.Sprintf("%s:%s", worker.host, worker.port), nil } + +// writes w's current state to etcd - no-op when etcd is disabled +// called immediately after every in-memory state transition. +func (pool *WorkerPool) persistWorker(w *Worker) { + if pool.etcd == nil { + return + } + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + rec := etcd.WorkerRecord{ + WorkerId: w.workerId, + State: int(w.state), + Host: w.host, + Port: w.port, + } + if err := pool.etcd.PutWorker(ctx, rec); err != nil { + slog.Error("etcd: failed to persist worker", "worker_id", w.workerId, "err", err) + } +} + +// removes a worker's record from etcd after it is fully destroyed. +func (pool *WorkerPool) evictWorker(workerId string) { + if pool.etcd == nil { + return + } + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := pool.etcd.DeleteWorker(ctx, workerId); err != nil { + slog.Error("etcd: failed to evict worker", "worker_id", workerId, "err", err) + } +} + +// persistMeta writes the pool's nextId and target to etcd. +func (pool *WorkerPool) persistMeta() { + if pool.etcd == nil { + return + } + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := pool.etcd.PutPoolMeta(ctx, etcd.PoolMeta{NextId: pool.nextId, Target: pool.target}); err != nil { + slog.Error("etcd: failed to persist pool meta", "err", err) + } +} + +// restoreFromEtcd reads all worker records from etcd and rebuilds the in-memory +// pool state. Called once during NewWorkerPool when etcd is enabled. +func (pool *WorkerPool) restoreFromEtcd() error { + ctx := context.Background() + + if meta, ok, err := pool.etcd.GetPoolMeta(ctx); err != nil { + return err + } else if ok { + pool.nextId = meta.NextId + pool.target = meta.Target + slog.Info("etcd: restored pool meta", "next_id", pool.nextId, "target", pool.target) + } + + records, err := pool.etcd.RestoreWorkers(ctx) + if err != nil { + return err + } + + for _, rec := range records { + w := pool.NewWorker(rec.WorkerId) + w.host = rec.Host + w.port = rec.Port + w.state = WorkerState(rec.State) + + switch w.state { + case RUNNING: + pool.workers[RUNNING][w.workerId] = w + pool.queue <- w + slog.Info("etcd: restored running worker", "worker_id", w.workerId, "host", w.host, "port", w.port) + + case CLEANING: + // boss died while worker was draining -> treat as RUNNING; + // updateCluster() will clean it if target < size. + w.state = RUNNING + pool.workers[RUNNING][w.workerId] = w + pool.queue <- w + pool.persistWorker(w) + slog.Info("etcd: restored cleaning worker as running", "worker_id", w.workerId) + + case STARTING, DESTROYING: + // mid-transition state: actual state is unknown. Drop it and let + // updateCluster() launch replacements to reach target. + pool.evictWorker(w.workerId) + slog.Warn("etcd: dropped ambiguous worker", "worker_id", w.workerId, "state", w.state) + } + } + + slog.Info("etcd: pool restore complete", "running", len(pool.workers[RUNNING]), "target", pool.target) + return nil +} + +// ResyncFromEtcd merges etcd state into the in-memory pool without clearing it. +// Called when this boss wins the leader election to add any workers the previous +// leader launched after this instance last read etcd. +func (pool *WorkerPool) ResyncFromEtcd() error { + if pool.etcd == nil { + return nil + } + ctx := context.Background() + + pool.Lock() + defer pool.Unlock() + + if meta, ok, err := pool.etcd.GetPoolMeta(ctx); err != nil { + return err + } else if ok { + pool.nextId = meta.NextId + pool.target = meta.Target + } + + records, err := pool.etcd.RestoreWorkers(ctx) + if err != nil { + return err + } + + for _, rec := range records { + known := false + for _, stateMap := range pool.workers { + if _, exists := stateMap[rec.WorkerId]; exists { + known = true + break + } + } + if known { + continue + } + + w := pool.NewWorker(rec.WorkerId) + w.host = rec.Host + w.port = rec.Port + w.state = WorkerState(rec.State) + + switch w.state { + case RUNNING, CLEANING: + w.state = RUNNING + pool.workers[RUNNING][w.workerId] = w + pool.queue <- w + pool.persistWorker(w) + slog.Info("etcd: resync added worker", "worker_id", w.workerId) + case STARTING, DESTROYING: + pool.evictWorker(w.workerId) + slog.Warn("etcd: resync dropped ambiguous worker", "worker_id", w.workerId, "state", rec.State) + } + } + + slog.Info("etcd: resync complete", "running", len(pool.workers[RUNNING]), "target", pool.target) + return nil +} diff --git a/go/boss/config/config.go b/go/boss/config/config.go index e232ad4df..bffc8533f 100644 --- a/go/boss/config/config.go +++ b/go/boss/config/config.go @@ -9,14 +9,23 @@ import ( var BossConf *Config +type EtcdConfig struct { + Endpoints []string `json:"endpoints"` + Prefix string `json:"prefix"` + Dial_timeout_sec int `json:"dial_timeout_sec"` + Enable_HA bool `json:"enable_ha"` +} + type Config struct { Platform string `json:"platform"` Scaling string `json:"scaling"` API_key string `json:"api_key"` Boss_port string `json:"boss_port"` + Boss_host string `json:"boss_host"` Worker_Cap int `json:"worker_cap"` Gcp GcpConfig `json:"gcp"` Local LocalPlatConfig `json:"local"` + Etcd EtcdConfig `json:"etcd"` } func LoadDefaults() error { @@ -28,6 +37,7 @@ func LoadDefaults() error { Worker_Cap: 4, Gcp: GetGcpConfigDefaults(), Local: GetLocalPlatformConfigDefaults(), + Etcd: EtcdConfig{Prefix: "ol", Dial_timeout_sec: 5}, } return checkConf() diff --git a/go/boss/etcd/client.go b/go/boss/etcd/client.go new file mode 100644 index 000000000..4534ed1a9 --- /dev/null +++ b/go/boss/etcd/client.go @@ -0,0 +1,41 @@ +package etcd + +import ( + "fmt" + "strings" + "time" + + clientv3 "go.etcd.io/etcd/client/v3" +) + +// client wraps the etcd v3 client and owns the connection lifecycle. +// all key-space operations are namespaced under a configurable prefix. +type Client struct { + raw *clientv3.Client + kv clientv3.KV + prefix string +} + +func NewClient(endpoints []string, prefix string, dialTimeout time.Duration) (*Client, error) { + raw, err := clientv3.New(clientv3.Config{ + Endpoints: endpoints, + DialTimeout: dialTimeout, + }) + if err != nil { + return nil, fmt.Errorf("etcd dial failed: %w", err) + } + return &Client{ + raw: raw, + kv: clientv3.NewKV(raw), + prefix: strings.TrimRight(prefix, "/"), + }, nil +} + +func (c *Client) Close() error { + return c.raw.Close() +} + +// key returns a namespaced etcd key. +func (c *Client) key(parts ...string) string { + return c.prefix + "/" + strings.Join(parts, "/") +} diff --git a/go/boss/etcd/leader.go b/go/boss/etcd/leader.go new file mode 100644 index 000000000..7c323c0a6 --- /dev/null +++ b/go/boss/etcd/leader.go @@ -0,0 +1,75 @@ +package etcd + +import ( + "context" + "fmt" + "sync" + + "go.etcd.io/etcd/client/v3/concurrency" +) + +// manages this boss instance's participation in the etcd election. +// only one boss is leader at a time - followers redirect mutating requests to leader +type LeaderElection struct { + session *concurrency.Session + election *concurrency.Election + mu sync.RWMutex + leader bool +} + +// creates an election participant backed by a TTL session. +// if this boss dies, the session expires and the next candidate wins within TTL +func (c *Client) NewLeaderElection(ctx context.Context) (*LeaderElection, error) { + session, err := concurrency.NewSession(c.raw, concurrency.WithTTL(10)) + if err != nil { + return nil, fmt.Errorf("etcd session: %w", err) + } + return &LeaderElection{ + session: session, + election: concurrency.NewElection(session, c.key("boss", "leader")), + }, nil +} + +// blocks until this instance wins the election or ctx is cancelled. +// selfAddr ("host:port") is stored as the election value so followers can +// redirect requests to the leader. +func (le *LeaderElection) Campaign(ctx context.Context, selfAddr string) error { + if err := le.election.Campaign(ctx, selfAddr); err != nil { + return err + } + le.mu.Lock() + le.leader = true + le.mu.Unlock() + return nil +} + +// yields leadership immediately so the next candidate wins without +// waiting for the TTL to expire. should be called on clean shutdown. +func (le *LeaderElection) Resign(ctx context.Context) error { + le.mu.Lock() + le.leader = false + le.mu.Unlock() + return le.election.Resign(ctx) +} + +func (le *LeaderElection) IsLeader() bool { + le.mu.RLock() + defer le.mu.RUnlock() + return le.leader +} + +// returns the current leader "host:port" by reading the election key. +func (le *LeaderElection) LeaderAddr(ctx context.Context) (string, error) { + resp, err := le.election.Leader(ctx) + if err != nil { + return "", fmt.Errorf("etcd leader lookup: %w", err) + } + if len(resp.Kvs) == 0 { + return "", fmt.Errorf("no leader elected yet") + } + return string(resp.Kvs[0].Value), nil +} + +func (le *LeaderElection) Close() error { + return le.session.Close() +} diff --git a/go/boss/etcd/worker_store.go b/go/boss/etcd/worker_store.go new file mode 100644 index 000000000..a20b83d74 --- /dev/null +++ b/go/boss/etcd/worker_store.go @@ -0,0 +1,91 @@ +package etcd + +import ( + "context" + "encoding/json" + "fmt" + "log/slog" + + clientv3 "go.etcd.io/etcd/client/v3" +) + +// etcd-serialized snapshot of a single worker. +// State mirrors the cloudvm WorkerState constants +type WorkerRecord struct { + WorkerId string `json:"worker_id"` + State int `json:"state"` + Host string `json:"host"` + Port string `json:"port"` +} + +// holds pool-level counters that must survive boss restarts. +type PoolMeta struct { + NextId int `json:"next_id"` + Target int `json:"target"` +} + +func (c *Client) workerKey(workerId string) string { + return c.key("workers", workerId) +} + +func (c *Client) poolMetaKey() string { + return c.key("pool", "meta") +} + +func (c *Client) PutWorker(ctx context.Context, rec WorkerRecord) error { + b, err := json.Marshal(rec) + if err != nil { + return fmt.Errorf("marshal worker record: %w", err) + } + _, err = c.kv.Put(ctx, c.workerKey(rec.WorkerId), string(b)) + return err +} + +func (c *Client) DeleteWorker(ctx context.Context, workerId string) error { + _, err := c.kv.Delete(ctx, c.workerKey(workerId)) + return err +} + +// fetches all worker records stored under the workers/ prefix. +func (c *Client) RestoreWorkers(ctx context.Context) ([]WorkerRecord, error) { + prefix := c.key("workers") + "/" + resp, err := c.kv.Get(ctx, prefix, clientv3.WithPrefix()) + if err != nil { + return nil, fmt.Errorf("etcd get workers: %w", err) + } + records := make([]WorkerRecord, 0, len(resp.Kvs)) + for _, kv := range resp.Kvs { + var rec WorkerRecord + if err := json.Unmarshal(kv.Value, &rec); err != nil { + slog.Warn("skipping unreadable worker record", "key", string(kv.Key), "err", err) + continue + } + records = append(records, rec) + } + return records, nil +} + +func (c *Client) PutPoolMeta(ctx context.Context, meta PoolMeta) error { + b, err := json.Marshal(meta) + if err != nil { + return fmt.Errorf("marshal pool meta: %w", err) + } + _, err = c.kv.Put(ctx, c.poolMetaKey(), string(b)) + return err +} + +// returns the stored pool metadata. +func (c *Client) GetPoolMeta(ctx context.Context) (PoolMeta, bool, error) { + resp, err := c.kv.Get(ctx, c.poolMetaKey()) + if err != nil { + return PoolMeta{}, false, fmt.Errorf("etcd get pool meta: %w", err) + } + if len(resp.Kvs) == 0 { + return PoolMeta{}, false, nil + } + var meta PoolMeta + if err := json.Unmarshal(resp.Kvs[0].Value, &meta); err != nil { + return PoolMeta{}, false, fmt.Errorf("unmarshal pool meta: %w", err) + } + return meta, true, nil +} diff --git a/go/go.mod b/go/go.mod index 58e168923..086b0a847 100644 --- a/go/go.mod +++ b/go/go.mod @@ -1,8 +1,6 @@ module github.com/open-lambda/open-lambda/go -go 1.24.0 - -toolchain go1.24.4 +go 1.25.0 require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 @@ -23,11 +21,11 @@ replace github.com/Azure/azure-sdk-for-go/sdk/storage/azblob => github.com/Azure replace github.com/Azure/azure-sdk-for-go/sdk/azidentity => github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 require ( - cel.dev/expr v0.23.0 // indirect + cel.dev/expr v0.25.1 // indirect cloud.google.com/go v0.121.1 // indirect cloud.google.com/go/auth v0.16.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect - cloud.google.com/go/compute/metadata v0.7.0 // indirect + cloud.google.com/go/compute/metadata v0.9.0 // indirect cloud.google.com/go/iam v1.5.2 // indirect cloud.google.com/go/monitoring v1.24.2 // indirect cloud.google.com/go/storage v1.55.0 // indirect @@ -35,7 +33,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect @@ -60,27 +58,31 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.33.17 // indirect github.com/aws/smithy-go v1.22.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect + github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect github.com/containerd/containerd v1.6.26 // indirect github.com/containerd/log v0.1.0 // indirect + github.com/coreos/go-semver v0.3.1 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/docker/docker v25.0.6+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect - github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect + github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect + github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-jose/go-jose/v4 v4.0.5 // indirect - github.com/go-logr/logr v1.4.2 // indirect + github.com/go-jose/go-jose/v4 v4.1.3 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v5 v5.2.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect github.com/google/wire v0.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect github.com/googleapis/gax-go/v2 v2.14.2 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/klauspost/compress v1.18.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect @@ -97,32 +99,37 @@ require ( github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect + github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect github.com/twmb/franz-go/pkg/kmsg v1.11.2 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/zeebo/errs v1.4.0 // indirect + go.etcd.io/etcd/api/v3 v3.6.11 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.6.11 // indirect + go.etcd.io/etcd/client/v3 v3.6.11 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/detectors/gcp v1.36.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect - go.opentelemetry.io/otel v1.36.0 // indirect - go.opentelemetry.io/otel/metric v1.36.0 // indirect - go.opentelemetry.io/otel/sdk v1.36.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect - go.opentelemetry.io/otel/trace v1.36.0 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/text v0.31.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.49.0 // indirect + golang.org/x/net v0.52.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.42.0 // indirect + golang.org/x/text v0.36.0 // indirect golang.org/x/time v0.11.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/api v0.235.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/grpc v1.73.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.10 // indirect ) diff --git a/go/go.sum b/go/go.sum index 11c94f6c5..748510d9a 100644 --- a/go/go.sum +++ b/go/go.sum @@ -1,5 +1,7 @@ cel.dev/expr v0.23.0 h1:wUb94w6OYQS4uXraxo9U+wUAs9jT47Xvl4iPgAwM2ss= cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.121.1 h1:S3kTQSydxmu1JfLRLpKtxRPA7rSrYPRPEUmL/PavVUw= cloud.google.com/go v0.121.1/go.mod h1:nRFlrHq39MNVWu+zESP2PosMWA0ryJw8KUBZ2iZpxbw= @@ -9,6 +11,8 @@ cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIi cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc= @@ -38,6 +42,8 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0 h1:OqVGm6Ei3x5+yZmSJG1Mh2NwHvpVmZ08CB5qJhT9Nuk= @@ -95,10 +101,16 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k= github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= github.com/containerd/containerd v1.6.26 h1:VVfrE6ZpyisvB1fzoY8Vkiq4sy+i5oF4uk7zu03RaHs= github.com/containerd/containerd v1.6.26/go.mod h1:I4TRdsdoo5MlKob5khDJS2EPT1l1oMNaE2MBm6FrwxM= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= @@ -106,6 +118,7 @@ github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg= github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= @@ -117,24 +130,34 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA= +github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g= +github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4= +github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsouza/go-dockerclient v1.10.1 h1:bSU5Wu2ARdub+iv9VtoDsN8yBUI0vgflmshbeQLKhvc= github.com/fsouza/go-dockerclient v1.10.1/go.mod h1:dyzGriw6v3pK4O4O1u/X+vXxDDsrnLLkCqYkcLsDq2k= github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= +github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= +github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= @@ -183,6 +206,9 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/gax-go/v2 v2.14.2 h1:eBLnkZ9635krYIPD+ag1USrOAI0Nr0QYF3+/3GqO0k0= github.com/googleapis/gax-go/v2 v2.14.2/go.mod h1:ON64QhlJkhVtSqp4v1uaK92VyZ2gmvDQsweuyLV+8+w= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= @@ -222,11 +248,13 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgm github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -234,6 +262,8 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= +github.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo= +github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -243,6 +273,7 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/twmb/franz-go v1.19.0 h1:FzBAPUeaip68X9cbLDesgQesa5zxKVaZMk+du98vj3c= github.com/twmb/franz-go v1.19.0/go.mod h1:4kFJ5tmbbl7asgwAGVuyG1ZMx0NNpYk7EqflvWfPCpM= github.com/twmb/franz-go/pkg/kmsg v1.11.2 h1:hIw75FpwcAjgeyfIGFqivAvwC5uNIOWRGvQgZhH4mhg= @@ -256,28 +287,52 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +go.etcd.io/etcd/api/v3 v3.6.11 h1:XFGTgrJ8nak3kB4NgMG8t7NT+lEeuuvKQAqUHKVgkWQ= +go.etcd.io/etcd/api/v3 v3.6.11/go.mod h1:HYfTh0jyh+uFgp6gMbxJteIDYY97yMuYz85Rnw6Gy9o= +go.etcd.io/etcd/client/pkg/v3 v3.6.11 h1:e41mp315Yn3QMGPmEzCyLsMINgJXTY/dX8kM++1csxU= +go.etcd.io/etcd/client/pkg/v3 v3.6.11/go.mod h1:DysuMe/inqRyC/1tjRR6hReH/VV9Lufs27YKSKBWWJg= +go.etcd.io/etcd/client/v3 v3.6.11 h1:LAByD96VmmeuairkvdAcE0RZnrmGz/q3ceeWePo9bwc= +go.etcd.io/etcd/client/v3 v3.6.11/go.mod h1:vOTDMCo+fGPEClJqcFEFSqZ+8e7WKV7AyqJjX//HR2w= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/detectors/gcp v1.36.0 h1:F7q2tNlCaHY9nMKHR6XH9/qkp8FktLnIcy6jJNyOCQw= go.opentelemetry.io/contrib/detectors/gcp v1.36.0/go.mod h1:IbBN8uAIIx734PTonTPxAxnjc2pQTxWNkwfstZ+6H2k= +go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE= +go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +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.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= gocloud.dev v0.42.0 h1:qzG+9ItUL3RPB62/Amugws28n+4vGZXEoJEAMfjutzw= gocloud.dev v0.42.0/go.mod h1:zkaYAapZfQisXOA4bzhsbA4ckiStGQ3Psvs9/OQ5dPM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -288,6 +343,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -315,9 +372,13 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= 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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -329,6 +390,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -346,6 +409,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -354,6 +419,7 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -363,6 +429,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -395,8 +463,12 @@ google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuO google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -404,6 +476,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= 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= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -415,6 +489,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=