diff --git a/cmd/sftp-server-driver_test.go b/cmd/sftp-server-driver_test.go new file mode 100644 index 000000000..c0a880997 --- /dev/null +++ b/cmd/sftp-server-driver_test.go @@ -0,0 +1,187 @@ +// Copyright (c) 2026 PGSTY +// SPDX-License-Identifier: AGPL-3.0-or-later + +package cmd + +import ( + "bytes" + "context" + "fmt" + "io" + "net" + "net/http" + "os" + "testing" + "time" + + "github.com/minio/madmin-go/v3" + "github.com/pkg/sftp" + "golang.org/x/crypto/ssh" +) + +// Exercise the production RequestServer driver against a real S3 backend. +// The library's filesystem Server and its ReadOnly option are a different path. +func TestSFTPRequestServerObjectOperations(t *testing.T) { + for _, secure := range []bool{false, true} { + t.Run(fmt.Sprintf("TLS=%t", secure), func(t *testing.T) { + c := &check{t, "ErasureSD"} + suite := newTestSuiteIAM(TestSuiteCommon{serverType: "ErasureSD", signer: signerV4, secure: secure}, false) + suite.SetUpSuite(c) + t.Cleanup(func() { suite.TearDownSuite(c) }) + previousTLS, previousTransport := globalIsTLS, globalRemoteFTPClientTransport + globalIsTLS = secure + globalRemoteFTPClientTransport = suite.TestSuiteCommon.client.Transport.(*http.Transport) + t.Cleanup(func() { + globalIsTLS, globalRemoteFTPClientTransport = previousTLS, previousTransport + }) + + ctx, cancel := context.WithTimeout(context.Background(), testDefaultTimeout) + defer cancel() + connect := func(policy string) *sftp.Client { + t.Helper() + accessKey, secretKey := mustGenerateCredentials(c) + if err := suite.adm.SetUser(ctx, accessKey, secretKey, madmin.AccountEnabled); err != nil { + t.Fatal(err) + } + if _, err := suite.adm.AttachPolicy(ctx, madmin.PolicyAssociationReq{Policies: []string{policy}, User: accessKey}); err != nil { + t.Fatal(err) + } + perms, err := sshPasswordAuth(newSSHConnMock(accessKey), []byte(secretKey)) + if err != nil { + t.Fatal(err) + } + return newSFTPRequestTestClient(t, perms) + } + client := connect("readwrite") + bucket := "/" + getRandomBucketName() + if err := client.Mkdir(bucket); err != nil { + t.Fatal(err) + } + read := func(client *sftp.Client, name string) []byte { + t.Helper() + f, err := client.Open(name) + if err != nil { + t.Fatal(err) + } + defer f.Close() + data, err := io.ReadAll(f) + if err != nil { + t.Fatal(err) + } + return data + } + for _, size := range []int{0, 32767, 32768, 65537} { + name := fmt.Sprintf("%s/中文-café-%d", bucket, size) + data := bytes.Repeat([]byte{byte(size)}, size) + f, err := client.Create(name) + if err != nil { + t.Fatal(err) + } + if n, err := f.ReadFrom(bytes.NewReader(data)); err != nil || n != int64(size) { + f.Close() + t.Fatalf("upload %s: n=%d, err=%v", name, n, err) + } + if err := f.Close(); err != nil { + t.Fatal(err) + } + if got := read(client, name); !bytes.Equal(got, data) { + t.Fatalf("download %s: byte mismatch", name) + } + info, err := client.Stat(name) + if err != nil || info.Size() != int64(size) { + t.Fatalf("stat %s: info=%v, err=%v", name, info, err) + } + } + entries, err := client.ReadDir(bucket) + if err != nil || len(entries) != 4 { + t.Fatalf("list: %d entries, err=%v", len(entries), err) + } + name := bucket + "/中文-café-65537" + original := read(client, name) + // Include list permission because Client.Remove also tries Rmdir; + // both requests must observe the denied delete, not a failed listing. + readonly := connect("consolereadonly") + if !bytes.Equal(read(readonly, name), original) { + t.Fatal("readonly download changed content") + } + if f, err := readonly.OpenFile(name, os.O_WRONLY|os.O_TRUNC); err == nil { + _, writeErr := f.Write([]byte("forbidden")) + closeErr := f.Close() + // The streaming driver can acknowledge buffered bytes before S3 + // rejects the PUT. Verify the object, not just the write status. + t.Logf("readonly write: write=%v close=%v", writeErr, closeErr) + } + if !bytes.Equal(read(client, name), original) { + t.Fatal("readonly upload modified content") + } + if err := readonly.Remove(name); err == nil { + t.Fatal("readonly delete succeeded") + } + if !bytes.Equal(read(client, name), original) { + t.Fatal("denied operation modified content") + } + // Remove retries Rmdir, which can mask a listing error for a user + // without ListBucket. Check the stored object even if it returns nil. + withoutList := connect("readonly") + withoutList.Remove(name) + if !bytes.Equal(read(client, name), original) { + t.Fatal("readonly user without listing permission deleted content") + } + for operation, err := range map[string]error{ + "hardlink": client.Link(name, bucket+"/hardlink"), + "symlink": client.Symlink(name, bucket+"/symlink"), + "rename": client.Rename(name, bucket+"/renamed"), + } { + if status, ok := err.(*sftp.StatusError); !ok || status.Code != uint32(sftp.ErrSSHFxOpUnsupported) { + t.Fatalf("%s: expected unsupported operation, got %v", operation, err) + } + } + for _, entry := range entries { + if err := client.Remove(bucket + "/" + entry.Name()); err != nil { + t.Fatal(err) + } + } + entries, err = client.ReadDir(bucket) + if err != nil || len(entries) != 0 { + t.Fatalf("list after deletion: %d entries, err=%v", len(entries), err) + } + // SILO exposes a missing object as a directory for stat-then-list + // clients. Keep that existing virtual-directory behavior. + if info, err := client.Stat(name); err != nil || !info.IsDir() { + t.Fatalf("stat virtual directory: info=%v, err=%v", info, err) + } + if err := client.RemoveDirectory(bucket); err != nil { + t.Fatal(err) + } + }) + } +} + +func newSFTPRequestTestClient(t *testing.T, perms *ssh.Permissions) *sftp.Client { + t.Helper() + serverConn, clientConn := net.Pipe() + deadline := time.Now().Add(time.Minute) + serverConn.SetDeadline(deadline) + clientConn.SetDeadline(deadline) + server := sftp.NewRequestServer(serverConn, NewSFTPDriver(perms, "127.0.0.1"), sftp.WithRSAllocator()) + done := make(chan struct{}) + go func() { + defer close(done) + server.Serve() + }() + t.Cleanup(func() { + clientConn.Close() + server.Close() + select { + case <-done: + case <-time.After(5 * time.Second): + t.Error("SFTP request server did not stop") + } + }) + client, err := sftp.NewClientPipe(clientConn, clientConn) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { client.Close() }) + return client +} diff --git a/go.mod b/go.mod index f9c465ab9..8160c0e58 100644 --- a/go.mod +++ b/go.mod @@ -77,7 +77,7 @@ require ( github.com/minio/zipindex v0.5.0 github.com/mitchellh/go-homedir v1.1.0 github.com/nats-io/nats-server/v2 v2.15.1 - github.com/nats-io/nats.go v1.54.0 + github.com/nats-io/nats.go v1.55.0 github.com/nats-io/stan.go v0.10.4 github.com/ncw/directio v1.0.5 github.com/nsqio/go-nsq v1.1.0 @@ -85,12 +85,12 @@ require ( github.com/philhofer/fwd v1.2.1 github.com/pierrec/lz4/v4 v4.1.33 github.com/pkg/errors v0.9.1 - github.com/pkg/sftp v1.13.11 + github.com/pkg/sftp v1.13.12 github.com/pkg/xattr v0.4.12 github.com/prometheus/client_golang v1.25.0 github.com/prometheus/client_model v0.6.3 github.com/prometheus/common v0.72.1 - github.com/prometheus/procfs v0.22.0 + github.com/prometheus/procfs v0.23.0 github.com/puzpuzpuz/xsync/v3 v3.5.1 github.com/rabbitmq/amqp091-go v1.16.0 github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 @@ -101,8 +101,8 @@ require ( github.com/valyala/bytebufferpool v1.0.0 github.com/xdg/scram v1.0.5 github.com/zeebo/xxh3 v1.1.0 - go.etcd.io/etcd/api/v3 v3.7.2 - go.etcd.io/etcd/client/v3 v3.7.2 + go.etcd.io/etcd/api/v3 v3.7.3 + go.etcd.io/etcd/client/v3 v3.7.3 go.uber.org/atomic v1.12.0 go.uber.org/zap v1.28.0 go.yaml.in/yaml/v3 v3.0.5 @@ -113,7 +113,7 @@ require ( golang.org/x/sys v0.49.0 golang.org/x/term v0.47.0 golang.org/x/time v0.16.0 - google.golang.org/api v0.307.0 + google.golang.org/api v0.308.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -125,8 +125,8 @@ require ( cloud.google.com/go/auth v0.24.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.3.0 // indirect cloud.google.com/go/compute/metadata v0.10.0 // indirect - cloud.google.com/go/iam v1.14.0 // indirect - cloud.google.com/go/monitoring v1.31.0 // indirect + cloud.google.com/go/iam v1.15.0 // indirect + cloud.google.com/go/monitoring v1.32.0 // indirect filippo.io/edwards25519 v1.2.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.13.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/storage/internal v0.1.0 // indirect @@ -137,7 +137,7 @@ require ( github.com/VividCortex/ewma v1.2.0 // indirect github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect github.com/antithesishq/antithesis-sdk-go v0.8.0-default-no-op // indirect - github.com/apache/arrow-go/v18 v18.7.0 // indirect + github.com/apache/arrow-go/v18 v18.8.0 // indirect github.com/apache/thrift v0.25.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -225,7 +225,7 @@ require ( github.com/lestrrat-go/dsig-secp256k1 v1.0.0 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/httprc/v3 v3.0.6 // indirect - github.com/lestrrat-go/jwx/v3 v3.3.0 // indirect + github.com/lestrrat-go/jwx/v3 v3.4.0 // indirect github.com/lestrrat-go/option/v2 v2.0.0 // indirect github.com/lucasb-eyer/go-colorful v1.4.1 // indirect github.com/lufia/plan9stats v0.0.0-20260802145828-341c2f0c90b5 // indirect @@ -282,7 +282,7 @@ require ( github.com/xdg/stringprep v1.0.3 // indirect github.com/xo/terminfo v1.2.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.7.2 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.7.3 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.47.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.72.0 // indirect diff --git a/go.sum b/go.sum index 8455f3678..be51e599c 100644 --- a/go.sum +++ b/go.sum @@ -15,14 +15,14 @@ cloud.google.com/go/auth/oauth2adapt v0.3.0 h1:FY8oSZpCYoUNv6QxVODuMjQz4IlSOVeiQ cloud.google.com/go/auth/oauth2adapt v0.3.0/go.mod h1:7+2uCm7++XFO+/lN06c2HXpDXb/NMNn2/UwyBPbTnkk= cloud.google.com/go/compute/metadata v0.10.0 h1:pyKMUQSwchgkIBBJGdILqQbs/BNJXqwSA7Ej6LAvvtY= cloud.google.com/go/compute/metadata v0.10.0/go.mod h1:rGFHRrIif570kSibjFTMbt6/4/tzgJWFGI/HVol4GIk= -cloud.google.com/go/iam v1.14.0 h1:YRIB1/4xxwJ+NfI6RQr1WaOoHHeV0MizJEj940nBXJA= -cloud.google.com/go/iam v1.14.0/go.mod h1:JTPZfbHdGXJrOYREtkRoFzCDGaBdbA7ILLKO/DDuav0= +cloud.google.com/go/iam v1.15.0 h1:U/wqjfrM0ceBFdPlOI2+cu68yPAxh72M8fe9uLG0+ZE= +cloud.google.com/go/iam v1.15.0/go.mod h1:HAVf7PNhTrNTrEc6fVB21l8ejkbzNTulJHYf7QtD424= cloud.google.com/go/logging v1.20.0 h1:l7yzCB8/JSY5PHT9RsaqdT1jaBGbM6KlSJDX210HlXM= cloud.google.com/go/logging v1.20.0/go.mod h1:ALUaJQZM691Eeujy9kFx0xREq3AMPuGd+pTRZuTYv+w= cloud.google.com/go/longrunning v1.3.0 h1:lZ6c8SJJBmILp/Wnr3vGnBLa0q+cYfSHRCcUfVI2hpI= cloud.google.com/go/longrunning v1.3.0/go.mod h1:wpgLxCn+UA3/TZ1bj/fW39mfDpwVlMPu1xKJyoMt7V0= -cloud.google.com/go/monitoring v1.31.0 h1:LCuAoYiq8snyL/eDAG/VC73uWFXeax8+YEfmoNGJUrY= -cloud.google.com/go/monitoring v1.31.0/go.mod h1:7uk2dIJIf7ra64dI1VuQ0ttoFqvtKjdzq46u6zNP1hU= +cloud.google.com/go/monitoring v1.32.0 h1:0bXxoh3o751jZnKDHgUDajaG8ZtqtKPMxhVmohRHI0Q= +cloud.google.com/go/monitoring v1.32.0/go.mod h1:FxmFKr7SUhb60LDuYvjUc6bk9i1+LyXaENR5qAEibrM= cloud.google.com/go/storage v1.70.0 h1:LQNHn0rRF94jVFfF3e416IzdQqIufa5GfF6HilQxb80= cloud.google.com/go/storage v1.70.0/go.mod h1:W84cNa070TZIegvTW67CBY+f5rxux8EJMb7YyiHdrls= cloud.google.com/go/trace v1.16.0 h1:GmQovzFc5F0CNfl0VLgL64aoTtu7xsM0YajW2GlG9+E= @@ -67,12 +67,12 @@ github.com/alecthomas/participle v0.7.1/go.mod h1:HfdmEuwvr12HXQN44HPWXR0lHmVolV github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI= github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= -github.com/andybalholm/brotli v1.2.2 h1:HzTuoo2ErYQqf5qvcJInB8uvqSVxRttzkFexPWtnceM= -github.com/andybalholm/brotli v1.2.2/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= +github.com/andybalholm/brotli v1.2.3 h1:8H1qwOkl2LPfjf3YezB90JnCliZb6SInJ/OJkEbA5NQ= +github.com/andybalholm/brotli v1.2.3/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/antithesishq/antithesis-sdk-go v0.8.0-default-no-op h1:1BOWQJweNyvZMlpAHXGLiZQn9S+QXGcz3xh94lC0w6E= github.com/antithesishq/antithesis-sdk-go v0.8.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= -github.com/apache/arrow-go/v18 v18.7.0 h1:Vw/i+cJyebUofT7JlqFpe65LrmwxULn166jjwStM4HY= -github.com/apache/arrow-go/v18 v18.7.0/go.mod h1:PM6IigLJkdMwIpeHXnymo+xZ52f42a9EYiLtRel4p/A= +github.com/apache/arrow-go/v18 v18.8.0 h1:BLOzbPv7bxMPgXPacAg6HQjnxupYsZzC4tf+FkqPU/M= +github.com/apache/arrow-go/v18 v18.8.0/go.mod h1:uJCFfCwq0KsxCmsCfQg4ft+LsW+iHYzAXiSDh5ug/8U= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/apache/thrift v0.25.0 h1:6LLlvoPjy8Cc/0b5TYRcTR3RZa2W0at3WQRcOkDwVGs= github.com/apache/thrift v0.25.0/go.mod h1:4lwyToijD9T70w7GlevFk7FnpY60Wv8I8krMkF6FkAo= @@ -387,8 +387,8 @@ github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZ github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= github.com/lestrrat-go/httprc/v3 v3.0.6 h1:4FpLQ18KK/ypPbVU3NLWJNRvH3kcYiqKqWfKGqNWxxI= github.com/lestrrat-go/httprc/v3 v3.0.6/go.mod h1:mSMtkZW92Z98M5YoNNztbRGxbXHql7tSitCvaxvo9l0= -github.com/lestrrat-go/jwx/v3 v3.3.0 h1:OXcYvQOQ7cxWzeZ/Q9sYk8ABe/kCSI371WmuACiCT+4= -github.com/lestrrat-go/jwx/v3 v3.3.0/go.mod h1:eIJhDcKHBwcgxqv8RiIylV67TVl1wJp/265IAHY1Db8= +github.com/lestrrat-go/jwx/v3 v3.4.0 h1:2YSO4sfAj+M90XUuEJZsMibRNpoh1KXP1iL+C/tFebg= +github.com/lestrrat-go/jwx/v3 v3.4.0/go.mod h1:jrZZIM3dgHB780ZrD/3H+ARR5ou4w3X3wFjWE+JWGMU= github.com/lestrrat-go/option/v2 v2.0.0 h1:XxrcaJESE1fokHy3FpaQ/cXW8ZsIdWcdFzzLOcID3Ss= github.com/lestrrat-go/option/v2 v2.0.0/go.mod h1:oSySsmzMoR0iRzCDCaUfsCzxQHUEuhOViQObyy7S6Vg= github.com/lib/pq v1.12.3 h1:tTWxr2YLKwIvK90ZXEw8GP7UFHtcbTtty8zsI+YjrfQ= @@ -486,8 +486,8 @@ github.com/nats-io/nats-server/v2 v2.15.1/go.mod h1:yeuYRtKVKIFtmMz2/YPk+6hvmNBn github.com/nats-io/nats-streaming-server v0.25.6 h1:8OBRaIl64u+DFvZYpF50RRzwG/yLcJZL0R7VMc7tp4Y= github.com/nats-io/nats-streaming-server v0.25.6/go.mod h1:LEcu6uGSDBB4O/IBUsDBHYk/O0K7XZza8nMjCIXicLk= github.com/nats-io/nats.go v1.22.1/go.mod h1:tLqubohF7t4z3du1QDPYJIQQyhb4wl6DhjxEajSI7UA= -github.com/nats-io/nats.go v1.54.0 h1:vsXoOxjHp/GmPUN+EcI7uOf/uB+iAP+kEsAFNQN0yzA= -github.com/nats-io/nats.go v1.54.0/go.mod h1:y+DZoD1oBOYfZTU681eTUiUjI0vbqYGixNVFHcjHJ0k= +github.com/nats-io/nats.go v1.55.0 h1:Ng8QKHdvdHIWoaiq0+d/aH1BWkxvcJxWJ0Y/9BPKx3M= +github.com/nats-io/nats.go v1.55.0/go.mod h1:y+DZoD1oBOYfZTU681eTUiUjI0vbqYGixNVFHcjHJ0k= github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= github.com/nats-io/nkeys v0.4.16 h1:rd5oAuLOb8mnAycB0xleuEBNS1pVVnN0fv/FF34Eypg= github.com/nats-io/nkeys v0.4.16/go.mod h1:llLgWoI0o4z/Q57q2R1kHfmocyhGV6VG/U18Glg1Afs= @@ -520,8 +520,8 @@ github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmd github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE= -github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0= +github.com/pkg/sftp v1.13.12 h1:Myhzy/ZzLPnCtE2F2WtDHsgs8RfgMnH2gfbHuCJhkMU= +github.com/pkg/sftp v1.13.12/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0= github.com/pkg/xattr v0.4.12 h1:rRTkSyFNTRElv6pkA3zpjHpQ90p/OdHQC1GmGh1aTjM= github.com/pkg/xattr v0.4.12/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= @@ -537,8 +537,8 @@ github.com/prometheus/client_model v0.6.3 h1:O0jaTVAYNxTHYInEPFJt5I3+sN8zqBtVMPT github.com/prometheus/client_model v0.6.3/go.mod h1:gpN5P9S7Rr6Yr92PiQ+Ixvhf6JZEkF1dnxsYL2aPBEM= github.com/prometheus/common v0.72.1 h1:ZAiQed/nk8IIcsdzb2TlJu23NEUDyDLQ9TXTN2WRK6Y= github.com/prometheus/common v0.72.1/go.mod h1:1IoBY4IRaJnhs2ESjNzjilP1cJ/P8pimGoomq7zRXrA= -github.com/prometheus/procfs v0.22.0 h1:6q9+/JL9IKAPbCmBrv9n5O5Ty3NKnciV5X7YGw0oics= -github.com/prometheus/procfs v0.22.0/go.mod h1:CvmFr/GVhIjIvWJZW3tgkODBQMRIf0EyWMQLHCHab58= +github.com/prometheus/procfs v0.23.0 h1:ad+S6FTkzwaMgacKLM5h6bNKExS+DMH0YiUwXItH/o4= +github.com/prometheus/procfs v0.23.0/go.mod h1:3AVXO0FqLafyYFU/V/IQRZlC8Rgqz8Dm/x6pKLK+RIk= github.com/prometheus/prom2json v1.5.0 h1:WIcAOjLE1x476W3dUlmTL6E/e98CgVGuwwYusl6MPP8= github.com/prometheus/prom2json v1.5.0/go.mod h1:xPp6KDhCA30btxmqEfg/K3DAwgTIkp7TJKi4+7jaYd8= github.com/prometheus/prometheus v0.315.1 h1:ZXaNKyUO5szJhhw7gKiP6b2jpx1QkS0S3CI1R1bPqIA= @@ -639,12 +639,12 @@ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.etcd.io/etcd/api/v3 v3.7.2 h1:xgt/6el1LsPWWYNLkhMAK4tZm6dF+1sCqDecpE5gdbk= -go.etcd.io/etcd/api/v3 v3.7.2/go.mod h1:RoRCBRt9BfBff1pIGZLUVMiz7wu3bY+b2qLysGu1HY4= -go.etcd.io/etcd/client/pkg/v3 v3.7.2 h1:SVtlR7tiSVAYOQ4nWPIyFXb4RMgEcnzeAG9RQ8MoNDU= -go.etcd.io/etcd/client/pkg/v3 v3.7.2/go.mod h1:HsSux/B3ahgyw/D5+d4YbZqicOi0mEbuxm6lIUdjAoI= -go.etcd.io/etcd/client/v3 v3.7.2 h1:Z66GqDQDI7zPDfVSsIBqGSK4mJYLtv8ESwXa4mPf+wY= -go.etcd.io/etcd/client/v3 v3.7.2/go.mod h1:x03t1qMs4tGZirCDJlMuzPBJdQffXJImIyEjLhNBCsY= +go.etcd.io/etcd/api/v3 v3.7.3 h1:2tumepXe+wi7Wab64uUO71K7ISQyUWLGC1DJbbc59sY= +go.etcd.io/etcd/api/v3 v3.7.3/go.mod h1:HOR9Qn4gb/1/hVAmYprmlLpvTe6ZgfgNS9Z/+Ty65po= +go.etcd.io/etcd/client/pkg/v3 v3.7.3 h1:5zMwNu3ycrzCeA5NwOfQbxFRhqq974chq1DrYMua4QI= +go.etcd.io/etcd/client/pkg/v3 v3.7.3/go.mod h1:/OhzqYrF0U7d1NOk55VMyUQGbYD1WoIe4bJwxb47wOk= +go.etcd.io/etcd/client/v3 v3.7.3 h1:UrXcetgkuSEocaBlQlulQRJlXLEnUAHuBRbHh0lue1Q= +go.etcd.io/etcd/client/v3 v3.7.3/go.mod h1:DcPxpqcpV8WIaRi/2waPCx0/Uq8rQUweDJaDYZk1gEE= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/detectors/gcp v1.47.0 h1:Ct6+aaiSO6Nk5SOb6PYcR7iWp+83YF/pL1OJcGqOmbg= @@ -781,8 +781,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= -google.golang.org/api v0.307.0 h1:KJJv1V/cOeCUrgKFippAhSg98QlR2IZFqubQKf7gQdg= -google.golang.org/api v0.307.0/go.mod h1:4XMH+b/ZEfuTbK7FnrFRY9c4xfFHVflGTKuy/i5wUmE= +google.golang.org/api v0.308.0 h1:iGb+4qT3nVb3uuIzwor3yP2nyu+rMZr31PvLFiRNJQk= +google.golang.org/api v0.308.0/go.mod h1:4XMH+b/ZEfuTbK7FnrFRY9c4xfFHVflGTKuy/i5wUmE= google.golang.org/genproto v0.0.0-20261019180522-ce908d29299b h1:+t2qGqt6R8CO622uiX1JpnRvRvSOQoVRV0DiPzUjKXg= google.golang.org/genproto v0.0.0-20261019180522-ce908d29299b/go.mod h1:XRIfc1yr5xsbF8xFw5+g7SEmLJX/eQ7MMazTRbnMMvI= google.golang.org/genproto/googleapis/api v0.0.0-20261019180522-ce908d29299b h1:nB3spRIaSPtxJpxb0k41yljROvm2Jrwfs2pSNdKS5y8=