From 98037da4d198a0557288fe44b991dad64d3a557a Mon Sep 17 00:00:00 2001 From: Keenan Gebze Date: Wed, 28 May 2025 00:58:46 +0700 Subject: [PATCH 1/6] update client --- example/auth-client/admin-access/main.go | 2 +- example/user-profile-client/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/auth-client/admin-access/main.go b/example/auth-client/admin-access/main.go index 8762c27..fddb689 100644 --- a/example/auth-client/admin-access/main.go +++ b/example/auth-client/admin-access/main.go @@ -75,7 +75,7 @@ func main() { authorizedUserSync := mycontentapiclient.Sync(authorizedUserClient, "*", sampleUsers, mycontentapiclient.OptionalConfig{ AuthorizationToken: *ar.IDToken, - }).WithImages(authorizedUserImagesClient, extractAuthorizedUserImages, ".") + }).WithImages(authorizedUserImagesClient, extractAuthorizedUserImages, ".", nil) errUC = authorizedUserSync.Execute(context.Background()) if errUC != nil { diff --git a/example/user-profile-client/main.go b/example/user-profile-client/main.go index b33f81a..76d212a 100644 --- a/example/user-profile-client/main.go +++ b/example/user-profile-client/main.go @@ -23,7 +23,7 @@ func main() { orgSync := mycontentapiclient.Sync(orgClient, "*", sampleOrg, mycontentapiclient.OptionalConfig{}) userSync := mycontentapiclient.Sync(userClient, "*", sampleUser, mycontentapiclient.OptionalConfig{}). - WithImages(userThumbnailClient, getUserProfileImage, ".") // upload from local URL, with . root directory + WithImages(userThumbnailClient, getUserProfileImage, ".", nil) // upload from local URL, with . root directory ctx := context.Background() orgSync.Execute(ctx) From 8a6b3990189d2350349289562de59ff08b4976c1 Mon Sep 17 00:00:00 2001 From: Keenan Gebze Date: Thu, 10 Jul 2025 02:10:25 +0700 Subject: [PATCH 2/6] initial explore --- .gitignore | 2 + delivery/raft-enabled-api/dragonboat.go | 51 +++++ delivery/raft-enabled-api/fsm.go | 83 +++++++ delivery/raft-enabled-api/fsm_disk.go | 279 ++++++++++++++++++++++++ example/raft/go.mod | 3 + example/raft/main.go | 156 +++++++++++++ example/raft/module_auth.go | 100 +++++++++ go.mod | 41 +++- go.sum | 192 +++++++++++++++- 9 files changed, 902 insertions(+), 5 deletions(-) create mode 100644 delivery/raft-enabled-api/dragonboat.go create mode 100644 delivery/raft-enabled-api/fsm.go create mode 100644 delivery/raft-enabled-api/fsm_disk.go create mode 100644 example/raft/go.mod create mode 100644 example/raft/main.go create mode 100644 example/raft/module_auth.go diff --git a/.gitignore b/.gitignore index 8cc92bc..29284ba 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ mochawesome-report/ go.work go.work.sum *.pem +.rjs + diff --git a/delivery/raft-enabled-api/dragonboat.go b/delivery/raft-enabled-api/dragonboat.go new file mode 100644 index 0000000..0032fb9 --- /dev/null +++ b/delivery/raft-enabled-api/dragonboat.go @@ -0,0 +1,51 @@ +package raftenabledapi + +import ( + "encoding/json" + "io" + "net/http" + + "github.com/julienschmidt/httprouter" + "github.com/lni/dragonboat/v4" + "github.com/lni/dragonboat/v4/config" +) + +type dragonboatImpl struct { + nh *dragonboat.NodeHost +} + +func NewDragonboatReplica(nh *dragonboat.NodeHost) *dragonboatImpl { + return nil +} + +type initializeRequest struct { + Password string `json:"password"` + GSIClientID string `json:"gsi_client_id"` + GSIAdminEmails string `json:"gsi_admin_emails"` + JWTSigningKey string `json:"jwt_signing_key"` + + InitialMember map[uint64]dragonboat.Target `json:"initial_member"` +} + +func (d *dragonboatImpl) StartReplica(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + payload, err := io.ReadAll(r.Body) + if err != nil { + return + } + + var req initializeRequest + err = json.Unmarshal(payload, &req) + if err != nil { + return + } + + rc := config.Config{ + ReplicaID: 0, + ShardID: 0, + } + + err = d.nh.StartOnDiskReplica(req.InitialMember, false, NewDiskKV, rc) + if err != nil { + return + } +} diff --git a/delivery/raft-enabled-api/fsm.go b/delivery/raft-enabled-api/fsm.go new file mode 100644 index 0000000..0cf959f --- /dev/null +++ b/delivery/raft-enabled-api/fsm.go @@ -0,0 +1,83 @@ +package raftenabledapi + +import ( + "encoding/binary" + "fmt" + "io" + "io/ioutil" + + sm "github.com/lni/dragonboat/v4/statemachine" +) + +// ExampleStateMachine is the IStateMachine implementation used in the +// helloworld example. +// See https://github.com/lni/dragonboat/blob/master/statemachine/rsm.go for +// more details of the IStateMachine interface. +type ExampleStateMachine struct { + ShardID uint64 + ReplicaID uint64 + Count uint64 +} + +// NewExampleStateMachine creates and return a new ExampleStateMachine object. +func NewExampleStateMachine(shardID uint64, + replicaID uint64) sm.IStateMachine { + return &ExampleStateMachine{ + ShardID: shardID, + ReplicaID: replicaID, + Count: 0, + } +} + +// Lookup performs local lookup on the ExampleStateMachine instance. In this example, +// we always return the Count value as a little endian binary encoded byte +// slice. +func (s *ExampleStateMachine) Lookup(query interface{}) (interface{}, error) { + result := make([]byte, 8) + binary.LittleEndian.PutUint64(result, s.Count) + return result, nil +} + +// Update updates the object using the specified committed raft entry. +func (s *ExampleStateMachine) Update(e sm.Entry) (sm.Result, error) { + // in this example, we print out the following hello world message for each + // incoming update request. we also increase the counter by one to remember + // how many updates we have applied + s.Count++ + fmt.Printf("from ExampleStateMachine.Update(), msg: %s, count:%d\n", + string(e.Cmd), s.Count) + return sm.Result{Value: uint64(len(e.Cmd))}, nil +} + +// SaveSnapshot saves the current IStateMachine state into a snapshot using the +// specified io.Writer object. +func (s *ExampleStateMachine) SaveSnapshot(w io.Writer, + fc sm.ISnapshotFileCollection, done <-chan struct{}) error { + // as shown above, the only state that can be saved is the Count variable + // there is no external file in this IStateMachine example, we thus leave + // the fc untouched + data := make([]byte, 8) + binary.LittleEndian.PutUint64(data, s.Count) + _, err := w.Write(data) + return err +} + +// RecoverFromSnapshot recovers the state using the provided snapshot. +func (s *ExampleStateMachine) RecoverFromSnapshot(r io.Reader, + files []sm.SnapshotFile, + done <-chan struct{}) error { + // restore the Count variable, that is the only state we maintain in this + // example, the input files is expected to be empty + data, err := ioutil.ReadAll(r) + if err != nil { + return err + } + v := binary.LittleEndian.Uint64(data) + s.Count = v + return nil +} + +// Close closes the IStateMachine instance. There is nothing for us to cleanup +// or release as this is a pure in memory data store. Note that the Close +// method is not guaranteed to be called as node can crash at any time. +func (s *ExampleStateMachine) Close() error { return nil } diff --git a/delivery/raft-enabled-api/fsm_disk.go b/delivery/raft-enabled-api/fsm_disk.go new file mode 100644 index 0000000..333e8a2 --- /dev/null +++ b/delivery/raft-enabled-api/fsm_disk.go @@ -0,0 +1,279 @@ +package raftenabledapi + +import ( + "encoding/binary" + "encoding/json" + "fmt" + "io" + "log" + "time" + + bolt "go.etcd.io/bbolt" + + sm "github.com/lni/dragonboat/v4/statemachine" +) + +const ( + testDBDirName string = "example-data" + currentDBFilename string = "current" + updatingDBFilename string = "current.updating" +) + +var ( + configBucket []byte = []byte("config") + + lastEchoKey []byte = []byte("echo") + gsiConfigKey []byte = []byte("gsi_config") + appliedIndexKey []byte = []byte("applied_index") +) + +// DiskKV is a state machine that implements the IOnDiskStateMachine interface. +// DiskKV stores key-value pairs in the underlying PebbleDB key-value store. As +// it is used as an example, it is implemented using the most basic features +// common in most key-value stores. This is NOT a benchmark program. +type DiskKV struct { + shardID uint64 + replicaID uint64 + lastApplied uint64 + db *bolt.DB + closed bool + aborted bool +} + +// NewDiskKV creates a new disk kv test state machine. +func NewDiskKV(clusterID uint64, nodeID uint64) sm.IOnDiskStateMachine { + d := &DiskKV{ + shardID: clusterID, + replicaID: nodeID, + } + return d +} + +// Open opens the state machine and return the index of the last Raft Log entry +// already updated into the state machine. +func (d *DiskKV) Open(stopc <-chan struct{}) (uint64, error) { + path := fmt.Sprintf(".rjs/%v/state-%v.db", d.replicaID, d.shardID) + db, err := bolt.Open(path, 0600, &bolt.Options{Timeout: 5 * time.Second}) + if err != nil { + return 0, err + } + + var lastAppliedIdx uint64 + err = db.Update(func(tx *bolt.Tx) error { + cb, err := tx.CreateBucketIfNotExists([]byte("state")) + if err != nil { + return err + } + + val := cb.Get([]byte("appliedIndex")) + if len(val) == 0 { + return nil + } + + lastAppliedIdx = binary.LittleEndian.Uint64(val) + + return nil + }) + if err != nil { + return 0, err + } + + d.db = db + d.lastApplied = lastAppliedIdx + + return d.lastApplied, nil +} + +// Lookup queries the state machine. +func (d *DiskKV) Lookup(key interface{}) (interface{}, error) { + var val []byte + // next, validate + // next, batch update + err := d.db.Update(func(tx *bolt.Tx) error { + bucket, err := tx.CreateBucketIfNotExists(configBucket) + if err != nil { + return err + } + + val = bucket.Get(lastEchoKey) + + return nil + }) + if err != nil { + return nil, err + } + + if err != nil { + return nil, err + } + + return string(val) + " waalaikumsalam", nil +} + +const ( + // Allow GSI authentication in the cluster + SetGSIConfig MessageType = "set_gsi_config" + + Echo MessageType = "echo" +) + +type MessageType string + +// Google Sign-in config that allows authentication to the cluster +type GSIConfig struct { + ClientID string `json:"client_id"` + AdminEmails string `json:"admin_emails"` +} + +// Update updates the state machine. In this example, all updates are put into +// a PebbleDB write batch and then atomically written to the DB together with +// the index of the last Raft Log entry. For simplicity, we always Sync the +// writes (db.wo.Sync=True). To get higher throughput, you can implement the +// Sync() method below and choose not to synchronize for every Update(). Sync() +// will periodically called by Dragonboat to synchronize the state. +func (d *DiskKV) Update(ents []sm.Entry) ([]sm.Entry, error) { + if d.aborted { + panic("update() called after abort set to true") + } + if d.closed { + panic("update called after Close()") + } + + for idx, e := range ents { + var cmd Message + + if err := json.Unmarshal(e.Cmd, &cmd); err != nil { + continue + } + + switch cmd.Type { + case Echo: + log.Println("RECEIVE ECHO", string(cmd.Payload)) + err := d.db.Update(func(tx *bolt.Tx) error { + bucket, err := tx.CreateBucketIfNotExists(configBucket) + if err != nil { + return err + } + + var msg string + err = json.Unmarshal(cmd.Payload, &msg) + if err != nil { + return err + } + + err = bucket.Put(lastEchoKey, []byte(msg)) + if err != nil { + return err + } + + return nil + }) + if err != nil { + log.Println("RECEIVE ECHO ERROR", string(cmd.Payload)) + + continue + } + case SetGSIConfig: + var gsiConfig GSIConfig + if err := json.Unmarshal(cmd.Payload, &gsiConfig); err != nil { + continue + } + + // next, validate + // next, batch update + err := d.db.Update(func(tx *bolt.Tx) error { + bucket, err := tx.CreateBucketIfNotExists(configBucket) + if err != nil { + return err + } + + err = bucket.Put(gsiConfigKey, cmd.Payload) + if err != nil { + return err + } + + return nil + }) + if err != nil { + continue + } + + ents[idx].Result = sm.Result{Value: uint64(len(cmd.Payload))} + } + } + + // save the applied index to the DB. + appliedIndex := make([]byte, 8) + binary.LittleEndian.PutUint64(appliedIndex, ents[len(ents)-1].Index) + + err := d.db.Update(func(tx *bolt.Tx) error { + bucket, err := tx.CreateBucketIfNotExists(configBucket) + if err != nil { + return err + } + err = bucket.Put(appliedIndexKey, appliedIndex) + if err != nil { + return err + } + return nil + }) + if err != nil { + return nil, err + } + + if d.lastApplied >= ents[len(ents)-1].Index { + panic("lastApplied not moving forward") + } + d.lastApplied = ents[len(ents)-1].Index + return ents, nil +} + +// Sync synchronizes all in-core state of the state machine. Since the Update +// method in this example already does that every time when it is invoked, the +// Sync method here is a NoOP. +func (d *DiskKV) Sync() error { + return nil +} + +// PrepareSnapshot prepares snapshotting. PrepareSnapshot is responsible to +// capture a state identifier that identifies a point in time state of the +// underlying data. In this example, we use Pebble's snapshot feature to +// achieve that. +func (d *DiskKV) PrepareSnapshot() (interface{}, error) { + return nil, nil +} + +// SaveSnapshot saves the state machine state identified by the state +// identifier provided by the input ctx parameter. Note that SaveSnapshot +// is not suppose to save the latest state. +func (d *DiskKV) SaveSnapshot(ctx interface{}, + w io.Writer, done <-chan struct{}) error { + + return nil +} + +// RecoverFromSnapshot recovers the state machine state from snapshot. The +// snapshot is recovered into a new DB first and then atomically swapped with +// the existing DB to complete the recovery. +func (d *DiskKV) RecoverFromSnapshot(r io.Reader, + done <-chan struct{}) error { + + return nil +} + +// Close closes the state machine. +func (d *DiskKV) Close() error { + err := d.db.Close() + if err != nil { + return err + } + + d.closed = true + + return nil +} + +type Message struct { + Type MessageType `json:"type"` + Payload json.RawMessage `json:"payload"` +} diff --git a/example/raft/go.mod b/example/raft/go.mod new file mode 100644 index 0000000..686a6b2 --- /dev/null +++ b/example/raft/go.mod @@ -0,0 +1,3 @@ +module github.com/desain-gratis/common/example/raft + +go 1.23.4 diff --git a/example/raft/main.go b/example/raft/main.go new file mode 100644 index 0000000..24700ab --- /dev/null +++ b/example/raft/main.go @@ -0,0 +1,156 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "net/http" + "os" + "os/signal" + "path" + "strconv" + "strings" + "time" + + raftenabledapi "github.com/desain-gratis/common/delivery/raft-enabled-api" + "github.com/julienschmidt/httprouter" + "github.com/lni/dragonboat/v4" + "github.com/lni/dragonboat/v4/config" +) + +const ( + // shard ID for config + defaultShardID uint64 = 128 + datadir string = ".rjs" // raft job scheduler +) + +func main() { + var replicaID uint64 + var httpAddr string + var raftAddr string + var bootstrap string + flag.Uint64Var(&replicaID, "replica-id", 1, "replica id for this host") + flag.StringVar(&httpAddr, "http-addr", "", "http bind adddress :") + flag.StringVar(&raftAddr, "raft-addr", "", "bind adddress :") + flag.StringVar(&bootstrap, "bootstrap", "", "comma separated of replica's [:
:] pair for cluster config") + + flag.Parse() + + nhc := config.NodeHostConfig{ + WALDir: path.Join(datadir, strconv.FormatUint(replicaID, 10), "raft", "wal"), + NodeHostDir: path.Join(datadir, strconv.FormatUint(replicaID, 10), "raft", "etc"), + RTTMillisecond: 200, + RaftAddress: raftAddr, + } + + bootstrapServerByReplicaID := make(map[uint64]dragonboat.Target) + // process + tokens := strings.Split(bootstrap, ",") + for _, token := range tokens { + if token == "" { + continue + } + st := strings.Split(token, ":") + replicaIDstr := st[0] + otherReplicaID, err := strconv.ParseUint(replicaIDstr, 10, 64) + if err != nil { + log.Panicf("invalid replica id: %v. not an uint64\n", replicaIDstr) + } + + othersRaftAddr := strings.Join(st[1:], ":") + + if replicaID == otherReplicaID || raftAddr == othersRaftAddr { + log.Panicf("conflicted replica ID: %v OR bind addr: %v\n", replicaID, raftAddr) + } + + bootstrapServerByReplicaID[otherReplicaID] = dragonboat.Target( + othersRaftAddr, + ) + } + + join := len(bootstrapServerByReplicaID) == 0 + + if !join { + // add ourself as part of the cluster + bootstrapServerByReplicaID[replicaID] = raftAddr + } + + nh, err := dragonboat.NewNodeHost(nhc) + if err != nil { + log.Panicln("err dragon rising", err) + return + } + + repc := config.Config{ + ReplicaID: replicaID, + ShardID: defaultShardID, + ElectionRTT: 10, + HeartbeatRTT: 1, + CheckQuorum: true, + SnapshotEntries: 100, // if snapshot is not implemented can crash + CompactionOverhead: 5, + } + + info := map[string]any{ + "replica_id": replicaID, + "shard_id": defaultShardID, + "join": join, + "bootstrap_info": bootstrapServerByReplicaID, + "http-addr": httpAddr, + "raft-addr": raftAddr, + } + + if err := nh.StartOnDiskReplica( + bootstrapServerByReplicaID, + join, + raftenabledapi.NewDiskKV, + repc, + ); err != nil { // config needs to be always be same as first init ..? + fmt.Fprintf(os.Stderr, "failed to add cluster, %v\n", err) + os.Exit(1) + } + + raftSession := nh.GetNoOPSession(defaultShardID) + + // http handler + + router := httprouter.New() + + enableAuthAPI(router, nh, raftSession, info) + + // start http endopoint + server := http.Server{ + Addr: httpAddr, + Handler: router, + ReadTimeout: time.Duration(10) * time.Second, + WriteTimeout: time.Duration(10) * time.Second, + } + + finished := make(chan struct{}) + go func() { + defer close(finished) + sigint := make(chan os.Signal, 1) + signal.Notify(sigint, os.Interrupt) + <-sigint + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + // log.Info().Msgf("Shutting down HTTP server..") + if err := server.Shutdown(ctx); err != nil { + // eg. timeout + // log.Err(err).Msgf("HTTP server Shutdown") + } + // log.Info().Msgf("Stopped serving new connections.") + }() + + // log.Info().Msgf("Serving at %v..\n", address) + if err := server.ListenAndServe(); err != http.ErrServerClosed { + // Error starting or closing listener: + // log.Fatal().Msgf("HTTP server ListendAndServe: %v", err) + } + + <-finished + log.Println("bye~ 👋🏼") +} diff --git a/example/raft/module_auth.go b/example/raft/module_auth.go new file mode 100644 index 0000000..ecb2d72 --- /dev/null +++ b/example/raft/module_auth.go @@ -0,0 +1,100 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "time" + + "github.com/julienschmidt/httprouter" + "github.com/lni/dragonboat/v4" + "github.com/lni/dragonboat/v4/client" +) + +func enableAuthAPI(router *httprouter.Router, nh *dragonboat.NodeHost, ses *client.Session, info map[string]any) { + router.POST("/auth/gsi", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second) + defer cancel() + + id, term, valid, err := nh.GetLeaderID(defaultShardID) + + info["leader_id"] = id + info["leader_term"] = term + info["leader_valid"] = valid + info["leader_err"] = err + + info["our_id"] = nh.ID() + + if nhregis, ok := nh.GetNodeHostRegistry(); ok { + info["nhregis_nshards"] = nhregis.NumOfShards() + if meta, ok := nhregis.GetMeta("test"); ok { + info["meta"] = meta + } + if si, ok := nhregis.GetShardInfo(defaultShardID); ok { + info["si_config_change_index"] = si.ConfigChangeIndex + info["si_leader_id"] = si.LeaderID + info["si_replicas"] = si.Replicas + info["si_shard_id"] = si.ShardID + info["si_term"] = si.Term + } + } + + res, err := nh.SyncPropose(ctx, ses, []byte(`{"type":"echo", "payload": "assalamualaikum"}`)) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + info["message"] = "err: " + err.Error() + result, _ := json.Marshal(info) + w.Write(result) + return + } + + w.WriteHeader(http.StatusOK) + info["message"] = fmt.Sprintf("SUCCESS: %v (%v)", string(res.Data), res.Value) + result, _ := json.Marshal(info) + w.Write(result) + }) + + router.GET("/ingfo", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second) + defer cancel() + + id, term, valid, err := nh.GetLeaderID(defaultShardID) + + info["leader_id"] = id + info["leader_term"] = term + info["leader_valid"] = valid + info["leader_err"] = err + + info["our_id"] = nh.ID() + + if nhregis, ok := nh.GetNodeHostRegistry(); ok { + info["nhregis_nshards"] = nhregis.NumOfShards() + if meta, ok := nhregis.GetMeta("test"); ok { + info["meta"] = meta + } + if si, ok := nhregis.GetShardInfo(defaultShardID); ok { + info["si_config_change_index"] = si.ConfigChangeIndex + info["si_leader_id"] = si.LeaderID + info["si_replicas"] = si.Replicas + info["si_shard_id"] = si.ShardID + info["si_term"] = si.Term + } + } + + res, err := nh.SyncRead(ctx, defaultShardID, []byte("echo")) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + info["message"] = "err: " + err.Error() + result, _ := json.Marshal(info) + w.Write(result) + return + } + + w.WriteHeader(http.StatusOK) + info["message"] = res.(string) + result, _ := json.Marshal(info) + w.Write(result) + }) + +} diff --git a/go.mod b/go.mod index 8de72d2..ebe62e2 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,9 @@ require ( github.com/kolesa-team/go-webp v1.0.4 github.com/lestrrat-go/jwx v1.2.31 github.com/lib/pq v1.10.9 + github.com/lni/dragonboat/v4 v4.0.0-20240618143154-6a1623140f27 github.com/rs/zerolog v1.33.0 + go.etcd.io/bbolt v1.4.2 golang.org/x/crypto v0.38.0 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d golang.org/x/oauth2 v0.21.0 @@ -32,36 +34,70 @@ require ( cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect cloud.google.com/go/compute/metadata v0.3.0 // indirect cloud.google.com/go/iam v1.1.8 // indirect + github.com/DataDog/zstd v1.5.2 // indirect + github.com/VictoriaMetrics/metrics v1.18.1 // indirect github.com/agext/levenshtein v1.2.1 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect + github.com/armon/go-metrics v0.4.1 // indirect + github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cockroachdb/errors v1.11.3 // indirect + github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v1.1.5 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/goccy/go-json v0.10.3 // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect + github.com/google/btree v1.0.0 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.4 // indirect github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect - github.com/kr/pretty v0.2.1 // indirect - github.com/kr/text v0.1.0 // indirect + github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/go-immutable-radix v1.0.0 // indirect + github.com/hashicorp/go-msgpack v0.5.3 // indirect + github.com/hashicorp/go-multierror v1.0.0 // indirect + github.com/hashicorp/go-sockaddr v1.0.0 // indirect + github.com/hashicorp/golang-lru v0.5.1 // indirect + github.com/hashicorp/memberlist v0.3.1 // indirect + github.com/klauspost/compress v1.16.0 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect github.com/lestrrat-go/blackmagic v1.0.2 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/option v1.0.1 // indirect + github.com/lni/goutils v1.4.0 // indirect + github.com/lni/vfs v0.2.1-0.20231221160030-d43d3c60804c // indirect github.com/maraino/go-mock v0.0.0-20180321183845-4c74c434cd3a // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/miekg/dns v1.1.26 // indirect github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect + github.com/pierrec/lz4/v4 v4.1.14 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.15.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect + github.com/valyala/fastrand v1.1.0 // indirect + github.com/valyala/histogram v1.2.0 // indirect github.com/yugabyte/gocql v0.0.0-20221110041640-6fc475c5aeb0 // indirect github.com/zclconf/go-cty v1.13.0 // indirect go.opencensus.io v0.24.0 // indirect @@ -70,6 +106,7 @@ require ( go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect + golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/sys v0.33.0 // indirect diff --git a/go.sum b/go.sum index 9cafdfe..5ba14b2 100644 --- a/go.sum +++ b/go.sum @@ -18,22 +18,56 @@ cloud.google.com/go/storage v1.42.0/go.mod h1:HjMXRFq65pGKFn6hxj6x3HCyR41uSB72Z0 filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/VictoriaMetrics/metrics v1.18.1 h1:OZ0+kTTto8oPfHnVAnTOoyl0XlRhRkoQrD2n2cOuRw0= +github.com/VictoriaMetrics/metrics v1.18.1/go.mod h1:ArjwVz7WpgpegX/JpB0zpNF2h2232kErkEnzH1sxMmA= github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +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= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw= +github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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= @@ -53,6 +87,14 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -62,11 +104,15 @@ github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +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-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -75,7 +121,9 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -88,6 +136,9 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6 github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -96,6 +147,7 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= @@ -109,22 +161,52 @@ github.com/googleapis/gax-go/v2 v2.12.4 h1:9gWcmF85Wvq4ryPFvGFaOgPIs1AQX0d0bcbGw github.com/googleapis/gax-go/v2 v2.12.4/go.mod h1:KYEYLorsnIGDi/rPC8b5TdlB9kbKoFubselGIoBMCwI= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14= github.com/hashicorp/hcl/v2 v2.21.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= +github.com/hashicorp/memberlist v0.3.1 h1:MXgUXLqva1QvpVEDQW1IQLG0wivQAtmFlHRQ+1vWZfM= +github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/keenangebze/gockle v0.0.0-20230217041857-980d2a32e9d6 h1:yWLCrksBTAd/oUrTPmH8rNLCfvBF2W/3C4usNrez6ow= github.com/keenangebze/gockle v0.0.0-20230217041857-980d2a32e9d6/go.mod h1:IJsqO+i2zpQoEOTYLZr06DKIbfV+2gZK6Ax3Vzbi71I= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kolesa-team/go-webp v1.0.4 h1:wQvU4PLG/X7RS0vAeyhiivhLRoxfLVRlDq4I3frdxIQ= github.com/kolesa-team/go-webp v1.0.4/go.mod h1:oMvdivD6K+Q5qIIkVC2w4k2ZUnI1H+MyP7inwgWq9aA= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 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= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= @@ -140,6 +222,12 @@ github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNB github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lni/dragonboat/v4 v4.0.0-20240618143154-6a1623140f27 h1:j7KujI7VnwlBTvbFYmVgPiJH1Ma43Mi/7ugofqb0A34= +github.com/lni/dragonboat/v4 v4.0.0-20240618143154-6a1623140f27/go.mod h1:mg6Umt1dofZCrC6QVP1EBiuYixCl3qSF0kpArddKpk0= +github.com/lni/goutils v1.4.0 h1:e1tNN+4zsbTpNvhG5cxirkH9Pdz96QAZ2j6+5tmjvqg= +github.com/lni/goutils v1.4.0/go.mod h1:LIHvF0fflR+zyXUQFQOiHPpKANf3UIr7DFIv5CBPOoU= +github.com/lni/vfs v0.2.1-0.20231221160030-d43d3c60804c h1:ceH82TOkLNOi+vEWGhfQmO+gOuXZ+2390WaefqV920M= +github.com/lni/vfs v0.2.1-0.20231221160030-d43d3c60804c/go.mod h1:CBBfEt4D1eutp+W+FRV3cZQsg9BEV1UVRS+5mP37rUE= github.com/maraino/go-mock v0.0.0-20180321183845-4c74c434cd3a h1:66Bs2T30mxkg+5ZQEb0z5556Ww4tIBZffUUNnFD5EUQ= github.com/maraino/go-mock v0.0.0-20180321183845-4c74c434cd3a/go.mod h1:KpdDhCgE2rvPhsnLbGZ8Uf1QORj6v92FOgFKnCz5CXM= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -149,26 +237,76 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +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/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE= +github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/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.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +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.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -176,12 +314,21 @@ 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/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8= +github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= +github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ= +github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY= github.com/yugabyte/gocql v0.0.0-20221110041640-6fc475c5aeb0 h1:68nrJsrWe0A6JiKnsjWChAaWhj20v+AwYJObtp86D1k= github.com/yugabyte/gocql v0.0.0-20221110041640-6fc475c5aeb0/go.mod h1:LAokR6+vevDCrTxk52U7p6ki+4qELu4XU7JUGYa2O2M= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zclconf/go-cty v1.13.0 h1:It5dfKTTZHe9aeppbNOda3mN7Ag7sg6QkBNm6TkyFa0= github.com/zclconf/go-cty v1.13.0/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= +go.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I= +go.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= @@ -196,24 +343,37 @@ go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucg go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= 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= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= @@ -222,12 +382,21 @@ golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 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= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 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= 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= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -235,6 +404,7 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= @@ -246,9 +416,16 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= google.golang.org/api v0.185.0 h1:ENEKk1k4jW8SmmaT6RE+ZasxmxezCrD5Vw4npvr+pAU= @@ -282,14 +459,23 @@ 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.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 571ea508b95162403444e3fcfe66df1735142a0a Mon Sep 17 00:00:00 2001 From: Keenan Gebze Date: Sun, 13 Jul 2025 03:29:25 +0700 Subject: [PATCH 3/6] fixes bug --- delivery/raft-enabled-api/fsm_disk.go | 55 ++++++++++++++- example/raft/main.go | 99 +++++++++++++++++++++++---- example/raft/module_auth.go | 74 +++++++++++++++++++- example/raft/system_event_listener.go | 47 +++++++++++++ 4 files changed, 256 insertions(+), 19 deletions(-) create mode 100644 example/raft/system_event_listener.go diff --git a/delivery/raft-enabled-api/fsm_disk.go b/delivery/raft-enabled-api/fsm_disk.go index 333e8a2..1f15e96 100644 --- a/delivery/raft-enabled-api/fsm_disk.go +++ b/delivery/raft-enabled-api/fsm_disk.go @@ -13,6 +13,8 @@ import ( sm "github.com/lni/dragonboat/v4/statemachine" ) +var Updatechan = make(chan string, 1048) + const ( testDBDirName string = "example-data" currentDBFilename string = "current" @@ -60,12 +62,12 @@ func (d *DiskKV) Open(stopc <-chan struct{}) (uint64, error) { var lastAppliedIdx uint64 err = db.Update(func(tx *bolt.Tx) error { - cb, err := tx.CreateBucketIfNotExists([]byte("state")) + cb, err := tx.CreateBucketIfNotExists(configBucket) if err != nil { return err } - val := cb.Get([]byte("appliedIndex")) + val := cb.Get(appliedIndexKey) if len(val) == 0 { return nil } @@ -81,6 +83,8 @@ func (d *DiskKV) Open(stopc <-chan struct{}) (uint64, error) { d.db = db d.lastApplied = lastAppliedIdx + log.Println("LAST APLPIED NYA PRIO?", lastAppliedIdx) + return d.lastApplied, nil } @@ -138,11 +142,17 @@ func (d *DiskKV) Update(ents []sm.Entry) ([]sm.Entry, error) { if d.closed { panic("update called after Close()") } + defer func() { + go func() { + Updatechan <- "updated" + }() + }() for idx, e := range ents { var cmd Message if err := json.Unmarshal(e.Cmd, &cmd); err != nil { + ents[idx].Result.Data = []byte("kamu kok gitu?") continue } @@ -224,6 +234,7 @@ func (d *DiskKV) Update(ents []sm.Entry) ([]sm.Entry, error) { if d.lastApplied >= ents[len(ents)-1].Index { panic("lastApplied not moving forward") } + d.lastApplied = ents[len(ents)-1].Index return ents, nil } @@ -249,6 +260,25 @@ func (d *DiskKV) PrepareSnapshot() (interface{}, error) { func (d *DiskKV) SaveSnapshot(ctx interface{}, w io.Writer, done <-chan struct{}) error { + // var lastAppliedIdx uint64 + var x []byte + _ = d.db.Update(func(tx *bolt.Tx) error { + cb, err := tx.CreateBucketIfNotExists(configBucket) + if err != nil { + return err + } + + val := cb.Get(appliedIndexKey) + if len(val) == 0 { + return nil + } + + x = val + + return nil + }) + + w.Write(x) return nil } @@ -258,6 +288,27 @@ func (d *DiskKV) SaveSnapshot(ctx interface{}, func (d *DiskKV) RecoverFromSnapshot(r io.Reader, done <-chan struct{}) error { + // save the applied index to the DB. + // appliedIndex := make([]byte, 8) + // binary.LittleEndian.PutUint64(appliedIndex, ents[len(ents)-1].Index) + + payload, _ := io.ReadAll(r) + + err := d.db.Update(func(tx *bolt.Tx) error { + bucket, err := tx.CreateBucketIfNotExists(configBucket) + if err != nil { + return err + } + err = bucket.Put(appliedIndexKey, payload) + if err != nil { + return err + } + return nil + }) + if err != nil { + return err + } + return nil } diff --git a/example/raft/main.go b/example/raft/main.go index 24700ab..212d627 100644 --- a/example/raft/main.go +++ b/example/raft/main.go @@ -17,6 +17,8 @@ import ( "github.com/julienschmidt/httprouter" "github.com/lni/dragonboat/v4" "github.com/lni/dragonboat/v4/config" + "github.com/lni/dragonboat/v4/logger" + "github.com/lni/dragonboat/v4/raftio" ) const ( @@ -25,23 +27,65 @@ const ( datadir string = ".rjs" // raft job scheduler ) +var leaderUpdate = make(chan leaderInfo, 12312) + +var _ raftio.IRaftEventListener = &raftListener{} + +type raftListener struct{} + +type leaderInfo struct { + replicaID uint64 + leaderID uint64 + shardID uint64 + term uint64 +} + +func (r *raftListener) LeaderUpdated(info raftio.LeaderInfo) { + if info.LeaderID == 0 { + log.Printf(" no la policia :( %+v\n", info) + return + } + log.Printf("leader updated!: %+v\n", info) + leaderUpdate <- leaderInfo{ + replicaID: info.ReplicaID, + leaderID: info.LeaderID, + shardID: info.ShardID, + term: info.Term, + } +} + +func init() { + logger.GetLogger("dragonboat").SetLevel(logger.DEBUG) +} + func main() { + finished := make(chan struct{}) + sigint := make(chan os.Signal, 1) + signal.Notify(sigint, os.Interrupt) + + defer func() { + log.Println("bye~ 👋🏼") + }() + var replicaID uint64 var httpAddr string var raftAddr string var bootstrap string + var joinFlag bool flag.Uint64Var(&replicaID, "replica-id", 1, "replica id for this host") flag.StringVar(&httpAddr, "http-addr", "", "http bind adddress :") flag.StringVar(&raftAddr, "raft-addr", "", "bind adddress :") flag.StringVar(&bootstrap, "bootstrap", "", "comma separated of replica's [:
:] pair for cluster config") + flag.BoolVar(&joinFlag, "join", false, "comma separated of replica's [:
:] pair for cluster config") flag.Parse() nhc := config.NodeHostConfig{ - WALDir: path.Join(datadir, strconv.FormatUint(replicaID, 10), "raft", "wal"), - NodeHostDir: path.Join(datadir, strconv.FormatUint(replicaID, 10), "raft", "etc"), - RTTMillisecond: 200, - RaftAddress: raftAddr, + WALDir: path.Join(datadir, strconv.FormatUint(replicaID, 10), "raft", "wal"), + NodeHostDir: path.Join(datadir, strconv.FormatUint(replicaID, 10), "raft", "etc"), + RTTMillisecond: 50, + RaftAddress: raftAddr, + RaftEventListener: &raftListener{}, } bootstrapServerByReplicaID := make(map[uint64]dragonboat.Target) @@ -69,7 +113,7 @@ func main() { ) } - join := len(bootstrapServerByReplicaID) == 0 + join := len(bootstrapServerByReplicaID) == 0 && joinFlag if !join { // add ourself as part of the cluster @@ -81,6 +125,7 @@ func main() { log.Panicln("err dragon rising", err) return } + defer nh.Close() repc := config.Config{ ReplicaID: replicaID, @@ -90,6 +135,7 @@ func main() { CheckQuorum: true, SnapshotEntries: 100, // if snapshot is not implemented can crash CompactionOverhead: 5, + WaitReady: true, } info := map[string]any{ @@ -111,13 +157,10 @@ func main() { os.Exit(1) } - raftSession := nh.GetNoOPSession(defaultShardID) - - // http handler - router := httprouter.New() - enableAuthAPI(router, nh, raftSession, info) + haveLeader := new(bool) + enableAuthAPI(router, nh, info, haveLeader) // start http endopoint server := http.Server{ @@ -127,11 +170,14 @@ func main() { WriteTimeout: time.Duration(10) * time.Second, } - finished := make(chan struct{}) + go func() { + for { + <-raftenabledapi.Updatechan + } + }() + go func() { defer close(finished) - sigint := make(chan os.Signal, 1) - signal.Notify(sigint, os.Interrupt) <-sigint ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) @@ -145,6 +191,32 @@ func main() { // log.Info().Msgf("Stopped serving new connections.") }() + // leadership update loop + go func() { + for { + // wait get leader? + log.Println("Listening for leadership update..") // only for one shard + info := <-leaderUpdate + if info.leaderID == 0 { + log.Println("No leader. LAPOLOCIAA") + *haveLeader = false + continue + } + + retryCount := 0 + for { + leaderID, term, valid, err := nh.GetLeaderID(defaultShardID) + if valid { + log.Println("LEADER-SAMA", leaderID, term, valid, err) + *haveLeader = true + break + } + retryCount++ + time.Sleep(time.Duration(retryCount) * 50 * time.Millisecond) + } + } + }() + // log.Info().Msgf("Serving at %v..\n", address) if err := server.ListenAndServe(); err != http.ErrServerClosed { // Error starting or closing listener: @@ -152,5 +224,4 @@ func main() { } <-finished - log.Println("bye~ 👋🏼") } diff --git a/example/raft/module_auth.go b/example/raft/module_auth.go index ecb2d72..4e7cdc1 100644 --- a/example/raft/module_auth.go +++ b/example/raft/module_auth.go @@ -4,15 +4,18 @@ import ( "context" "encoding/json" "fmt" + "io" "net/http" "time" "github.com/julienschmidt/httprouter" "github.com/lni/dragonboat/v4" - "github.com/lni/dragonboat/v4/client" + "github.com/lni/dragonboat/v4/statemachine" + "github.com/rs/zerolog/log" ) -func enableAuthAPI(router *httprouter.Router, nh *dragonboat.NodeHost, ses *client.Session, info map[string]any) { +func enableAuthAPI(router *httprouter.Router, nh *dragonboat.NodeHost, info map[string]any, haveLeader *bool) { + sess := nh.GetNoOPSession(defaultShardID) router.POST("/auth/gsi", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second) defer cancel() @@ -40,7 +43,15 @@ func enableAuthAPI(router *httprouter.Router, nh *dragonboat.NodeHost, ses *clie } } - res, err := nh.SyncPropose(ctx, ses, []byte(`{"type":"echo", "payload": "assalamualaikum"}`)) + payload, err := io.ReadAll(r.Body) + if err != nil { + payload = []byte(`hehe`) + log.Error().Msgf("failed to read body") + } + + ses := nh.GetNoOPSession(defaultShardID) + + res, err := nh.SyncPropose(ctx, ses, payload) if err != nil { w.WriteHeader(http.StatusInternalServerError) info["message"] = "err: " + err.Error() @@ -97,4 +108,61 @@ func enableAuthAPI(router *httprouter.Router, nh *dragonboat.NodeHost, ses *clie w.Write(result) }) + router.GET("/member", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + // this will block until we have leader + if !*haveLeader { + w.WriteHeader(404) + w.Write([]byte("no leader goodbye!")) + return + } + + retry := 0 + + var result statemachine.Result + var err error + for { + ctx, c := context.WithTimeout(r.Context(), 1*time.Second) + result, err = nh.SyncPropose(ctx, sess, []byte("hello world!")) + c() + if err == nil { + break + } + + if err != dragonboat.ErrTimeout && err != dragonboat.ErrShardNotReady { + break + } + + retry++ + if retry > 3 { + break + } + time.Sleep(time.Duration(retry) * 10 * time.Millisecond) + } + if err != nil { + w.WriteHeader(404) + w.Write([]byte(fmt.Sprintf("nooo~! la politzia ... %v", err))) + return + } + w.Write([]byte(result.Data)) + }) + + router.GET("/gossip", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + cfg := nh.NodeHostConfig() + payload, _ := json.Marshal(cfg.Gossip) + w.Write([]byte(string(payload))) + }) + +} + +func printMembership(ctx context.Context, nh *dragonboat.NodeHost) (string, error) { + + // ses := nh.GetNoOPSession(defaultShardID) + var m *dragonboat.Membership + var err error + + ctx, c := context.WithTimeout(ctx, 2000*time.Millisecond) + defer c() + m, err = nh.SyncGetShardMembership(ctx, defaultShardID) + + return fmt.Sprintf("MEMBERZIP %+v %+v", m, err), nil } diff --git a/example/raft/system_event_listener.go b/example/raft/system_event_listener.go new file mode 100644 index 0000000..90b5897 --- /dev/null +++ b/example/raft/system_event_listener.go @@ -0,0 +1,47 @@ +package main + +import ( + "log" + + "github.com/lni/dragonboat/v4/raftio" +) + +var Ready = make(chan string) + +var _ raftio.ISystemEventListener = &seListener{} + +type seListener struct{} + +func (s *seListener) NodeHostShuttingDown() { + log.Printf("NodeHostShuttingDown()") +} + +func (s *seListener) NodeUnloaded(info raftio.NodeInfo) { + log.Printf("NodeUnloaded() replica=%v shard=%v!\n", info.ReplicaID, info.ShardID) +} +func (s *seListener) NodeDeleted(info raftio.NodeInfo) { + log.Printf("NodeDeleted() replica=%v shard=%v!\n", info.ReplicaID, info.ShardID) +} +func (s *seListener) NodeReady(info raftio.NodeInfo) { + log.Printf("NodeReady() replica=%v shard=%v!\n", info.ReplicaID, info.ShardID) + // Ready <- "IM READE" +} + +func (s *seListener) MembershipChanged(info raftio.NodeInfo) { + log.Printf("MembershipChanged() replica=%v shard=%v\n", info.ReplicaID, info.ShardID) +} + +func (s *seListener) ConnectionEstablished(info raftio.ConnectionInfo) { + log.Printf("ConnectionEstablished() addr=%v snap=%v\n", info.Address, info.SnapshotConnection) + +} +func (s *seListener) ConnectionFailed(info raftio.ConnectionInfo) {} +func (s *seListener) SendSnapshotStarted(info raftio.SnapshotInfo) {} +func (s *seListener) SendSnapshotCompleted(info raftio.SnapshotInfo) {} +func (s *seListener) SendSnapshotAborted(info raftio.SnapshotInfo) {} +func (s *seListener) SnapshotReceived(info raftio.SnapshotInfo) {} +func (s *seListener) SnapshotRecovered(info raftio.SnapshotInfo) {} +func (s *seListener) SnapshotCreated(info raftio.SnapshotInfo) {} +func (s *seListener) SnapshotCompacted(info raftio.SnapshotInfo) {} +func (s *seListener) LogCompacted(info raftio.EntryInfo) {} +func (s *seListener) LogDBCompacted(info raftio.EntryInfo) {} From 8a74d9bae74cc36e26de58c96b73829589122e9a Mon Sep 17 00:00:00 2001 From: Keenan Gebze Date: Tue, 15 Jul 2025 00:36:29 +0700 Subject: [PATCH 4/6] raft auth with new authapi --- .../raft/app-auth/idtoken_authlogic_admin.go | 63 +++++++++ .../raft/app-auth/idtoken_authlogic_user.go | 104 ++++++++++++++ example/raft/module_auth.go | 130 +++--------------- 3 files changed, 186 insertions(+), 111 deletions(-) create mode 100644 example/raft/app-auth/idtoken_authlogic_admin.go create mode 100644 example/raft/app-auth/idtoken_authlogic_user.go diff --git a/example/raft/app-auth/idtoken_authlogic_admin.go b/example/raft/app-auth/idtoken_authlogic_admin.go new file mode 100644 index 0000000..4eb224f --- /dev/null +++ b/example/raft/app-auth/idtoken_authlogic_admin.go @@ -0,0 +1,63 @@ +package plugin + +import ( + "net/http" + "time" + + authapi "github.com/desain-gratis/common/delivery/auth-api" + types "github.com/desain-gratis/common/types/http" + "github.com/desain-gratis/common/types/protobuf/session" + "google.golang.org/api/idtoken" + "google.golang.org/protobuf/proto" +) + +var ( + _ authapi.TokenBuilder = &adminAuth{} +) + +type adminAuth struct { + adminEmail map[string]struct{} + expiryMinutes int +} + +// AdminAuthLogic from id token (google, microsoft, etc.) in to our own self signed token +func AdminAuthLogic(adminEmail map[string]struct{}, expiryMinutes int) *adminAuth { + return &adminAuth{ + adminEmail: adminEmail, + expiryMinutes: expiryMinutes, + } +} + +func (a *adminAuth) BuildToken(r *http.Request, authMethod string, auth *idtoken.Payload) (tokenData proto.Message, apiData any, expiry time.Time, err *types.CommonError) { + claim := authapi.GetOIDCClaims(auth.Claims) + + if _, ok := a.adminEmail[claim.Email]; !ok { + errUC := &types.CommonError{ + Errors: []types.Error{ + { + HTTPCode: http.StatusUnauthorized, + Code: "UNAUTHORIZED", + Message: "You do not have access to any organization! Please contact API owner team for getting one ☎️", + }, + }, + } + return nil, nil, expiry, errUC + } + + expiry = time.Now().Add(time.Duration(a.expiryMinutes) * time.Minute) // long-lived token + + tokenData = &session.SessionData{ + NonRegisteredId: &session.OIDCClaim{ + Iss: claim.Iss, + Sub: claim.Sub, + Name: claim.Name, + Nickname: claim.Nickname, + Email: claim.Email, + }, + SignInMethod: authMethod, + SignInEmail: claim.Email, + IsSuperAdmin: true, // ADMIN + } + + return tokenData, tokenData, expiry, nil +} diff --git a/example/raft/app-auth/idtoken_authlogic_user.go b/example/raft/app-auth/idtoken_authlogic_user.go new file mode 100644 index 0000000..6bd89ea --- /dev/null +++ b/example/raft/app-auth/idtoken_authlogic_user.go @@ -0,0 +1,104 @@ +package plugin + +import ( + "net/http" + "strings" + "time" + + authapi "github.com/desain-gratis/common/delivery/auth-api" + "github.com/desain-gratis/common/example/auth/entity" + types "github.com/desain-gratis/common/types/http" + "github.com/desain-gratis/common/types/protobuf/session" + "github.com/desain-gratis/common/usecase/mycontent" + "google.golang.org/api/idtoken" + "google.golang.org/protobuf/proto" +) + +var ( + _ authapi.TokenBuilder = &userAuth{} +) + +type userAuth struct { + authUser mycontent.Usecase[*entity.UserAuthorization] + expiryMinutes int +} + +// AdminAuthLogic from id token (google, microsoft, etc.) in to our own self signed token +func NewUserAuthLogic(authUser mycontent.Usecase[*entity.UserAuthorization], expiryMinutes int) *userAuth { + return &userAuth{ + authUser: authUser, + expiryMinutes: expiryMinutes, + } +} + +func (a *userAuth) BuildToken(r *http.Request, authMethod string, auth *idtoken.Payload) (tokenData proto.Message, apiData any, expiry time.Time, err *types.CommonError) { + claim := authapi.GetOIDCClaims(auth.Claims) + + // Locale + // TODO parse to clean string + lang := strings.Split(r.Header.Get("Accept-Language"), ";") + + // Enterprise capability (login based on organization) + grants := make(map[string]*session.Grant) + + // notice that "root" is hardcoded + // also, we get the authentication based on claim.Email. + authData, errUserUC := a.authUser.Get(r.Context(), "root", []string{}, claim.Email) + if errUserUC != nil { + return nil, nil, expiry, errUserUC + } + + if len(authData) != 1 { + uerrUserUC := &types.CommonError{ + Errors: []types.Error{ + {Message: "Failed to get user auth: " + errUserUC.Err().Error(), Code: "NOT_FOUND"}, + }} + + return nil, nil, expiry, uerrUserUC + } + + userData := authData[0] + + expiry = time.Now().Add(time.Duration(a.expiryMinutes) * time.Minute) // long-lived token + + var img string + if userData.DefaultProfile.Avatar1x1 != nil { + img = userData.DefaultProfile.Avatar1x1.ThumbnailUrl + } + + for namespace, auth := range userData.Authorization { + grants[namespace] = &session.Grant{ + UiAndApiPermission: auth.UiAndApiPermission, + GroupId: auth.UserGroupID2, // todo: + } + } + + tokenData = &session.SessionData{ + NonRegisteredId: &session.OIDCClaim{ + Iss: claim.Iss, + Sub: claim.Sub, + Name: claim.Name, + Nickname: claim.Nickname, + Email: claim.Email, + }, + Grants: grants, + SignInMethod: authMethod, + SignInEmail: claim.Email, + IsSuperAdmin: false, + } + + apiData = &authapi.SignInResponse{ + LoginProfile: &authapi.Profile{ + DisplayName: claim.Name, + Email: claim.Email, + ImageURL: img, + }, + Locale: lang, + // collection of grants NOT signed, for debugging. + // DO NOT USE THIS FOR BACK END VALIDATION + Grants: grants, + Expiry: expiry.Format(time.RFC3339), + } + + return tokenData, apiData, expiry, nil +} diff --git a/example/raft/module_auth.go b/example/raft/module_auth.go index 4e7cdc1..c65f2fc 100644 --- a/example/raft/module_auth.go +++ b/example/raft/module_auth.go @@ -2,112 +2,40 @@ package main import ( "context" - "encoding/json" "fmt" - "io" "net/http" "time" + authapi "github.com/desain-gratis/common/delivery/auth-api" + idtokensigner "github.com/desain-gratis/common/delivery/auth-api/idtoken-signer" + idtokenverifier "github.com/desain-gratis/common/delivery/auth-api/idtoken-verifier" + plugin "github.com/desain-gratis/common/example/raft/app-auth" "github.com/julienschmidt/httprouter" "github.com/lni/dragonboat/v4" "github.com/lni/dragonboat/v4/statemachine" - "github.com/rs/zerolog/log" ) func enableAuthAPI(router *httprouter.Router, nh *dragonboat.NodeHost, info map[string]any, haveLeader *bool) { - sess := nh.GetNoOPSession(defaultShardID) - router.POST("/auth/gsi", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second) - defer cancel() - - id, term, valid, err := nh.GetLeaderID(defaultShardID) - - info["leader_id"] = id - info["leader_term"] = term - info["leader_valid"] = valid - info["leader_err"] = err + signerVerifier := idtokensigner.NewSimple( + "raft-app", + map[string]string{ + "key-v1": "85746{K=q's)", + }, + "key-v1", + ) - info["our_id"] = nh.ID() + gsiAuth := idtokenverifier.GSIAuth("web client ID") + appAuth := idtokenverifier.AppAuth(signerVerifier, "app") - if nhregis, ok := nh.GetNodeHostRegistry(); ok { - info["nhregis_nshards"] = nhregis.NumOfShards() - if meta, ok := nhregis.GetMeta("test"); ok { - info["meta"] = meta - } - if si, ok := nhregis.GetShardInfo(defaultShardID); ok { - info["si_config_change_index"] = si.ConfigChangeIndex - info["si_leader_id"] = si.LeaderID - info["si_replicas"] = si.Replicas - info["si_shard_id"] = si.ShardID - info["si_term"] = si.Term - } - } + adminTokenBuilder := plugin.AdminAuthLogic(map[string]struct{}{"keenan.gebze@gmail.com": struct{}{}}, 1*30) + userTokenBuilder := plugin.NewUserAuthLogic(nil, 8*60) - payload, err := io.ReadAll(r.Body) - if err != nil { - payload = []byte(`hehe`) - log.Error().Msgf("failed to read body") - } + router.GET("/auth/admin", gsiAuth(authapi.GetToken(adminTokenBuilder, signerVerifier))) + router.GET("/auth/user/gsi", gsiAuth(authapi.GetToken(userTokenBuilder, signerVerifier))) - ses := nh.GetNoOPSession(defaultShardID) - - res, err := nh.SyncPropose(ctx, ses, payload) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - info["message"] = "err: " + err.Error() - result, _ := json.Marshal(info) - w.Write(result) - return - } - - w.WriteHeader(http.StatusOK) - info["message"] = fmt.Sprintf("SUCCESS: %v (%v)", string(res.Data), res.Value) - result, _ := json.Marshal(info) - w.Write(result) - }) - - router.GET("/ingfo", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second) - defer cancel() - - id, term, valid, err := nh.GetLeaderID(defaultShardID) - - info["leader_id"] = id - info["leader_term"] = term - info["leader_valid"] = valid - info["leader_err"] = err - - info["our_id"] = nh.ID() - - if nhregis, ok := nh.GetNodeHostRegistry(); ok { - info["nhregis_nshards"] = nhregis.NumOfShards() - if meta, ok := nhregis.GetMeta("test"); ok { - info["meta"] = meta - } - if si, ok := nhregis.GetShardInfo(defaultShardID); ok { - info["si_config_change_index"] = si.ConfigChangeIndex - info["si_leader_id"] = si.LeaderID - info["si_replicas"] = si.Replicas - info["si_shard_id"] = si.ShardID - info["si_term"] = si.Term - } - } - - res, err := nh.SyncRead(ctx, defaultShardID, []byte("echo")) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - info["message"] = "err: " + err.Error() - result, _ := json.Marshal(info) - w.Write(result) - return - } - - w.WriteHeader(http.StatusOK) - info["message"] = res.(string) - result, _ := json.Marshal(info) - w.Write(result) - }) + router.GET("/member-only", appAuth(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {})) + sess := nh.GetNoOPSession(defaultShardID) router.GET("/member", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { // this will block until we have leader if !*haveLeader { @@ -145,24 +73,4 @@ func enableAuthAPI(router *httprouter.Router, nh *dragonboat.NodeHost, info map[ } w.Write([]byte(result.Data)) }) - - router.GET("/gossip", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - cfg := nh.NodeHostConfig() - payload, _ := json.Marshal(cfg.Gossip) - w.Write([]byte(string(payload))) - }) - -} - -func printMembership(ctx context.Context, nh *dragonboat.NodeHost) (string, error) { - - // ses := nh.GetNoOPSession(defaultShardID) - var m *dragonboat.Membership - var err error - - ctx, c := context.WithTimeout(ctx, 2000*time.Millisecond) - defer c() - m, err = nh.SyncGetShardMembership(ctx, defaultShardID) - - return fmt.Sprintf("MEMBERZIP %+v %+v", m, err), nil } From 045f369e14f96ce34d5c01430d23dd420c667543 Mon Sep 17 00:00:00 2001 From: Keenan Gebze Date: Thu, 17 Jul 2025 02:17:11 +0700 Subject: [PATCH 5/6] fix go.mod --- example/raft/go.mod | 91 ++++++++++++ example/raft/go.sum | 330 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 421 insertions(+) create mode 100644 example/raft/go.sum diff --git a/example/raft/go.mod b/example/raft/go.mod index 686a6b2..70a32d8 100644 --- a/example/raft/go.mod +++ b/example/raft/go.mod @@ -1,3 +1,94 @@ module github.com/desain-gratis/common/example/raft go 1.23.4 + +replace github.com/desain-gratis/common => ../.. + +require ( + github.com/desain-gratis/common v0.0.0-20250522185906-27414d245d67 + github.com/desain-gratis/common/example/auth v0.0.0-20250714193823-0653a050800a + github.com/julienschmidt/httprouter v1.3.0 + github.com/lni/dragonboat/v4 v4.0.0-20240618143154-6a1623140f27 + google.golang.org/api v0.242.0 + google.golang.org/protobuf v1.36.6 +) + +require ( + cloud.google.com/go/auth v0.16.2 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + cloud.google.com/go/compute/metadata v0.7.0 // indirect + github.com/DataDog/zstd v1.5.2 // indirect + github.com/VictoriaMetrics/metrics v1.18.1 // indirect + github.com/armon/go-metrics v0.4.1 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cockroachdb/errors v1.11.3 // indirect + github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v1.1.5 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/goccy/go-json v0.10.3 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/btree v1.0.0 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/google/uuid v1.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/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/go-immutable-radix v1.0.0 // indirect + github.com/hashicorp/go-msgpack v0.5.3 // indirect + github.com/hashicorp/go-multierror v1.0.0 // indirect + github.com/hashicorp/go-sockaddr v1.0.0 // indirect + github.com/hashicorp/golang-lru v0.5.1 // indirect + github.com/hashicorp/memberlist v0.3.1 // indirect + github.com/klauspost/compress v1.16.0 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect + github.com/lestrrat-go/blackmagic v1.0.2 // indirect + github.com/lestrrat-go/httpcc v1.0.1 // indirect + github.com/lestrrat-go/iter v1.0.2 // indirect + github.com/lestrrat-go/jwx v1.2.31 // indirect + github.com/lestrrat-go/option v1.0.1 // indirect + github.com/lni/goutils v1.4.0 // indirect + github.com/lni/vfs v0.2.1-0.20231221160030-d43d3c60804c // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/miekg/dns v1.1.26 // indirect + github.com/pierrec/lz4/v4 v4.1.14 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.15.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/rs/zerolog v1.33.0 // indirect + github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect + github.com/valyala/fastrand v1.1.0 // indirect + github.com/valyala/histogram v1.2.0 // indirect + go.etcd.io/bbolt v1.4.2 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/otel v1.36.0 // indirect + go.opentelemetry.io/otel/metric v1.36.0 // indirect + go.opentelemetry.io/otel/trace v1.36.0 // indirect + golang.org/x/crypto v0.39.0 // indirect + golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect + golang.org/x/net v0.41.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sync v0.15.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.26.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect + google.golang.org/grpc v1.73.0 // indirect +) diff --git a/example/raft/go.sum b/example/raft/go.sum new file mode 100644 index 0000000..3171cc4 --- /dev/null +++ b/example/raft/go.sum @@ -0,0 +1,330 @@ +cloud.google.com/go/auth v0.16.2 h1:QvBAGFPLrDeoiNjyfVunhQ10HKNYuOwZ5noee0M5df4= +cloud.google.com/go/auth v0.16.2/go.mod h1:sRBas2Y1fB1vZTdurouM0AzuYQBMZinrUYL8EufhtEA= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +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= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/VictoriaMetrics/metrics v1.18.1 h1:OZ0+kTTto8oPfHnVAnTOoyl0XlRhRkoQrD2n2cOuRw0= +github.com/VictoriaMetrics/metrics v1.18.1/go.mod h1:ArjwVz7WpgpegX/JpB0zpNF2h2232kErkEnzH1sxMmA= +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= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw= +github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +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/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= +github.com/desain-gratis/common/example/auth v0.0.0-20250714193823-0653a050800a h1:4BfAVUsaSLElAnKWfTmxRbzXCGTBq/xXgqlEsD1giVw= +github.com/desain-gratis/common/example/auth v0.0.0-20250714193823-0653a050800a/go.mod h1:4QvFmFecj4CnzSVsheEOy5se7iIahQIEgiLpZS5HQdM= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-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-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/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +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-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +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/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/memberlist v0.3.1 h1:MXgUXLqva1QvpVEDQW1IQLG0wivQAtmFlHRQ+1vWZfM= +github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +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= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= +github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= +github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= +github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= +github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= +github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= +github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= +github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= +github.com/lestrrat-go/jwx v1.2.31 h1:/OM9oNl/fzyldpv5HKZ9m7bTywa7COUfg8gujd9nJ54= +github.com/lestrrat-go/jwx v1.2.31/go.mod h1:eQJKoRwWcLg4PfD5CFA5gIZGxhPgoPYq9pZISdxLf0c= +github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= +github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lni/dragonboat/v4 v4.0.0-20240618143154-6a1623140f27 h1:j7KujI7VnwlBTvbFYmVgPiJH1Ma43Mi/7ugofqb0A34= +github.com/lni/dragonboat/v4 v4.0.0-20240618143154-6a1623140f27/go.mod h1:mg6Umt1dofZCrC6QVP1EBiuYixCl3qSF0kpArddKpk0= +github.com/lni/goutils v1.4.0 h1:e1tNN+4zsbTpNvhG5cxirkH9Pdz96QAZ2j6+5tmjvqg= +github.com/lni/goutils v1.4.0/go.mod h1:LIHvF0fflR+zyXUQFQOiHPpKANf3UIr7DFIv5CBPOoU= +github.com/lni/vfs v0.2.1-0.20231221160030-d43d3c60804c h1:ceH82TOkLNOi+vEWGhfQmO+gOuXZ+2390WaefqV920M= +github.com/lni/vfs v0.2.1-0.20231221160030-d43d3c60804c/go.mod h1:CBBfEt4D1eutp+W+FRV3cZQsg9BEV1UVRS+5mP37rUE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +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/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE= +github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/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.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +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.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +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.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +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/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +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/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8= +github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= +github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ= +github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I= +go.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM= +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/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +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/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= +go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= +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/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= +go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= +go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= +go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= +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/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= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +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= +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= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.242.0 h1:7Lnb1nfnpvbkCiZek6IXKdJ0MFuAZNAJKQfA1ws62xg= +google.golang.org/api v0.242.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= +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/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 725977e0cfcc3756842190e6b18671c218b8aaf4 Mon Sep 17 00:00:00 2001 From: Keenan Gebze Date: Thu, 17 Jul 2025 02:21:24 +0700 Subject: [PATCH 6/6] tidy2 --- .../raft/app-auth/idtoken_authlogic_user.go | 19 ------- example/raft/app-auth/token_parser.go | 24 ++++++++ example/raft/app-auth/utility.go | 55 +++++++++++++++++++ example/raft/module_auth.go | 6 +- 4 files changed, 82 insertions(+), 22 deletions(-) create mode 100644 example/raft/app-auth/token_parser.go create mode 100644 example/raft/app-auth/utility.go diff --git a/example/raft/app-auth/idtoken_authlogic_user.go b/example/raft/app-auth/idtoken_authlogic_user.go index 6bd89ea..4a0fac9 100644 --- a/example/raft/app-auth/idtoken_authlogic_user.go +++ b/example/raft/app-auth/idtoken_authlogic_user.go @@ -2,7 +2,6 @@ package plugin import ( "net/http" - "strings" "time" authapi "github.com/desain-gratis/common/delivery/auth-api" @@ -34,10 +33,6 @@ func NewUserAuthLogic(authUser mycontent.Usecase[*entity.UserAuthorization], exp func (a *userAuth) BuildToken(r *http.Request, authMethod string, auth *idtoken.Payload) (tokenData proto.Message, apiData any, expiry time.Time, err *types.CommonError) { claim := authapi.GetOIDCClaims(auth.Claims) - // Locale - // TODO parse to clean string - lang := strings.Split(r.Header.Get("Accept-Language"), ";") - // Enterprise capability (login based on organization) grants := make(map[string]*session.Grant) @@ -61,11 +56,6 @@ func (a *userAuth) BuildToken(r *http.Request, authMethod string, auth *idtoken. expiry = time.Now().Add(time.Duration(a.expiryMinutes) * time.Minute) // long-lived token - var img string - if userData.DefaultProfile.Avatar1x1 != nil { - img = userData.DefaultProfile.Avatar1x1.ThumbnailUrl - } - for namespace, auth := range userData.Authorization { grants[namespace] = &session.Grant{ UiAndApiPermission: auth.UiAndApiPermission, @@ -88,15 +78,6 @@ func (a *userAuth) BuildToken(r *http.Request, authMethod string, auth *idtoken. } apiData = &authapi.SignInResponse{ - LoginProfile: &authapi.Profile{ - DisplayName: claim.Name, - Email: claim.Email, - ImageURL: img, - }, - Locale: lang, - // collection of grants NOT signed, for debugging. - // DO NOT USE THIS FOR BACK END VALIDATION - Grants: grants, Expiry: expiry.Format(time.RFC3339), } diff --git a/example/raft/app-auth/token_parser.go b/example/raft/app-auth/token_parser.go new file mode 100644 index 0000000..4948594 --- /dev/null +++ b/example/raft/app-auth/token_parser.go @@ -0,0 +1,24 @@ +package plugin + +import ( + "context" + + types "github.com/desain-gratis/common/types/http" + "github.com/desain-gratis/common/types/protobuf/session" + "google.golang.org/protobuf/proto" +) + +func ParseToken(ctx context.Context, payload []byte) (any, *types.CommonError) { + var sess session.SessionData + + err := proto.Unmarshal(payload, &sess) + if err != nil { + return nil, &types.CommonError{ + Errors: []types.Error{ + {Message: "Error parsing token"}, + }, + } + } + + return &sess, nil +} diff --git a/example/raft/app-auth/utility.go b/example/raft/app-auth/utility.go new file mode 100644 index 0000000..dfb5f4f --- /dev/null +++ b/example/raft/app-auth/utility.go @@ -0,0 +1,55 @@ +package plugin + +import ( + "context" + "net/http" + + types "github.com/desain-gratis/common/types/http" + "github.com/desain-gratis/common/types/protobuf/session" +) + +const ( + AuthCtxKey key = "auth-ctx-key" +) + +type key string + +func getAuth(ctx context.Context) *session.SessionData { + auth, _ := ctx.Value(AuthCtxKey).(*session.SessionData) + return auth +} + +func verifyNamespace(auth *session.SessionData, namespace string) *types.CommonError { + // is this a valid namespace ? + if namespace == "" { + return &types.CommonError{ + Errors: []types.Error{ + { + HTTPCode: http.StatusUnauthorized, + Code: "EMPTY_NAMESPACE", + Message: "Every entity in mycontent have a namespace, please specify one", + }, + }, + } + } + + // if super admin, then bypass namespace authorization + if auth.IsSuperAdmin { + return nil + } + + // is this user authorized to post on behalf of data's namespace ..? + if _, ok := auth.Grants[namespace]; !ok { + return &types.CommonError{ + Errors: []types.Error{ + { + HTTPCode: http.StatusUnauthorized, + Code: "UNAUTHORIZED_NAMESPACE", + Message: "You're not authorized to post on behalf of this namespace", + }, + }, + } + } + + return nil +} diff --git a/example/raft/module_auth.go b/example/raft/module_auth.go index c65f2fc..6025372 100644 --- a/example/raft/module_auth.go +++ b/example/raft/module_auth.go @@ -16,7 +16,7 @@ import ( ) func enableAuthAPI(router *httprouter.Router, nh *dragonboat.NodeHost, info map[string]any, haveLeader *bool) { - signerVerifier := idtokensigner.NewSimple( + signerVerifier := idtokensigner.New( "raft-app", map[string]string{ "key-v1": "85746{K=q's)", @@ -25,9 +25,9 @@ func enableAuthAPI(router *httprouter.Router, nh *dragonboat.NodeHost, info map[ ) gsiAuth := idtokenverifier.GSIAuth("web client ID") - appAuth := idtokenverifier.AppAuth(signerVerifier, "app") + appAuth := idtokenverifier.AppAuth(signerVerifier, plugin.AuthCtxKey, plugin.ParseToken) - adminTokenBuilder := plugin.AdminAuthLogic(map[string]struct{}{"keenan.gebze@gmail.com": struct{}{}}, 1*30) + adminTokenBuilder := plugin.AdminAuthLogic(map[string]struct{}{"keenan.gebze@gmail.com": {}}, 1*30) userTokenBuilder := plugin.NewUserAuthLogic(nil, 8*60) router.GET("/auth/admin", gsiAuth(authapi.GetToken(adminTokenBuilder, signerVerifier)))