Compare commits
27 Commits
issue-1041
...
articles-v
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
075cc341e8 | ||
|
|
532fcc3dfe | ||
|
|
b003d6c6ae | ||
|
|
8fa0fae05a | ||
|
|
3fe2ec7bde | ||
|
|
6389979bce | ||
|
|
210fd0ae15 | ||
|
|
f95b483a13 | ||
|
|
b71c37e20a | ||
|
|
c27b5f5dfe | ||
|
|
0a31eacb3d | ||
|
|
70b0115ea6 | ||
|
|
dfafd14767 | ||
|
|
e3fdbc8341 | ||
|
|
1bf442537f | ||
|
|
211fb08028 | ||
|
|
846124e280 | ||
|
|
e1a9901654 | ||
|
|
5d0cf1d4a5 | ||
|
|
cd3d297a3d | ||
|
|
52f4d0f055 | ||
|
|
72c9e9377c | ||
|
|
0aaa741b5b | ||
|
|
0e9870b7a9 | ||
|
|
accb06d131 | ||
|
|
1787bce6cb | ||
|
|
141febd413 |
@@ -290,7 +290,7 @@ func getAWSAPIConfig(argIdx int) (*awsapi.Config, error) {
|
||||
accessKey := awsAccessKey.GetOptionalArg(argIdx)
|
||||
secretKey := awsSecretKey.GetOptionalArg(argIdx)
|
||||
service := awsService.GetOptionalArg(argIdx)
|
||||
cfg, err := awsapi.NewConfig(ec2Endpoint, stsEndpoint, region, roleARN, accessKey, secretKey, service)
|
||||
cfg, err := awsapi.NewConfig(ec2Endpoint, stsEndpoint, region, roleARN, accessKey, secretKey, service, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -233,13 +233,18 @@ var (
|
||||
rwTotal = metrics.NewCounter(`vmalert_remotewrite_total`)
|
||||
|
||||
// sentRows and sentBytes are historical counters that can now be replaced by flushedRows and flushedBytes histograms. They may be deprecated in the future after the new histograms have been adopted for some time.
|
||||
sentRows = metrics.NewCounter(`vmalert_remotewrite_sent_rows_total`)
|
||||
sentBytes = metrics.NewCounter(`vmalert_remotewrite_sent_bytes_total`)
|
||||
flushedRows = metrics.NewHistogram(`vmalert_remotewrite_sent_rows`)
|
||||
flushedBytes = metrics.NewHistogram(`vmalert_remotewrite_sent_bytes`)
|
||||
droppedRows = metrics.NewCounter(`vmalert_remotewrite_dropped_rows_total`)
|
||||
sendDuration = metrics.NewFloatCounter(`vmalert_remotewrite_send_duration_seconds_total`)
|
||||
bufferFlushDuration = metrics.NewHistogram(`vmalert_remotewrite_flush_duration_seconds`)
|
||||
sentRows = metrics.NewCounter(`vmalert_remotewrite_sent_rows_total`)
|
||||
sentBytes = metrics.NewCounter(`vmalert_remotewrite_sent_bytes_total`)
|
||||
flushedRows = metrics.NewHistogram(`vmalert_remotewrite_sent_rows`)
|
||||
flushedBytes = metrics.NewHistogram(`vmalert_remotewrite_sent_bytes`)
|
||||
droppedRows = metrics.NewCounter(`vmalert_remotewrite_dropped_rows_total`)
|
||||
sendDuration = metrics.NewFloatCounter(`vmalert_remotewrite_send_duration_seconds_total`)
|
||||
bufferFlushDuration = metrics.NewHistogram(`vmalert_remotewrite_flush_duration_seconds`)
|
||||
remoteWriteQueueSize = metrics.NewHistogram(`vmalert_remotewrite_queue_size`)
|
||||
|
||||
_ = metrics.NewGauge(`vmalert_remotewrite_queue_capacity`, func() float64 {
|
||||
return float64(*maxQueueSize)
|
||||
})
|
||||
|
||||
_ = metrics.NewGauge(`vmalert_remotewrite_concurrency`, func() float64 {
|
||||
return float64(*concurrency)
|
||||
@@ -253,6 +258,7 @@ func GetDroppedRows() int { return int(droppedRows.Get()) }
|
||||
// it to remote-write endpoint. Flush performs limited amount of retries
|
||||
// if request fails.
|
||||
func (c *Client) flush(ctx context.Context, wr *prompb.WriteRequest) {
|
||||
remoteWriteQueueSize.Update(float64(len(c.input)))
|
||||
if len(wr.Timeseries) < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -381,7 +381,9 @@ func (g *Group) Start(ctx context.Context, rw remotewrite.RWClient, rr datasourc
|
||||
|
||||
if len(g.Rules) < 1 {
|
||||
g.metrics.iterationDuration.UpdateDuration(start)
|
||||
g.mu.Lock()
|
||||
g.LastEvaluation = start
|
||||
g.mu.Unlock()
|
||||
return ts
|
||||
}
|
||||
|
||||
@@ -395,7 +397,9 @@ func (g *Group) Start(ctx context.Context, rw remotewrite.RWClient, rr datasourc
|
||||
}
|
||||
}
|
||||
g.metrics.iterationDuration.UpdateDuration(start)
|
||||
g.mu.Lock()
|
||||
g.LastEvaluation = start
|
||||
g.mu.Unlock()
|
||||
return ts
|
||||
}
|
||||
|
||||
@@ -405,11 +409,11 @@ func (g *Group) Start(ctx context.Context, rw remotewrite.RWClient, rr datasourc
|
||||
g.mu.Unlock()
|
||||
defer g.evalCancel()
|
||||
|
||||
realEvalTS := eval(evalCtx, evalTS)
|
||||
|
||||
t := time.NewTicker(g.Interval)
|
||||
defer t.Stop()
|
||||
|
||||
realEvalTS := eval(evalCtx, evalTS)
|
||||
|
||||
// restore the rules state after the first evaluation
|
||||
// so only active alerts can be restored.
|
||||
if rr != nil {
|
||||
|
||||
@@ -47,13 +47,12 @@ var (
|
||||
"It is recommended setting this value to values smaller than -http.idleConnTimeout set at backend services")
|
||||
responseTimeout = flag.Duration("responseTimeout", 5*time.Minute, "The timeout for receiving a response from backend")
|
||||
|
||||
requestBufferSize = flagutil.NewBytes("requestBufferSize", defaultBodyBufferSize, "The size of the buffer for reading the request body before proxying the request to backends. "+
|
||||
requestBufferSize = flagutil.NewBytes("requestBufferSize", 32*1024, "The size of the buffer for reading the request body before proxying the request to backends. "+
|
||||
"This allows reducing the consumption of backend resources when processing requests from clients connected via slow networks. "+
|
||||
"Set to 0 to disable request buffering. See https://docs.victoriametrics.com/victoriametrics/vmauth/#request-body-buffering. "+
|
||||
" Disabling request buffering also disables request retries configured with '-maxRequestBodySizeToRetry'")
|
||||
maxRequestBodySizeToRetry = flagutil.NewBytes("maxRequestBodySizeToRetry", defaultBodyBufferSize, "The maximum request body size in memory for potential retries at other backends. "+
|
||||
"Request bodies larger than this size cannot be retried if the backend fails. Zero or negative value disables request retries. "+
|
||||
"See also '-requestBufferSize' flag, which controlls a size of the buffer for potential retry.")
|
||||
"Set to 0 to disable request buffering. See https://docs.victoriametrics.com/victoriametrics/vmauth/#request-body-buffering")
|
||||
maxRequestBodySizeToRetry = flagutil.NewBytes("maxRequestBodySizeToRetry", 16*1024, "The maximum request body size to buffer in memory for potential retries at other backends. "+
|
||||
"Request bodies larger than this size cannot be retried if the backend fails. Zero or negative value disables request body buffering and retries. "+
|
||||
"See also -requestBufferSize")
|
||||
|
||||
maxConcurrentRequests = flag.Int("maxConcurrentRequests", 1000, "The maximum number of concurrent requests vmauth can process simultaneously. "+
|
||||
"Requests exceeding this limit are queued for up to -maxQueueDuration and then rejected with '429 Too Many Requests' http status code if the limit is still reached. "+
|
||||
@@ -90,8 +89,6 @@ var (
|
||||
"Recommended when vmauth is exposed to the internet.")
|
||||
)
|
||||
|
||||
const defaultBodyBufferSize = 16 * 1024
|
||||
|
||||
func main() {
|
||||
// Write flags and help message to stdout, since it is easier to grep or pipe.
|
||||
flag.CommandLine.SetOutput(os.Stdout)
|
||||
@@ -352,25 +349,13 @@ func endConcurrencyLimit() {
|
||||
<-concurrencyLimitCh
|
||||
}
|
||||
|
||||
func getMaxRequestBufSize() int {
|
||||
rbs := requestBufferSize.IntN()
|
||||
rbstr := maxRequestBodySizeToRetry.IntN()
|
||||
if rbs <= 0 {
|
||||
// request buffering disabled
|
||||
// it also disables request retries as a side effect
|
||||
return 0
|
||||
}
|
||||
// for backward compatibility we must use max value for both flags
|
||||
return max(rbs, rbstr)
|
||||
}
|
||||
|
||||
func bufferRequestBody(ctx context.Context, r io.ReadCloser, userName string) (io.ReadCloser, error) {
|
||||
if r == nil {
|
||||
// This is a GET request with nil reader.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
maxBufSize := getMaxRequestBufSize()
|
||||
maxBufSize := max(requestBufferSize.IntN(), maxRequestBodySizeToRetry.IntN())
|
||||
if maxBufSize <= 0 {
|
||||
return r, nil
|
||||
}
|
||||
@@ -401,7 +386,7 @@ func bufferRequestBody(ctx context.Context, r io.ReadCloser, userName string) (i
|
||||
}
|
||||
}
|
||||
|
||||
bb := newBufferedBody(r, buf, maxBufSize, maxRequestBodySizeToRetry.IntN())
|
||||
bb := newBufferedBody(r, buf, maxBufSize)
|
||||
return bb, nil
|
||||
}
|
||||
|
||||
@@ -825,14 +810,11 @@ type bufferedBody struct {
|
||||
// bufOffset is the offset at buf for already read bytes.
|
||||
bufOffset int
|
||||
|
||||
// cannotRetry is set to true if buf size exceeds max retry body size
|
||||
// cannotRetry is set to true after Close() call on non-nil r.
|
||||
cannotRetry bool
|
||||
|
||||
// bodyWasClosed is set to true at Close if request retry is not possible
|
||||
bodyWasClosed bool
|
||||
}
|
||||
|
||||
func newBufferedBody(r io.ReadCloser, buf []byte, maxBufSize, maxBufRetrySize int) *bufferedBody {
|
||||
func newBufferedBody(r io.ReadCloser, buf []byte, maxBufSize int) *bufferedBody {
|
||||
// Do not use sync.Pool here, since http.RoundTrip may still use request body after return.
|
||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/8051
|
||||
|
||||
@@ -842,15 +824,14 @@ func newBufferedBody(r io.ReadCloser, buf []byte, maxBufSize, maxBufRetrySize in
|
||||
}
|
||||
|
||||
return &bufferedBody{
|
||||
r: r,
|
||||
buf: buf,
|
||||
cannotRetry: len(buf) > maxBufRetrySize || maxBufRetrySize == 0,
|
||||
r: r,
|
||||
buf: buf,
|
||||
}
|
||||
}
|
||||
|
||||
// Read implements io.Reader interface.
|
||||
func (bb *bufferedBody) Read(p []byte) (int, error) {
|
||||
if bb.bodyWasClosed {
|
||||
if bb.cannotRetry {
|
||||
return 0, fmt.Errorf("cannot read already closed body")
|
||||
}
|
||||
if bb.bufOffset < len(bb.buf) {
|
||||
@@ -865,16 +846,14 @@ func (bb *bufferedBody) Read(p []byte) (int, error) {
|
||||
}
|
||||
|
||||
func (bb *bufferedBody) canRetry() bool {
|
||||
return !bb.cannotRetry
|
||||
return bb.r == nil
|
||||
}
|
||||
|
||||
// Close implements io.Closer interface.
|
||||
func (bb *bufferedBody) Close() error {
|
||||
bb.resetReader()
|
||||
if bb.cannotRetry {
|
||||
bb.bodyWasClosed = true
|
||||
}
|
||||
if bb.r != nil {
|
||||
bb.cannotRetry = true
|
||||
return bb.r.Close()
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -1714,6 +1714,13 @@ func TestBufferRequestBody_Failure(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
|
||||
defaultMaxRequestBodySizeToRetry := maxRequestBodySizeToRetry.String()
|
||||
defer func() {
|
||||
if err := maxRequestBodySizeToRetry.Set(defaultMaxRequestBodySizeToRetry); err != nil {
|
||||
t.Fatalf("cannot reset maxRequestBodySizeToRetry: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
defaultMaxQueueDuration := *maxQueueDuration
|
||||
defer func() {
|
||||
*maxQueueDuration = defaultMaxQueueDuration
|
||||
@@ -1722,6 +1729,9 @@ func TestBufferRequestBody_Failure(t *testing.T) {
|
||||
f := func(body *mockBody, expectedResponse string) {
|
||||
t.Helper()
|
||||
|
||||
if err := maxRequestBodySizeToRetry.Set("0"); err != nil {
|
||||
t.Fatalf("cannot set maxRequestBodySizeToRetry: %s", err)
|
||||
}
|
||||
if err := requestBufferSize.Set("2048"); err != nil {
|
||||
t.Fatalf("cannot set requestBufferSize: %s", err)
|
||||
}
|
||||
@@ -1834,6 +1844,16 @@ func TestBufferedBody_RetrySuccess(t *testing.T) {
|
||||
t.Fatalf("cannot set requestBufferSize: %s", err)
|
||||
}
|
||||
|
||||
defaultMaxRequestBodySizeToRetry := maxRequestBodySizeToRetry.String()
|
||||
defer func() {
|
||||
if err := maxRequestBodySizeToRetry.Set(defaultMaxRequestBodySizeToRetry); err != nil {
|
||||
t.Fatalf("cannot reset maxRequestBodySizeToRetry: %s", err)
|
||||
}
|
||||
}()
|
||||
if err := maxRequestBodySizeToRetry.Set("0"); err != nil {
|
||||
t.Fatalf("cannot set maxRequestBodySizeToRetry: %s", err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
rb, err := bufferRequestBody(ctx, io.NopCloser(bytes.NewBufferString(s)), "foo")
|
||||
if err != nil {
|
||||
@@ -1882,6 +1902,16 @@ func TestBufferedBody_RetrySuccessPartialRead(t *testing.T) {
|
||||
t.Fatalf("cannot set requestBufferSize: %s", err)
|
||||
}
|
||||
|
||||
defaultMaxRequestBodySizeToRetry := maxRequestBodySizeToRetry.String()
|
||||
defer func() {
|
||||
if err := maxRequestBodySizeToRetry.Set(defaultMaxRequestBodySizeToRetry); err != nil {
|
||||
t.Fatalf("cannot reset maxRequestBodySizeToRetry: %s", err)
|
||||
}
|
||||
}()
|
||||
if err := maxRequestBodySizeToRetry.Set("0"); err != nil {
|
||||
t.Fatalf("cannot set maxRequestBodySizeToRetry: %s", err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
rb, err := bufferRequestBody(ctx, io.NopCloser(bytes.NewBufferString(s)), "foo")
|
||||
if err != nil {
|
||||
@@ -1934,6 +1964,16 @@ func TestBufferedBody_RetryFailureTooBigBody(t *testing.T) {
|
||||
f := func(s string, maxBodySize int) {
|
||||
t.Helper()
|
||||
|
||||
defaultRequestBufferSize := requestBufferSize.String()
|
||||
defer func() {
|
||||
if err := requestBufferSize.Set(defaultRequestBufferSize); err != nil {
|
||||
t.Fatalf("cannot reset requestBufferSize: %s", err)
|
||||
}
|
||||
}()
|
||||
if err := requestBufferSize.Set("0"); err != nil {
|
||||
t.Fatalf("cannot set requestBufferSize: %s", err)
|
||||
}
|
||||
|
||||
defaultMaxRequestBodySizeToRetry := maxRequestBodySizeToRetry.String()
|
||||
defer func() {
|
||||
if err := maxRequestBodySizeToRetry.Set(defaultMaxRequestBodySizeToRetry); err != nil {
|
||||
@@ -2009,9 +2049,10 @@ func TestBufferedBody_RetryFailureZeroOrNegativeMaxBodySize(t *testing.T) {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
bb, ok := rb.(*bufferedBody)
|
||||
canRetry := ok && bb.canRetry()
|
||||
if canRetry {
|
||||
t.Fatalf("canRetry() must return false before reading anything")
|
||||
canRetry := !ok || bb.canRetry()
|
||||
|
||||
if !canRetry {
|
||||
t.Fatalf("canRetry() must return true before reading anything")
|
||||
}
|
||||
data, err := io.ReadAll(rb)
|
||||
if err != nil {
|
||||
@@ -2028,8 +2069,8 @@ func TestBufferedBody_RetryFailureZeroOrNegativeMaxBodySize(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error in io.ReadAll: %s", err)
|
||||
}
|
||||
if len(data) > 0 {
|
||||
t.Fatalf("unexpected non-empty data read\ngot\n%s", data)
|
||||
if string(data) != s {
|
||||
t.Fatalf("unexpected data read\ngot\n%s\nwant\n%s", data, s)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/procutil"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/pushmetrics"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/snapshot"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/snapshot/snapshotutil"
|
||||
)
|
||||
|
||||
@@ -11,6 +11,16 @@
|
||||
|
||||
{% stripspace %}
|
||||
|
||||
{% func ExportCSVHeader(fieldNames []string) %}
|
||||
{% if len(fieldNames) == 0 %}{% return %}{% endif %}
|
||||
{%s= fieldNames[0] %}
|
||||
{% for _, fieldName := range fieldNames[1:] %}
|
||||
,
|
||||
{%s= fieldName %}
|
||||
{% endfor %}
|
||||
{% newline %}
|
||||
{% endfunc %}
|
||||
|
||||
{% func ExportCSVLine(xb *exportBlock, fieldNames []string) %}
|
||||
{% if len(xb.timestamps) == 0 || len(fieldNames) == 0 %}{% return %}{% endif %}
|
||||
{% for i, timestamp := range xb.timestamps %}
|
||||
|
||||
132
app/vmselect/prometheus/export_test.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/storage"
|
||||
)
|
||||
|
||||
func TestExportCSVHeader(t *testing.T) {
|
||||
f := func(fieldNames []string, expected string) {
|
||||
t.Helper()
|
||||
got := ExportCSVHeader(fieldNames)
|
||||
if got != expected {
|
||||
t.Fatalf("ExportCSVHeader(%v): got %q; want %q", fieldNames, got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
f(nil, "")
|
||||
f([]string{}, "")
|
||||
|
||||
f([]string{"__value__"}, "__value__\n")
|
||||
f([]string{"__timestamp__"}, "__timestamp__\n")
|
||||
f([]string{"__timestamp__:rfc3339"}, "__timestamp__:rfc3339\n")
|
||||
f([]string{"__name__"}, "__name__\n")
|
||||
f([]string{"job"}, "job\n")
|
||||
|
||||
f([]string{"__timestamp__:rfc3339", "__value__"}, "__timestamp__:rfc3339,__value__\n")
|
||||
f([]string{"__value__", "__timestamp__"}, "__value__,__timestamp__\n")
|
||||
f([]string{"job", "instance"}, "job,instance\n")
|
||||
|
||||
f([]string{"__name__", "__value__", "__timestamp__:unix_s"}, "__name__,__value__,__timestamp__:unix_s\n")
|
||||
f([]string{"job", "instance", "__value__", "__timestamp__:unix_ms"}, "job,instance,__value__,__timestamp__:unix_ms\n")
|
||||
f([]string{"__timestamp__:custom:2006-01-02", "__value__", "host", "dc", "env"},
|
||||
"__timestamp__:custom:2006-01-02,__value__,host,dc,env\n")
|
||||
|
||||
// duplicate fields
|
||||
f([]string{"__value__", "__value__"}, "__value__,__value__\n")
|
||||
f([]string{"__timestamp__", "__timestamp__:rfc3339"}, "__timestamp__,__timestamp__:rfc3339\n")
|
||||
}
|
||||
|
||||
func TestExportCSVLine(t *testing.T) {
|
||||
localBak := time.Local
|
||||
time.Local = time.UTC
|
||||
defer func() { time.Local = localBak }()
|
||||
|
||||
f := func(mn *storage.MetricName, timestamps []int64, values []float64, fieldNames []string, expected string) {
|
||||
t.Helper()
|
||||
xb := &exportBlock{
|
||||
mn: mn,
|
||||
timestamps: timestamps,
|
||||
values: values,
|
||||
}
|
||||
got := ExportCSVLine(xb, fieldNames)
|
||||
if got != expected {
|
||||
t.Fatalf("ExportCSVLine: got %q; want %q", got, expected)
|
||||
}
|
||||
}
|
||||
|
||||
mn := &storage.MetricName{
|
||||
MetricGroup: []byte("cpu_usage"),
|
||||
Tags: []storage.Tag{
|
||||
{Key: []byte("job"), Value: []byte("node")},
|
||||
{Key: []byte("instance"), Value: []byte("localhost:9090")},
|
||||
},
|
||||
}
|
||||
|
||||
// empty inputs
|
||||
f(mn, nil, nil, []string{"__value__"}, "")
|
||||
f(mn, []int64{}, []float64{}, []string{"__value__"}, "")
|
||||
f(mn, []int64{1000}, []float64{1.5}, nil, "")
|
||||
f(mn, []int64{1000}, []float64{1.5}, []string{}, "")
|
||||
|
||||
f(mn, []int64{1000}, []float64{42.5}, []string{"__value__"}, "42.5\n")
|
||||
f(mn, []int64{1704067200000}, []float64{1}, []string{"__timestamp__"}, "1704067200000\n")
|
||||
f(mn, []int64{1704067200000}, []float64{1}, []string{"__timestamp__:unix_s"}, "1704067200\n")
|
||||
f(mn, []int64{1704067200000}, []float64{1}, []string{"__timestamp__:unix_ms"}, "1704067200000\n")
|
||||
f(mn, []int64{1704067200000}, []float64{1}, []string{"__timestamp__:unix_ns"}, "1704067200000000000\n")
|
||||
f(mn, []int64{1704067200000}, []float64{1}, []string{"__timestamp__:rfc3339"}, "2024-01-01T00:00:00Z\n")
|
||||
|
||||
f(mn, []int64{1000}, []float64{1}, []string{"__name__"}, "cpu_usage\n")
|
||||
f(mn, []int64{1000}, []float64{1}, []string{"job"}, "node\n")
|
||||
f(mn, []int64{1000}, []float64{1}, []string{"instance"}, "localhost:9090\n")
|
||||
f(mn, []int64{1000}, []float64{1}, []string{"missing_label"}, "\n")
|
||||
|
||||
// multiple fields
|
||||
f(mn, []int64{1704067200000}, []float64{99.9},
|
||||
[]string{"__timestamp__:unix_s", "__value__", "job"},
|
||||
"1704067200,99.9,node\n")
|
||||
|
||||
// multiple rows
|
||||
f(mn, []int64{1000, 2000}, []float64{1.1, 2.2},
|
||||
[]string{"__value__", "__timestamp__"},
|
||||
"1.1,1000\n2.2,2000\n")
|
||||
f(mn, []int64{1000, 2000, 3000}, []float64{10, 20, 30},
|
||||
[]string{"__timestamp__:unix_s", "__value__"},
|
||||
"1,10\n2,20\n3,30\n")
|
||||
|
||||
// escaping for special characters in tag values
|
||||
f(&storage.MetricName{
|
||||
MetricGroup: []byte("m"),
|
||||
Tags: []storage.Tag{{Key: []byte("desc"), Value: []byte("a,b")}},
|
||||
}, []int64{1000}, []float64{1}, []string{"desc"}, "\"a,b\"\n")
|
||||
|
||||
f(&storage.MetricName{
|
||||
MetricGroup: []byte("m"),
|
||||
Tags: []storage.Tag{{Key: []byte("desc"), Value: []byte(`say "hello"`)}},
|
||||
}, []int64{1000}, []float64{1}, []string{"desc"}, "\"say \\\"hello\\\"\"\n")
|
||||
|
||||
f(&storage.MetricName{
|
||||
MetricGroup: []byte("m"),
|
||||
Tags: []storage.Tag{{Key: []byte("desc"), Value: []byte("line1\nline2")}},
|
||||
}, []int64{1000}, []float64{1}, []string{"desc"}, "\"line1\\nline2\"\n")
|
||||
|
||||
// header and data line field counts must match
|
||||
fieldNames := []string{"__name__", "job", "instance", "__value__", "__timestamp__:unix_s"}
|
||||
header := ExportCSVHeader(fieldNames)
|
||||
line := ExportCSVLine(&exportBlock{
|
||||
mn: mn,
|
||||
timestamps: []int64{1704067200000},
|
||||
values: []float64{99.9},
|
||||
}, fieldNames)
|
||||
headerCommas := strings.Count(header, ",")
|
||||
lineCommas := strings.Count(line, ",")
|
||||
if headerCommas != lineCommas {
|
||||
t.Fatalf("header has %d commas, data line has %d commas", headerCommas, lineCommas)
|
||||
}
|
||||
if headerCommas != len(fieldNames)-1 {
|
||||
t.Fatalf("expected %d commas in header, got %d", len(fieldNames)-1, headerCommas)
|
||||
}
|
||||
}
|
||||
@@ -175,6 +175,7 @@ func ExportCSVHandler(startTime time.Time, w http.ResponseWriter, r *http.Reques
|
||||
w.Header().Set("Content-Type", "text/csv; charset=utf-8")
|
||||
bw := bufferedwriter.Get(w)
|
||||
defer bufferedwriter.Put(bw)
|
||||
WriteExportCSVHeader(bw, fieldNames)
|
||||
sw := newScalableWriter(bw)
|
||||
writeCSVLine := func(xb *exportBlock, workerID uint) error {
|
||||
if len(xb.timestamps) == 0 {
|
||||
|
||||
@@ -4842,137 +4842,6 @@ func TestExecSuccess(t *testing.T) {
|
||||
resultExpected := []netstorage.Result{}
|
||||
f(q, resultExpected)
|
||||
})
|
||||
// buckets that are consecutively empty at left and right ends will not be preserved.
|
||||
t.Run(`buckets_limit(trim_zero_preserve_empty_when_limit_not_reached)`, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
q := `sort(buckets_limit(3, (
|
||||
alias(label_set(36, "le", "+Inf"), "metric"),
|
||||
alias(label_set(36, "le", "25"), "metric"),
|
||||
alias(label_set(36, "le", "21"), "metric"),
|
||||
alias(label_set(36, "le", "19"), "metric"),
|
||||
alias(label_set(36, "le", "18"), "metric"),
|
||||
alias(label_set(36, "le", "17"), "metric"),
|
||||
alias(label_set(36, "le", "16"), "metric"),
|
||||
alias(label_set(27, "le", "12"), "metric"),
|
||||
alias(label_set(14, "le", "9"), "metric"),
|
||||
alias(label_set(0, "le", "6"), "metric"),
|
||||
alias(label_set(0, "le", "1"), "metric"),
|
||||
)))`
|
||||
r1 := netstorage.Result{
|
||||
MetricName: metricNameExpected,
|
||||
Values: []float64{14, 14, 14, 14, 14, 14},
|
||||
Timestamps: timestampsExpected,
|
||||
}
|
||||
r1.MetricName.MetricGroup = []byte("metric")
|
||||
r1.MetricName.Tags = []storage.Tag{
|
||||
{
|
||||
Key: []byte("le"),
|
||||
Value: []byte("9"),
|
||||
},
|
||||
}
|
||||
r2 := netstorage.Result{
|
||||
MetricName: metricNameExpected,
|
||||
Values: []float64{27, 27, 27, 27, 27, 27},
|
||||
Timestamps: timestampsExpected,
|
||||
}
|
||||
r2.MetricName.MetricGroup = []byte("metric")
|
||||
r2.MetricName.Tags = []storage.Tag{
|
||||
{
|
||||
Key: []byte("le"),
|
||||
Value: []byte("12"),
|
||||
},
|
||||
}
|
||||
r3 := netstorage.Result{
|
||||
MetricName: metricNameExpected,
|
||||
Values: []float64{36, 36, 36, 36, 36, 36},
|
||||
Timestamps: timestampsExpected,
|
||||
}
|
||||
r3.MetricName.MetricGroup = []byte("metric")
|
||||
r3.MetricName.Tags = []storage.Tag{
|
||||
{
|
||||
Key: []byte("le"),
|
||||
Value: []byte("16"),
|
||||
},
|
||||
}
|
||||
resultExpected := []netstorage.Result{r1, r2, r3}
|
||||
f(q, resultExpected)
|
||||
})
|
||||
|
||||
// the number of non-empty bucket doesn't reach the given "limit", so some empty buckets will be preserved
|
||||
t.Run(`buckets_limit(trim_zero)`, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
q := `sort(buckets_limit(5, (
|
||||
alias(label_set(36, "le", "18"), "metric"),
|
||||
alias(label_set(36, "le", "17"), "metric"),
|
||||
alias(label_set(36, "le", "16"), "metric"),
|
||||
alias(label_set(27, "le", "12"), "metric"),
|
||||
alias(label_set(14, "le", "9"), "metric"),
|
||||
alias(label_set(0, "le", "6"), "metric"),
|
||||
alias(label_set(0, "le", "1"), "metric"),
|
||||
)))`
|
||||
r1 := netstorage.Result{
|
||||
MetricName: metricNameExpected,
|
||||
Values: []float64{0, 0, 0, 0, 0, 0},
|
||||
Timestamps: timestampsExpected,
|
||||
}
|
||||
r1.MetricName.MetricGroup = []byte("metric")
|
||||
r1.MetricName.Tags = []storage.Tag{
|
||||
{
|
||||
Key: []byte("le"),
|
||||
Value: []byte("6"),
|
||||
},
|
||||
}
|
||||
r2 := netstorage.Result{
|
||||
MetricName: metricNameExpected,
|
||||
Values: []float64{14, 14, 14, 14, 14, 14},
|
||||
Timestamps: timestampsExpected,
|
||||
}
|
||||
r2.MetricName.MetricGroup = []byte("metric")
|
||||
r2.MetricName.Tags = []storage.Tag{
|
||||
{
|
||||
Key: []byte("le"),
|
||||
Value: []byte("9"),
|
||||
},
|
||||
}
|
||||
r3 := netstorage.Result{
|
||||
MetricName: metricNameExpected,
|
||||
Values: []float64{27, 27, 27, 27, 27, 27},
|
||||
Timestamps: timestampsExpected,
|
||||
}
|
||||
r3.MetricName.MetricGroup = []byte("metric")
|
||||
r3.MetricName.Tags = []storage.Tag{
|
||||
{
|
||||
Key: []byte("le"),
|
||||
Value: []byte("12"),
|
||||
},
|
||||
}
|
||||
r4 := netstorage.Result{
|
||||
MetricName: metricNameExpected,
|
||||
Values: []float64{36, 36, 36, 36, 36, 36},
|
||||
Timestamps: timestampsExpected,
|
||||
}
|
||||
r4.MetricName.MetricGroup = []byte("metric")
|
||||
r4.MetricName.Tags = []storage.Tag{
|
||||
{
|
||||
Key: []byte("le"),
|
||||
Value: []byte("16"),
|
||||
},
|
||||
}
|
||||
r5 := netstorage.Result{
|
||||
MetricName: metricNameExpected,
|
||||
Values: []float64{36, 36, 36, 36, 36, 36},
|
||||
Timestamps: timestampsExpected,
|
||||
}
|
||||
r5.MetricName.MetricGroup = []byte("metric")
|
||||
r5.MetricName.Tags = []storage.Tag{
|
||||
{
|
||||
Key: []byte("le"),
|
||||
Value: []byte("17"),
|
||||
},
|
||||
}
|
||||
resultExpected := []netstorage.Result{r1, r2, r3, r4, r5}
|
||||
f(q, resultExpected)
|
||||
})
|
||||
t.Run(`buckets_limit(unused)`, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
q := `sort(buckets_limit(5, (
|
||||
@@ -6359,6 +6228,50 @@ func TestExecSuccess(t *testing.T) {
|
||||
resultExpected := []netstorage.Result{r1, r2, r3, r4, r5, r6, r7}
|
||||
f(q, resultExpected)
|
||||
})
|
||||
t.Run(`sum(histogram_over_time) by (vmrange)`, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
q := `sort_by_label(
|
||||
buckets_limit(
|
||||
3,
|
||||
sum(histogram_over_time(alias(label_set(rand(0)*1.3+1.1, "foo", "bar"), "xxx")[200s:5s])) by (vmrange)
|
||||
), "le"
|
||||
)`
|
||||
r1 := netstorage.Result{
|
||||
MetricName: metricNameExpected,
|
||||
Values: []float64{40, 40, 40, 40, 40, 40},
|
||||
Timestamps: timestampsExpected,
|
||||
}
|
||||
r1.MetricName.Tags = []storage.Tag{
|
||||
{
|
||||
Key: []byte("le"),
|
||||
Value: []byte("+Inf"),
|
||||
},
|
||||
}
|
||||
r2 := netstorage.Result{
|
||||
MetricName: metricNameExpected,
|
||||
Values: []float64{0, 0, 0, 0, 0, 0},
|
||||
Timestamps: timestampsExpected,
|
||||
}
|
||||
r2.MetricName.Tags = []storage.Tag{
|
||||
{
|
||||
Key: []byte("le"),
|
||||
Value: []byte("1.000e+00"),
|
||||
},
|
||||
}
|
||||
r3 := netstorage.Result{
|
||||
MetricName: metricNameExpected,
|
||||
Values: []float64{40, 40, 40, 40, 40, 40},
|
||||
Timestamps: timestampsExpected,
|
||||
}
|
||||
r3.MetricName.Tags = []storage.Tag{
|
||||
{
|
||||
Key: []byte("le"),
|
||||
Value: []byte("2.448e+00"),
|
||||
},
|
||||
}
|
||||
resultExpected := []netstorage.Result{r1, r2, r3}
|
||||
f(q, resultExpected)
|
||||
})
|
||||
t.Run(`sum(histogram_over_time)`, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
q := `sum(histogram_over_time(alias(label_set(rand(0)*1.3+1.1, "foo", "bar"), "xxx")[200s:5s]))`
|
||||
|
||||
@@ -461,41 +461,6 @@ func transformBucketsLimit(tfa *transformFuncArg) ([]*timeseries, error) {
|
||||
prevValue = value
|
||||
}
|
||||
}
|
||||
|
||||
// Remove buckets that are consecutively empty at left and right ends to obtain more accurate max and min values.
|
||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10417.
|
||||
epsilon := 1e-9
|
||||
l := 0
|
||||
r := len(leGroup) - 1
|
||||
trimLeft := true
|
||||
for r-l+1 > limit {
|
||||
leftHits := math.Abs(leGroup[l].hits)
|
||||
rightHits := math.Abs(leGroup[r].hits)
|
||||
leftEmpty := !math.IsNaN(leftHits) && leftHits <= epsilon
|
||||
rightEmpty := !math.IsNaN(rightHits) && rightHits <= epsilon
|
||||
if !leftEmpty && !rightEmpty {
|
||||
break
|
||||
}
|
||||
if trimLeft {
|
||||
if leftHits < epsilon {
|
||||
l++
|
||||
}
|
||||
// switch the trim pointer to the right side if needed
|
||||
if rightHits < epsilon {
|
||||
trimLeft = false
|
||||
}
|
||||
} else {
|
||||
if rightHits < epsilon {
|
||||
r--
|
||||
}
|
||||
// switch the trim pointer to the left side if needed
|
||||
if leftHits < epsilon {
|
||||
trimLeft = true
|
||||
}
|
||||
}
|
||||
}
|
||||
leGroup = leGroup[l : r+1]
|
||||
|
||||
for len(leGroup) > limit {
|
||||
// Preserve the first and the last bucket for better accuracy for min and max values
|
||||
xxMinIdx := 1
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
<meta property="og:title" content="UI for VictoriaMetrics">
|
||||
<meta property="og:url" content="https://victoriametrics.com/">
|
||||
<meta property="og:description" content="Explore and troubleshoot your VictoriaMetrics data">
|
||||
<script type="module" crossorigin src="./assets/index-KEOgEEMl.js"></script>
|
||||
<script type="module" crossorigin src="./assets/index-C24BPpD_.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-COnpUsM8.js">
|
||||
<link rel="modulepreload" crossorigin href="./assets/vendor-Mr0bmX1E.js">
|
||||
<link rel="modulepreload" crossorigin href="./assets/vendor-BWBgVCcr.js">
|
||||
<link rel="stylesheet" crossorigin href="./assets/vendor-CnsZ1jie.css">
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-D2OEy8Ra.css">
|
||||
</head>
|
||||
|
||||
228
app/vmui/packages/vmui/package-lock.json
generated
@@ -17,7 +17,7 @@
|
||||
"react-input-mask": "^2.0.4",
|
||||
"react-router-dom": "^7.13.2",
|
||||
"uplot": "^1.6.32",
|
||||
"vite": "^8.0.2",
|
||||
"vite": "^8.0.7",
|
||||
"web-vitals": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -903,25 +903,27 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz",
|
||||
"integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==",
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.2.tgz",
|
||||
"integrity": "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/core": "^1.7.1",
|
||||
"@emnapi/runtime": "^1.7.1",
|
||||
"@tybys/wasm-util": "^0.10.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emnapi/core": "^1.7.1",
|
||||
"@emnapi/runtime": "^1.7.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-project/types": {
|
||||
"version": "0.122.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.122.0.tgz",
|
||||
"integrity": "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==",
|
||||
"version": "0.123.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.123.0.tgz",
|
||||
"integrity": "sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/Boshen"
|
||||
@@ -1050,9 +1052,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1073,9 +1072,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1096,9 +1092,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1119,9 +1112,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1142,9 +1132,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1165,9 +1152,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1334,9 +1318,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-android-arm64": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-SJ+/g+xNnOh6NqYxD0V3uVN4W3VfnrGsC9/hoglicgTNfABFG9JjISvkkU0dNY84MNHLWyOgxP9v9Y9pX4S7+A==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-5ZiiecKH2DXAVJTNN13gNMUcCDg4Jy8ZjbXEsPnqa248wgOVeYRX0iqXXD5Jz4bI9BFHgKsI2qmyJynstbmr+g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1350,9 +1334,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-darwin-arm64": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-7WQgR8SfOPwmDZGFkThUvsmd/nwAWv91oCO4I5LS7RKrssPZmOt7jONN0cW17ydGC1n/+puol1IpoieKqQidmg==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-tz/v/8G77seu8zAB3A5sK3UFoOl06zcshEzhUO62sAEtrEuW/H1CcyoupOrD+NbQJytYgA4CppXPzlrmp4JZKA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1366,9 +1350,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-darwin-x64": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-39Ks6UvIHq4rEogIfQBoBRusj0Q0nPVWIvqmwBLaT6aqQGIakHdESBVOPRRLacy4WwUPIx4ZKzfZ9PMW+IeyUQ==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-8DakphqOz8JrMYWTJmWA+vDJxut6LijZ8Xcdc4flOlAhU7PNVwo2MaWBF9iXjJAPo5rC/IxEFZDhJ3GC7NHvug==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1382,9 +1366,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-freebsd-x64": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-jfsm0ZHfhiqrvWjJAmzsqiIFPz5e7mAoCOPBNTcNgkiid/LaFKiq92+0ojH+nmJmKYkre4t71BWXUZDNp7vsag==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-4wBQFfjDuXYN/SVI8inBF3Aa+isq40rc6VMFbk5jcpolUBTe5cYnMsHZ51nFWsx3PVyyNN3vgoESki0Hmr/4BA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1398,9 +1382,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-zjQaUtSyq1nVe3nxmlSCuR96T1LPlpvmJ0SZy0WJFEsV4kFbXcq2u68L4E6O0XeFj4aex9bEauqjW8UQBeAvfQ==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-JW/e4yPIXLms+jmnbwwy5LA/LxVwZUWLN8xug+V200wzaVi5TEGIWQlh8o91gWYFxW609euI98OCCemmWGuPrw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -1414,15 +1398,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm64-gnu": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-WMW1yE6IOnehTcFE9eipFkm3XN63zypWlrJQ2iF7NrQ9b2LDRjumFoOGJE8RJJTJCTBAdmLMnJ8uVitACUUo1Q==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-ZfKWpXiUymDnavepCaM6KG/uGydJ4l2nBmMxg60Ci4CbeefpqjPWpfaZM7PThOhk2dssqBAcwLc6rAyr0uTdXg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1433,15 +1414,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm64-musl": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-jfndI9tsfm4APzjNt6QdBkYwre5lRPUgHeDHoI7ydKUuJvz3lZeCfMsI56BZj+7BYqiKsJm7cfd/6KYV7ubrBg==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-bmRg3O6Z0gq9yodKKWCIpnlH051sEfdVwt+6m5UDffAQMUUqU0xjnQqqAUm+Gu7ofAAly9DqiQDtKu2nPDEABA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1452,15 +1430,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-ZlFgw46NOAGMgcdvdYwAGu2Q+SLFA9LzbJLW+iyMOJyhj5wk6P3KEE9Gct4xWwSzFoPI7JCdYmYMzVtlgQ+zfw==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-8Wtnbw4k7pMYN9B/mOEAsQ8HOiq7AZ31Ig4M9BKn2So4xRaFEhtCSa4ZJaOutOWq50zpgR4N5+L/opnlaCx8wQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1471,15 +1446,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-s390x-gnu": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-hIOYmuT6ofM4K04XAZd3OzMySEO4K0/nc9+jmNcxNAxRi6c5UWpqfw3KMFV4MVFWL+jQsSh+bGw2VqmaPMTLyw==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-D/0Nlo8mQuxSMohNJUF2lDXWRsFDsHldfRRgD9bRgktj+EndGPj4DOV37LqDKPYS+osdyhZEH7fTakTAEcW7qg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1490,15 +1462,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-x64-gnu": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-qXBQQO9OvkjjQPLdUVr7Nr2t3QTZI7s4KZtfw7HzBgjbmAPSFwSv4rmET9lLSgq3rH/ndA3ngv3Qb8l2njoPNA==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-eRrPvat2YaVQcwwKi/JzOP6MKf1WRnOCr+VaI3cTWz3ZoLcP/654z90lVCJ4dAuMEpPdke0n+qyAqXDZdIC4rA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1509,15 +1478,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-x64-musl": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-/tpFfoSTzUkH9LPY+cYbqZBDyyX62w5fICq9qzsHLL8uTI6BHip3Q9Uzft0wylk/i8OOwKik8OxW+QAhDmzwmg==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-PsdONiFRp8hR8KgVjTWjZ9s7uA3uueWL0t74/cKHfM4dR5zXYv4AjB8BvA+QDToqxAFg4ZkcVEqeu5F7inoz5w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1528,9 +1494,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-openharmony-arm64": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-mcp3Rio2w72IvdZG0oQ4bM2c2oumtwHfUfKncUM6zGgz0KgPz4YmDPQfnXEiY5t3+KD/i8HG2rOB/LxdmieK2g==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-hCNXgC5dI3TVOLrPT++PKFNZ+1EtS0mLQwfXXXSUD/+rGlB65gZDwN/IDuxLpQP4x8RYYHqGomlUXzpO8aVI2w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1544,25 +1510,27 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-wasm32-wasi": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-LXk5Hii1Ph9asuGRjBuz8TUxdc1lWzB7nyfdoRgI0WGPZKmCxvlKk8KfYysqtr4MfGElu/f/pEQRh8fcEgkrWw==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-viLS5C5et8NFtLWw9Sw3M/w4vvnVkbWkO7wSNh3C+7G1+uCkGpr6PcjNDSFcNtmXY/4trjPBqUfcOL+P3sWy/g==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@napi-rs/wasm-runtime": "^1.1.1"
|
||||
"@emnapi/core": "1.9.1",
|
||||
"@emnapi/runtime": "1.9.1",
|
||||
"@napi-rs/wasm-runtime": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-arm64-msvc": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-dDwf5otnx0XgRY1yqxOC4ITizcdzS/8cQ3goOWv3jFAo4F+xQYni+hnMuO6+LssHHdJW7+OCVL3CoU4ycnh35Q==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-Fqa3Tlt1xL4wzmAYxGNFV36Hb+VfPc9PYU+E25DAnswXv3ODDu/yyWjQDbXMo5AGWkQVjLgQExuVu8I/UaZhPQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1576,9 +1544,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-x64-msvc": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-LN4/skhSggybX71ews7dAj6r2geaMJfm3kMbK2KhFMg9B10AZXnKoLCVVgzhMHL0S+aKtr4p8QbAW8k+w95bAA==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-/pLI5kPkGEi44TDlnbio3St/5gUFeN51YWNAk/Gnv6mEQBOahRBh52qVFVBpmrnU01n2yysvBML9Ynu7K4kGAQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1592,9 +1560,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/pluginutils": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-xQO9vbwBecJRv9EUcQ/y0dzSTJgA7Q6UVN7xp6B81+tBGSLVAK03yJ9NkJaUA7JFD91kbjxRSC/mDnmvXzbHoQ==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@rollup/pluginutils": {
|
||||
@@ -5178,9 +5146,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -5201,9 +5166,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -5224,9 +5186,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -5247,9 +5206,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6158,13 +6114,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rolldown": {
|
||||
"version": "1.0.0-rc.11",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.11.tgz",
|
||||
"integrity": "sha512-NRjoKMusSjfRbSYiH3VSumlkgFe7kYAa3pzVOsVYVFY3zb5d7nS+a3KGQ7hJKXuYWbzJKPVQ9Wxq2UvyK+ENpw==",
|
||||
"version": "1.0.0-rc.13",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.13.tgz",
|
||||
"integrity": "sha512-bvVj8YJmf0rq4pSFmH7laLa6pYrhghv3PRzrCdRAr23g66zOKVJ4wkvFtgohtPLWmthgg8/rkaqRHrpUEh0Zbw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@oxc-project/types": "=0.122.0",
|
||||
"@rolldown/pluginutils": "1.0.0-rc.11"
|
||||
"@oxc-project/types": "=0.123.0",
|
||||
"@rolldown/pluginutils": "1.0.0-rc.13"
|
||||
},
|
||||
"bin": {
|
||||
"rolldown": "bin/cli.mjs"
|
||||
@@ -6173,21 +6129,21 @@
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rolldown/binding-android-arm64": "1.0.0-rc.11",
|
||||
"@rolldown/binding-darwin-arm64": "1.0.0-rc.11",
|
||||
"@rolldown/binding-darwin-x64": "1.0.0-rc.11",
|
||||
"@rolldown/binding-freebsd-x64": "1.0.0-rc.11",
|
||||
"@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.11",
|
||||
"@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.11",
|
||||
"@rolldown/binding-linux-arm64-musl": "1.0.0-rc.11",
|
||||
"@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.11",
|
||||
"@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.11",
|
||||
"@rolldown/binding-linux-x64-gnu": "1.0.0-rc.11",
|
||||
"@rolldown/binding-linux-x64-musl": "1.0.0-rc.11",
|
||||
"@rolldown/binding-openharmony-arm64": "1.0.0-rc.11",
|
||||
"@rolldown/binding-wasm32-wasi": "1.0.0-rc.11",
|
||||
"@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.11",
|
||||
"@rolldown/binding-win32-x64-msvc": "1.0.0-rc.11"
|
||||
"@rolldown/binding-android-arm64": "1.0.0-rc.13",
|
||||
"@rolldown/binding-darwin-arm64": "1.0.0-rc.13",
|
||||
"@rolldown/binding-darwin-x64": "1.0.0-rc.13",
|
||||
"@rolldown/binding-freebsd-x64": "1.0.0-rc.13",
|
||||
"@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.13",
|
||||
"@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.13",
|
||||
"@rolldown/binding-linux-arm64-musl": "1.0.0-rc.13",
|
||||
"@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.13",
|
||||
"@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.13",
|
||||
"@rolldown/binding-linux-x64-gnu": "1.0.0-rc.13",
|
||||
"@rolldown/binding-linux-x64-musl": "1.0.0-rc.13",
|
||||
"@rolldown/binding-openharmony-arm64": "1.0.0-rc.13",
|
||||
"@rolldown/binding-wasm32-wasi": "1.0.0-rc.13",
|
||||
"@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.13",
|
||||
"@rolldown/binding-win32-x64-msvc": "1.0.0-rc.13"
|
||||
}
|
||||
},
|
||||
"node_modules/rxjs": {
|
||||
@@ -6437,7 +6393,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"libc": "glibc",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6454,7 +6409,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": "glibc",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6471,7 +6425,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"libc": "musl",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6488,7 +6441,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": "musl",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6505,7 +6457,6 @@
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"libc": "musl",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6522,7 +6473,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": "musl",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6539,7 +6489,6 @@
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"libc": "glibc",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6556,7 +6505,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": "glibc",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -7382,15 +7330,15 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.2.tgz",
|
||||
"integrity": "sha512-1gFhNi+bHhRE/qKZOJXACm6tX4bA3Isy9KuKF15AgSRuRazNBOJfdDemPBU16/mpMxApDPrWvZ08DcLPEoRnuA==",
|
||||
"version": "8.0.7",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.7.tgz",
|
||||
"integrity": "sha512-P1PbweD+2/udplnThz3btF4cf6AgPky7kk23RtHUkJIU5BIxwPprhRGmOAHs6FTI7UiGbTNrgNP6jSYD6JaRnw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lightningcss": "^1.32.0",
|
||||
"picomatch": "^4.0.3",
|
||||
"picomatch": "^4.0.4",
|
||||
"postcss": "^8.5.8",
|
||||
"rolldown": "1.0.0-rc.11",
|
||||
"rolldown": "1.0.0-rc.13",
|
||||
"tinyglobby": "^0.2.15"
|
||||
},
|
||||
"bin": {
|
||||
@@ -7408,7 +7356,7 @@
|
||||
"peerDependencies": {
|
||||
"@types/node": "^20.19.0 || >=22.12.0",
|
||||
"@vitejs/devtools": "^0.1.0",
|
||||
"esbuild": "^0.27.0",
|
||||
"esbuild": "^0.27.0 || ^0.28.0",
|
||||
"jiti": ">=1.21.0",
|
||||
"less": "^4.0.0",
|
||||
"sass": "^1.70.0",
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"react-input-mask": "^2.0.4",
|
||||
"react-router-dom": "^7.13.2",
|
||||
"uplot": "^1.6.32",
|
||||
"vite": "^8.0.2",
|
||||
"vite": "^8.0.7",
|
||||
"web-vitals": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -16,23 +16,29 @@ export const getExportDataUrl = (server: string, query: string, period: TimePara
|
||||
return `${server}/api/v1/export?${params}`;
|
||||
};
|
||||
|
||||
export const getExportCSVDataUrl = (server: string, query: string[], period: TimeParams, reduceMemUsage: boolean): string => {
|
||||
const getBaseParams = (period: TimeParams, query: string[]): URLSearchParams => {
|
||||
const params = new URLSearchParams({
|
||||
start: period.start.toString(),
|
||||
end: period.end.toString(),
|
||||
format: "__name__,__value__,__timestamp__:unix_ms",
|
||||
});
|
||||
query.forEach((q => params.append("match[]", q)));
|
||||
return params;
|
||||
};
|
||||
|
||||
export const getLabelsUrl = (server: string, query: string[], period: TimeParams): string => {
|
||||
const params = getBaseParams(period, query);
|
||||
return `${server}/api/v1/labels?${params}`;
|
||||
};
|
||||
|
||||
export const getExportCSVDataUrl = (server: string, query: string[], period: TimeParams, reduceMemUsage: boolean, format: string): string => {
|
||||
const params = getBaseParams(period, query);
|
||||
params.set("format", format);
|
||||
if (reduceMemUsage) params.set("reduce_mem_usage", "1");
|
||||
return `${server}/api/v1/export/csv?${params}`;
|
||||
};
|
||||
|
||||
export const getExportJSONDataUrl = (server: string, query: string[], period: TimeParams, reduceMemUsage: boolean): string => {
|
||||
const params = new URLSearchParams({
|
||||
start: period.start.toString(),
|
||||
end: period.end.toString(),
|
||||
});
|
||||
query.forEach((q => params.append("match[]", q)));
|
||||
const params = getBaseParams(period, query);
|
||||
if (reduceMemUsage) params.set("reduce_mem_usage", "1");
|
||||
return `${server}/api/v1/export?${params}`;
|
||||
};
|
||||
|
||||
29
app/vmui/packages/vmui/src/api/raw-query.test.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { fetchRawQueryCSVExport } from "./raw-query";
|
||||
|
||||
describe("fetchRawQueryCSVExport", () => {
|
||||
it.skip("requests all label columns before exporting CSV data", async () => {
|
||||
const fetchMock = vi.fn()
|
||||
.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
json: async () => ({ data: ["job", "__name__", "instance"] }),
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
text: async () => "up,localhost:9100,node_exporter,1,1710000000000",
|
||||
});
|
||||
|
||||
const result = await fetchRawQueryCSVExport(
|
||||
"http://localhost:8428",
|
||||
["up"],
|
||||
{ start: 1710000000, end: 1710000300, step: "15s", date: "2024-03-09T16:05:00Z" },
|
||||
false,
|
||||
fetchMock as unknown as typeof fetch,
|
||||
);
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledTimes(2);
|
||||
expect(fetchMock.mock.calls[0][0]).toBe("http://localhost:8428/api/v1/labels?start=1710000000&end=1710000300&match%5B%5D=up");
|
||||
expect(fetchMock.mock.calls[1][0]).toBe("http://localhost:8428/api/v1/export/csv?start=1710000000&end=1710000300&match%5B%5D=up&format=__name__%2Cinstance%2Cjob%2C__value__%2C__timestamp__%3Aunix_ms");
|
||||
expect(result).toBe("up,localhost:9100,node_exporter,1,1710000000000");
|
||||
});
|
||||
});
|
||||
31
app/vmui/packages/vmui/src/api/raw-query.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { getExportCSVDataUrl, getLabelsUrl } from "./query-range";
|
||||
import { TimeParams } from "../types";
|
||||
import { getCSVExportColumns } from "../utils/csv";
|
||||
|
||||
interface LabelsResponse {
|
||||
data?: string[];
|
||||
}
|
||||
|
||||
export const fetchRawQueryCSVExport = async (
|
||||
serverUrl: string,
|
||||
query: string[],
|
||||
period: TimeParams,
|
||||
reduceMemUsage: boolean,
|
||||
fetchFn: typeof fetch = fetch,
|
||||
): Promise<string> => {
|
||||
const labelsResponse = await fetchFn(getLabelsUrl(serverUrl, query, period));
|
||||
if (!labelsResponse.ok) {
|
||||
throw new Error(await labelsResponse.text());
|
||||
}
|
||||
|
||||
const { data = [] } = (await labelsResponse.json()) as LabelsResponse;
|
||||
const columns = getCSVExportColumns(data);
|
||||
const format = columns.join(",");
|
||||
|
||||
const response = await fetchFn(getExportCSVDataUrl(serverUrl, query, period, reduceMemUsage, format));
|
||||
if (!response.ok) {
|
||||
throw new Error(await response.text());
|
||||
}
|
||||
|
||||
return await response.text();
|
||||
};
|
||||
@@ -6,10 +6,11 @@ import { useTimeState } from "../../../state/time/TimeStateContext";
|
||||
import { useAppState } from "../../../state/common/StateContext";
|
||||
import { useCustomPanelState } from "../../../state/customPanel/CustomPanelStateContext";
|
||||
import { isValidHttpUrl } from "../../../utils/url";
|
||||
import { getExportCSVDataUrl, getExportDataUrl, getExportJSONDataUrl } from "../../../api/query-range";
|
||||
import { getExportDataUrl, getExportJSONDataUrl } from "../../../api/query-range";
|
||||
import { parseLineToJSON } from "../../../utils/json";
|
||||
import { downloadCSV, downloadJSON } from "../../../utils/file";
|
||||
import { useSnack } from "../../../contexts/Snackbar";
|
||||
import { fetchRawQueryCSVExport } from "../../../api/raw-query";
|
||||
|
||||
interface FetchQueryParams {
|
||||
hideQuery?: number[];
|
||||
@@ -67,11 +68,8 @@ export const useFetchExport = ({ hideQuery, showAllSeries }: FetchQueryParams):
|
||||
const getFilename = (format: ExportFormats) => `vmui_export_${query.join("_")}_${period.start}_${period.end}.${format}`;
|
||||
return {
|
||||
csv: async () => {
|
||||
const url = getExportCSVDataUrl(serverUrl, query, period, reduceMemUsage);
|
||||
const response = await fetch(url);
|
||||
try {
|
||||
let text = await response.text();
|
||||
text = "name,value,timestamp\n" + text;
|
||||
const text = await fetchRawQueryCSVExport(serverUrl, query, period, reduceMemUsage);
|
||||
downloadCSV(text, getFilename("csv"));
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { formatValueToCSV } from "./csv";
|
||||
import { formatValueToCSV, getCSVExportColumns } from "./csv";
|
||||
|
||||
describe("formatValueToCSV", () => {
|
||||
it("should wrap value in quotes if it contains a comma", () => {
|
||||
@@ -32,3 +32,10 @@ describe("formatValueToCSV", () => {
|
||||
expect(result).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getCSVExportColumns", () => {
|
||||
it("should prepend metric name and append value and timestamp columns", () => {
|
||||
const result = getCSVExportColumns(["instance", "__name__", "job", "instance"]);
|
||||
expect(result.join(",")).toEqual("__name__,instance,job,__value__,__timestamp__:unix_ms");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,3 +2,8 @@ export const formatValueToCSV= (value: string) =>
|
||||
(value.includes(",") || value.includes("\n") || value.includes("\""))
|
||||
? "\"" + value.replace(/"/g, "\"\"") + "\""
|
||||
: value;
|
||||
|
||||
export const getCSVExportColumns = (labelNames: string[]) => {
|
||||
const labels = Array.from(new Set(labelNames.filter((label) => label && label !== "__name__"))).sort();
|
||||
return ["__name__", ...labels, "__value__", "__timestamp__:unix_ms"];
|
||||
};
|
||||
|
||||
@@ -3,7 +3,9 @@ package tests
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand/v2"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/apptest"
|
||||
)
|
||||
@@ -70,3 +72,162 @@ func TestClusterMultilevelSelect(t *testing.T) {
|
||||
assertSeries(vmselectL1)
|
||||
assertSeries(vmselectL2)
|
||||
}
|
||||
|
||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10678.
|
||||
func TestClusterMultilevelPartialResponse(t *testing.T) {
|
||||
tc := apptest.NewTestCase(t)
|
||||
defer tc.Stop()
|
||||
// Set up the following multi-level cluster configuration:
|
||||
//
|
||||
// |--> available vmstorage
|
||||
// | ------> vmselect1 --|
|
||||
// | |--> available vmstorage
|
||||
// global-vmselect -------|
|
||||
// | |--> available vmstorage
|
||||
// | ------> vmselect2 --|
|
||||
// |--> unavailable vmstorage
|
||||
|
||||
vmstorage1 := tc.MustStartVmstorage("vmstorage1", []string{
|
||||
"-storageDataPath=" + tc.Dir() + "/vmstorage1",
|
||||
})
|
||||
vmstorage2 := tc.MustStartVmstorage("vmstorage2", []string{
|
||||
"-storageDataPath=" + tc.Dir() + "/vmstorage2",
|
||||
})
|
||||
regionalVmselect1 := tc.MustStartVmselect("regional-vmselect1", []string{
|
||||
"-storageNode=" + vmstorage1.VmselectAddr() + "," + vmstorage2.VmselectAddr(),
|
||||
})
|
||||
regionalVmselect2 := tc.MustStartVmselect("regional-vmselect2", []string{
|
||||
"-storageNode=" + vmstorage1.VmselectAddr() + "," + noopTCPServerAddr(t),
|
||||
})
|
||||
globalVmselect := tc.MustStartVmselect("global-vmselect", []string{
|
||||
"-storageNode=" + regionalVmselect1.ClusternativeListenAddr() + "," + regionalVmselect2.ClusternativeListenAddr(),
|
||||
})
|
||||
|
||||
// 1. /api/v1/query
|
||||
qopts := apptest.QueryOpts{Tenant: "0"}
|
||||
assertQuery := func(app *apptest.Vmselect, want *apptest.PrometheusAPIV1QueryResponse) {
|
||||
t.Helper()
|
||||
tc.Assert(&apptest.AssertOptions{
|
||||
Msg: "unexpected /api/v1/query response",
|
||||
Got: func() any {
|
||||
res := app.PrometheusAPIV1Query(t, `{__name__=~".*"}`, qopts)
|
||||
res.Sort()
|
||||
return res
|
||||
},
|
||||
Want: want,
|
||||
})
|
||||
}
|
||||
// regional-vmselect1 should return full response.
|
||||
assertQuery(regionalVmselect1, &apptest.PrometheusAPIV1QueryResponse{
|
||||
Status: "success",
|
||||
IsPartial: false,
|
||||
Data: &apptest.QueryData{ResultType: "vector", Result: []*apptest.QueryResult{}},
|
||||
})
|
||||
// regional-vmselect2 should return partial response.
|
||||
assertQuery(regionalVmselect2, &apptest.PrometheusAPIV1QueryResponse{
|
||||
Status: "success",
|
||||
IsPartial: true,
|
||||
Data: &apptest.QueryData{ResultType: "vector", Result: []*apptest.QueryResult{}},
|
||||
})
|
||||
// global-vmselect should return partial response.
|
||||
assertQuery(globalVmselect, &apptest.PrometheusAPIV1QueryResponse{
|
||||
Status: "success",
|
||||
IsPartial: true,
|
||||
Data: &apptest.QueryData{ResultType: "vector", Result: []*apptest.QueryResult{}},
|
||||
})
|
||||
|
||||
// 2. /api/v1/labels
|
||||
start := time.Now().Unix()
|
||||
assertLabel := func(app *apptest.Vmselect, want *apptest.PrometheusAPIV1LabelsResponse) {
|
||||
t.Helper()
|
||||
tc.Assert(&apptest.AssertOptions{
|
||||
Msg: "unexpected /api/v1/label response",
|
||||
|
||||
Got: func() any {
|
||||
res := app.PrometheusAPIV1Labels(t, `{__name__="up"}`, apptest.QueryOpts{
|
||||
Start: fmt.Sprintf("%d", start-100),
|
||||
End: fmt.Sprintf("%d", start),
|
||||
})
|
||||
return res
|
||||
},
|
||||
Want: want,
|
||||
})
|
||||
}
|
||||
|
||||
// regional-vmselect1 should return full response.
|
||||
assertLabel(regionalVmselect1, &apptest.PrometheusAPIV1LabelsResponse{
|
||||
Status: "success",
|
||||
IsPartial: false,
|
||||
Data: make([]string, 0),
|
||||
})
|
||||
// regional-vmselect2 should return partial response.
|
||||
assertLabel(regionalVmselect2, &apptest.PrometheusAPIV1LabelsResponse{
|
||||
Status: "success",
|
||||
IsPartial: true,
|
||||
Data: make([]string, 0),
|
||||
})
|
||||
// global-vmselect should return partial response.
|
||||
assertLabel(globalVmselect, &apptest.PrometheusAPIV1LabelsResponse{
|
||||
Status: "success",
|
||||
IsPartial: true,
|
||||
Data: make([]string, 0),
|
||||
})
|
||||
|
||||
// 3. /api/v1/label/%s/values
|
||||
assertSeries := func(app *apptest.Vmselect, want *apptest.PrometheusAPIV1SeriesResponse) {
|
||||
t.Helper()
|
||||
tc.Assert(&apptest.AssertOptions{
|
||||
Msg: "unexpected /api/v1/series response",
|
||||
|
||||
Got: func() any {
|
||||
res := app.PrometheusAPIV1Series(t, `{__name__="up"}`, apptest.QueryOpts{
|
||||
Start: fmt.Sprintf("%d", start-100),
|
||||
End: fmt.Sprintf("%d", start),
|
||||
})
|
||||
return res
|
||||
},
|
||||
Want: want,
|
||||
})
|
||||
}
|
||||
|
||||
// regional-vmselect1 should return full response.
|
||||
assertSeries(regionalVmselect1, &apptest.PrometheusAPIV1SeriesResponse{
|
||||
Status: "success",
|
||||
IsPartial: false,
|
||||
Data: make([]map[string]string, 0),
|
||||
})
|
||||
// regional-vmselect2 should return partial response.
|
||||
assertSeries(regionalVmselect2, &apptest.PrometheusAPIV1SeriesResponse{
|
||||
Status: "success",
|
||||
IsPartial: true,
|
||||
Data: make([]map[string]string, 0),
|
||||
})
|
||||
// global-vmselect should return partial response.
|
||||
assertSeries(globalVmselect, &apptest.PrometheusAPIV1SeriesResponse{
|
||||
Status: "success",
|
||||
IsPartial: true,
|
||||
Data: make([]map[string]string, 0),
|
||||
})
|
||||
}
|
||||
|
||||
// noopTCPServerAddr start local tcp server,
|
||||
// which immediately closes any incoming connections
|
||||
// and return it's address
|
||||
func noopTCPServerAddr(t *testing.T) string {
|
||||
t.Helper()
|
||||
ln, err := net.Listen("tcp", "localhost:0")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create listener: %v", err)
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
conn, err := ln.Accept()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
conn.Close()
|
||||
}
|
||||
}()
|
||||
t.Cleanup(func() { ln.Close() })
|
||||
return ln.Addr().String()
|
||||
}
|
||||
|
||||
@@ -305,6 +305,11 @@ func TestSingleVMAgentDropOnOverload(t *testing.T) {
|
||||
// See initRemoteWriteCtxs function in remotewrite.go for details.
|
||||
"-remoteWrite.maxRowsPerBlock=1000000000",
|
||||
"-remoteWrite.tmpDataPath=" + tc.Dir() + "/vmagent",
|
||||
|
||||
// Delay retry logic to avoid race conditions with waitFor assertions.
|
||||
// It improves the test stability on resource-constrained runners.
|
||||
// Should be bigger than retries * period
|
||||
"-remoteWrite.retryMinInterval=3s",
|
||||
}, ``)
|
||||
|
||||
const (
|
||||
|
||||
@@ -4001,6 +4001,138 @@
|
||||
"title": "Datapoints drop rate ($instance)",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "victoriametrics-metrics-datasource",
|
||||
"uid": "$ds"
|
||||
},
|
||||
"description": "Displays the maximum 99th percentile of the number of time series pending in the remote write queue.\n\nThe maximum queue size is configured by remoteWrite.maxQueueSize. \nvmalert will begin dropping data if the queue has no room for newly generated data.\nThe queue can fill rapidly when heavy rules generate millions of series, or when remote write requests are unable to send data to the destination in a timely manner, causing data to accumulate in the queue. Consider tuning -remoteWrite.maxQueueSize or -remoteWrite.concurrency.\n\nSee also the Rows per request panel.",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisBorderShow": false,
|
||||
"axisCenteredZero": false,
|
||||
"axisColorMode": "text",
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"barWidthFactor": 0.6,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"insertNulls": false,
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "auto",
|
||||
"showValues": false,
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "max"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"fixedColor": "red",
|
||||
"mode": "fixed"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "custom.fillOpacity",
|
||||
"value": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 38
|
||||
},
|
||||
"id": 68,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"hideZeros": false,
|
||||
"mode": "multi",
|
||||
"sort": "desc"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "12.2.0",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "victoriametrics-metrics-datasource",
|
||||
"uid": "$ds"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "max(histogram_quantile(0.99, sum(increase(vmalert_remotewrite_queue_size_bucket{job=~\"$job\", instance=~\"$instance\"}[$__rate_interval])) by (instance, vmrange))) > 1",
|
||||
"legendFormat": "current",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "victoriametrics-metrics-datasource",
|
||||
"uid": "$ds"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "min(vmalert_remotewrite_queue_capacity{job=~\"$job\", instance=~\"$instance\"})",
|
||||
"hide": false,
|
||||
"instant": false,
|
||||
"legendFormat": "max",
|
||||
"range": true,
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"title": "Remote write queue size ($instance)",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "victoriametrics-metrics-datasource",
|
||||
@@ -4066,10 +4198,10 @@
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 38
|
||||
"x": 0,
|
||||
"y": 46
|
||||
},
|
||||
"id": 68,
|
||||
"id": 69,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
@@ -4092,7 +4224,7 @@
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "max(histogram_quantile(0.99, sum(increase(vmalert_remotewrite_sent_rows_bucket{job=~\"$job\", instance=~\"$instance\"}[$__rate_interval])) by (instance, vmrange)))",
|
||||
"legendFormat": "__auto",
|
||||
"legendFormat": "max",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
@@ -4168,7 +4300,7 @@
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"x": 12,
|
||||
"y": 46
|
||||
},
|
||||
"id": 54,
|
||||
|
||||
@@ -4000,6 +4000,138 @@
|
||||
"title": "Datapoints drop rate ($instance)",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "$ds"
|
||||
},
|
||||
"description": "Displays the maximum 99th percentile of the number of time series pending in the remote write queue.\n\nThe maximum queue size is configured by remoteWrite.maxQueueSize. \nvmalert will begin dropping data if the queue has no room for newly generated data.\nThe queue can fill rapidly when heavy rules generate millions of series, or when remote write requests are unable to send data to the destination in a timely manner, causing data to accumulate in the queue. Consider tuning -remoteWrite.maxQueueSize or -remoteWrite.concurrency.\n\nSee also the Rows per request panel.",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisBorderShow": false,
|
||||
"axisCenteredZero": false,
|
||||
"axisColorMode": "text",
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"barWidthFactor": 0.6,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"insertNulls": false,
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "auto",
|
||||
"showValues": false,
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "max"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"fixedColor": "red",
|
||||
"mode": "fixed"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "custom.fillOpacity",
|
||||
"value": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 38
|
||||
},
|
||||
"id": 68,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"hideZeros": false,
|
||||
"mode": "multi",
|
||||
"sort": "desc"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "12.2.0",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "$ds"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "max(histogram_quantile(0.99, sum(increase(vmalert_remotewrite_queue_size_bucket{job=~\"$job\", instance=~\"$instance\"}[$__rate_interval])) by (instance, vmrange))) > 1",
|
||||
"legendFormat": "current",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "$ds"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "min(vmalert_remotewrite_queue_capacity{job=~\"$job\", instance=~\"$instance\"})",
|
||||
"hide": false,
|
||||
"instant": false,
|
||||
"legendFormat": "max",
|
||||
"range": true,
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"title": "Remote write queue size ($instance)",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
@@ -4065,10 +4197,10 @@
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 38
|
||||
"x": 0,
|
||||
"y": 46
|
||||
},
|
||||
"id": 68,
|
||||
"id": 69,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
@@ -4091,7 +4223,7 @@
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "max(histogram_quantile(0.99, sum(increase(vmalert_remotewrite_sent_rows_bucket{job=~\"$job\", instance=~\"$instance\"}[$__rate_interval])) by (instance, vmrange)))",
|
||||
"legendFormat": "__auto",
|
||||
"legendFormat": "max",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
@@ -4167,7 +4299,7 @@
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"x": 12,
|
||||
"y": 46
|
||||
},
|
||||
"id": 54,
|
||||
|
||||
@@ -85,6 +85,20 @@ groups:
|
||||
to the configured remote write URL. This may result into gaps in recording rules or alerts state.
|
||||
Check vmalert's logs for detailed error message."
|
||||
|
||||
- alert: RemoteWriteQueueHighUsage
|
||||
expr: histogram_quantile(0.99, sum(increase(vmalert_remotewrite_queue_size_bucket[5m])) by (job, instance, vmrange)) / vmalert_remotewrite_queue_capacity > 0.8
|
||||
for: 15m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "Remote write queue capacity on the vmalert instance {{ $labels.instance }} has exceeded 80% utilization"
|
||||
description: "The remote write queue on vmalert instance {{ $labels.instance }} has consistently high utilization.
|
||||
The queue acts as a buffer between rules generating series and remote-write client consuming and pushing these series. When queue overflows, vmalert will start dropping newly generated series.
|
||||
Queue may overflow due to multiple reasons:
|
||||
1. Some bad rules produce too many series at once. This can be limited using the global `-rule.resultsLimit` flag or `limit` param at the rule group level.
|
||||
2. Remote write connection is slow. Increase `-remoteWrite.concurrency`, so vmalert could establish more concurrent connections.
|
||||
3. The queue size is too small. Increase `-remoteWrite.maxQueueSize` to extend the buffer size. Note that a larger queue will result in higher memory consumption when the queue is full."
|
||||
|
||||
- alert: AlertmanagerErrors
|
||||
expr: increase(vmalert_alerts_send_errors_total[5m]) > 0
|
||||
for: 15m
|
||||
@@ -94,3 +108,4 @@ groups:
|
||||
summary: "vmalert instance {{ $labels.instance }} is failing to send notifications to Alertmanager"
|
||||
description: "vmalert instance {{ $labels.instance }} is failing to send alert notifications to \"{{ $labels.addr }}\".
|
||||
Check vmalert's logs for detailed error message."
|
||||
|
||||
|
||||
@@ -1,19 +1,132 @@
|
||||
VictoriaMetrics provides a rich set of public playgrounds that let you explore the full observability stack — metrics, logs, and traces — and even use migration tools without installing or configuring anything locally.
|
||||
VictoriaMetrics offers public playgrounds where you can try the full observability stack online.
|
||||
|
||||
These playgrounds are backed by real VictoriaMetrics components and data, making them ideal for:
|
||||
Some playgrounds are based on the [OpenTelemetry Astronomy Shop demo](https://github.com/open-telemetry/opentelemetry-demo), a sample microservices application that generates realistic metrics, logs, and traces. Other playgrounds use benchmark workloads such as [prometheus-benchmark](https://github.com/VictoriaMetrics/prometheus-benchmark) to demonstrate ingestion and query performance for Prometheus-compatible systems.
|
||||
|
||||
- Learning VictoriaMetrics query languages
|
||||
- Trying dashboards and queries interactively
|
||||
- Validating migration paths
|
||||
These playgrounds are ideal for:
|
||||
|
||||
- Learning [MetricsQL](https://docs.victoriametrics.com/victoriametrics/metricsql/) and [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/)
|
||||
- Trying out dashboards and queries interactively
|
||||
- Demonstrating features in talks or workshops
|
||||
|
||||
In this section, we'll walk through each available playground, explain what it does, and link to the relevant GitHub repositories.
|
||||
In the following sections, we'll walk through each playground, explain its purpose, and link to the corresponding GitHub repositories.
|
||||
|
||||
## Docker Compose Demo
|
||||
## VictoriaMetrics Playground
|
||||
|
||||
A fast, cost-effective, and scalable monitoring solution and time series database designed for collecting, storing, querying, and alerting on metrics.
|
||||
|
||||
- Try it: <https://play.victoriametrics.com/>
|
||||
- Documentation: <https://docs.victoriametrics.com/victoriametrics/>
|
||||
|
||||
The playground is represented by [cluster version of VictoriaMetrics](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/).
|
||||
It collects metrics from [OpenTelemetry Astronomy Shop demo](https://github.com/open-telemetry/opentelemetry-demo) and
|
||||
various services in our Kubernetes playground namespace.
|
||||
|
||||
VictoriaMetrics web UI is represented via [VMUI](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#vmui).
|
||||
It allows querying metrics, plotting graphs, exploring cardinality, viewing alerting and recording rules, debugging relabeling rules, etc.
|
||||
|
||||
The best place to get started is with the [Cardinality Explorer](https://play.victoriametrics.com/select/0/prometheus/graph/#/cardinality) page, found under **Explore** > **Explore Cardinality**.
|
||||
This view shows what's stored in the database for the specified day, lets you browse top metrics and labels in the dataset, and lets you drill down into them without writing a single line of MetricsQL.
|
||||
|
||||

|
||||
<figcaption style="text-align: center; font-style: italic;">Cardinality Explorer in VictoriaMetrics</figcaption>
|
||||
|
||||
Try plotting graphs on the **Query** tab - [`sum(rate(vm_http_requests_total[5m])) by(path) > 0`](https://play.victoriametrics.com/select/0/prometheus/graph/#/?g0.range_input=30m&g0.relative_time=last_30_minutes&g0.tab=0&g0.expr=sum%28rate%28vm_http_requests_total%5B5m%5D%29%29+by%28path%29+%3E+0):
|
||||
|
||||

|
||||
|
||||
> VictoriaMetrics is also represented as a datasource in [Grafana playground](#grafana-playground).
|
||||
|
||||
## VictoriaLogs Playground
|
||||
|
||||
High-performance, lightweight, zero-config, schema-free database for logs that is easy to use and scales both vertically and horizontally,
|
||||
from very small setups to large-scale deployments handling terabytes per day.
|
||||
|
||||
- Try it: <https://play-vmlogs.victoriametrics.com/>
|
||||
- Documentation: <https://docs.victoriametrics.com/victorialogs/>
|
||||
|
||||
The playground is represented by [cluster version of VictoriaLogs](https://docs.victoriametrics.com/victorialogs/cluster/).
|
||||
It stores logs from [OpenTelemetry Astronomy Shop demo](https://github.com/open-telemetry/opentelemetry-demo) and various
|
||||
other services that run in our k8s playground namespace.
|
||||
|
||||
VictoriaLogs [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui) allows querying log entries, plotting graphs,
|
||||
exploring stored datasets, live tailing.
|
||||
|
||||
To start exploring the data, look at the sidebar. It shows the stream fields available in the dataset,
|
||||
and clicking any field or value automatically applies a filter, so you can browse the logs before writing your own query.
|
||||
|
||||

|
||||
|
||||
On the `Query` tab, click on the `Query examples` button to see examples of the most common search queries to start with.
|
||||
|
||||
> VictoriaLogs is also represented as a datasource in [Grafana playground](#grafana-playground).
|
||||
|
||||
## VictoriaTraces Playground
|
||||
|
||||
VictoriaTraces is a fast and scalable database for traces, built on top of VictoriaLogs.
|
||||
|
||||
- Try it: <https://play-grafana.victoriametrics.com/explore> (choose `Jaeger` datasource)
|
||||
- Documentation: <https://docs.victoriametrics.com/victoriatraces/>
|
||||
|
||||
> [!NOTE]
|
||||
> VictoriaTraces doesn't have its own web UI. Instead, it implements Jaeger API for [integrating with Jaeger UI or Grafana](https://docs.victoriametrics.com/victoriatraces/querying/).
|
||||
|
||||
VictoriaTraces playground stores traces from [OpenTelemetry Astronomy Shop demo](https://github.com/open-telemetry/opentelemetry-demo).
|
||||
|
||||
To view trace data, follow these steps:
|
||||
1. On the [Grafana Playground](https://play-grafana.victoriametrics.com/), select **Explore** in the sidebar
|
||||
2. Select VictoriaTraces / Jaeger in the combo box near the top-left corner
|
||||
3. In **Query Type** select "Search"
|
||||
4. Select one of the services and press **Run Query**
|
||||
|
||||

|
||||
|
||||
> VictoriaTraces is also represented as a datasource in [Grafana playground](#grafana-playground).
|
||||
|
||||
## Grafana Playground
|
||||
|
||||
- Try it: <https://play-grafana.victoriametrics.com>
|
||||
|
||||
Grafana playground contains examples of dashboards and datasources for VictoriaMetrics, VictoriaLogs, and VictoriaTraces.
|
||||
It allows viewing metrics, logs, and traces generated by [OpenTelemetry Astronomy Shop demo](https://github.com/open-telemetry/opentelemetry-demo).
|
||||
|
||||
Try viewing available dashboards or just browse via Grafana's explore page to query and [correlate signals](https://docs.victoriametrics.com/opentelemetry/#correlations).
|
||||
|
||||

|
||||
|
||||
## VMAnomaly Playground
|
||||
|
||||
VMAnomaly analyzes metrics, logs, or traces using VictoriaMetrics' built-in anomaly detection model to generate an [anomaly score](https://docs.victoriametrics.com/anomaly-detection/faq/#what-is-anomaly-score). An `anomaly_score > 1` indicates an anomalous condition that deserves attention.
|
||||
|
||||
The [anomaly metrics playground](https://play-vmanomaly.victoriametrics.com/metrics/) shows anomalies in CPU utilization.
|
||||
|
||||

|
||||
<figcaption style="text-align: center; font-style: italic;">Exploring anomalies on metric data on CPU utilization</figcaption>
|
||||
|
||||
The [anomaly logs playground](https://play-vmanomaly.victoriametrics.com/logs/) shows by default anomalies in log ingestion.
|
||||
|
||||

|
||||
<figcaption style="text-align: center; font-style: italic;">Finding anomalies in log ingestion</figcaption>
|
||||
|
||||
And the [anomaly trace playground](https://play-vmanomaly.victoriametrics.com/traces/) analyzes spans with error status.
|
||||
|
||||

|
||||
<figcaption style="text-align: center; font-style: italic;">Analyzing traces for service error anomalies</figcaption>
|
||||
|
||||
## Docker Compose Playgrounds
|
||||
|
||||
We provide Docker Compose examples for:
|
||||
|
||||
We provide Docker Compose files for:
|
||||
- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/deployment/docker/README.md)
|
||||
- [VictoriaLogs](https://github.com/VictoriaMetrics/VictoriaLogs/blob/master/deployment/docker/README.md)
|
||||
- [VictoriaTraces](https://github.com/VictoriaMetrics/VictoriaTraces/blob/master/deployment/docker/README.md).
|
||||
- [VictoriaTraces](https://github.com/VictoriaMetrics/VictoriaTraces/blob/master/deployment/docker/README.md)
|
||||
|
||||
The Docker Compose examples demonstrate how various components could be configured, provisioned, and interconnected.
|
||||
These examples aren't intended for production use.
|
||||
|
||||
## VictoriaMetrics Cloud
|
||||
|
||||
VictoriaMetrics UIs are also included in the [Explore](https://docs.victoriametrics.com/victoriametrics-cloud/exploring-data/) section of VictoriaMetrics and VictoriaLogs deployments, embedded in VictoriaMetrics Cloud.
|
||||
|
||||
You can experiment with your own data during the month‑long trial without deploying VictoriaStack in your infrastructure. To get started, follow [this guide](https://docs.victoriametrics.com/victoriametrics-cloud/get-started/quickstart/).
|
||||
|
||||
|
||||
The compose files are already configured, provisioned, and interconnected. They can be used to quickly set up a demo environment, suitable for a [quick start](https://docs.victoriametrics.com/victoriametrics/quick-start/).
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
weight: 6
|
||||
title: Cloud Playground
|
||||
menu:
|
||||
docs:
|
||||
parent: "playgrounds"
|
||||
weight: 6
|
||||
tags:
|
||||
- victoriametrics
|
||||
- cloud
|
||||
- playground
|
||||
- monitoring
|
||||
---
|
||||
|
||||
- Try it: <https://console.victoriametrics.cloud/explore>
|
||||
|
||||
VictoriaMetrics UIs are included in the explore section of VictoriaMetrics and VictoriaLogs deployments embedded in VictoriaMetrics Cloud.
|
||||
|
||||
You can experiment with your own data without the need to deploy the VictoriaMetrics Stack in your local environment for free for a month by following this guide: [VictoriaMetrics Cloud Quickstart](https://docs.victoriametrics.com/victoriametrics-cloud/get-started/quickstart/).
|
||||
|
||||
Once set up, follow this guide to explore your data: <https://docs.victoriametrics.com/victoriametrics-cloud/exploring-data/>
|
||||
BIN
docs/playgrounds/grafana-node-exporter.webp
Normal file
|
After Width: | Height: | Size: 208 KiB |
@@ -1,45 +0,0 @@
|
||||
---
|
||||
weight: 4
|
||||
title: Grafana Playground
|
||||
menu:
|
||||
docs:
|
||||
parent: "playgrounds"
|
||||
weight: 4
|
||||
tags:
|
||||
- grafana
|
||||
- playground
|
||||
- metrics
|
||||
- logs
|
||||
- traces
|
||||
---
|
||||
|
||||
- Try it: <https://play-grafana.victoriametrics.com/>
|
||||
|
||||
This playground is particularly useful if you already use Grafana and want to see how VictoriaMetrics integrates into existing workflows. It provides a hosted Grafana instance preconfigured with:
|
||||
|
||||
- [VictoriaMetrics](https://docs.victoriametrics.com/victoriametrics/) as a metrics data source
|
||||
- [VictoriaLogs](https://docs.victoriametrics.com/victorialogs/) as a logs data source
|
||||
- [VictoriaTraces](https://docs.victoriametrics.com/victoriatraces/) as a Jaeger data source for traces
|
||||
|
||||
## What can you do here?
|
||||
|
||||
- Explore [real dashboards](https://play-grafana.victoriametrics.com/dashboards) built on top of VictoriaMetrics
|
||||
- See how [MetricsQL](https://docs.victoriametrics.com/victoriametrics/metricsql/) and [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/) are used in Grafana panels
|
||||
- Explore correlation with the help of the [OpenTelemetry Collector dashboard](https://play-grafana.victoriametrics.com/d/BKf2sowmj/opentelemetry-collector)
|
||||
- Learn dashboard design and visualization best practices
|
||||
|
||||

|
||||
<figcaption style="text-align: center; font-style: italic;">Grafana dashboard in the playground</figcaption>
|
||||
|
||||
The OpenTelemetry Collector dashboard is built on the official [OpenTelemetry Astronomy Shop demo](https://github.com/VictoriaMetrics-Community/opentelemetry-demo). It lets you visualize and understand telemetry data alongside VictoriaMetrics Stack observability signals, using VictoriaMetrics for metrics, VictoriaLogs for logs, and VictoriaTraces for traces.
|
||||
|
||||
For an always-updated list of dashboards, bookmark this playground.
|
||||
|
||||
## Distribution
|
||||
|
||||
Relevant GitHub:
|
||||
- VictoriaMetrics Grafana datasource: <https://github.com/VictoriaMetrics/victoriametrics-datasource>
|
||||
- VictoriaLogs Grafana datasource: <https://github.com/VictoriaMetrics/victorialogs-datasource>
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 94 KiB |
@@ -1,42 +0,0 @@
|
||||
---
|
||||
weight: 8
|
||||
title: LogQL to LogsQL Playground
|
||||
menu:
|
||||
docs:
|
||||
parent: "playgrounds"
|
||||
weight: 8
|
||||
tags:
|
||||
- logsql
|
||||
- loki
|
||||
- victorialogs
|
||||
- playground
|
||||
- monitoring
|
||||
---
|
||||
|
||||
- Try it: <https://play-logql.victoriametrics.com/>
|
||||
|
||||
For teams migrating from Grafana Loki, this simple UI provides a useful [translator from LogQL to LogsQL](https://docs.victoriametrics.com/victorialogs/logql-to-logsql/).
|
||||
|
||||

|
||||
|
||||
## What can you do here?
|
||||
|
||||
The query-language translation tool automatically converts Loki queries into VictoriaLogs queries, reducing friction when adopting VictoriaLogs in environments already using Loki.
|
||||
|
||||
Type your LogQL query and press **Execute**.
|
||||
|
||||
For example, this LogQL query:
|
||||
|
||||
```text
|
||||
{collector="otel-collector"} |= "POST"
|
||||
```
|
||||
|
||||
Translates into the equivalent [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/)
|
||||
|
||||
```text
|
||||
{collector="otel-collector"} "POST"
|
||||
```
|
||||
|
||||
## Distribution
|
||||
|
||||
- GitHub: <https://github.com/VictoriaMetrics-Community/logql-to-logsql>
|
||||
|
Before Width: | Height: | Size: 140 KiB |
@@ -1,46 +0,0 @@
|
||||
---
|
||||
weight: 7
|
||||
title: SQL to LogsQL Playground
|
||||
menu:
|
||||
docs:
|
||||
parent: "playgrounds"
|
||||
weight: 7
|
||||
tags:
|
||||
- logsql
|
||||
- SQL
|
||||
- victorialogs
|
||||
- playground
|
||||
- monitoring
|
||||
---
|
||||
|
||||
- Try it: <https://play-sql.victoriametrics.com/>
|
||||
|
||||
This playground enables you to query data from a VictoriaLogs instance or translate SQL to [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/) without querying.
|
||||
|
||||

|
||||
|
||||
## What can you do here?
|
||||
|
||||
First, run `SHOW TABLES;` to view all the existing tables in the SQL database and their equivalent query in [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/).
|
||||
|
||||
Then, type your SQL query and press **Execute**.
|
||||
|
||||
For example, this query:
|
||||
|
||||
```sql
|
||||
SELECT _time, _msg
|
||||
FROM logs
|
||||
WHERE _msg LIKE 'error'
|
||||
ORDER BY _time DESC
|
||||
LIMIT 100
|
||||
```
|
||||
|
||||
Translates into:
|
||||
|
||||
```text
|
||||
_msg:error | fields _time, _msg | sort by (_time desc) | limit 100
|
||||
```
|
||||
|
||||
## Distribution
|
||||
|
||||
- GitHub: <https://github.com/VictoriaMetrics/sql-to-logsql>
|
||||
|
Before Width: | Height: | Size: 88 KiB |
@@ -1,44 +0,0 @@
|
||||
---
|
||||
weight: 2
|
||||
title: VictoriaLogs Playground
|
||||
menu:
|
||||
docs:
|
||||
parent: "playgrounds"
|
||||
weight: 2
|
||||
tags:
|
||||
- victorialogs
|
||||
- playground
|
||||
- logs
|
||||
---
|
||||
|
||||
- Try it: <https://play-vmlogs.victoriametrics.com/>
|
||||
- Query language reference: [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/)
|
||||
|
||||
This playground focuses on VictoriaLogs and lets you test the query engine on a demo log set. The playground demonstrates how VictoriaLogs handles high-volume log data with predictable performance and low operational overhead.
|
||||
|
||||

|
||||
<figcaption style="text-align: center; font-style: italic;">VictoriaLogs playground</figcaption>
|
||||
|
||||
## What can you do here?
|
||||
|
||||
The WebUI provides the following modes for displaying query results:
|
||||
- Group: results are displayed as a table with rows grouped by stream fields.
|
||||
- Table: displays query results as a table.
|
||||
- JSON: displays raw JSON response from `/select/logsql/query` HTTP API.
|
||||
- Live: displays live tailing results for the given query.
|
||||
|
||||
As a starting point, you can type `collector: "otel-collector"` in the query field to search for entries collected by OpenTelemetry.
|
||||
|
||||

|
||||
<figcaption style="text-align: center; font-style: italic;">Log entries collected with the OpenTelemetry collector</figcaption>
|
||||
|
||||
Typing `error AND _time:24h` shows you the entries containing the text "error" during the last 24 hours.
|
||||

|
||||
|
||||
The **Overview** provides a quick, high-level look at the logs stored in VictoriaLogs. It helps you understand the volume and structure of your log data before diving into detailed queries. You can see log ingestion trends, identify the most common fields and values, and quickly spot noisy or unusual streams. From here, you can click on fields or values to automatically apply filters and start exploring your data with LogsQL.
|
||||
|
||||

|
||||
|
||||
## Distribution
|
||||
|
||||
- GitHub: <https://github.com/VictoriaMetrics/VictoriaLogs>
|
||||
@@ -1,63 +0,0 @@
|
||||
---
|
||||
weight: 1
|
||||
title: VictoriaMetrics Playground
|
||||
menu:
|
||||
docs:
|
||||
parent: "playgrounds"
|
||||
weight: 1
|
||||
tags:
|
||||
- victoriametrics
|
||||
---
|
||||
|
||||
- Try it: <https://play.victoriametrics.com/>
|
||||
- Query language reference: [MetricsQL](https://docs.victoriametrics.com/victoriametrics/metricsql/)
|
||||
|
||||
This is the primary playground for VictoriaMetrics, powered by VMUI and backed by a VictoriaMetrics cluster installation. Use it to experiment with the query engine, see available pages, or try tools such as the relabeling debugger.
|
||||
|
||||
This playground is the best starting point for understanding how VictoriaMetrics stores and queries metrics at scale.
|
||||
|
||||

|
||||
<figcaption style="text-align: center; font-style: italic;">VictoriaMetrics playground</figcaption>
|
||||
|
||||
## What can you do here?
|
||||
|
||||
The query tab provides a sandbox to experiment with [MetricsQL](https://docs.victoriametrics.com/victoriametrics/metricsql/). Turn on Autocomplete and start typing to discover time series. You can add multiple queries and compare them.
|
||||
|
||||
You can try these to get started:
|
||||
|
||||
- Average CPU usage per job: `sum(rate(process_cpu_seconds_total[5m])) by (job)`
|
||||
- HTTP requests per-second rate: `sum(rate(vm_http_requests_total[5m]))`
|
||||
- Top 5 CPU intensive jobs `topk(5, sum(rate(process_cpu_seconds_total[5m])) by (job))`
|
||||
|
||||
Below is an example of average CPU usage per job:
|
||||
|
||||
```text
|
||||
sum(rate(process_cpu_seconds_total[5m])) by (job)
|
||||
```
|
||||
|
||||

|
||||
<figcaption style="text-align: center; font-style: italic;">Average CPU usage per job</figcaption>
|
||||
|
||||
Here, we are requesting the per-second rate of HTTP requests:
|
||||
|
||||
```text
|
||||
sum(rate(vm_http_requests_total[5m]))
|
||||
```
|
||||
|
||||

|
||||
<figcaption style="text-align: center; font-style: italic;">HTTP requests per second</figcaption>
|
||||
|
||||
And here is an example for obtaining the top 5 high CPU jobs:
|
||||
|
||||
```text
|
||||
topk(5, sum(rate(process_cpu_seconds_total[5m])) by (job))
|
||||
```
|
||||
|
||||

|
||||
<figcaption style="text-align: center; font-style: italic;">Top 5 CPU intensive jobs</figcaption>
|
||||
|
||||
For a deep dive into all the features of this playground, please visit the [VMUI](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#vmui) page.
|
||||
|
||||
## Distribution
|
||||
|
||||
- GitHub: <https://github.com/VictoriaMetrics/VictoriaMetrics>
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
weight: 3
|
||||
title: VictoriaTraces Playground
|
||||
menu:
|
||||
docs:
|
||||
parent: "playgrounds"
|
||||
weight: 3
|
||||
tags:
|
||||
- victoriatraces
|
||||
- playground
|
||||
- monitoring
|
||||
---
|
||||
|
||||
- Try it: <https://play-vtraces.victoriametrics.com/>
|
||||
- Query language reference: [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/)
|
||||
|
||||
> [!NOTE] Note
|
||||
> This playground is currently under development, as the main project it is correlated with, VictoriaTraces, is also under development.
|
||||
|
||||
VictoriaTraces provides a UI for browsing raw data and Jaeger APIs/Grafana data source for trace visualization. This playground showcases VictoriaTraces, the VictoriaMetrics backend for distributed tracing, and enables trace searching, visualization, and service graph/dependency analysis.
|
||||
|
||||

|
||||
<figcaption style="text-align: center; font-style: italic;">Grafana playground showing VictoriaTraces/Jaeger datasource</figcaption>
|
||||
|
||||
## What can you do here?
|
||||
|
||||
The WebUI provides the following modes for displaying query results:
|
||||
- Group: results are displayed as a table with rows grouped by stream fields.
|
||||
- Table: displays query results as a table.
|
||||
- JSON: displays raw JSON response from the HTTP API.
|
||||
- Live: displays live tailing results for the given query.
|
||||
|
||||
## Distribution
|
||||
|
||||
- GitHub: <https://github.com/VictoriaMetrics/VictoriaTraces>
|
||||
|
||||
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 101 KiB |
BIN
docs/playgrounds/vl-vmui.webp
Normal file
|
After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 110 KiB |
BIN
docs/playgrounds/vmanomaly-logs.webp
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
docs/playgrounds/vmanomaly-metrics.webp
Normal file
|
After Width: | Height: | Size: 150 KiB |
BIN
docs/playgrounds/vmanomaly-traces.webp
Normal file
|
After Width: | Height: | Size: 98 KiB |
@@ -1,44 +0,0 @@
|
||||
---
|
||||
weight: 5
|
||||
title: Anomaly Detection Playground
|
||||
menu:
|
||||
docs:
|
||||
parent: "playgrounds"
|
||||
weight: 5
|
||||
tags:
|
||||
- vmanomaly
|
||||
- playground
|
||||
- monitoring
|
||||
---
|
||||
|
||||
- Try it: <https://play-vmanomaly.victoriametrics.com/metrics/vmui/>
|
||||
- UI Guide: <https://docs.victoriametrics.com/anomaly-detection/ui/#example-usage>
|
||||
|
||||
The playground demonstrates automatic [anomaly detection](https://docs.victoriametrics.com/anomaly-detection/).
|
||||
|
||||

|
||||
<figcaption style="text-align: center; font-style: italic;">Exploring model fit for CPU usage series</figcaption>
|
||||
|
||||
The playground showcases anomaly detection data (native timeseries or converted to timeseries) using VictoriaMetrics, VictoriaLogs, or VictoriaTraces datasources, respectively:
|
||||
|
||||
- <https://play-vmanomaly.victoriametrics.com/metrics/>
|
||||
- <https://play-vmanomaly.victoriametrics.com/logs/>
|
||||
- <https://play-vmanomaly.victoriametrics.com/traces/>
|
||||
|
||||
## What can you do here?
|
||||
|
||||
The Anomaly Detection playground lets you:
|
||||
- Understand how [MetricsQL](https://docs.victoriametrics.com/victoriametrics/metricsql/) and [LogsQL](https://docs.victoriametrics.com/victorialogs/logsql/) are used to generate input data for anomaly detection.
|
||||
- Explore metrics data enriched with anomaly scores, predictions, and confidence intervals.
|
||||
- Visualize anomalies directly in VMUI, including consecutive anomalies that last over time rather than being a single point, to imitate how alerting rules trigger on such data.
|
||||
- Learn how anomaly scores can be used for alerting purposes by exploring generated alerting rules.
|
||||
|
||||
## Distribution & setup
|
||||
|
||||
VMAnomaly is distributed through various channels:
|
||||
|
||||
- [Installation guide](https://docs.victoriametrics.com/anomaly-detection/quickstart/)
|
||||
- Docker containers available in [Docker Hub](https://hub.docker.com/r/victoriametrics/vmanomaly) and [Quay.io](https://quay.io/repository/victoriametrics/vmanomaly)
|
||||
- [Helm charts](https://github.com/VictoriaMetrics/helm-charts) (including anomaly setups)
|
||||
- [VM Operator](https://docs.victoriametrics.com/operator/resources/vmanomaly/)
|
||||
|
||||
|
Before Width: | Height: | Size: 84 KiB |
BIN
docs/playgrounds/vmui-cardinality-explorer.webp
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
docs/playgrounds/vmui-rate-http-requests-total.webp
Normal file
|
After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 93 KiB |
@@ -23,6 +23,7 @@ See also [case studies](https://docs.victoriametrics.com/victoriametrics/casestu
|
||||
* [CERN: The CMS monitoring infrastructure and applications](https://arxiv.org/pdf/2007.03630.pdf)
|
||||
* [Forbes: The (Almost) Infinitely Scalable Open Source Monitoring Dream](https://www.forbes.com/sites/adrianbridgwater/2022/08/16/the-almost-infinitely-scalable-open-source-monitoring-dream/)
|
||||
* [Forbes: The Agility In Cloud Observability](https://www.forbes.com/sites/adrianbridgwater/2023/07/05/the-agility-in-cloud-observability/)
|
||||
* [Airbnb: Building a high-volume metrics pipeline with OpenTelemetry and vmagent](https://medium.com/airbnb-engineering/building-a-high-volume-metrics-pipeline-with-opentelemetry-and-vmagent-c714d6910b45)
|
||||
* [Bedrock: Monitoring at scale with Victoria Metrics](https://tech.bedrockstreaming.com/2022/09/06/monitoring-at-scale-with-victoriametrics.html)
|
||||
* [TiDB by PingCap: Scaling Observability: Why TiDB Moved from Prometheus to VictoriaMetrics](https://www.pingcap.com/blog/tidb-observability-migrating-prometheus-victoriametrics/)
|
||||
* [TigrisData: We do our billing with Prometheus](https://www.tigrisdata.com/blog/billing-prometheus/)
|
||||
@@ -112,6 +113,7 @@ See also [case studies](https://docs.victoriametrics.com/victoriametrics/casestu
|
||||
* [FreeBSD: monitoring with VictoriaMetrics and Grafana](https://setevoy.medium.com/freebsd-monitoring-with-victoriametrics-and-grafana-f789904f2628)
|
||||
* [QCon London 2026: Wrangling Telemetry at Scale, a Guide to Self-Hosted Observability](https://www.infoq.com/news/2026/03/self-hosted-observability/)
|
||||
* [How We Made Telemetry Queries 10x Faster: Chunk-Split Caching for Metrics, Logs, and Traces](https://mirastacklabs.ai/blog/chunk-split-caching/)
|
||||
* [Building a high-volume metrics pipeline with OpenTelemetry and vmagent](https://medium.com/airbnb-engineering/building-a-high-volume-metrics-pipeline-with-opentelemetry-and-vmagent-c714d6910b45)
|
||||
|
||||
## Third-party articles and slides about VictoriaLogs
|
||||
|
||||
|
||||
@@ -795,6 +795,7 @@ curl http://<victoriametrics-addr>:8428/api/v1/export/csv -d 'format=<format>' -
|
||||
```
|
||||
|
||||
The exported CSV data can be imported to VictoriaMetrics via [/api/v1/import/csv](#how-to-import-csv-data).
|
||||
The first line of the file is a header row derived from the `format` parameter.
|
||||
|
||||
The [deduplication](#deduplication) is applied for the data exported in CSV by default. It is possible to export raw data without de-duplication by passing `reduce_mem_usage=1` query arg to `/api/v1/export/csv`.
|
||||
|
||||
@@ -936,6 +937,8 @@ The `format` query arg must contain comma-separated list of parsing rules for CS
|
||||
* `rfc3339` - timestamp in [RFC3339](https://tools.ietf.org/html/rfc3339) format, i.e. `2006-01-02T15:04:05Z`.
|
||||
* `custom:<layout>` - custom layout for the timestamp. The `<layout>` may contain arbitrary time layout according to [time.Parse rules in Go](https://golang.org/pkg/time/#Parse).
|
||||
|
||||
The first row is treated as a header but can be skipped if any `time` or `metric` column contains a non-numeric value.
|
||||
|
||||
Each request to `/api/v1/import/csv` may contain arbitrary number of CSV lines.
|
||||
|
||||
Example for importing CSV data via `/api/v1/import/csv`:
|
||||
|
||||
@@ -26,22 +26,32 @@ See also [LTS releases](https://docs.victoriametrics.com/victoriametrics/lts-rel
|
||||
|
||||
## tip
|
||||
|
||||
**Update Note 1:** [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) and `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): [CSV export](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#how-to-export-csv-data) (`/api/v1/export/csv`) now adds a header row as the first line of the response, so existing CSV-processing scripts may need to skip this header. See [#10666](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10666).
|
||||
|
||||
* SECURITY: upgrade Go builder from Go1.26.1 to Go1.26.2. See [the list of issues addressed in Go1.26.2](https://github.com/golang/go/issues?q=milestone%3AGo1.26.2%20label%3ACherryPickApproved).
|
||||
|
||||
* FEATURE: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/): add per-URL `-remoteWrite.disableMetadata` flag to disable metadata sending for specific remote storage URLs. See [#10711](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10711). Thanks to @evkuzin for the contribution.
|
||||
* FEATURE: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/): add `profile` option to `ec2_sd_configs` for loading credentials from named AWS profiles in `~/.aws/credentials` and `~/.aws/config`, including `source_profile` chaining and `role_arn` resolution. See [ec2_sd_configs docs](https://docs.victoriametrics.com/victoriametrics/sd_configs/#ec2_sd_configs). Issue [#1685](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1685). Thanks to @andriibeee for the contribution.
|
||||
* FEATURE: introduce `vm_filestream_fsync_duration_seconds_total` and `vm_filestream_fsync_calls_total` metrics, which can be used for detecting slow storage if it cannot keep up with the current data ingestion rate. See [#10432](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10432). Thanks to @mehrdadbn9 for the contribution.
|
||||
* FEATURE: [vmctl](https://docs.victoriametrics.com/victoriametrics/vmctl/): add dedicated `thanos` mode for [migrating data from Thanos](https://docs.victoriametrics.com/victoriametrics/vmctl/thanos/). This mode supports both raw and downsampled Thanos blocks, including all aggregate types (count, sum, min, max, counter). Each aggregate is imported as a separate metric with resolution and aggregate type suffixes (e.g., `metric_name:5m:count`). The new mode uses `--thanos-*` prefixed flags: `--thanos-snapshot`, `--thanos-concurrency`, `--thanos-filter-time-start`, `--thanos-filter-time-end`, `--thanos-filter-label`, `--thanos-filter-label-value`, and `--thanos-aggr-types`. See [#9262](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/9262).
|
||||
* FEATURE: [dashboards/alert-statistics](https://grafana.com/grafana/dashboards/24553): add pending and firing alerts stats; fix query in `FIRING over time by group` panel. See [#10571](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10571). Thanks to @sias32 for the contribution.
|
||||
* FEATURE: [vmalert](https://docs.victoriametrics.com/victoriametrics/vmalert/): add random jitter to concurrent periodical flushers targeting the remote write destination. This helps spread remote write flushes across the flush interval, avoiding congestion at the remote write destination and enhancing queue data consumption. See [#10729](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10729).
|
||||
* FEATURE: [vmalert](https://docs.victoriametrics.com/victoriametrics/vmalert/): expose `vmalert_remotewrite_sent_rows` and `vmalert_remotewrite_sent_bytes` histograms to provide better visibility into remote write request sizes. See [#10727](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10727).
|
||||
* FEATURE: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/): allow setting `-1` value for `-remoteWrite.maxHourlySeries` and `-remoteWrite.maxDailySeries` command-line flags. This automatically sets limits to the highest possible value in order to enable tracking without enforcing any limits. This is helpful for estimating current usage before applying real limits. See [#9614](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/9614).
|
||||
* FEATURE: `vminsert` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): optimize vminsert buffer size per vmstorage node based on available CPU, memory and storage node count to reduce OOM risk. See [#10725](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10725).
|
||||
* FEATURE: [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) and `vmstorage` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): allow setting `-1` value for `-storage.maxHourlySeries` and `-storage.maxDailySeries` command-line flags. This automatically sets limits to the highest possible value in order to enable tracking without enforcing any limits. This is helpful for estimating current usage before applying real limits. See [#9614](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/9614).
|
||||
* FEATURE: [vmalert](https://docs.victoriametrics.com/victoriametrics/vmalert/): expose `vmalert_remotewrite_queue_size` and `vmalert_remotewrite_queue_capacity` to facilitate monitoring of remote write queue usage. See [#10765](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10765).
|
||||
* FEATURE: [vmui](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#vmui): CSV export on the `Raw Query` tab now includes all labels from the executed query. VMUI no longer prepends a header row, as it is now provided by the backend. See [#10667](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10667) and [#10666](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10666). Thanks to @lawrence3699 for the contribution.
|
||||
* FEATURE: [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) and `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): add header row to `/api/v1/export/csv` output and auto-detect header rows during import via `/api/v1/import/csv`. See [#10666](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10666). Thanks to @andriibeee for the contribution.
|
||||
* FEATURE: all VictoriaMetrics components: expose operating system name and release version as metric `vm_os_info`. See [#10481](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10481).
|
||||
* FEATURE: [vmalert](https://docs.victoriametrics.com/victoriametrics/vmalert/): align group evaluation time with the `eval_offset` option to help manage group execution more effectively. See [#10772](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10772).
|
||||
|
||||
* BUGFIX: [vmbackup](https://docs.victoriametrics.com/vmbackup/), [vmbackupmanager](https://docs.victoriametrics.com/victoriametrics/vmbackupmanager/): retry the requests that failed with unexpected EOF due to unstable network to S3 service. See [#10699](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10699).
|
||||
* BUGFIX: All VictoriaMetrics components: Fix an issue where `unsupported` metric metadata type was exposed for summaries and quantiles if a summary wasn't updated within a certain time window. See [metrics#120](https://github.com/VictoriaMetrics/metrics/issues/120) and [metrics#121](https://github.com/VictoriaMetrics/metrics/pull/121).
|
||||
* BUGFIX: [vmauth](https://docs.victoriametrics.com/victoriametrics/vmauth/): align request body buffering flags - `maxRequestBodySizeToRetry` and `requestBufferSize` to the same `16KB` value. Allow disabling request buffering by setting `requestBufferSize=0`. See [#10675](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10675)
|
||||
* BUGFIX: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/): fix `scrape_series_added` metric to update only on successful scrapes, aligning its behavior with Prometheus. See [#10653](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10653).
|
||||
* BUGFIX: [MetricsQL](https://docs.victoriametrics.com/victoriametrics/metricsql/): improve the selection algorithm of [buckets_limit](https://docs.victoriametrics.com/victoriametrics/metricsql/#buckets_limit) to remove consecutive empty buckets at the beginning and end to obtain more accurate min and max values. See [#10417](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10417).
|
||||
* BUGFIX: `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): prevent partial responses from second-level vmselect nodes in [multi-level cluster setups](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/#multi-level-cluster-setup). Ensures response completeness and correctness, and avoids cache pollution in top-level vmselect. See [#10678](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10678).
|
||||
* BUGFIX: [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) and `vmstorage` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): Fix storage connection saturation spikes at 00:00 UTC and improve data ingestion when the storage is restarted during the first hour of the day. See [10698](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10698).
|
||||
* BUGFIX: [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) and `vmstorage` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): prevent rare panic during storage start-up at 100% disk usage. See [#10747](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10747) Thanks to @nmn3m for the contribution.
|
||||
|
||||
## [v1.139.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.139.0)
|
||||
|
||||
|
||||
@@ -648,6 +648,12 @@ scrape_configs:
|
||||
#
|
||||
# role_arn: "..."
|
||||
|
||||
# profile is an optional named AWS profile from ~/.aws/config and ~/.aws/credentials.
|
||||
# When set, credentials and role_arn are resolved from the profile, with source_profile
|
||||
# chaining supported. See https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
|
||||
#
|
||||
# profile: "..."
|
||||
|
||||
# port is an optional port to scrape metrics from.
|
||||
# By default, port 80 is used.
|
||||
#
|
||||
|
||||
@@ -1236,8 +1236,8 @@ For example:
|
||||
```yaml
|
||||
groups:
|
||||
- name: BaseGroup
|
||||
interval: 1m
|
||||
eval_offset: 10s
|
||||
interval: 5m
|
||||
eval_offset: 1m
|
||||
rules:
|
||||
- record: http_server_request_duration_seconds:sum_rate:5m:http_get
|
||||
expr: |
|
||||
@@ -1258,8 +1258,8 @@ groups:
|
||||
)
|
||||
)
|
||||
- name: TopGroup
|
||||
interval: 1m
|
||||
eval_offset: 40s
|
||||
interval: 5m
|
||||
eval_offset: 3m
|
||||
rules:
|
||||
- record: http_server_request_duration_seconds:sum_rate:5m:merged
|
||||
expr: |
|
||||
@@ -1271,20 +1271,20 @@ groups:
|
||||
This configuration ensures that rules in `BaseGroup` are executed at(assuming vmalert starts at `12:00:00`):
|
||||
|
||||
```
|
||||
[12:00:10, 12:01:10, 12:02:10, 12:03:10...]
|
||||
[12:01:00, 12:06:00, 12:11:00, 12:16:00...]
|
||||
```
|
||||
|
||||
while rules in group `TopGroup` are executed at:
|
||||
|
||||
```
|
||||
[12:00:40, 12:01:40, 12:02:40, 12:03:40...]
|
||||
[12:03:00, 12:08:00, 12:13:00, 12:18:00...]
|
||||
```
|
||||
|
||||
As a result, `TopGroup` always gets the latest results of `BaseGroup`.
|
||||
As a result, `TopGroup` can consistently obtain the latest results from `BaseGroup` if `BaseGroup` completes its evaluation and uploads its results to the datasource within 2 minutes.
|
||||
|
||||
By default, the `eval_offset` values should be at least 30 seconds apart to accommodate the
|
||||
`-search.latencyOffset(default 30s)` command-line flag at vmselect or VictoriaMetrics single-node.
|
||||
The minimum `eval_offset` gap can be adjusted accordingly with `-search.latencyOffset`.
|
||||
The minimum `eval_offset` gap should be adjusted according to the sum of the execution duration of `BaseGroup` and `-search.latencyOffset`.
|
||||
|
||||
### Notifier configuration file
|
||||
|
||||
|
||||
@@ -1137,7 +1137,7 @@ The following [metrics](https://docs.victoriametrics.com/victoriametrics/vmauth/
|
||||
* `vmauth_buffer_request_body_duration_seconds` - the [summary](https://docs.victoriametrics.com/victoriametrics/keyconcepts/#summary) for the request body buffering duration.
|
||||
Use this metric to understand buffering performance and identify slow clients.
|
||||
|
||||
See also [concurrency limits](https://docs.victoriametrics.com/victoriametrics/vmauth/#concurrency-limits).
|
||||
See also [concurrency limits](https://docs.victoriametrics.com/victoriametrics/vmauth/#concurrency-limiting).
|
||||
|
||||
## Backend TLS setup
|
||||
|
||||
|
||||
174
go.mod
@@ -3,7 +3,7 @@ module github.com/VictoriaMetrics/VictoriaMetrics
|
||||
go 1.26.2
|
||||
|
||||
require (
|
||||
cloud.google.com/go/storage v1.60.0
|
||||
cloud.google.com/go/storage v1.62.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.4
|
||||
@@ -12,20 +12,20 @@ require (
|
||||
github.com/VictoriaMetrics/fastcache v1.13.3
|
||||
github.com/VictoriaMetrics/metrics v1.43.1
|
||||
github.com/VictoriaMetrics/metricsql v0.86.0
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.1
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.8
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.22.1
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.0
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.5
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.14
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.22.13
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.99.0
|
||||
github.com/bmatcuk/doublestar/v4 v4.10.0
|
||||
github.com/cespare/xxhash/v2 v2.3.0
|
||||
github.com/cheggaaa/pb/v3 v3.1.7
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang/snappy v1.0.0
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/googleapis/gax-go/v2 v2.17.0
|
||||
github.com/influxdata/influxdb v1.12.2
|
||||
github.com/klauspost/compress v1.18.4
|
||||
github.com/prometheus/prometheus v0.309.1
|
||||
github.com/googleapis/gax-go/v2 v2.21.0
|
||||
github.com/influxdata/influxdb v1.12.3
|
||||
github.com/klauspost/compress v1.18.5
|
||||
github.com/prometheus/prometheus v0.311.1
|
||||
github.com/urfave/cli/v2 v2.27.7
|
||||
github.com/valyala/fastjson v1.6.10
|
||||
github.com/valyala/fastrand v1.1.0
|
||||
@@ -33,44 +33,44 @@ require (
|
||||
github.com/valyala/gozstd v1.24.0
|
||||
github.com/valyala/histogram v1.2.0
|
||||
github.com/valyala/quicktemplate v1.8.0
|
||||
golang.org/x/net v0.51.0
|
||||
golang.org/x/oauth2 v0.35.0
|
||||
golang.org/x/sys v0.41.0
|
||||
google.golang.org/api v0.267.0
|
||||
golang.org/x/net v0.52.0
|
||||
golang.org/x/oauth2 v0.36.0
|
||||
golang.org/x/sys v0.43.0
|
||||
google.golang.org/api v0.275.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
cel.dev/expr v0.25.1 // indirect
|
||||
cloud.google.com/go v0.123.0 // indirect
|
||||
cloud.google.com/go/auth v0.18.2 // indirect
|
||||
cloud.google.com/go/auth v0.20.0 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||
cloud.google.com/go/iam v1.5.3 // indirect
|
||||
cloud.google.com/go/monitoring v1.24.3 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect
|
||||
cloud.google.com/go/iam v1.7.0 // indirect
|
||||
cloud.google.com/go/monitoring v1.25.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.7.1 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.32.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.56.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.56.0 // indirect
|
||||
github.com/VividCortex/ewma v1.2.0 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 // indirect
|
||||
github.com/aws/smithy-go v1.24.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.10 // indirect
|
||||
github.com/aws/smithy-go v1.24.3 // indirect
|
||||
github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
|
||||
@@ -80,9 +80,10 @@ require (
|
||||
github.com/dennwc/varint v1.0.0 // indirect
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.37.0 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.3 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/fatih/color v1.19.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.3 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.9.1 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
|
||||
@@ -90,18 +91,18 @@ require (
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1 // 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.12 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect
|
||||
github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 // indirect
|
||||
github.com/hashicorp/go-version v1.8.0 // indirect
|
||||
github.com/hashicorp/go-version v1.9.0 // indirect
|
||||
github.com/jpillora/backoff v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/knadh/koanf/maps v0.1.2 // indirect
|
||||
github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
|
||||
github.com/knadh/koanf/v2 v2.3.2 // indirect
|
||||
github.com/knadh/koanf/v2 v2.3.4 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.20 // indirect
|
||||
github.com/mattn/go-isatty v0.0.21 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.23 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
@@ -109,64 +110,71 @@ require (
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||
github.com/oklog/ulid/v2 v2.1.1 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.146.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.146.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.146.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.149.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.149.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.149.0 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.23.2 // indirect
|
||||
github.com/prometheus/client_golang/exp v0.0.0-20260211201220-bf37be4fecc0 // indirect
|
||||
github.com/prometheus/client_golang/exp v0.0.0-20260408213824-a4984284cf47 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.67.5 // indirect
|
||||
github.com/prometheus/otlptranslator v1.0.0 // indirect
|
||||
github.com/prometheus/procfs v0.19.2 // indirect
|
||||
github.com/prometheus/procfs v0.20.1 // indirect
|
||||
github.com/prometheus/sigv4 v0.4.1 // indirect
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
|
||||
github.com/puzpuzpuz/xsync/v4 v4.4.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect
|
||||
github.com/stretchr/testify v1.11.1 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/collector/component v1.52.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap v1.52.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.146.1 // indirect
|
||||
go.opentelemetry.io/collector/consumer v1.52.0 // indirect
|
||||
go.opentelemetry.io/collector/featuregate v1.52.0 // indirect
|
||||
go.opentelemetry.io/collector/internal/componentalias v0.146.1 // indirect
|
||||
go.opentelemetry.io/collector/pdata v1.52.0 // indirect
|
||||
go.opentelemetry.io/collector/pipeline v1.52.0 // indirect
|
||||
go.opentelemetry.io/collector/processor v1.52.0 // indirect
|
||||
go.opentelemetry.io/collector/semconv v0.128.0 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.40.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.65.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect
|
||||
go.opentelemetry.io/otel v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.40.0 // indirect
|
||||
go.opentelemetry.io/collector/component v1.55.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap v1.55.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.149.0 // indirect
|
||||
go.opentelemetry.io/collector/consumer v1.55.0 // indirect
|
||||
go.opentelemetry.io/collector/featuregate v1.55.0 // indirect
|
||||
go.opentelemetry.io/collector/internal/componentalias v0.149.0 // indirect
|
||||
go.opentelemetry.io/collector/pdata v1.55.0 // indirect
|
||||
go.opentelemetry.io/collector/pipeline v1.55.0 // indirect
|
||||
go.opentelemetry.io/collector/processor v1.55.0 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.43.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.68.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.68.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 // indirect
|
||||
go.opentelemetry.io/otel v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.43.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/goleak v1.3.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.1 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.4 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/crypto v0.48.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
golang.org/x/time v0.14.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d // indirect
|
||||
google.golang.org/grpc v1.79.3 // indirect
|
||||
golang.org/x/crypto v0.49.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/term v0.41.0 // indirect
|
||||
golang.org/x/text v0.35.0 // indirect
|
||||
golang.org/x/time v0.15.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20260406210006-6f92a3bedf2d // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260406210006-6f92a3bedf2d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d // indirect
|
||||
google.golang.org/grpc v1.80.0 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apimachinery v0.35.1 // indirect
|
||||
k8s.io/client-go v0.35.1 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect
|
||||
k8s.io/apimachinery v0.35.3 // indirect
|
||||
k8s.io/client-go v0.35.3 // indirect
|
||||
k8s.io/klog/v2 v2.140.0 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20260330154417-16be699c7b31 // indirect
|
||||
k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect
|
||||
sigs.k8s.io/yaml v1.6.0 // indirect
|
||||
)
|
||||
|
||||
533
go.sum
@@ -2,32 +2,32 @@ cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=
|
||||
cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=
|
||||
cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
|
||||
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
|
||||
cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM=
|
||||
cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M=
|
||||
cloud.google.com/go/auth v0.20.0 h1:kXTssoVb4azsVDoUiF8KvxAqrsQcQtB53DcSgta74CA=
|
||||
cloud.google.com/go/auth v0.20.0/go.mod h1:942/yi/itH1SsmpyrbnTMDgGfdy2BUqIKyd0cyYLc5Q=
|
||||
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.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
||||
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
|
||||
cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc=
|
||||
cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU=
|
||||
cloud.google.com/go/logging v1.13.2 h1:qqlHCBvieJT9Cdq4QqYx1KPadCQ2noD4FK02eNqHAjA=
|
||||
cloud.google.com/go/logging v1.13.2/go.mod h1:zaybliM3yun1J8mU2dVQ1/qDzjbOqEijZCn6hSBtKak=
|
||||
cloud.google.com/go/longrunning v0.8.0 h1:LiKK77J3bx5gDLi4SMViHixjD2ohlkwBi+mKA7EhfW8=
|
||||
cloud.google.com/go/longrunning v0.8.0/go.mod h1:UmErU2Onzi+fKDg2gR7dusz11Pe26aknR4kHmJJqIfk=
|
||||
cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhOdsgaE=
|
||||
cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
|
||||
cloud.google.com/go/storage v1.60.0 h1:oBfZrSOCimggVNz9Y/bXY35uUcts7OViubeddTTVzQ8=
|
||||
cloud.google.com/go/storage v1.60.0/go.mod h1:q+5196hXfejkctrnx+VYU8RKQr/L3c0cBIlrjmiAKE0=
|
||||
cloud.google.com/go/trace v1.11.7 h1:kDNDX8JkaAG3R2nq1lIdkb7FCSi1rCmsEtKVsty7p+U=
|
||||
cloud.google.com/go/trace v1.11.7/go.mod h1:TNn9d5V3fQVf6s4SCveVMIBS2LJUqo73GACmq/Tky0s=
|
||||
cloud.google.com/go/iam v1.7.0 h1:JD3zh0C6LHl16aCn5Akff0+GELdp1+4hmh6ndoFLl8U=
|
||||
cloud.google.com/go/iam v1.7.0/go.mod h1:tetWZW1PD/m6vcuY2Zj/aU0eCHNPuxedbnbRTyKXvdY=
|
||||
cloud.google.com/go/logging v1.14.0 h1:xpPpY8cVT6n9DgIRgrWyE+YEsGlO/994pWnbc7o5Eh4=
|
||||
cloud.google.com/go/logging v1.14.0/go.mod h1:jmI+Try/fZeOTOAer3wVYOuPf9WX9PyzhlSDoBAi4HM=
|
||||
cloud.google.com/go/longrunning v0.9.0 h1:0EzbDEGsAvOZNbqXopgniY0w0a1phvu5IdUFq8grmqY=
|
||||
cloud.google.com/go/longrunning v0.9.0/go.mod h1:pkTz846W7bF4o2SzdWJ40Hu0Re+UoNT6Q5t+igIcb8E=
|
||||
cloud.google.com/go/monitoring v1.25.0 h1:HnsTIOxTN6BCSkt1P/Im23r1m7MHTTpmSYCzPkW7NK4=
|
||||
cloud.google.com/go/monitoring v1.25.0/go.mod h1:wlj6rX+JGyusw/8+2duW4cJ6kmDHGmde3zMTJuG3Jpc=
|
||||
cloud.google.com/go/storage v1.62.0 h1:w2pQJhpUqVerMON45vatE2FpCYsNTf7OHjkn6ux5mMU=
|
||||
cloud.google.com/go/storage v1.62.0/go.mod h1:T5hz3qzcpnxZ5LdKc7y8Tw7lh4v9zeeVyrD/cLJAzZU=
|
||||
cloud.google.com/go/trace v1.12.0 h1:XvWHYfr9q88cX4pZyou6qCcSagnuASyUq2ej1dB6NzQ=
|
||||
cloud.google.com/go/trace v1.12.0/go.mod h1:TOYfyeoyCGsSH0ifXD6Aius24uQI9xV3RyvOdljFIyg=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 h1:fou+2+WFTib47nS+nz/ozhEBnvU96bKHy6LjRsY4E28=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0/go.mod h1:t76Ruy8AHvUAC8GfMWJMa0ElSbuIcO03NLpynfbgsPA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 h1:fhqpLE3UEXi9lPaBRpQ6XuRW0nU7hgg4zlmZZa+a9q4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0/go.mod h1:7dCRMLwisfRH3dBupKeNCioWYUZ4SS09Z14H+7i8ZoY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 h1:LkHbJbgF3YyvC53aqYGR+wWQDn2Rdp9AQdGndf9QvY4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0/go.mod h1:QyiQdW4f4/BIfB8ZutZ2s+28RAgfa/pT+zS++ZHyM1I=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 h1:bXwSugBiSbgtz7rOtbfGf+woewp4f06orW9OP5BjHLA=
|
||||
@@ -38,18 +38,18 @@ github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.4 h1:jWQK1GI+LeGGUKBAD
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.4/go.mod h1:8mwH4klAm9DUgR2EEHyEEAQlRDvLPyg5fQry3y+cDew=
|
||||
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
|
||||
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgvJqCH0sFfrBUTnUJSBrBf7++ypk+twtRs=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.7.1 h1:edShSHV3DV90+kt+CMaEXEzR9QF7wFrPJxVGz2blMIU=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.7.1/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=
|
||||
github.com/Code-Hex/go-generics-cache v1.5.1 h1:6vhZGc5M7Y/YD8cIUcY8kcuQLB4cHR7U+0KMqAA0KcU=
|
||||
github.com/Code-Hex/go-generics-cache v1.5.1/go.mod h1:qxcC9kRVrct9rHeiYpFWSoW1vxyillCVzX13KZG8dl4=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 h1:UnDZ/zFfG1JhH/DqxIZYU/1CUAlTUScoXD/LcM2Ykk8=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0/go.mod h1:IA1C1U7jO/ENqm/vhi7V9YYpBsp+IMyqNrEN94N7tVc=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0 h1:7t/qx5Ost0s0wbA/VDrByOooURhp+ikYwv20i9Y07TQ=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0/go.mod h1:vB2GH9GAYYJTO3mEn8oYwzEdhlayZIdQz6zdzgUIRvA=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 h1:0s6TxfCu2KHkkZPnBfsQ2y5qia0jl3MMrmBhu3nCOYk=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.32.0 h1:rIkQfkCOVKc1OiRCNcSDD8ml5RJlZbH/Xsq7lbpynwc=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.32.0/go.mod h1:RD2SsorTmYhF6HkTmDw7KmPYQk8OBYwTkuasChwv7R4=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.56.0 h1:O2sXMyJh8b7devAGdE+163xtRurt0RVpB6DIzX5vGfg=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.56.0/go.mod h1:hEpiGU18xf70qb3jbTcIggWAiEfX/cOIVc2OTe4OegA=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.56.0 h1:ZIT85vKP7LBS84XJ0WdJ3dPOX3iz4j3c0+lpajGQMyo=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.56.0/go.mod h1:rqP9UEhOXv9WhQ7Gjz+G5y/pf8+BJZW5/Ts0AhE0PwE=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.56.0 h1:0YP0+/ixwu+Uqeu/FGiBZNQ19huiUxxiPXIc9WsLKuQ=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.56.0/go.mod h1:6ZZMQhZKDvUvkJw2rc+oDP90tMMzuU/J+5HG1ZmPOmE=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/VictoriaMetrics/VictoriaLogs v0.0.0-20260218111324-95b48d57d032 h1:kKVeXC+HAcMeMLefoKCWf934y9MoLU8V3Da7k6WP4K8=
|
||||
@@ -70,52 +70,58 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah
|
||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
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/aws/aws-sdk-go-v2 v1.41.1 h1:ABlyEARCDLN034NhxlRUSZr4l71mh+T5KAeGh6cerhU=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 h1:489krEF9xIGkOaaX3CE/Be2uWjiXrkCH6gUX+bZA/BU=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4/go.mod h1:IOAPF6oT9KCsceNTvvYMNHy0+kMF8akOjeDvPENWxp4=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.8 h1:iu+64gwDKEoKnyTQskSku72dAwggKI5sV6rNvgSMpMs=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.8/go.mod h1:MI2XvA+qDi3i9AJxX1E2fu730syEBzp/jnXrjxuHwgI=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.8 h1:Jp2JYH1lRT3KhX4mshHPvVYsR5qqRec3hGvEarNYoR0=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.8/go.mod h1:fZG9tuvyVfxknv1rKibIz3DobRaFw1Poe8IKtXB3XYY=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 h1:I0GyV8wiYrP8XpA70g1HBcQO1JlQxCMTW9npl5UbDHY=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17/go.mod h1:tyw7BOl5bBe/oqvoIeECFJjMdzXoa/dfVz3QQ5lgHGA=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.22.1 h1:IbWiN670htmBioc+Zj32vSpJgQ2+OYSlvTvfQ1nCORQ=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.22.1/go.mod h1:tw/B596EUhBWDFGdDGuLC21fVU4A3s4/5Efy8S39W18=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 h1:xOLELNKGp2vsiteLsvLPwxC+mYmO6OZ8PYgiuPJzF8U=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17/go.mod h1:5M5CI3D12dNOtH3/mk6minaRwI2/37ifCURZISxA/IQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 h1:WWLqlh79iO48yLkj1v3ISRNiv+3KdQoZ6JWyfcsyQik=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17/go.mod h1:EhG22vHRrvF8oXSTYStZhJc1aUgKtnJe+aOiFEV90cM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17 h1:JqcdRG//czea7Ppjb+g/n4o8i/R50aTBHkA7vu0lK+k=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17/go.mod h1:CO+WeGmIdj/MlPel2KwID9Gt7CNq4M65HUfBW97liM0=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.277.0 h1:RHJSkRXDGkAKrV4CTEsZsZkOmSpxXKO4aKx4rXd94K4=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.277.0/go.mod h1:Wg68QRgy2gEGGdmTPU/UbVpdv8sM14bUZmF64KFwAsY=
|
||||
github.com/aws/aws-sdk-go-v2/service/ecs v1.69.5 h1:5nkhwt0d/gjuT3AQ2LUK0aFRNB3MGlzB2elqy/ZsKP4=
|
||||
github.com/aws/aws-sdk-go-v2/service/ecs v1.69.5/go.mod h1:LQMlcWBoiFVD3vUVEz42ST0yTiaDujv2dRE6sXt1yPE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8 h1:Z5EiPIzXKewUQK0QTMkutjiaPVeVYXX7KIqhXu/0fXs=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8/go.mod h1:FsTpJtvC4U1fyDXk7c71XoDv3HlRm8V3NiYLeYLh5YE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 h1:RuNSMoozM8oXlgLG/n6WLaFGoea7/CddrCfIiSA+xdY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17/go.mod h1:F2xxQ9TZz5gDWsclCtPQscGpP0VUOc8RqgFM3vDENmU=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17 h1:bGeHBsGZx0Dvu/eJC0Lh9adJa3M1xREcndxLNZlve2U=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17/go.mod h1:dcW24lbU0CzHusTE8LLHhRLI42ejmINN8Lcr22bwh/g=
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.10 h1:MQuZZ6Tq1qQabPlkVxrCMdyVl70Ogl4AERZKo+y9Wzo=
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.10/go.mod h1:U5C3JME1ibKESmpzBAqlRpTYZfVbTqrb5ICJm+sVVd8=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.0 h1:oeu8VPlOre74lBA/PMhxa5vewaMIMmILM+RraSyB8KA=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.0/go.mod h1:5jggDlZ2CLQhwJBiZJb4vfk4f0GxWdEDruWKEJ1xOdo=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 h1:VrhDvQib/i0lxvr3zqlUwLwJP4fpmpyD9wYG1vfSu+Y=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5/go.mod h1:k029+U8SY30/3/ras4G/Fnv/b88N4mAfliNn08Dem4M=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 h1:v6EiMvhEYBoHABfbGB4alOYmCIrcgyPPiBE1wZAEbqk=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9/go.mod h1:yifAsgBxgJWn3ggx70A3urX2AN49Y5sJTD1UQFlfqBw=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.14 h1:0jbJeuEHlwKJ9PfXtpSFc4MF+WIWORdhN1n30ITZGFM=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.14/go.mod h1:sTGThjphYE4Ohw8vJiRStAcu3rbjtXRsdNB0TvZ5wwo=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 h1:5fFjR/ToSOzB2OQ/XqWpZBmNvmP/pJ1jOWYlFDJTjRQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6/go.mod h1:qgFDZQSD/Kys7nJnVqYlWKnh0SSdMjAi0uSwON4wgYQ=
|
||||
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
|
||||
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 h1:eBMB84YGghSocM7PsjmmPffTa+1FBUeNvGvFou6V/4o=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8/go.mod h1:lyw7GFp3qENLh7kwzf7iMzAxDn+NzjXEAGjKS2UOKqI=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.14 h1:opVIRo/ZbbI8OIqSOKmpFaY7IwfFUOCCXBsUpJOwDdI=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.14/go.mod h1:U4/V0uKxh0Tl5sxmCBZ3AecYny4UNlVmObYjKuuaiOo=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.14 h1:n+UcGWAIZHkXzYt87uMFBv/l8THYELoX6gVcUvgl6fI=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.14/go.mod h1:cJKuyWB59Mqi0jM3nFYQRmnHVQIcgoxjEMAbLkpr62w=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21 h1:NUS3K4BTDArQqNu2ih7yeDLaS3bmHD0YndtA6UP884g=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21/go.mod h1:YWNWJQNjKigKY1RHVJCuupeWDrrHjRqHm0N9rdrWzYI=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.22.13 h1:uMC4oL6G3MNhodo358QEqSDjrgvzV3TUQ58nyQSGq2E=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.22.13/go.mod h1:Cer86AE2686DvVUe57LPve3jUBmbujuaonSX8pNzGgw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 h1:Rgg6wvjjtX8bNHcvi9OnXWwcE0a2vGpbwmtICOsvcf4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21/go.mod h1:A/kJFst/nm//cyqonihbdpQZwiUhhzpqTsdbhDdRF9c=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 h1:PEgGVtPoB6NTpPrBgqSE5hE/o47Ij9qk/SEZFbUOe9A=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21/go.mod h1:p+hz+PRAYlY3zcpJhPwXlLC4C+kqn70WIHwnzAfs6ps=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 h1:rWyie/PxDRIdhNf4DzRk0lvjVOqFJuNnO8WwaIRVxzQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22/go.mod h1:zd/JsJ4P7oGfUhXn1VyLqaRZwPmZwg44Jf2dS84Dm3Y=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.296.0 h1:98Miqj16un1WLNyM1RjVDhXYumhqZrQfAeG8i4jPG6o=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.296.0/go.mod h1:T6ndRfdhnXLIY5oKBHjYZDVj706los2zGdpThppquvA=
|
||||
github.com/aws/aws-sdk-go-v2/service/ecs v1.74.0 h1:YS5TXaEvzDb+sV+wdQFUtuCAk0GeFR9Ai6HFdxpz6q8=
|
||||
github.com/aws/aws-sdk-go-v2/service/ecs v1.74.0/go.mod h1:10kBgdaNJz0FO/+JWDUH+0rtSjkn5yafgavDDmmhFzs=
|
||||
github.com/aws/aws-sdk-go-v2/service/elasticache v1.51.12 h1:S066ajzfPRCSW4lsSHOYglne6SNi2CHt1u5omzW1RBg=
|
||||
github.com/aws/aws-sdk-go-v2/service/elasticache v1.51.12/go.mod h1:86SE4NcXxbxr8KTG3yOyDmd4HyiFmKl8TexXnhYJ+Bw=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 h1:JRaIgADQS/U6uXDqlPiefP32yXTda7Kqfx+LgspooZM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13/go.mod h1:CEuVn5WqOMilYl+tbccq8+N2ieCy0gVn3OtRb0vBNNM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 h1:c31//R3xgIJMSC8S6hEVq+38DcvUlgFY0FM6mSI5oto=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21/go.mod h1:r6+pf23ouCB718FUxaqzZdbpYFyDtehyZcmP5KL9FkA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 h1:ZlvrNcHSFFWURB8avufQq9gFsheUgjVD9536obIknfM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21/go.mod h1:cv3TNhVrssKR0O/xxLJVRfd2oazSnZnkUeTf6ctUwfQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/kafka v1.49.1 h1:BgBatWcQIFqF1l6KGHjv66V0d/ISnWrTwxDx/Jf6EJM=
|
||||
github.com/aws/aws-sdk-go-v2/service/kafka v1.49.1/go.mod h1:pMpys+PlrN//vj8j5s0oOAMJjauj81VkHzIZxPVWOro=
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.51.0 h1:cg6PxzoIide2wiEyLfikOFN+XwHafwR8p5+L9U1E8dQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.51.0/go.mod h1:YvX7hjUWecrKX8fBkbEncyddEW85xjNH+u5JHioITOw=
|
||||
github.com/aws/aws-sdk-go-v2/service/rds v1.117.0 h1:T1Xe9sYxSUUQOvd1RsFeVk/IXFPdqSiN0atXu/Hy/8A=
|
||||
github.com/aws/aws-sdk-go-v2/service/rds v1.117.0/go.mod h1:QbXW4coAMakHQhf1qhE0eVVCen9gwB/Kvn+HHHKhpGY=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.99.0 h1:hlSuz394kV0vhv9drL5lhuEFbEOEP1VyQpy15qWh1Pk=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.99.0/go.mod h1:uoA43SdFwacedBfSgfFSjjCvYe8aYBS7EnU5GZ/YKMM=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.9 h1:QKZH0S178gCmFEgst8hN0mCX1KxLgHBKKY/CLqwP8lg=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.9/go.mod h1:7yuQJoT+OoH8aqIxw9vwF+8KpvLZ8AWmvmUWHsGQZvI=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.15 h1:lFd1+ZSEYJZYvv9d6kXzhkZu07si3f+GQ1AaYwa2LUM=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.15/go.mod h1:WSvS1NLr7JaPunCXqpJnWk1Bjo7IxzZXrZi1QQCkuqM=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19 h1:dzztQ1YmfPrxdrOiuZRMF6fuOwWlWpD2StNLTceKpys=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19/go.mod h1:YO8TrYtFdl5w/4vmjL8zaBSsiNp3w0L1FfKVKenZT7w=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.10 h1:p8ogvvLugcR/zLBXTXrTkj0RYBUdErbMnAFFp12Lm/U=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.10/go.mod h1:60dv0eZJfeVXfbT1tFJinbHrDfSJ2GZl4Q//OSSNAVw=
|
||||
github.com/aws/smithy-go v1.24.3 h1:XgOAaUgx+HhVBoP4v8n6HCQoTRDhoMghKqw4LNHsDNg=
|
||||
github.com/aws/smithy-go v1.24.3/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
|
||||
github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 h1:6df1vn4bBlDDo4tARvBm7l6KA9iVMnE3NWizDeWSrps=
|
||||
github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3/go.mod h1:CIWtjkly68+yqLPbvwwR/fjNJA/idrtULjZWh2v1ys0=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
@@ -142,14 +148,14 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE=
|
||||
github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA=
|
||||
github.com/digitalocean/godo v1.171.0 h1:QwpkwWKr3v7yxc8D4NQG973NoR9APCEWjYnLOQeXVpQ=
|
||||
github.com/digitalocean/godo v1.171.0/go.mod h1:xQsWpVCCbkDrWisHA72hPzPlnC+4W5w/McZY5ij9uvU=
|
||||
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
|
||||
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/digitalocean/godo v1.178.0 h1:+B4xGOaoFwwwpM7TKhoyGHdmFg5eF9zDB1YfOLvNJ2E=
|
||||
github.com/digitalocean/godo v1.178.0/go.mod h1:xQsWpVCCbkDrWisHA72hPzPlnC+4W5w/McZY5ij9uvU=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=
|
||||
github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
|
||||
github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/edsrzf/mmap-go v1.2.0 h1:hXLYlkbaPzt1SaQk+anYwKSRNhufIDCchSPkUD6dD84=
|
||||
@@ -166,25 +172,25 @@ github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMD
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0=
|
||||
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM=
|
||||
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
|
||||
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
|
||||
github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
||||
github.com/fxamacker/cbor/v2 v2.9.1 h1:2rWm8B193Ll4VdjsJY28jxs70IdDsHRWgQYAI80+rMQ=
|
||||
github.com/fxamacker/cbor/v2 v2.9.1/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
|
||||
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk=
|
||||
github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM=
|
||||
github.com/go-openapi/jsonreference v0.21.3 h1:96Dn+MRPa0nYAR8DR1E03SblB5FJvh7W6krPI0Z7qMc=
|
||||
github.com/go-openapi/jsonreference v0.21.3/go.mod h1:RqkUP0MrLf37HqxZxrIAtTWW4ZJIK1VzduhXYBEeGc4=
|
||||
github.com/go-openapi/jsonpointer v0.22.5 h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA=
|
||||
github.com/go-openapi/jsonpointer v0.22.5/go.mod h1:gyUR3sCvGSWchA2sUBJGluYMbe1zazrYWIkWPjjMUY0=
|
||||
github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8=
|
||||
github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4=
|
||||
github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU=
|
||||
github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ=
|
||||
github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4=
|
||||
@@ -193,8 +199,8 @@ github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjf
|
||||
github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU=
|
||||
github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y=
|
||||
github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk=
|
||||
github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI=
|
||||
github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag=
|
||||
github.com/go-openapi/swag/jsonname v0.25.5 h1:8p150i44rv/Drip4vWI3kGi9+4W9TdI3US3uUYSFhSo=
|
||||
github.com/go-openapi/swag/jsonname v0.25.5/go.mod h1:jNqqikyiAK56uS7n8sLkdaNY/uq6+D2m2LANat09pKU=
|
||||
github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA=
|
||||
github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY=
|
||||
github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s=
|
||||
@@ -209,8 +215,8 @@ github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv4
|
||||
github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE=
|
||||
github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw=
|
||||
github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc=
|
||||
github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4=
|
||||
github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA=
|
||||
github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk=
|
||||
github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/go-zookeeper/zk v1.0.4 h1:DPzxraQx7OrPyXq2phlGlNSIyWEsAox0RJmjTseMV6I=
|
||||
@@ -229,8 +235,8 @@ github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnL
|
||||
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
||||
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/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0=
|
||||
github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU=
|
||||
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=
|
||||
@@ -238,12 +244,12 @@ 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.12 h1:Fg+zsqzYEs1ZnvmcztTYxhgCBsx3eEhEwQ1W/lHq/sQ=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.12/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg=
|
||||
github.com/googleapis/gax-go/v2 v2.17.0 h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc=
|
||||
github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY=
|
||||
github.com/gophercloud/gophercloud/v2 v2.9.0 h1:Y9OMrwKF9EDERcHFSOTpf/6XGoAI0yOxmsLmQki4LPM=
|
||||
github.com/gophercloud/gophercloud/v2 v2.9.0/go.mod h1:Ki/ILhYZr/5EPebrPL9Ej+tUg4lqx71/YH2JWVeU+Qk=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.14 h1:yh8ncqsbUY4shRD5dA6RlzjJaT4hi3kII+zYw8wmLb8=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg=
|
||||
github.com/googleapis/gax-go/v2 v2.21.0 h1:h45NjjzEO3faG9Lg/cFrBh2PgegVVgzqKzuZl/wMbiI=
|
||||
github.com/googleapis/gax-go/v2 v2.21.0/go.mod h1:But/NJU6TnZsrLai/xBAQLLz+Hc7fHZJt/hsCz3Fih4=
|
||||
github.com/gophercloud/gophercloud/v2 v2.11.1 h1:jCs4vLH8sJgRqrPzqVfWgl7uI6JnIIlsgeIRM0uHjxY=
|
||||
github.com/gophercloud/gophercloud/v2 v2.11.1/go.mod h1:Rm0YvKQ4QYX2rY9XaDKnjRzSGwlG5ge4h6ABYnmkKQM=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||
github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 h1:cLN4IBkmkYZNnk7EAJ0BHIethd+J6LqxFNw5mSiI2bM=
|
||||
@@ -262,24 +268,24 @@ github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJ
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
|
||||
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
|
||||
github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4=
|
||||
github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA=
|
||||
github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4=
|
||||
github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/nomad/api v0.0.0-20251216171439-1dee0671280e h1:wGl06iy/H90NSbWjfXWeRwk9SJOks0u4voIryeJFlSA=
|
||||
github.com/hashicorp/nomad/api v0.0.0-20251216171439-1dee0671280e/go.mod h1:sldFTIgs+FsUeKU3LwVjviAIuksxD8TzDOn02MYwslE=
|
||||
github.com/hashicorp/nomad/api v0.0.0-20260324203407-b27b0c2e019a h1:HGwfgBNl90YBiHdbzZ/+8aMxO1UL9B/yNTAXa8iB8z8=
|
||||
github.com/hashicorp/nomad/api v0.0.0-20260324203407-b27b0c2e019a/go.mod h1:KkLNLU0Nyfh5jWsFoF/PsmMbKpRIAoIV4lmQoJWgKCk=
|
||||
github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
|
||||
github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
|
||||
github.com/hetznercloud/hcloud-go/v2 v2.32.0 h1:BRe+k7ESdYv3xQLBGdKUfk+XBFRJNGKzq70nJI24ciM=
|
||||
github.com/hetznercloud/hcloud-go/v2 v2.32.0/go.mod h1:hAanyyfn9M0cMmZ68CXzPCF54KRb9EXd8eiE2FHKGIE=
|
||||
github.com/influxdata/influxdb v1.12.2 h1:Y0ZBu47gYVbDCRPMFOrlRRZ3grdqPGIJxerFysVSq+g=
|
||||
github.com/influxdata/influxdb v1.12.2/go.mod h1:EwqFMB6GKV0Huug82Msa5f8QfXhqETUmC4L9A0QZJQM=
|
||||
github.com/ionos-cloud/sdk-go/v6 v6.3.5 h1:6fHArdV1lf50iRhCkCP7wkvGwWzVwi+l9w1t5mwkOa8=
|
||||
github.com/ionos-cloud/sdk-go/v6 v6.3.5/go.mod h1:nUGHP4kZHAZngCVr4v6C8nuargFrtvt7GrzH/hqn7c4=
|
||||
github.com/hetznercloud/hcloud-go/v2 v2.36.0 h1:HlLL/aaVXUulqe+rsjoJmrxKhPi1MflL5O9iq5QEtvo=
|
||||
github.com/hetznercloud/hcloud-go/v2 v2.36.0/go.mod h1:MnN/QJEa/RYNQiiVoJjNHPntM7Z1wlYPgJ2HA40/cDE=
|
||||
github.com/influxdata/influxdb v1.12.3 h1:nrqbOazMNQt969yQ7fXepY9hvy7xyg+efN1eb0bihfg=
|
||||
github.com/influxdata/influxdb v1.12.3/go.mod h1:czsGl4TCm2kWtzEHsGh74Nye77o/KgmKsLtF4/L9QVc=
|
||||
github.com/ionos-cloud/sdk-go/v6 v6.3.6 h1:l/TtKgdQ1wUH3DDe2SfFD78AW+TJWdEbDpQhHkWd6CM=
|
||||
github.com/ionos-cloud/sdk-go/v6 v6.3.6/go.mod h1:nUGHP4kZHAZngCVr4v6C8nuargFrtvt7GrzH/hqn7c4=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
@@ -288,14 +294,14 @@ github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRt
|
||||
github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k=
|
||||
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.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
|
||||
github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
|
||||
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
|
||||
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||
github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo=
|
||||
github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
|
||||
github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE=
|
||||
github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A=
|
||||
github.com/knadh/koanf/v2 v2.3.2 h1:Ee6tuzQYFwcZXQpc2MiVeC6qHMandf5SMUJJNoFp/c4=
|
||||
github.com/knadh/koanf/v2 v2.3.2/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28=
|
||||
github.com/knadh/koanf/v2 v2.3.4 h1:fnynNSDlujWE+v83hAp8wKr/cdoxHLO0629SN+U8Urc=
|
||||
github.com/knadh/koanf/v2 v2.3.4/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28=
|
||||
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00=
|
||||
github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
@@ -304,16 +310,16 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/linode/linodego v1.63.0 h1:MdjizfXNJDVJU6ggoJmMO5O9h4KGPGivNX0fzrAnstk=
|
||||
github.com/linode/linodego v1.63.0/go.mod h1:GoiwLVuLdBQcAebxAVKVL3mMYUgJZR/puOUSla04xBE=
|
||||
github.com/linode/linodego v1.66.0 h1:rK8QJFaV53LWOEJvb/evhTg/dP5ElvtuZmx4iv4RJds=
|
||||
github.com/linode/linodego v1.66.0/go.mod h1:12ykGs9qsvxE+OU3SXuW2w+DTruWF35FPlXC7gGk2tU=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.20 h1:WcT52H91ZUAwy8+HUkdM3THM6gXqXuLJi9O3rjcQQaQ=
|
||||
github.com/mattn/go-runewidth v0.0.20/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
|
||||
github.com/miekg/dns v1.1.69 h1:Kb7Y/1Jo+SG+a2GtfoFUfDkG//csdRPwRLkCsxDG9Sc=
|
||||
github.com/miekg/dns v1.1.69/go.mod h1:7OyjD9nEba5OkqQ/hB4fy3PIoxafSZJtducccIelz3g=
|
||||
github.com/mattn/go-isatty v0.0.21 h1:xYae+lCNBP7QuW4PUnNG61ffM4hVIfm+zUzDuSzYLGs=
|
||||
github.com/mattn/go-isatty v0.0.21/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
|
||||
github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw=
|
||||
github.com/mattn/go-runewidth v0.0.23/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
|
||||
github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI=
|
||||
github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
@@ -336,16 +342,16 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s=
|
||||
github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.146.0 h1:ggrxN//EQOeG0dXw6iKnKG5E84om3z68DxSZNh3bSjE=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.146.0/go.mod h1:douArNQN+Tl1f5uFRC4HZxmcIXDLYUNnI82PodFInRo=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.146.0 h1:4ECxx5C6LLZaLUfNApaw/bC/AxxBIewns2MvgalKxH0=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.146.0/go.mod h1:AFhMSPTpRw83Pmlbym0tMJK3gsRmpXKbWuFNwRtBqjw=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.146.0 h1:MgPBUx3AgY3CrTr2y8hFi4HYOV06SW4fsetuExztsT0=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.146.0/go.mod h1:co1v8pBSgMyGWZDL79JhqpFND39Q4MZGo00ymF4W5Mo=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.149.0 h1:Zovdium/2408dqJzSxA5XebZBxGBnDkfrai1HKT5Omc=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.149.0/go.mod h1:ughjuka9JQd81X6we9PmdvaiIjeOWtKK04BladDtzZc=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.149.0 h1:OZKthV+cLQO5MCFhBQme3AveZ5vorqaFwb0Qn8jvSQQ=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.149.0/go.mod h1:eB74l+/1nW5tofwCjD5TKRqHFYnBSWo0j0xWD8BHYuE=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.149.0 h1:4QJFwu4guYeLNnlHLYWJQx8Dps6ii1rwjE9B9dekYdY=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.149.0/go.mod h1:K/+3geevCDJiJew7MuQU481B9JNlc7eLEFv4t59WGRM=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||
github.com/ovh/go-ovh v1.9.0 h1:6K8VoL3BYjVV3In9tPJUdT7qMx9h0GExN9EXx1r2kKE=
|
||||
github.com/ovh/go-ovh v1.9.0/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c=
|
||||
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
|
||||
@@ -360,34 +366,34 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
|
||||
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
|
||||
github.com/prometheus/client_golang/exp v0.0.0-20260211201220-bf37be4fecc0 h1:6s5oJJll5QWZe/yKYhnW9eg6BWaOshBhqpk6SgMpyhc=
|
||||
github.com/prometheus/client_golang/exp v0.0.0-20260211201220-bf37be4fecc0/go.mod h1:Vf0QcmVhGqpjLxZOaWrFSep86vchQtJmbztFaMM4f6Q=
|
||||
github.com/prometheus/client_golang/exp v0.0.0-20260408213824-a4984284cf47 h1:T3e9v0JkIsRw9GKIw8kumjtPeroVzD44+dqpWzXQD84=
|
||||
github.com/prometheus/client_golang/exp v0.0.0-20260408213824-a4984284cf47/go.mod h1:xA9/W/d/j+zeg2Kp3UgOF+E2rbq7KNVa5PLJPJBE0lw=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
|
||||
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
|
||||
github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos=
|
||||
github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM=
|
||||
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
|
||||
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
|
||||
github.com/prometheus/prometheus v0.309.1 h1:jutK6eCYDpWdPTUbVbkcQsNCMO9CCkSwjQRMLds4jSo=
|
||||
github.com/prometheus/prometheus v0.309.1/go.mod h1:d+dOGiVhuNDa4MaFXHVdnUBy/CzqlcNTooR8oM1wdTU=
|
||||
github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
|
||||
github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
|
||||
github.com/prometheus/prometheus v0.311.1 h1:15uKGfULPFWIIvrY46PiqyaXTHU+4HO3c/SFz7Z1sEY=
|
||||
github.com/prometheus/prometheus v0.311.1/go.mod h1:gjsCxTKtHO1Q8T9333u1s+lUR1OjPyM7ruuGH8RvVyo=
|
||||
github.com/prometheus/sigv4 v0.4.1 h1:EIc3j+8NBea9u1iV6O5ZAN8uvPq2xOIUPcqCTivHuXs=
|
||||
github.com/prometheus/sigv4 v0.4.1/go.mod h1:eu+ZbRvsc5TPiHwqh77OWuCnWK73IdkETYY46P4dXOU=
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg=
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
|
||||
github.com/puzpuzpuz/xsync/v4 v4.4.0 h1:vlSN6/CkEY0pY8KaB0yqo/pCLZvp9nhdbBdjipT4gWo=
|
||||
github.com/puzpuzpuz/xsync/v4 v4.4.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.35 h1:8xfn1RzeI9yoCUuEwDy08F+No6PcKZGEDOQ6hrRyLts=
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.35/go.mod h1:47B1d/YXmSAxlJxUJxClzHR6b3T4M1WyCvwENPQNBWc=
|
||||
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
|
||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36 h1:ObX9hZmK+VmijreZO/8x9pQ8/P/ToHD/bdSb4Eg4tUo=
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36/go.mod h1:LEsDu4BubxK7/cWhtlQWfuxwL4rf/2UEpxXz1o1EMtM=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo=
|
||||
github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs=
|
||||
github.com/stackitcloud/stackit-sdk-go/core v0.20.1 h1:odiuhhRXmxvEvnVTeZSN9u98edvw2Cd3DcnkepncP3M=
|
||||
github.com/stackitcloud/stackit-sdk-go/core v0.20.1/go.mod h1:fqto7M82ynGhEnpZU6VkQKYWYoFG5goC076JWXTUPRQ=
|
||||
github.com/stackitcloud/stackit-sdk-go/core v0.23.0 h1:zPrOhf3Xe47rKRs1fg/AqKYUiJJRYjdcv+3qsS50mEs=
|
||||
github.com/stackitcloud/stackit-sdk-go/core v0.23.0/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@@ -416,8 +422,8 @@ github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OL
|
||||
github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY=
|
||||
github.com/valyala/quicktemplate v1.8.0 h1:zU0tjbIqTRgKQzFY1L42zq0qR3eh4WoQQdIdqCysW5k=
|
||||
github.com/valyala/quicktemplate v1.8.0/go.mod h1:qIqW8/igXt8fdrUln5kOSb+KWMaJ4Y8QUsfd1k6L2jM=
|
||||
github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs=
|
||||
github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI=
|
||||
github.com/vultr/govultr/v3 v3.28.1 h1:KR3LhppYARlBujY7+dcrE7YKL0Yo9qXL+msxykKQrLI=
|
||||
github.com/vultr/govultr/v3 v3.28.1/go.mod h1:2zyUw9yADQaGwKnwDesmIOlBNLrm7edsCfWHFJpWKf8=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 h1:FnBeRrxr7OU4VvAzt5X7s6266i6cSVkkFPS0TuXWbIg=
|
||||
@@ -426,70 +432,68 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
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/collector/component v1.52.0 h1:RYk1KTz8g+tU9mcYGz2gXJJDS8A9NJv2lta3JoWSZXg=
|
||||
go.opentelemetry.io/collector/component v1.52.0/go.mod h1:7ZgH6qsvUDSIk3JuZfxPv2qHeeUz3Y6znAWGdtp1r78=
|
||||
go.opentelemetry.io/collector/component/componentstatus v0.146.1 h1:91kcSsNFFQh6SjAf5tfGqW+pmOe5Sjppyo3ixpMzBK0=
|
||||
go.opentelemetry.io/collector/component/componentstatus v0.146.1/go.mod h1:L//+E5/RLWvRgFcxH8YWJkgtuAhWuOZAi0bP8ffpQYs=
|
||||
go.opentelemetry.io/collector/component/componenttest v0.146.1 h1:biVtrJfjLJD22RS5qiDVjupn/yNRrlxok/e1K3j7TgQ=
|
||||
go.opentelemetry.io/collector/component/componenttest v0.146.1/go.mod h1:cxbQHpKuqAFbX8jFTVcMBvhzINX9TmsuEfi3GFBvvOs=
|
||||
go.opentelemetry.io/collector/confmap v1.52.0 h1:Tp2csSqXyYy42r3OHxHSAg0aGCSQH7J6+EwCt4Kg4vo=
|
||||
go.opentelemetry.io/collector/confmap v1.52.0/go.mod h1:j0oKnokAKoLRpr9IxFL+TfO+1bS65z+BFKk5jyz++2A=
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.146.1 h1:w7svS2W6XNTem+8cOjtj3qX3TcPRcB/GhljRE8Br8NY=
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.146.1/go.mod h1:4IEuoWr9PE02eS7R5GRR+6+iIpM2dqtS58bZEPSs28c=
|
||||
go.opentelemetry.io/collector/consumer v1.52.0 h1:jHAv2SaafE1SRMJ/2fTAYACKo6tp5fCI2H/YYUqUm48=
|
||||
go.opentelemetry.io/collector/consumer v1.52.0/go.mod h1:pb+eeJInUz/rVU0ujJYqzEcOSsvkdNeLg6xpSVRRqUY=
|
||||
go.opentelemetry.io/collector/consumer/consumertest v0.146.1 h1:A93hCl8awc9ennKI0DoJ0m4iud0NrN9I4qsYjG4Izd8=
|
||||
go.opentelemetry.io/collector/consumer/consumertest v0.146.1/go.mod h1:3OU6HKYNST/vWeQuJvotONB1HZP2VHuW/EvU8akKV6Y=
|
||||
go.opentelemetry.io/collector/consumer/xconsumer v0.146.1 h1:PjsHQMIM8BkOAqRiZWR70MWAgXyGFBO1ISAsd3Rbg9I=
|
||||
go.opentelemetry.io/collector/consumer/xconsumer v0.146.1/go.mod h1:oBwVdFUZa3GO4w29+ExBBBC/dOOANL5gSPWeHDeYtDs=
|
||||
go.opentelemetry.io/collector/featuregate v1.52.0 h1:Ba/6lL8BY+wWbQ8w7aOWzbyl4WG8i8eSGl2fnrBHBnE=
|
||||
go.opentelemetry.io/collector/featuregate v1.52.0/go.mod h1:PS7zY/zaCb28EqciePVwRHVhc3oKortTFXsi3I6ee4g=
|
||||
go.opentelemetry.io/collector/internal/componentalias v0.146.1 h1:sdBw19iyzyHOPzro63FtNpxUVR9XLALdWlFgQgd4V1w=
|
||||
go.opentelemetry.io/collector/internal/componentalias v0.146.1/go.mod h1:5M3pX4yzYkDiEs2WiLJt6vi/kY0/oNz3qNTcH8ZrjJs=
|
||||
go.opentelemetry.io/collector/internal/testutil v0.146.1 h1:hpemuw5sLSYIqflJdScFikLhCjHxKuJWC2Lwyh9yeCI=
|
||||
go.opentelemetry.io/collector/internal/testutil v0.146.1/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE=
|
||||
go.opentelemetry.io/collector/pdata v1.52.0 h1:jp76qKVZsQqB6yK2C6bolPOi1uU+jhsTDsp71d5MOhk=
|
||||
go.opentelemetry.io/collector/pdata v1.52.0/go.mod h1:+w6A2FXrMDDIwjRgQaud11Ifobng/j/FW3upZtaVKHc=
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.146.1 h1:W0bNpO+H7zLtH0+FfIBjTdUA0r7e4iAxPQ+PpkMlVlU=
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.146.1/go.mod h1:gNaqTrI/3sdZxtwYcR4yei89Kd3T1rXKGFpVonPQv/U=
|
||||
go.opentelemetry.io/collector/pdata/testdata v0.146.1 h1:MbDzTt/R+aXWrLa+c3WfQx9Wjd/XK6pTgM4dcWLUdlE=
|
||||
go.opentelemetry.io/collector/pdata/testdata v0.146.1/go.mod h1:IcY6Hg13ObCFc3gpv6MRjZqUa0kCmLC5pojMmwlTj3U=
|
||||
go.opentelemetry.io/collector/pipeline v1.52.0 h1:3I7Dq1eFUjM+OTqyESXBIa59fUjGBLoEkw3k8vRaOKQ=
|
||||
go.opentelemetry.io/collector/pipeline v1.52.0/go.mod h1:RD90NG3Jbk965Xaqym3JyHkuol4uZJjQVUkD9ddXJIs=
|
||||
go.opentelemetry.io/collector/processor v1.52.0 h1:u9xenI6FfM6uYRI1d3r6ZRXqtGf7i6AT05qyrjmbYRE=
|
||||
go.opentelemetry.io/collector/processor v1.52.0/go.mod h1:1u59uoSbalsIxzwIkxlyqjJlNtAu10aoXoKxrga/crU=
|
||||
go.opentelemetry.io/collector/processor/processortest v0.146.1 h1:stVYMS7wGAPDTuFYeuvWQJGAoO6p21THB+XSKUC+sfQ=
|
||||
go.opentelemetry.io/collector/processor/processortest v0.146.1/go.mod h1:M1d3uHwU9I0p2apwWsQv57NyHt0ytsWfg31HfA9RXJE=
|
||||
go.opentelemetry.io/collector/processor/xprocessor v0.146.1 h1:5w8BVZv6jrOviQ2cdrdSwZm1lqOn8215OqD5tE+c1Z4=
|
||||
go.opentelemetry.io/collector/processor/xprocessor v0.146.1/go.mod h1:1zTeAGtpb+v6Eit6t4JY8fAML9Elb0yN6TXFoG9Ldnw=
|
||||
go.opentelemetry.io/collector/semconv v0.128.0 h1:MzYOz7Vgb3Kf5D7b49pqqgeUhEmOCuT10bIXb/Cc+k4=
|
||||
go.opentelemetry.io/collector/semconv v0.128.0/go.mod h1:OPXer4l43X23cnjLXIZnRj/qQOjSuq4TgBLI76P9hns=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.40.0 h1:Awaf8gmW99tZTOWqkLCOl6aw1/rxAWVlHsHIZ3fT2sA=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.40.0/go.mod h1:99OY9ZCqyLkzJLTh5XhECpLRSxcZl+ZDKBEO+jMBFR4=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0 h1:XmiuHzgJt067+a6kwyAzkhXooYVv3/TOw9cM2VfJgUM=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0/go.mod h1:KDgtbWKTQs4bM+VPUr6WlL9m/WXcmkCcBlIzqxPGzmI=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.65.0 h1:ab5U7DpTjjN8pNgwqlA/s0Csb+N2Raqo9eTSDhfg4Z8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.65.0/go.mod h1:nwFJC46Dxhqz5R9k7IV8To/Z46JPvW+GNKhTxQQlUzg=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0=
|
||||
go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=
|
||||
go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 h1:5gn2urDL/FBnK8OkCfD1j3/ER79rUuTYmCvlXBKeYL8=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0/go.mod h1:0fBG6ZJxhqByfFZDwSwpZGzJU671HkwpWaNe2t4VUPI=
|
||||
go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=
|
||||
go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=
|
||||
go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=
|
||||
go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg=
|
||||
go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=
|
||||
go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=
|
||||
go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE=
|
||||
go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI=
|
||||
go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8=
|
||||
go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA=
|
||||
go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk=
|
||||
go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4=
|
||||
go.opentelemetry.io/collector/component v1.55.0 h1:45nb42/UqPDhRdS8FgGRDybRsWSuvS+r6WC2VTVqIRw=
|
||||
go.opentelemetry.io/collector/component v1.55.0/go.mod h1:7EpGxVpqFkZ2HidyiE9MLvh4cuKU7ye6i5OtxxiYKps=
|
||||
go.opentelemetry.io/collector/component/componentstatus v0.149.0 h1:6UM+yHoMtZmyu1Sz8Gy9B27eBtURR5sFinWf2LRdE7Y=
|
||||
go.opentelemetry.io/collector/component/componentstatus v0.149.0/go.mod h1:6jTQab606D+ICobKO/q4UrPy6hwvU3ZY+LcJnPrurds=
|
||||
go.opentelemetry.io/collector/component/componenttest v0.149.0 h1:7SSYIiLpe84LGfYAp7RCkzYuYLuYVSZVn/K/qsJZgHY=
|
||||
go.opentelemetry.io/collector/component/componenttest v0.149.0/go.mod h1:8xPU3XMsI+J4vfy87YG1bsCVTeedligKWgBcPEZ0yzw=
|
||||
go.opentelemetry.io/collector/confmap v1.55.0 h1:pBJbjWfIT3q8cy+eVcHCCYXx984NxOjaGTHqIWsXC1A=
|
||||
go.opentelemetry.io/collector/confmap v1.55.0/go.mod h1:rSKNE5ztWU6fS0pT8rwACn573r4jJc4QzJyoQzZIVtE=
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.149.0 h1:D/WzrxKOKedRztoY/MiAj9z8W0/2unpTCbANFCwvuuY=
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.149.0/go.mod h1:lJ1nHIQbH6L5wnj5vTWGr7RWi5Kib2KX5stAxar13Jo=
|
||||
go.opentelemetry.io/collector/consumer v1.55.0 h1:7Per8P4J0nlBrFVSXb+nwZ+egiel1BRtggZngyykGsM=
|
||||
go.opentelemetry.io/collector/consumer v1.55.0/go.mod h1:Qrn5fDp/HpDmUp+l2RGKsdKyOPlgGlaZPKvw/z9FfEc=
|
||||
go.opentelemetry.io/collector/consumer/consumertest v0.149.0 h1:IxOkDInfuUM8mT+rMNGtdUuuDlV9X2VS4WAQ/dZSYqg=
|
||||
go.opentelemetry.io/collector/consumer/consumertest v0.149.0/go.mod h1:ZMvFzch5IRjYBvj6WPc30HRy19smS0WFBXaOu16Wac0=
|
||||
go.opentelemetry.io/collector/consumer/xconsumer v0.149.0 h1:2z0wRTDsWqPdcC8xp9HJIAJej+07g4/yJrS0xkJJ4hA=
|
||||
go.opentelemetry.io/collector/consumer/xconsumer v0.149.0/go.mod h1:AG9w3bk38dq3Rk7C2JGf3jw4ldxR063ujYBm3eiMJ7k=
|
||||
go.opentelemetry.io/collector/featuregate v1.55.0 h1:s/bE8135+8GZpVlQ9qLXQjvprE9KNOGsLhNkqm+EDEU=
|
||||
go.opentelemetry.io/collector/featuregate v1.55.0/go.mod h1:PS7zY/zaCb28EqciePVwRHVhc3oKortTFXsi3I6ee4g=
|
||||
go.opentelemetry.io/collector/internal/componentalias v0.149.0 h1:0cH1hCy4vujhnAc6z4baLM0mauFZPfyqF9HtQF6YvGo=
|
||||
go.opentelemetry.io/collector/internal/componentalias v0.149.0/go.mod h1:8oIpxyFLZECp6O7zFDTGeWw72CQ67C8wb6FqAL9wvCo=
|
||||
go.opentelemetry.io/collector/internal/testutil v0.149.0 h1:OWfUPO3NFKSaJtz/SBZph/2ENHbr/VbzzlBadKUhm8o=
|
||||
go.opentelemetry.io/collector/internal/testutil v0.149.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE=
|
||||
go.opentelemetry.io/collector/pdata v1.55.0 h1:WBgye8bo8koUyV9Vmp/r2Q3lgDezdsgfKDQAaM1oT2I=
|
||||
go.opentelemetry.io/collector/pdata v1.55.0/go.mod h1:6jPrbM4tuliCPACDznjFtxnnHisfKfzwrBVoeuESYuk=
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.149.0 h1:4/uI7wsgMnmBZm6Z/VNY6sWnaFN09+Nk3jr7XEmTtOk=
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.149.0/go.mod h1:4uprs5wMp4MI1/bcP5mYERfobFxBn+QoeNFQBUSVk/U=
|
||||
go.opentelemetry.io/collector/pdata/testdata v0.149.0 h1:Y9WCJpr9fvpCGmvh6wK0i+QtOn0OyGXnoOkLfq7xtok=
|
||||
go.opentelemetry.io/collector/pdata/testdata v0.149.0/go.mod h1:5BscHKM7cy9lzPMpnaIFaTOMI8SI02AsEF4rH3aRJBg=
|
||||
go.opentelemetry.io/collector/pipeline v1.55.0 h1:jxFicLy3QYWQaQZp2f+wdCfHpOYb3mKNTqHR1KIut+U=
|
||||
go.opentelemetry.io/collector/pipeline v1.55.0/go.mod h1:RD90NG3Jbk965Xaqym3JyHkuol4uZJjQVUkD9ddXJIs=
|
||||
go.opentelemetry.io/collector/processor v1.55.0 h1:d4bCnvtAVTjy1/3JOj3ud6eEZCMsaz2C9lVStB1FM/8=
|
||||
go.opentelemetry.io/collector/processor v1.55.0/go.mod h1:ruMOb0N76S+H8rhzkLoIzALAMCe7XI9qFONDWsR5IOA=
|
||||
go.opentelemetry.io/collector/processor/processortest v0.149.0 h1:J73vvUuqyG2Ojnc2CQd6yNqI/wqoWuZuNo/JQH7WTsU=
|
||||
go.opentelemetry.io/collector/processor/processortest v0.149.0/go.mod h1:z7YKrOnM/y6h7ovZ3JKpCLqzRlE+xoeAhf9PU76EGtg=
|
||||
go.opentelemetry.io/collector/processor/xprocessor v0.149.0 h1:hmQS3HfO9VqSVsf5h1qIwg5DRYzP1WHxg32tBkHW2Es=
|
||||
go.opentelemetry.io/collector/processor/xprocessor v0.149.0/go.mod h1:kMEqqiVkTFedwNmFRg2wjA9A+CE44+CrM1wHb5Vfu0k=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.43.0 h1:62yY3dT7/ShwOxzA0RsKRgshBmfElKI4d/Myu2OxDFU=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.43.0/go.mod h1:RyaZMFY7yi1kAs45S6mbFGz8O8rqB0dTY14uzvG4LCs=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.68.0 h1:0Qx7VGBacMm9ZENQ7TnNObTYI4ShC+lHI16seduaxZo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.68.0/go.mod h1:Sje3i3MjSPKTSPvVWCaL8ugBzJwik3u4smCjUeuupqg=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.68.0 h1:cuXaPAfIoJKsYjBjPSb2nKZEmgM43zVr25l37IxhKME=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.68.0/go.mod h1:BuzhPofpCzlDi/Q/Xjg54M4/3oWqqyDe2Zeq7A2I0QE=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 h1:CqXxU8VOmDefoh0+ztfGaymYbhdB/tT3zs79QaZTNGY=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0/go.mod h1:BuhAPThV8PBHBvg8ZzZ/Ok3idOdhWIodywz2xEcRbJo=
|
||||
go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
|
||||
go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 h1:lSZHgNHfbmQTPfuTmWVkEu8J8qXaQwuV30pjCcAUvP8=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0/go.mod h1:so9ounLcuoRDu033MW/E0AD4hhUjVqswrMF5FoZlBcw=
|
||||
go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
|
||||
go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
|
||||
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
|
||||
go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
|
||||
go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
|
||||
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
|
||||
go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM=
|
||||
go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk=
|
||||
go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ=
|
||||
go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U=
|
||||
go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0=
|
||||
go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
@@ -498,71 +502,70 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
||||
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
|
||||
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
|
||||
go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
|
||||
go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
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.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||
golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a h1:ovFr6Z0MNmU7nH8VaX5xqw+05ST2uO1exVfZPVqRC5o=
|
||||
golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA=
|
||||
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
|
||||
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
|
||||
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 h1:jiDhWWeC7jfWqR9c/uplMOqJ0sbNlNWv0UkzE0vX1MA=
|
||||
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90/go.mod h1:xE1HEv6b+1SCZ5/uscMRjUBKtIxworgEcEi+/n9NQDQ=
|
||||
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.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
|
||||
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
|
||||
golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
|
||||
golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/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.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
|
||||
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
|
||||
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
|
||||
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
|
||||
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
|
||||
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
||||
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
||||
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.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.0.0-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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=
|
||||
golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=
|
||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=
|
||||
golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
||||
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
||||
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
|
||||
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
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.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
|
||||
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
|
||||
golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
|
||||
golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
|
||||
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=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/api v0.267.0 h1:w+vfWPMPYeRs8qH1aYYsFX68jMls5acWl/jocfLomwE=
|
||||
google.golang.org/api v0.267.0/go.mod h1:Jzc0+ZfLnyvXma3UtaTl023TdhZu6OMBP9tJ+0EmFD0=
|
||||
google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d h1:vsOm753cOAMkt76efriTCDKjpCbK18XGHMJHo0JUKhc=
|
||||
google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:0oz9d7g9QLSdv9/lgbIjowW1JoxMbxmBVNe8i6tORJI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d h1:EocjzKLywydp5uZ5tJ79iP6Q0UjDnyiHkGRWxuPBP8s=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:48U2I+QQUYhsFrg2SY6r+nJzeOtjey7j//WBESw+qyQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d h1:t/LOSXPJ9R0B6fnZNyALBRfZBH0Uy0gT+uR+SJ6syqQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
|
||||
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||
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.275.0 h1:vfY5d9vFVJeWEZT65QDd9hbndr7FyZ2+6mIzGAh71NI=
|
||||
google.golang.org/api v0.275.0/go.mod h1:Fnag/EWUPIcJXuIkP1pjoTgS5vdxlk3eeemL7Do6bvw=
|
||||
google.golang.org/genproto v0.0.0-20260406210006-6f92a3bedf2d h1:N1Ec54vZnIPd7MnxRiYLW+oY4fDR4BOS/LrssdD9+ek=
|
||||
google.golang.org/genproto v0.0.0-20260406210006-6f92a3bedf2d/go.mod h1:c2hJ1grtnH0xUiEKGDGkjGNTJ1Hy2LrblyKOHF0sqRM=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260406210006-6f92a3bedf2d h1:/aDRtSZJjyLQzm75d+a1wOJaqyKBMvIAfeQmoa3ORiI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260406210006-6f92a3bedf2d/go.mod h1:etfGUgejTiadZAUaEP14NP97xi1RGeawqkjDARA/UOs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d h1:wT2n40TBqFY6wiwazVK9/iTWbsQrgk5ZfCSVFLO9LQA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
|
||||
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@@ -572,30 +575,30 @@ gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnf
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.67.1 h1:tVBILHy0R6e4wkYOn3XmiITt/hEVH4TFMYvAX2Ytz6k=
|
||||
gopkg.in/ini.v1 v1.67.1/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss=
|
||||
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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.35.1 h1:0PO/1FhlK/EQNVK5+txc4FuhQibV25VLSdLMmGpDE/Q=
|
||||
k8s.io/api v0.35.1/go.mod h1:28uR9xlXWml9eT0uaGo6y71xK86JBELShLy4wR1XtxM=
|
||||
k8s.io/apimachinery v0.35.1 h1:yxO6gV555P1YV0SANtnTjXYfiivaTPvCTKX6w6qdDsU=
|
||||
k8s.io/apimachinery v0.35.1/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
|
||||
k8s.io/client-go v0.35.1 h1:+eSfZHwuo/I19PaSxqumjqZ9l5XiTEKbIaJ+j1wLcLM=
|
||||
k8s.io/client-go v0.35.1/go.mod h1:1p1KxDt3a0ruRfc/pG4qT/3oHmUj1AhSHEcxNSGg+OA=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE=
|
||||
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
|
||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=
|
||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
||||
k8s.io/api v0.35.3 h1:pA2fiBc6+N9PDf7SAiluKGEBuScsTzd2uYBkA5RzNWQ=
|
||||
k8s.io/api v0.35.3/go.mod h1:9Y9tkBcFwKNq2sxwZTQh1Njh9qHl81D0As56tu42GA4=
|
||||
k8s.io/apimachinery v0.35.3 h1:MeaUwQCV3tjKP4bcwWGgZ/cp/vpsRnQzqO6J6tJyoF8=
|
||||
k8s.io/apimachinery v0.35.3/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
|
||||
k8s.io/client-go v0.35.3 h1:s1lZbpN4uI6IxeTM2cpdtrwHcSOBML1ODNTCCfsP1pg=
|
||||
k8s.io/client-go v0.35.3/go.mod h1:RzoXkc0mzpWIDvBrRnD+VlfXP+lRzqQjCmKtiwZ8Q9c=
|
||||
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
|
||||
k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=
|
||||
k8s.io/kube-openapi v0.0.0-20260330154417-16be699c7b31 h1:V+sn9a/1fEYDGwnllCmqXBk8x7obZ+hl869Q3Abumkg=
|
||||
k8s.io/kube-openapi v0.0.0-20260330154417-16be699c7b31/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0=
|
||||
k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 h1:kBawHLSnx/mYHmRnNUf9d4CpjREbeZuxoSGOX/J+aYM=
|
||||
k8s.io/utils v0.0.0-20260319190234-28399d86e0b5/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8=
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||
|
||||
@@ -36,6 +36,7 @@ func WritePrometheusMetrics(w io.Writer) {
|
||||
if currentTime.Sub(metricsCacheLastUpdateTime) > time.Second {
|
||||
var bb bytesutil.ByteBuffer
|
||||
writePrometheusMetrics(&bb)
|
||||
writeOSMetrics(&bb)
|
||||
metricsCache.Store(&bb)
|
||||
metricsCacheLastUpdateTime = currentTime
|
||||
}
|
||||
|
||||
25
lib/appmetrics/osmetrics.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package appmetrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/VictoriaMetrics/metrics"
|
||||
)
|
||||
|
||||
type osInfo struct {
|
||||
name string
|
||||
release string
|
||||
}
|
||||
|
||||
var os osInfo
|
||||
var initOSOnce sync.Once
|
||||
|
||||
func writeOSMetrics(w io.Writer) {
|
||||
initOSOnce.Do(initOS)
|
||||
|
||||
if os.name != "" {
|
||||
metrics.WriteGaugeUint64(w, fmt.Sprintf(`vm_os_info{os=%q, release=%q}`, os.name, os.release), 1)
|
||||
}
|
||||
}
|
||||
20
lib/appmetrics/osmetrics_darwin.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package appmetrics
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||
)
|
||||
|
||||
func initOS() {
|
||||
os = osInfo{name: "darwin"}
|
||||
|
||||
out, err := exec.Command("sysctl", "-n", "kern.osrelease").Output()
|
||||
if err != nil {
|
||||
logger.Warnf("vm_os_info metric will miss release info since exec 'sysctl -n \"kern.osrelease\"' call failed: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
os.release = strings.TrimSpace(string(out))
|
||||
}
|
||||
26
lib/appmetrics/osmetrics_linux.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package appmetrics
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||
)
|
||||
|
||||
func initOS() {
|
||||
os = osInfo{name: "linux"}
|
||||
|
||||
var uname syscall.Utsname
|
||||
if err := syscall.Uname(&uname); err != nil {
|
||||
logger.Warnf("vm_os_info metric will miss release info since syscall.Uname failed: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
ur := make([]byte, 0, len(uname.Release))
|
||||
for _, v := range uname.Release {
|
||||
if v == 0 {
|
||||
break
|
||||
}
|
||||
ur = append(ur, byte(v))
|
||||
}
|
||||
os.release = string(ur)
|
||||
}
|
||||
6
lib/appmetrics/osmetrics_other.go
Normal file
@@ -0,0 +1,6 @@
|
||||
//go:build !linux && !windows && !darwin
|
||||
|
||||
package appmetrics
|
||||
|
||||
func initOS() {
|
||||
}
|
||||
19
lib/appmetrics/osmetrics_windows.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package appmetrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func initOS() {
|
||||
os = osInfo{name: "windows"}
|
||||
|
||||
ver := windows.RtlGetVersion()
|
||||
if ver == nil {
|
||||
logger.Warnf("vm_os_info metric will miss release info since windows.RtlGetVersion returned nil version")
|
||||
return
|
||||
}
|
||||
os.release = fmt.Sprintf("%d.%d.%d", ver.MajorVersion, ver.MinorVersion, ver.BuildNumber)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package awsapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
@@ -8,6 +9,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -37,6 +39,9 @@ type Config struct {
|
||||
defaultAccessKey string
|
||||
defaultSecretKey string
|
||||
|
||||
// profile is the named AWS profile to use from shared credentials/config files.
|
||||
profile string
|
||||
|
||||
// Real credentials used for accessing EC2 API.
|
||||
creds *credentials
|
||||
credsLock sync.Mutex
|
||||
@@ -51,7 +56,7 @@ type credentials struct {
|
||||
}
|
||||
|
||||
// NewConfig returns new AWS Config from the given args.
|
||||
func NewConfig(ec2Endpoint, stsEndpoint, region, roleARN, accessKey, secretKey, service string) (*Config, error) {
|
||||
func NewConfig(ec2Endpoint, stsEndpoint, region, roleARN, accessKey, secretKey, service, profile string) (*Config, error) {
|
||||
cfg := &Config{
|
||||
client: http.DefaultClient,
|
||||
region: region,
|
||||
@@ -61,6 +66,7 @@ func NewConfig(ec2Endpoint, stsEndpoint, region, roleARN, accessKey, secretKey,
|
||||
service: service,
|
||||
defaultAccessKey: os.Getenv("AWS_ACCESS_KEY_ID"),
|
||||
defaultSecretKey: os.Getenv("AWS_SECRET_ACCESS_KEY"),
|
||||
profile: profile,
|
||||
}
|
||||
if cfg.service == "" {
|
||||
cfg.service = "aps"
|
||||
@@ -184,8 +190,8 @@ func (cfg *Config) getFreshAPICredentials() (*credentials, error) {
|
||||
// There is no need in refreshing statically set api credentials if roleARN isn't set.
|
||||
return cfg.creds, nil
|
||||
}
|
||||
if time.Until(cfg.creds.Expiration) > 10*time.Second {
|
||||
// credentials aren't expired yet.
|
||||
if cfg.creds != nil && (cfg.creds.Expiration.IsZero() || time.Until(cfg.creds.Expiration) > 10*time.Second) {
|
||||
// credentials aren't expired yet; zero expiration means they don't expire (e.g. static profile keys).
|
||||
return cfg.creds, nil
|
||||
}
|
||||
// credentials have been expired. Update them.
|
||||
@@ -207,6 +213,8 @@ func (cfg *Config) getAPICredentials() (*credentials, error) {
|
||||
if relativeURI := os.Getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"); len(relativeURI) > 0 {
|
||||
fullURI = "http://169.254.170.2" + relativeURI
|
||||
}
|
||||
// roleARN may be overridden by profile's role_arn config entry.
|
||||
roleARN := cfg.roleARN
|
||||
switch {
|
||||
case len(acNew.AccessKeyID) > 0 && len(acNew.SecretAccessKey) > 0:
|
||||
case len(cfg.webTokenPath) > 0:
|
||||
@@ -229,6 +237,29 @@ func (cfg *Config) getAPICredentials() (*credentials, error) {
|
||||
return nil, err
|
||||
}
|
||||
acNew = ac
|
||||
case len(cfg.profile) > 0:
|
||||
sourceProfile, profileRoleARN, err := readAWSConfigFile(cfg.profile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot read config file for profile %q: %w", cfg.profile, err)
|
||||
}
|
||||
credProfile := cfg.profile
|
||||
if sourceProfile != "" {
|
||||
if sourceProfile == cfg.profile {
|
||||
return nil, fmt.Errorf("source_profile for %q points to itself", cfg.profile)
|
||||
}
|
||||
credProfile = sourceProfile
|
||||
}
|
||||
if roleARN == "" {
|
||||
roleARN = profileRoleARN
|
||||
}
|
||||
ac, err := readSharedCredentials(credProfile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot read shared credentials for profile %q: %w", credProfile, err)
|
||||
}
|
||||
if ac == nil {
|
||||
return nil, fmt.Errorf("missing credentials for profile %q", credProfile)
|
||||
}
|
||||
acNew = ac
|
||||
default:
|
||||
// we need instance credentials if we do not have access keys
|
||||
ac, err := getInstanceRoleCredentials(cfg.client)
|
||||
@@ -238,10 +269,10 @@ func (cfg *Config) getAPICredentials() (*credentials, error) {
|
||||
acNew = ac
|
||||
}
|
||||
// read credentials from sts api, if role_arn is defined
|
||||
if len(cfg.roleARN) > 0 {
|
||||
ac, err := cfg.getRoleARNCredentials(acNew, cfg.roleARN)
|
||||
if len(roleARN) > 0 {
|
||||
ac, err := cfg.getRoleARNCredentials(acNew, roleARN)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get credentials for role_arn %q: %w", cfg.roleARN, err)
|
||||
return nil, fmt.Errorf("cannot get credentials for role_arn %q: %w", roleARN, err)
|
||||
}
|
||||
acNew = ac
|
||||
}
|
||||
@@ -254,6 +285,112 @@ func (cfg *Config) getAPICredentials() (*credentials, error) {
|
||||
return acNew, nil
|
||||
}
|
||||
|
||||
// readSharedCredentials reads credentials from ~/.aws/credentials for the given profile.
|
||||
func readSharedCredentials(profile string) (*credentials, error) {
|
||||
path := os.Getenv("AWS_SHARED_CREDENTIALS_FILE")
|
||||
if path == "" {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get home directory: %w", err)
|
||||
}
|
||||
path = filepath.Join(home, ".aws", "credentials")
|
||||
}
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("cannot read %q: %w", path, err)
|
||||
}
|
||||
section := readSection(data, profile)
|
||||
if section == nil {
|
||||
return nil, nil
|
||||
}
|
||||
accessKey := section["aws_access_key_id"]
|
||||
secretKey := section["aws_secret_access_key"]
|
||||
if accessKey == "" || secretKey == "" {
|
||||
return nil, fmt.Errorf("missing aws_access_key_id or aws_secret_access_key for profile %q in %q", profile, path)
|
||||
}
|
||||
return &credentials{
|
||||
AccessKeyID: accessKey,
|
||||
SecretAccessKey: secretKey,
|
||||
Token: section["aws_session_token"],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// readAWSConfigFile returns source_profile and role_arn for the given profile from ~/.aws/config.
|
||||
func readAWSConfigFile(profile string) (sourceProfile, roleARN string, err error) {
|
||||
path := os.Getenv("AWS_CONFIG_FILE")
|
||||
if path == "" {
|
||||
tilde, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("cannot get home directory: %w", err)
|
||||
}
|
||||
path = filepath.Join(tilde, ".aws", "config")
|
||||
}
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return "", "", nil
|
||||
}
|
||||
return "", "", fmt.Errorf("cannot read %q: %w", path, err)
|
||||
}
|
||||
// named profiles use "profile " prefix in config file; "default" is the exception
|
||||
sectionName := "profile " + profile
|
||||
if profile == "default" {
|
||||
sectionName = "default"
|
||||
}
|
||||
section := readSection(data, sectionName)
|
||||
if section == nil {
|
||||
return "", "", nil
|
||||
}
|
||||
return section["source_profile"], section["role_arn"], nil
|
||||
}
|
||||
|
||||
// readSection returns key-value pairs for the given section from AWS config/credentials file data.
|
||||
func readSection(data []byte, section string) map[string]string {
|
||||
sectionBytes := []byte(strings.TrimSpace(section))
|
||||
var result map[string]string
|
||||
inSection := false
|
||||
for len(data) > 0 {
|
||||
var line []byte
|
||||
if i := bytes.IndexByte(data, '\n'); i >= 0 {
|
||||
line, data = data[:i], data[i+1:]
|
||||
} else {
|
||||
line, data = data, nil
|
||||
}
|
||||
line = bytes.TrimSpace(line)
|
||||
// '#' is the only recognized comment character. See https://stackoverflow.com/questions/43217469/how-do-you-comment-out-lines-in-aws-cli-config-and-credentials-files
|
||||
if len(line) == 0 || line[0] == '#' {
|
||||
continue
|
||||
}
|
||||
if line[0] == '[' {
|
||||
end := bytes.IndexByte(line, ']')
|
||||
if end < 0 {
|
||||
continue
|
||||
}
|
||||
// strip double quotes to handle profile names with spaces, e.g. [profile "my profile"]
|
||||
header := bytes.ReplaceAll(bytes.TrimSpace(line[1:end]), []byte{'"'}, nil)
|
||||
inSection = bytes.EqualFold(header, sectionBytes)
|
||||
continue
|
||||
}
|
||||
if !inSection {
|
||||
continue
|
||||
}
|
||||
eq := bytes.IndexByte(line, '=')
|
||||
if eq < 0 {
|
||||
continue
|
||||
}
|
||||
key := string(bytes.TrimSpace(line[:eq]))
|
||||
value := string(bytes.TrimSpace(line[eq+1:]))
|
||||
if result == nil {
|
||||
result = make(map[string]string)
|
||||
}
|
||||
result[key] = value
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// getCredentialsByPath makes request to metadata service and retrieves container credentials
|
||||
// https://docs.aws.amazon.com/sdkref/latest/guide/feature-container-credentials.html
|
||||
func getCredentialsByPath(client *http.Client, uri, token string) (*credentials, error) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
@@ -296,6 +297,178 @@ func TestParseARNCredentialsSuccess(t *testing.T) {
|
||||
f(s2, "AssumeRoleWithWebIdentity", credsExpected2)
|
||||
}
|
||||
|
||||
func TestReadSection(t *testing.T) {
|
||||
f := func(data, section string, expectedResult map[string]string) {
|
||||
t.Helper()
|
||||
result := readSection([]byte(data), section)
|
||||
if !reflect.DeepEqual(result, expectedResult) {
|
||||
t.Fatalf("unexpected result for section %q;\ngot\n%v\nwant\n%v", section, result, expectedResult)
|
||||
}
|
||||
}
|
||||
|
||||
// missing section
|
||||
f("[foo]\nkey=val\n", "spoon", nil)
|
||||
|
||||
// happy path
|
||||
f("[default]\naws_access_key_id = HESOYAM\naws_secret_access_key = BAGUVIX\n", " default ", map[string]string{
|
||||
"aws_access_key_id": "HESOYAM",
|
||||
"aws_secret_access_key": "BAGUVIX",
|
||||
})
|
||||
|
||||
// comments and blank lines are skipped
|
||||
f("# some comment\n[default]\n\npipeline = green\ntests = well written and stable", "default", map[string]string{
|
||||
"pipeline": "green",
|
||||
"tests": "well written and stable",
|
||||
})
|
||||
|
||||
// profile prefix used in config file
|
||||
f("[profile account-one]\nsource_profile = root\nrole_arn = arn:aws:iam::000000000001:role/prometheus\n", "profile account-one", map[string]string{
|
||||
"source_profile": "root",
|
||||
"role_arn": "arn:aws:iam::000000000001:role/prometheus",
|
||||
})
|
||||
|
||||
// multiple sections - only the matching one is returned
|
||||
f("[default]\nregion=us-east-1\n[profile foo]\nrole_arn=arn:foo\n", "profile foo", map[string]string{
|
||||
"role_arn": "arn:foo",
|
||||
})
|
||||
|
||||
// quirky line endings just in case
|
||||
f("[test]\r\nfoo=bar\r\nbeep=boop\r\n", "test", map[string]string{
|
||||
"foo": "bar",
|
||||
"beep": "boop",
|
||||
})
|
||||
}
|
||||
|
||||
func TestReadAWSConfigFile(t *testing.T) {
|
||||
f := func(content, profile, wantSourceProfile, wantRoleARN string) {
|
||||
t.Helper()
|
||||
tempDir := t.TempDir()
|
||||
cfgPath := filepath.Join(tempDir, "config")
|
||||
if err := os.WriteFile(cfgPath, []byte(content), 0600); err != nil {
|
||||
t.Fatalf("cannot write config file: %v", err)
|
||||
}
|
||||
t.Setenv("AWS_CONFIG_FILE", cfgPath)
|
||||
sourceProfile, roleARN, err := readAWSConfigFile(profile)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if sourceProfile != wantSourceProfile {
|
||||
t.Fatalf("unexpected source_profile; got %q, want %q", sourceProfile, wantSourceProfile)
|
||||
}
|
||||
if roleARN != wantRoleARN {
|
||||
t.Fatalf("unexpected role_arn; got %q, want %q", roleARN, wantRoleARN)
|
||||
}
|
||||
}
|
||||
|
||||
// profile with source_profile and role_arn
|
||||
f("[profile account-one]\nsource_profile = root\nrole_arn = arn:aws:iam::111:role/r\n",
|
||||
"account-one", "root", "arn:aws:iam::111:role/r")
|
||||
|
||||
// default profile
|
||||
f("[default]\nrole_arn = arn:aws:iam::222:role/r\n",
|
||||
"default", "", "arn:aws:iam::222:role/r")
|
||||
|
||||
// profile not found returns empty strings
|
||||
f("[profile other]\nrole_arn = arn:foo\n",
|
||||
"missing", "", "")
|
||||
}
|
||||
|
||||
func TestReadSharedCredentials(t *testing.T) {
|
||||
f := func(content, profile string, wantCreds *credentials) {
|
||||
t.Helper()
|
||||
tempDir := t.TempDir()
|
||||
credsPath := filepath.Join(tempDir, "credentials")
|
||||
if err := os.WriteFile(credsPath, []byte(content), 0600); err != nil {
|
||||
t.Fatalf("cannot write credentials file: %v", err)
|
||||
}
|
||||
t.Setenv("AWS_SHARED_CREDENTIALS_FILE", credsPath)
|
||||
creds, err := readSharedCredentials(profile)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(creds, wantCreds) {
|
||||
t.Fatalf("unexpected creds;\ngot\n%+v\nwant\n%+v", creds, wantCreds)
|
||||
}
|
||||
}
|
||||
|
||||
// basic credentials
|
||||
f("[root]\naws_access_key_id = AKID\naws_secret_access_key = SECRET\n", "root", &credentials{
|
||||
AccessKeyID: "AKID",
|
||||
SecretAccessKey: "SECRET",
|
||||
})
|
||||
|
||||
// credentials with session token
|
||||
f("[root]\naws_access_key_id = AKID\naws_secret_access_key = SECRET\naws_session_token = TOKEN\n", "root", &credentials{
|
||||
AccessKeyID: "AKID",
|
||||
SecretAccessKey: "SECRET",
|
||||
Token: "TOKEN",
|
||||
})
|
||||
|
||||
// profile not found
|
||||
f("[other]\naws_access_key_id = AKID\naws_secret_access_key = SECRET\n", "missing", nil)
|
||||
}
|
||||
|
||||
func TestGetAPICredentialsWithProfile(t *testing.T) {
|
||||
responses := map[string]string{
|
||||
"AssumeRole": `
|
||||
<AssumeRoleResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
|
||||
<AssumeRoleResult>
|
||||
<Credentials>
|
||||
<AccessKeyId>PROFILEROLEID</AccessKeyId>
|
||||
<SecretAccessKey>PROFILEROLESECRET</SecretAccessKey>
|
||||
<SessionToken>PROFILEROLETOKEN</SessionToken>
|
||||
<Expiration>2025-01-01T00:00:00Z</Expiration>
|
||||
</Credentials>
|
||||
</AssumeRoleResult>
|
||||
<ResponseMetadata><RequestId>test</RequestId></ResponseMetadata>
|
||||
</AssumeRoleResponse>
|
||||
`,
|
||||
}
|
||||
|
||||
tempDir := t.TempDir()
|
||||
|
||||
configContent := "[profile myprofile]\nsource_profile = root\nrole_arn = arn:aws:iam::123:role/myrole\n"
|
||||
configPath := filepath.Join(tempDir, "config")
|
||||
if err := os.WriteFile(configPath, []byte(configContent), 0600); err != nil {
|
||||
t.Fatalf("cannot write config: %v", err)
|
||||
}
|
||||
credsContent := "[root]\naws_access_key_id = ROOTAKID\naws_secret_access_key = ROOTSECRET\n"
|
||||
credsPath := filepath.Join(tempDir, "credentials")
|
||||
if err := os.WriteFile(credsPath, []byte(credsContent), 0600); err != nil {
|
||||
t.Fatalf("cannot write credentials: %v", err)
|
||||
}
|
||||
|
||||
t.Setenv("AWS_CONFIG_FILE", configPath)
|
||||
t.Setenv("AWS_SHARED_CREDENTIALS_FILE", credsPath)
|
||||
|
||||
rt := &fakeRoundTripper{responses: make(map[string]*http.Response)}
|
||||
for action, value := range responses {
|
||||
recorder := httptest.NewRecorder()
|
||||
recorder.WriteHeader(http.StatusOK)
|
||||
_, _ = recorder.WriteString(value)
|
||||
rt.responses[action] = recorder.Result()
|
||||
}
|
||||
|
||||
cfg := &Config{
|
||||
profile: "myprofile",
|
||||
stsEndpoint: "http://sts.fake",
|
||||
client: &http.Client{Transport: rt},
|
||||
}
|
||||
creds, err := cfg.getAPICredentials()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
credsExpected := &credentials{
|
||||
AccessKeyID: "PROFILEROLEID",
|
||||
SecretAccessKey: "PROFILEROLESECRET",
|
||||
Token: "PROFILEROLETOKEN",
|
||||
Expiration: mustParseRFC3339("2025-01-01T00:00:00Z"),
|
||||
}
|
||||
if !reflect.DeepEqual(creds, credsExpected) {
|
||||
t.Fatalf("unexpected creds;\ngot\n%+v\nwant\n%+v", creds, credsExpected)
|
||||
}
|
||||
}
|
||||
|
||||
func mustParseRFC3339(s string) time.Time {
|
||||
expTime, err := time.Parse(time.RFC3339, s)
|
||||
if err != nil {
|
||||
|
||||
@@ -37,7 +37,7 @@ func newAPIConfig(sdc *SDConfig) (*apiConfig, error) {
|
||||
if stsEndpoint == "" {
|
||||
stsEndpoint = sdc.Endpoint
|
||||
}
|
||||
awsCfg, err := awsapi.NewConfig(sdc.Endpoint, stsEndpoint, sdc.Region, sdc.RoleARN, sdc.AccessKey, sdc.SecretKey.String(), "ec2")
|
||||
awsCfg, err := awsapi.NewConfig(sdc.Endpoint, stsEndpoint, sdc.Region, sdc.RoleARN, sdc.AccessKey, sdc.SecretKey.String(), "ec2", sdc.Profile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ type SDConfig struct {
|
||||
STSEndpoint string `yaml:"sts_endpoint,omitempty"`
|
||||
AccessKey string `yaml:"access_key,omitempty"`
|
||||
SecretKey *promauth.Secret `yaml:"secret_key,omitempty"`
|
||||
// TODO add support for Profile, not working atm
|
||||
// Profile string `yaml:"profile,omitempty"`
|
||||
// Profile is the named AWS profile from ~/.aws/config and ~/.aws/credentials.
|
||||
Profile string `yaml:"profile,omitempty"`
|
||||
RoleARN string `yaml:"role_arn,omitempty"`
|
||||
// RefreshInterval time.Duration `yaml:"refresh_interval"`
|
||||
// refresh_interval is obtained from `-promscrape.ec2SDCheckInterval` command-line option.
|
||||
|
||||
@@ -71,11 +71,58 @@ type metric struct {
|
||||
// Unmarshal unmarshals csv lines from s according to the given cds.
|
||||
func (rs *Rows) Unmarshal(s string, cds []ColumnDescriptor) {
|
||||
rs.sc.Init(s)
|
||||
rs.Rows, rs.tagsPool, rs.metricsPool = parseRows(&rs.sc, rs.Rows[:0], rs.tagsPool[:0], rs.metricsPool[:0], cds)
|
||||
rs.Rows, rs.tagsPool, rs.metricsPool = parseRows(&rs.sc, rs.Rows[:0], rs.tagsPool[:0], rs.metricsPool[:0], cds, false)
|
||||
}
|
||||
|
||||
func parseRows(sc *scanner, dst []Row, tags []Tag, metrics []metric, cds []ColumnDescriptor) ([]Row, []Tag, []metric) {
|
||||
// UnmarshalDetectHeader is similar to Unmarshal, but skips the first row if it looks like CSV header
|
||||
// Must only be called for the first data block in a stream.
|
||||
func (rs *Rows) UnmarshalDetectHeader(s string, cds []ColumnDescriptor) {
|
||||
rs.sc.Init(s)
|
||||
rs.Rows, rs.tagsPool, rs.metricsPool = parseRows(&rs.sc, rs.Rows[:0], rs.tagsPool[:0], rs.metricsPool[:0], cds, true)
|
||||
}
|
||||
|
||||
// isHeaderRow returns true if the current scanner line looks like a CSV header.
|
||||
func isHeaderRow(sc *scanner, cds []ColumnDescriptor) bool {
|
||||
isHeader := false
|
||||
col := uint(0)
|
||||
for sc.NextColumn() {
|
||||
if col >= uint(len(cds)) {
|
||||
continue
|
||||
}
|
||||
cd := &cds[col]
|
||||
col++
|
||||
if cd.isEmpty() || sc.Column == "" {
|
||||
continue
|
||||
}
|
||||
if cd.ParseTimestamp != nil {
|
||||
if _, err := cd.ParseTimestamp(sc.Column); err != nil {
|
||||
isHeader = true
|
||||
}
|
||||
}
|
||||
if cd.MetricName != "" {
|
||||
if _, err := fastfloat.Parse(sc.Column); err != nil {
|
||||
isHeader = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return isHeader
|
||||
}
|
||||
|
||||
func parseRows(sc *scanner, dst []Row, tags []Tag, metrics []metric, cds []ColumnDescriptor, skipHeader bool) ([]Row, []Tag, []metric) {
|
||||
for sc.NextLine() {
|
||||
if skipHeader {
|
||||
skipHeader = false
|
||||
savedLine := sc.Line
|
||||
if isHeaderRow(sc, cds) {
|
||||
sc.Line = savedLine
|
||||
sc.isLastColumn = false
|
||||
sc.Error = nil
|
||||
continue
|
||||
}
|
||||
sc.Line = savedLine
|
||||
sc.isLastColumn = false
|
||||
sc.Error = nil
|
||||
}
|
||||
line := sc.Line
|
||||
var r Row
|
||||
col := uint(0)
|
||||
|
||||
@@ -2,6 +2,7 @@ package csvimport
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -318,3 +319,182 @@ func TestRowsUnmarshalSuccess(t *testing.T) {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestHeaderDetection(t *testing.T) {
|
||||
f := func(format, s string, rowsExpected []Row) {
|
||||
t.Helper()
|
||||
cds, err := ParseColumnDescriptors(format)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when parsing %q: %s", format, err)
|
||||
}
|
||||
var rs Rows
|
||||
rs.UnmarshalDetectHeader(s, cds)
|
||||
if !reflect.DeepEqual(rs.Rows, rowsExpected) {
|
||||
t.Fatalf("unexpected rows;\ngot\n%v\nwant\n%v", rs.Rows, rowsExpected)
|
||||
}
|
||||
rs.Reset()
|
||||
rs.UnmarshalDetectHeader(s, cds)
|
||||
if !reflect.DeepEqual(rs.Rows, rowsExpected) {
|
||||
t.Fatalf("unexpected rows on second unmarshal;\ngot\n%v\nwant\n%v", rs.Rows, rowsExpected)
|
||||
}
|
||||
}
|
||||
|
||||
// non-numeric metric column
|
||||
f("1:metric:foo", "value\n123", []Row{
|
||||
{Metric: "foo", Value: 123},
|
||||
})
|
||||
f("1:metric:foo", "foo\n42", []Row{
|
||||
{Metric: "foo", Value: 42},
|
||||
})
|
||||
|
||||
// non-numeric timestamp column
|
||||
f("1:metric:foo,2:time:unix_s", "value,timestamp\n123,456", []Row{
|
||||
{Metric: "foo", Value: 123, Timestamp: 456000},
|
||||
})
|
||||
f("1:metric:foo,2:time:unix_ms", "value,timestamp\n10,2000", []Row{
|
||||
{Metric: "foo", Value: 10, Timestamp: 2000},
|
||||
})
|
||||
f("1:metric:foo,2:time:rfc3339", "value,timestamp\n10,2024-01-01T00:00:00Z", []Row{
|
||||
{Metric: "foo", Value: 10, Timestamp: 1704067200000},
|
||||
})
|
||||
|
||||
// header with labels
|
||||
f("1:label:host,2:metric:cpu,3:time:unix_s",
|
||||
"host,value,timestamp\nmyhost,99.5,1000",
|
||||
[]Row{
|
||||
{Metric: "cpu", Tags: []Tag{{Key: "host", Value: "myhost"}}, Value: 99.5, Timestamp: 1000000},
|
||||
})
|
||||
|
||||
// header with multiple data rows
|
||||
f("1:metric:foo,2:time:unix_s",
|
||||
"value,timestamp\n10,100\n20,200\n30,300",
|
||||
[]Row{
|
||||
{Metric: "foo", Value: 10, Timestamp: 100000},
|
||||
{Metric: "foo", Value: 20, Timestamp: 200000},
|
||||
{Metric: "foo", Value: 30, Timestamp: 300000},
|
||||
})
|
||||
|
||||
// header with multiple metrics per row
|
||||
f("1:metric:bid,2:metric:ask,3:time:unix_s",
|
||||
"bid,ask,timestamp\n1.5,1.6,1000",
|
||||
[]Row{
|
||||
{Metric: "bid", Value: 1.5, Timestamp: 1000000},
|
||||
{Metric: "ask", Value: 1.6, Timestamp: 1000000},
|
||||
})
|
||||
|
||||
// one non-numeric metric column is enough to detect the header
|
||||
f("1:metric:foo,2:metric:bar", "123,count\n1,2", []Row{
|
||||
{Metric: "foo", Value: 1},
|
||||
{Metric: "bar", Value: 2},
|
||||
})
|
||||
|
||||
// header only, no data
|
||||
f("1:metric:foo,2:time:unix_s", "value,timestamp", nil)
|
||||
|
||||
// column gap
|
||||
f("3:metric:foo", "a,b,value\na,b,123", []Row{
|
||||
{Metric: "foo", Value: 123},
|
||||
})
|
||||
|
||||
// numeric first row
|
||||
f("1:metric:foo,2:time:unix_s", "123,456", []Row{
|
||||
{Metric: "foo", Value: 123, Timestamp: 456000},
|
||||
})
|
||||
f("1:metric:foo", "123\n456", []Row{
|
||||
{Metric: "foo", Value: 123},
|
||||
{Metric: "foo", Value: 456},
|
||||
})
|
||||
|
||||
// valid rfc3339 parses as data, not header
|
||||
f("1:metric:foo,2:time:rfc3339", "123,2024-01-01T00:00:00Z", []Row{
|
||||
{Metric: "foo", Value: 123, Timestamp: 1704067200000},
|
||||
})
|
||||
|
||||
// No header — text label columns don't trigger detection
|
||||
f("1:label:host,2:metric:foo,3:time:unix_s",
|
||||
"myhost,42,1000\notherhost,99,2000",
|
||||
[]Row{
|
||||
{Metric: "foo", Tags: []Tag{{Key: "host", Value: "myhost"}}, Value: 42, Timestamp: 1000000},
|
||||
{Metric: "foo", Tags: []Tag{{Key: "host", Value: "otherhost"}}, Value: 99, Timestamp: 2000000},
|
||||
})
|
||||
|
||||
// numeric label "404" is not a false positive
|
||||
f("1:label:status,2:metric:count,3:time:unix_s",
|
||||
"404,100,1704067200",
|
||||
[]Row{
|
||||
{Metric: "count", Tags: []Tag{{Key: "status", Value: "404"}}, Value: 100, Timestamp: 1704067200000},
|
||||
})
|
||||
|
||||
// empty input
|
||||
f("1:metric:foo", "", nil)
|
||||
|
||||
// single numeric row
|
||||
f("1:metric:foo", "69", []Row{
|
||||
{Metric: "foo", Value: 69},
|
||||
})
|
||||
}
|
||||
|
||||
func TestUnmarshalBackwardCompatibility(t *testing.T) {
|
||||
f := func(format, s string, rowsExpected []Row) {
|
||||
t.Helper()
|
||||
cds, err := ParseColumnDescriptors(format)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when parsing %q: %s", format, err)
|
||||
}
|
||||
var rs Rows
|
||||
rs.Unmarshal(s, cds)
|
||||
if !reflect.DeepEqual(rs.Rows, rowsExpected) {
|
||||
t.Fatalf("unexpected rows;\ngot\n%v\nwant\n%v", rs.Rows, rowsExpected)
|
||||
}
|
||||
}
|
||||
|
||||
f("1:metric:foo,2:time:unix_s", "123,456", []Row{
|
||||
{Metric: "foo", Value: 123, Timestamp: 456000},
|
||||
})
|
||||
f("1:metric:foo", "10\n20\n30", []Row{
|
||||
{Metric: "foo", Value: 10},
|
||||
{Metric: "foo", Value: 20},
|
||||
{Metric: "foo", Value: 30},
|
||||
})
|
||||
f("1:label:env,2:metric:m,3:time:unix_s",
|
||||
"prod,42,1000\nstaging,99,2000",
|
||||
[]Row{
|
||||
{Metric: "m", Tags: []Tag{{Key: "env", Value: "prod"}}, Value: 42, Timestamp: 1000000},
|
||||
{Metric: "m", Tags: []Tag{{Key: "env", Value: "staging"}}, Value: 99, Timestamp: 2000000},
|
||||
})
|
||||
}
|
||||
|
||||
func TestExportImportRoundTrip(t *testing.T) {
|
||||
format := "1:label:host,2:metric:cpu,3:time:unix_s"
|
||||
cds, err := ParseColumnDescriptors(format)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
// Simulated export output: header + data rows
|
||||
exported := strings.Join([]string{
|
||||
"host,value,timestamp",
|
||||
"server1,85.5,1704067200",
|
||||
"server2,92.3,1704067200",
|
||||
"server1,88.1,1704067260",
|
||||
}, "\n")
|
||||
|
||||
var rs Rows
|
||||
rs.UnmarshalDetectHeader(exported, cds)
|
||||
expected := []Row{
|
||||
{Metric: "cpu", Tags: []Tag{{Key: "host", Value: "server1"}}, Value: 85.5, Timestamp: 1704067200000},
|
||||
{Metric: "cpu", Tags: []Tag{{Key: "host", Value: "server2"}}, Value: 92.3, Timestamp: 1704067200000},
|
||||
{Metric: "cpu", Tags: []Tag{{Key: "host", Value: "server1"}}, Value: 88.1, Timestamp: 1704067260000},
|
||||
}
|
||||
if !reflect.DeepEqual(rs.Rows, expected) {
|
||||
t.Fatalf("round-trip mismatch;\ngot\n%v\nwant\n%v", rs.Rows, expected)
|
||||
}
|
||||
|
||||
// Without header detection the header line is an invalid row;
|
||||
// the 3 data rows are still parsed.
|
||||
rs.Reset()
|
||||
rs.Unmarshal(exported, cds)
|
||||
if len(rs.Rows) != 3 {
|
||||
t.Fatalf("expected 3 rows; got %d", len(rs.Rows))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,11 +49,14 @@ func Parse(req *http.Request, callback func(rows []csvimport.Row) error) error {
|
||||
|
||||
ctx := getStreamContext(reader)
|
||||
defer putStreamContext(ctx)
|
||||
firstRow := true
|
||||
for ctx.Read() {
|
||||
uw := getUnmarshalWork()
|
||||
uw.ctx = ctx
|
||||
uw.callback = callback
|
||||
uw.cds = cds
|
||||
uw.firstRow = firstRow
|
||||
firstRow = false
|
||||
uw.reqBuf, ctx.reqBuf = ctx.reqBuf, uw.reqBuf
|
||||
ctx.wg.Add(1)
|
||||
protoparserutil.ScheduleUnmarshalWork(uw)
|
||||
@@ -144,6 +147,7 @@ type unmarshalWork struct {
|
||||
callback func(rows []csvimport.Row) error
|
||||
cds []csvimport.ColumnDescriptor
|
||||
reqBuf []byte
|
||||
firstRow bool
|
||||
}
|
||||
|
||||
func (uw *unmarshalWork) reset() {
|
||||
@@ -152,6 +156,7 @@ func (uw *unmarshalWork) reset() {
|
||||
uw.callback = nil
|
||||
uw.cds = nil
|
||||
uw.reqBuf = uw.reqBuf[:0]
|
||||
uw.firstRow = false
|
||||
}
|
||||
|
||||
func (uw *unmarshalWork) runCallback(rows []csvimport.Row) {
|
||||
@@ -168,7 +173,11 @@ func (uw *unmarshalWork) runCallback(rows []csvimport.Row) {
|
||||
|
||||
// Unmarshal implements protoparserutil.UnmarshalWork
|
||||
func (uw *unmarshalWork) Unmarshal() {
|
||||
uw.rows.Unmarshal(bytesutil.ToUnsafeString(uw.reqBuf), uw.cds)
|
||||
if uw.firstRow {
|
||||
uw.rows.UnmarshalDetectHeader(bytesutil.ToUnsafeString(uw.reqBuf), uw.cds)
|
||||
} else {
|
||||
uw.rows.Unmarshal(bytesutil.ToUnsafeString(uw.reqBuf), uw.cds)
|
||||
}
|
||||
rows := uw.rows.Rows
|
||||
rowsRead.Add(len(rows))
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
// Later we could consider to make this limit configurable
|
||||
const maxSnappyBlockSize = 56_000_000
|
||||
|
||||
// ReadUncompressedData reads uncompressed data from r using the given encoding and then passes it to the callback.
|
||||
// ReadUncompressedData reads uncompressed data from r using the given contentType and then passes it to the callback.
|
||||
//
|
||||
// The maxDataSize limits the maximum data size, which can be read from r.
|
||||
//
|
||||
|
||||
@@ -268,7 +268,8 @@ func MustOpenStorage(path string, opts OpenOptions) *Storage {
|
||||
|
||||
// check for free disk space before opening the table
|
||||
// to prevent unexpected part merges. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4023
|
||||
s.startFreeDiskSpaceWatcher()
|
||||
freeSpaceBytes := fs.MustGetFreeSpace(s.path)
|
||||
s.isReadOnly.Store(freeSpaceBytes < freeDiskSpaceLimitBytes)
|
||||
|
||||
// Load data
|
||||
tablePath := filepath.Join(path, dataDirname)
|
||||
@@ -306,14 +307,15 @@ func MustOpenStorage(path string, opts OpenOptions) *Storage {
|
||||
s.pendingHourEntries = &uint64set.Set{}
|
||||
// Load nextDayMetricIDs cache after the data table is opened since it
|
||||
// requires the partition index to operate properly.
|
||||
date := fasttime.UnixDate()
|
||||
nextDayMetricIDs := s.mustLoadNextDayMetricIDs(date)
|
||||
timestamp := fasttime.UnixTimestamp()
|
||||
nextDayMetricIDs := s.mustLoadNextDayMetricIDs(timestamp)
|
||||
s.nextDayMetricIDs.Store(nextDayMetricIDs)
|
||||
s.pendingNextDayMetricIDs = &uint64set.Set{}
|
||||
|
||||
s.startCurrHourMetricIDsUpdater()
|
||||
s.startNextDayMetricIDsUpdater()
|
||||
s.startLegacyRetentionWatcher()
|
||||
s.startFreeDiskSpaceWatcher()
|
||||
|
||||
return s
|
||||
}
|
||||
@@ -793,12 +795,12 @@ func (s *Storage) nextDayMetricIDsUpdater() {
|
||||
for {
|
||||
select {
|
||||
case <-s.stopCh:
|
||||
date := fasttime.UnixDate()
|
||||
s.updateNextDayMetricIDs(date)
|
||||
timestamp := fasttime.UnixTimestamp()
|
||||
s.updateNextDayMetricIDs(timestamp)
|
||||
return
|
||||
case <-ticker.C:
|
||||
date := fasttime.UnixDate()
|
||||
s.updateNextDayMetricIDs(date)
|
||||
timestamp := fasttime.UnixTimestamp()
|
||||
s.updateNextDayMetricIDs(timestamp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -859,7 +861,15 @@ func (s *Storage) MustClose() {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Storage) mustLoadNextDayMetricIDs(date uint64) *nextDayMetricIDs {
|
||||
func (s *Storage) mustLoadNextDayMetricIDs(timestamp uint64) *nextDayMetricIDs {
|
||||
date := timestamp / (24 * 3600)
|
||||
if isFirstHourOfDay(timestamp) {
|
||||
// If this is the first hour of the day, allow to load nextDayMetricIDs
|
||||
// collected during the next day index prefill during the last hour of
|
||||
// the day before to speed up data ingestion. See updatePerDateData()
|
||||
// and updateNextDayMetricIDs().
|
||||
date--
|
||||
}
|
||||
ptw := s.tb.MustGetPartition(int64(date+1) * msecPerDay)
|
||||
nextDayIDBID := ptw.pt.idb.id
|
||||
s.tb.PutPartition(ptw)
|
||||
@@ -1976,6 +1986,11 @@ func (s *Storage) add(rows []rawRow, dstMrs []*MetricRow, mrs []MetricRow, preci
|
||||
seriesRepopulated++
|
||||
slowInsertsCount++
|
||||
}
|
||||
// TODO(rtm0): Possibly a bug: pending entry is added and if
|
||||
// 1) it happens to be sync'ed to currHourMetricIDs before
|
||||
// updatePerDateData() is executed AND
|
||||
// 2) that metricID hasn't been registered for that day
|
||||
// the metric will be lost.
|
||||
addToPendingHourEntries(hour, lTSID.TSID.MetricID)
|
||||
continue
|
||||
}
|
||||
@@ -2230,12 +2245,14 @@ func (s *Storage) updatePerDateData(rows []rawRow, mrs []*MetricRow, hmPrev, hmC
|
||||
hmCurrDate := hmCurr.hour / 24
|
||||
nextDayMetricIDsCache := s.nextDayMetricIDs.Load()
|
||||
nextDayIDBID := nextDayMetricIDsCache.idbID
|
||||
nextDayDate := nextDayMetricIDsCache.date + 1
|
||||
nextDayMetricIDs := &nextDayMetricIDsCache.metricIDs
|
||||
ts := fasttime.UnixTimestamp()
|
||||
// Start pre-populating the next per-day inverted index during the last hour of the current day.
|
||||
// pMin linearly increases from 0 to 1 during the last hour of the day.
|
||||
pMin := (float64(ts%(3600*24)) / 3600) - 23
|
||||
currentHour := ts / 3600
|
||||
firstHourOfDay := isFirstHourOfDay(ts)
|
||||
type pendingDateMetricID struct {
|
||||
date uint64
|
||||
tsid *TSID
|
||||
@@ -2279,14 +2296,26 @@ func (s *Storage) updatePerDateData(rows []rawRow, mrs []*MetricRow, hmPrev, hmC
|
||||
}
|
||||
}
|
||||
|
||||
if firstHourOfDay && date == nextDayDate && nextDayMetricIDs.Has(metricID) {
|
||||
// Fast path: the metricID has already been added to the per-day
|
||||
// index during the next day prefill.
|
||||
//
|
||||
// At 00:00 UTC, nextDayMetricIDs become equivalent to
|
||||
// currHourMetricIDs. Use it during the first hour of the day
|
||||
// since currHourMetricIDs is not populated yet.
|
||||
continue
|
||||
}
|
||||
|
||||
if date == hmCurrDate && hmCurr.m.Has(metricID) {
|
||||
// Fast path: the metricID is in the current hour cache.
|
||||
// This means the metricID has been already added to per-day inverted index.
|
||||
// This means the metricID has been already added to per-day
|
||||
// inverted index.
|
||||
continue
|
||||
}
|
||||
|
||||
if date == hmPrevDate && hmPrev.m.Has(metricID) {
|
||||
// Fast path: the metricID is already registered for its day on the previous hour.
|
||||
// Fast path: the metricID is already registered for its day on the
|
||||
// previous hour.
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -2400,12 +2429,29 @@ func fastHashUint64(x uint64) uint64 {
|
||||
// the last hour of the day when the per-day index is prefilled with the next
|
||||
// day entries (see updatePerDayData()).
|
||||
type nextDayMetricIDs struct {
|
||||
idbID uint64
|
||||
date uint64
|
||||
// idbID is the id of the indexDB that stores the next day (date+1) metrics.
|
||||
idbID uint64
|
||||
|
||||
// date is the date (usually the current date) relatively to which the next
|
||||
// day is taken. So next day is date+1.
|
||||
date uint64
|
||||
|
||||
// metricIDs is the set of metricIDs for the next day.
|
||||
metricIDs uint64set.Set
|
||||
}
|
||||
|
||||
func (s *Storage) updateNextDayMetricIDs(date uint64) {
|
||||
// updateNextDayMetricIDs updates s.nextDayMetricIDs with the metricIDs for the
|
||||
// date that follows the timestamp date. For example, if timestamp corresponds
|
||||
// to 2000-01-01, then s.nextDayMetricIDs holds the metricIDs for 2000-01-02.
|
||||
//
|
||||
// The s.nextDayMetricIDs.date and timestamp date must match, otherwise
|
||||
// s.nextDayMetricIDs will be reset. The only exception is the first hour of the
|
||||
// next day when s.nextDayMetricIDs is neither updated with new metricIDs nor
|
||||
// reset. During this time s.nextDayMetricIDs is used in place of
|
||||
// s.currHourMetricIDs to speed up per-day index creation.
|
||||
// See updatePerDateData().
|
||||
func (s *Storage) updateNextDayMetricIDs(timestamp uint64) {
|
||||
date := timestamp / (3600 * 24)
|
||||
ptw := s.tb.MustGetPartition(int64(date+1) * msecPerDay)
|
||||
nextDayIDBID := ptw.pt.idb.id
|
||||
s.tb.PutPartition(ptw)
|
||||
@@ -2414,6 +2460,20 @@ func (s *Storage) updateNextDayMetricIDs(date uint64) {
|
||||
pendingMetricIDs := s.pendingNextDayMetricIDs
|
||||
s.pendingNextDayMetricIDs = &uint64set.Set{}
|
||||
s.pendingNextDayMetricIDsLock.Unlock()
|
||||
|
||||
if e.date+1 == date && isFirstHourOfDay(timestamp) {
|
||||
// Do not reset nextDayMetricIDs during the first hour of the next day
|
||||
// to speed up the creation of per-day indexes in updatePerDateData().
|
||||
//
|
||||
// updatePerDateData() relies on currHourMetricIDs and
|
||||
// prevHourMetricIDs contents to decide whether the per-day index
|
||||
// entries have already been created. At exactly 00:00 UTC (and some
|
||||
// time after it) currHourMetricIDs is empty and prevHourMetricIDs
|
||||
// cannot be used because it contains metricIDs for the previous
|
||||
// day.
|
||||
return
|
||||
}
|
||||
|
||||
// Not comparing indexDB IDs because different idb ids imply different date.
|
||||
if pendingMetricIDs.Len() == 0 && e.date == date {
|
||||
// Fast path: nothing to update.
|
||||
@@ -2434,7 +2494,8 @@ func (s *Storage) updateNextDayMetricIDs(date uint64) {
|
||||
pendingMetricIDs.Union(&e.metricIDs)
|
||||
} else {
|
||||
// Do not add pendingMetricIDs from the previous day to the current day,
|
||||
// since this may result in missing registration of the metricIDs in the per-day inverted index.
|
||||
// since this may result in missing registration of the metricIDs in the
|
||||
// per-day inverted index.
|
||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3309
|
||||
pendingMetricIDs = &uint64set.Set{}
|
||||
}
|
||||
|
||||
@@ -554,36 +554,72 @@ func TestStorageAddRows_nextDayIndexPrefill(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestStorageMustLoadNextDayMetricIDs(t *testing.T) {
|
||||
defer testRemoveAll(t)
|
||||
|
||||
assertNextDayMetricIDs := func(t *testing.T, gotNextDayMetricIDs *nextDayMetricIDs, wantIDBID, wantDate uint64, wantLen int) {
|
||||
t.Helper()
|
||||
|
||||
if got, want := gotNextDayMetricIDs.idbID, wantIDBID; got != want {
|
||||
t.Fatalf("unexpected nextDayMetricIDs idb id: got %d, want %d", got, want)
|
||||
}
|
||||
if got, want := gotNextDayMetricIDs.date, wantDate; got != want {
|
||||
t.Fatalf("unexpected nextDayMetricIDs date: got %d, want %d", got, want)
|
||||
}
|
||||
if got, want := gotNextDayMetricIDs.metricIDs.Len(), wantLen; got != want {
|
||||
t.Fatalf("unexpected nextDayMetricIDs count: got %d, want %d", got, want)
|
||||
}
|
||||
func assertPendingNextDayMetricIDsEmpty(t *testing.T, s *Storage) {
|
||||
t.Helper()
|
||||
got := s.pendingNextDayMetricIDs.Len()
|
||||
if got != 0 {
|
||||
t.Fatalf("unexpected s.pendingNextDayMetricIDs count: got %d, want 0", got)
|
||||
}
|
||||
}
|
||||
|
||||
func assertPendingNextDayMetricIDsNotEmpty(t *testing.T, s *Storage) {
|
||||
t.Helper()
|
||||
got := s.pendingNextDayMetricIDs.Len()
|
||||
if got == 0 {
|
||||
t.Fatalf("unexpected s.pendingNextDayMetricIDs count: got 0, want > 0")
|
||||
}
|
||||
}
|
||||
|
||||
func assertNextDayMetricIDs(t *testing.T, s *Storage, wantIDBID, wantDate uint64, wantLen int) {
|
||||
t.Helper()
|
||||
|
||||
gotNextDayMetricIDs := s.nextDayMetricIDs.Load()
|
||||
|
||||
if got, want := gotNextDayMetricIDs.idbID, wantIDBID; got != want {
|
||||
t.Fatalf("unexpected nextDayMetricIDs idb id: got %d, want %d", got, want)
|
||||
}
|
||||
if got, want := gotNextDayMetricIDs.date, wantDate; got != want {
|
||||
t.Fatalf("unexpected nextDayMetricIDs date: got %d, want %d", got, want)
|
||||
}
|
||||
if got, want := gotNextDayMetricIDs.metricIDs.Len(), wantLen; got != want {
|
||||
t.Fatalf("unexpected nextDayMetricIDs count: got %d, want %d", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func sleepUntil(t *testing.T, year int, month time.Month, day, hour, min, sec, nsec int) {
|
||||
t.Helper()
|
||||
future := time.Date(year, month, day, hour, min, sec, nsec, time.UTC)
|
||||
now := time.Now().UTC()
|
||||
d := future.Sub(now)
|
||||
if d <= 0 {
|
||||
t.Fatalf("future time %v is before now time %v", future, now)
|
||||
}
|
||||
time.Sleep(d)
|
||||
}
|
||||
|
||||
// TestStorageNextDayMetricIDs_updatedAsynchronously verifies that the metricIDs
|
||||
// registered in per-day index during the next day prefill do not appear in
|
||||
// Storage.nextDayMetricIDs right away but only after some time (seconds).
|
||||
func TestStorageNextDayMetricIDs_updatedAsynchronously(t *testing.T) {
|
||||
defer testRemoveAll(t)
|
||||
|
||||
synctest.Test(t, func(t *testing.T) {
|
||||
// synctest starts at 2000-01-01T00:00:00Z.
|
||||
// Advance time to 23:30 to enable next day prefill.
|
||||
time.Sleep(23*time.Hour + 30*time.Minute) // 2000-01-01T23:30:00Z
|
||||
date := uint64(time.Now().UnixMilli()) / msecPerDay
|
||||
|
||||
// Advance time to the last hour of the day to enable next day index
|
||||
// prefill.
|
||||
sleepUntil(t, 2000, 1, 1, 23, 30, 30, 0)
|
||||
|
||||
const numSeries = 1000
|
||||
s := MustOpenStorage(t.Name(), OpenOptions{})
|
||||
defer s.MustClose()
|
||||
ptw := s.tb.MustGetPartition(time.Now().UnixMilli())
|
||||
idbID := ptw.pt.idb.id
|
||||
s.tb.PutPartition(ptw)
|
||||
|
||||
date := uint64(time.Now().UnixMilli()) / msecPerDay
|
||||
rng := rand.New(rand.NewSource(1))
|
||||
|
||||
// Insert some data.
|
||||
mrs := testGenerateMetricRowsWithPrefix(rng, numSeries, "metric", TimeRange{
|
||||
MinTimestamp: time.Now().Add(-15 * time.Minute).UnixMilli(),
|
||||
MaxTimestamp: time.Now().UnixMilli(),
|
||||
@@ -591,50 +627,201 @@ func TestStorageMustLoadNextDayMetricIDs(t *testing.T) {
|
||||
s.AddRows(mrs, defaultPrecisionBits)
|
||||
s.DebugFlush()
|
||||
|
||||
// The next day metricIDs must appear in pendingNextDayMetricIDs cache.
|
||||
if s.pendingNextDayMetricIDs.Len() == 0 {
|
||||
t.Fatalf("unexpected pendingNextDayMetricIDs count: got 0, want > 0")
|
||||
}
|
||||
// Immediately after data ingestion, the next day metricIDs must appear
|
||||
// in s.pendingNextDayMetricIDs but not in the s.nextDayMetricIDs. The
|
||||
// pending metrics will be moved to it by a background task a few seconds
|
||||
// later.
|
||||
assertPendingNextDayMetricIDsNotEmpty(t, s)
|
||||
assertNextDayMetricIDs(t, s, idbID, date, 0)
|
||||
numNextDayMetricIDs := s.pendingNextDayMetricIDs.Len()
|
||||
// But not in the nextDayMetricIDs cache. The pending metrics will be
|
||||
// moved to it by a bg process a few seconds later.
|
||||
assertNextDayMetricIDs(t, s.nextDayMetricIDs.Load(), idbID, date, 0)
|
||||
|
||||
// Wait for nextDayMetricIDs cache to populate.
|
||||
time.Sleep(15 * time.Second)
|
||||
synctest.Wait()
|
||||
|
||||
// At this point, pending metricIDs must have been moved to
|
||||
// nextDayMetricIDs cache and the pendingNextDayMetricIDs must be empty.
|
||||
if got := s.pendingNextDayMetricIDs.Len(); got != 0 {
|
||||
t.Fatalf("unexpected pendingNextDayMetricIDs count: got %d, want 0", got)
|
||||
}
|
||||
// While the actual cache, must contain the exact number of metricIDs
|
||||
// Wait for nextDayMetricIDs to populate. Pending metricIDs must be
|
||||
// moved to nextDayMetricIDs after which pendingNextDayMetricIDs must be
|
||||
// empty. nextDayMetricIDs must contain the exact number of metricIDs
|
||||
// that once were pending.
|
||||
assertNextDayMetricIDs(t, s.nextDayMetricIDs.Load(), idbID, date, numNextDayMetricIDs)
|
||||
time.Sleep(15 * time.Second)
|
||||
assertPendingNextDayMetricIDsEmpty(t, s)
|
||||
assertNextDayMetricIDs(t, s, idbID, date, numNextDayMetricIDs)
|
||||
})
|
||||
}
|
||||
|
||||
// Close the storage to persist nextDayMetricIDs cache to a file.
|
||||
s.MustClose()
|
||||
// Open the storage again to ensure that the cache is populated
|
||||
// correctly.
|
||||
s = MustOpenStorage(t.Name(), OpenOptions{})
|
||||
if got := s.pendingNextDayMetricIDs.Len(); got != 0 {
|
||||
t.Fatalf("unexpected pendingNextDayMetricIDs count: got %d, want 0", got)
|
||||
}
|
||||
assertNextDayMetricIDs(t, s.nextDayMetricIDs.Load(), idbID, date, numNextDayMetricIDs)
|
||||
s.MustClose()
|
||||
// TestStorageNextDayMetricIDs_loadFromStoreToFile verifies the logic of loading
|
||||
// Storage.nextDayMetricIDs from file during the storage start-up and storing it
|
||||
// back to a file during the storage shutdown.
|
||||
func TestStorageNextDayMetricIDs_loadFromStoreToFile(t *testing.T) {
|
||||
defer testRemoveAll(t)
|
||||
|
||||
// Advance the time by one day and open the storage.
|
||||
// Since the current date and the date in the cache file do not match,
|
||||
// nothing will be loaded into cache.
|
||||
time.Sleep(24 * time.Hour)
|
||||
date = uint64(time.Now().UnixMilli()) / msecPerDay
|
||||
s = MustOpenStorage(t.Name(), OpenOptions{})
|
||||
if got := s.pendingNextDayMetricIDs.Len(); got != 0 {
|
||||
t.Fatalf("unexpected pendingNextDayMetricIDs count: got %d, want 0", got)
|
||||
}
|
||||
assertNextDayMetricIDs(t, s.nextDayMetricIDs.Load(), idbID, date, 0)
|
||||
synctest.Test(t, func(t *testing.T) {
|
||||
// synctest starts at 2000-01-01T00:00:00Z.
|
||||
|
||||
// Advance time to the last hour of the day to enable next day index
|
||||
// prefill.
|
||||
sleepUntil(t, 2000, 1, 1, 23, 30, 30, 0)
|
||||
|
||||
const numSeries = 1000
|
||||
s := MustOpenStorage(t.Name(), OpenOptions{})
|
||||
ptw := s.tb.MustGetPartition(time.Now().UnixMilli())
|
||||
idbID := ptw.pt.idb.id
|
||||
s.tb.PutPartition(ptw)
|
||||
date := uint64(time.Now().UnixMilli()) / msecPerDay
|
||||
|
||||
// Insert some data. Next day metricIDs must appear in
|
||||
// Storage.nextDayMetricIDs.
|
||||
rng := rand.New(rand.NewSource(1))
|
||||
mrs := testGenerateMetricRowsWithPrefix(rng, numSeries, "metric", TimeRange{
|
||||
MinTimestamp: time.Now().Add(-15 * time.Minute).UnixMilli(),
|
||||
MaxTimestamp: time.Now().UnixMilli(),
|
||||
})
|
||||
s.AddRows(mrs, defaultPrecisionBits)
|
||||
s.DebugFlush()
|
||||
numNextDayMetricIDs := s.pendingNextDayMetricIDs.Len()
|
||||
time.Sleep(15 * time.Second)
|
||||
assertNextDayMetricIDs(t, s, idbID, date, numNextDayMetricIDs)
|
||||
|
||||
// Close the storage to persist nextDayMetricIDs to a file and then open
|
||||
// it again to ensure that nextDayMetricIDs is populated correctly.
|
||||
s.MustClose()
|
||||
s = MustOpenStorage(t.Name(), OpenOptions{})
|
||||
assertNextDayMetricIDs(t, s, idbID, date, numNextDayMetricIDs)
|
||||
|
||||
// Close storage and open it again at the last moment of the day.
|
||||
// nextDayMetricIDs must still be populated.
|
||||
s.MustClose()
|
||||
sleepUntil(t, 2000, 1, 1, 23, 59, 59, 999_999_999)
|
||||
s = MustOpenStorage(t.Name(), OpenOptions{})
|
||||
assertNextDayMetricIDs(t, s, idbID, date, numNextDayMetricIDs)
|
||||
|
||||
// Close storage and open it again at the first second of the next day.
|
||||
// nextDayMetricIDs must still be populated because nextDayMetricIDs
|
||||
// needs to be preserved during the first hour of the day in order to
|
||||
// speed up data ingestion.
|
||||
s.MustClose()
|
||||
sleepUntil(t, 2000, 1, 2, 0, 0, 0, 0)
|
||||
s = MustOpenStorage(t.Name(), OpenOptions{})
|
||||
assertNextDayMetricIDs(t, s, idbID, date, numNextDayMetricIDs)
|
||||
|
||||
// Close storage and open it again at the last moment of the first hour
|
||||
// of the next day. nextDayMetricIDs must still be populated.
|
||||
s.MustClose()
|
||||
sleepUntil(t, 2000, 1, 2, 0, 59, 59, 999_999_999)
|
||||
s = MustOpenStorage(t.Name(), OpenOptions{})
|
||||
assertNextDayMetricIDs(t, s, idbID, date, numNextDayMetricIDs)
|
||||
|
||||
// Close storage and open it again at the first second of the second
|
||||
// hour of the next day. nextDayMetricIDs must be reset.
|
||||
s.MustClose()
|
||||
sleepUntil(t, 2000, 1, 2, 1, 0, 0, 0)
|
||||
s = MustOpenStorage(t.Name(), OpenOptions{})
|
||||
assertNextDayMetricIDs(t, s, idbID, date+1, 0)
|
||||
|
||||
// Close the storage and open it again at the last hour.
|
||||
// Insert data again to populate nextDayMetricIDs.
|
||||
s.MustClose()
|
||||
sleepUntil(t, 2000, 1, 2, 23, 30, 0, 0)
|
||||
s = MustOpenStorage(t.Name(), OpenOptions{})
|
||||
mrs = testGenerateMetricRowsWithPrefix(rng, numSeries, "metric", TimeRange{
|
||||
MinTimestamp: time.Now().Add(-15 * time.Minute).UnixMilli(),
|
||||
MaxTimestamp: time.Now().UnixMilli(),
|
||||
})
|
||||
s.AddRows(mrs, defaultPrecisionBits)
|
||||
s.DebugFlush()
|
||||
numNextDayMetricIDs = s.pendingNextDayMetricIDs.Len()
|
||||
time.Sleep(15 * time.Second)
|
||||
assertNextDayMetricIDs(t, s, idbID, date+1, numNextDayMetricIDs)
|
||||
|
||||
// Close storage and open it again 24h later.
|
||||
// While it is the last hour of the day, the current date and the date
|
||||
// in nextDayMetricIDs do not match and therefore nextDayMetricIDs must
|
||||
// not be populated.
|
||||
s.MustClose()
|
||||
sleepUntil(t, 2000, 1, 3, 23, 30, 0, 0)
|
||||
s = MustOpenStorage(t.Name(), OpenOptions{})
|
||||
assertNextDayMetricIDs(t, s, idbID, date+2, 0)
|
||||
|
||||
// Ingest some data and confirm nextDayMetricIDs is not empty.
|
||||
mrs = testGenerateMetricRowsWithPrefix(rng, numSeries, "metric", TimeRange{
|
||||
MinTimestamp: time.Now().Add(-15 * time.Minute).UnixMilli(),
|
||||
MaxTimestamp: time.Now().UnixMilli(),
|
||||
})
|
||||
s.AddRows(mrs, defaultPrecisionBits)
|
||||
s.DebugFlush()
|
||||
numNextDayMetricIDs = s.pendingNextDayMetricIDs.Len()
|
||||
time.Sleep(15 * time.Second)
|
||||
assertNextDayMetricIDs(t, s, idbID, date+2, numNextDayMetricIDs)
|
||||
|
||||
// Close storage and open it again at the first hour of the day after
|
||||
// tomorrow. While it is the last hour of the day, the metricIDs in
|
||||
// nextDayMetricIDs is not from yesterday but the day before yesterday
|
||||
// and therefore nextDayMetricIDs must not be populated but it's date
|
||||
// must still be day before the current date.
|
||||
s.MustClose()
|
||||
sleepUntil(t, 2000, 1, 5, 0, 30, 0, 0)
|
||||
s = MustOpenStorage(t.Name(), OpenOptions{})
|
||||
assertNextDayMetricIDs(t, s, idbID, date+3, 0)
|
||||
|
||||
// Close the storage to conclude the test.
|
||||
s.MustClose()
|
||||
})
|
||||
}
|
||||
|
||||
// TestStorageNextDayMetricIDs_loadFromStoreToFile verifies the logic of updating
|
||||
// Storage.nextDayMetricIDs at runtime.
|
||||
func TestStorageNextDayMetricIDs_update(t *testing.T) {
|
||||
defer testRemoveAll(t)
|
||||
|
||||
synctest.Test(t, func(t *testing.T) {
|
||||
// synctest starts at 2000-01-01T00:00:00Z.
|
||||
|
||||
// Advance time to just before the last hour of the day.
|
||||
sleepUntil(t, 2000, 1, 1, 22, 59, 59, 999_999_999)
|
||||
|
||||
const numSeries = 1000
|
||||
s := MustOpenStorage(t.Name(), OpenOptions{})
|
||||
defer s.MustClose()
|
||||
ptw := s.tb.MustGetPartition(time.Now().UnixMilli())
|
||||
idbID := ptw.pt.idb.id
|
||||
s.tb.PutPartition(ptw)
|
||||
date := uint64(time.Now().UnixMilli()) / msecPerDay
|
||||
rng := rand.New(rand.NewSource(1))
|
||||
|
||||
// The next day index prefill must not start before the last hour of the
|
||||
// day. Therefore, nextDayMetricIDs must be empty.
|
||||
mrs := testGenerateMetricRowsWithPrefix(rng, numSeries, "metric", TimeRange{
|
||||
MinTimestamp: time.Now().Add(-15 * time.Minute).UnixMilli(),
|
||||
MaxTimestamp: time.Now().UnixMilli(),
|
||||
})
|
||||
s.AddRows(mrs, defaultPrecisionBits)
|
||||
s.DebugFlush()
|
||||
assertNextDayMetricIDs(t, s, idbID, date, 0)
|
||||
|
||||
// Advance time to the middle of the last hour of the day to enable next
|
||||
// day prefill and insert some data. Next day metricIDs must appear in
|
||||
// Storage.nextDayMetricIDs.
|
||||
sleepUntil(t, 2000, 1, 1, 23, 30, 0, 0)
|
||||
mrs = testGenerateMetricRowsWithPrefix(rng, numSeries, "metric", TimeRange{
|
||||
MinTimestamp: time.Now().Add(-15 * time.Minute).UnixMilli(),
|
||||
MaxTimestamp: time.Now().UnixMilli(),
|
||||
})
|
||||
s.AddRows(mrs, defaultPrecisionBits)
|
||||
s.DebugFlush()
|
||||
numNextDayMetricIDs := s.pendingNextDayMetricIDs.Len()
|
||||
time.Sleep(15 * time.Second)
|
||||
assertNextDayMetricIDs(t, s, idbID, date, numNextDayMetricIDs)
|
||||
|
||||
// Advance the time to the end of the last hour of the current day and
|
||||
// confirm that nextDayMetricIDs are not reset during this hour.
|
||||
sleepUntil(t, 2000, 1, 1, 23, 59, 59, 999_999_999)
|
||||
assertNextDayMetricIDs(t, s, idbID, date, numNextDayMetricIDs)
|
||||
|
||||
// Advance the time to the end of the first hour of the next day and
|
||||
// confirm that nextDayMetricIDs are not reset during this hour.
|
||||
sleepUntil(t, 2000, 1, 2, 0, 59, 59, 999_999_999)
|
||||
assertNextDayMetricIDs(t, s, idbID, date, numNextDayMetricIDs)
|
||||
|
||||
// Advance the time to the beginning of the second hour of the next day and
|
||||
// confirm that nextDayMetricIDs is reset.
|
||||
sleepUntil(t, 2000, 1, 2, 1, 0, 30, 0)
|
||||
assertNextDayMetricIDs(t, s, idbID, date+1, 0)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,12 @@ func timestampFromTime(t time.Time) int64 {
|
||||
return t.UnixNano() / 1e6
|
||||
}
|
||||
|
||||
// Returns true if the timestamp (must be in seconds) is within the first hour
|
||||
// of the day.
|
||||
func isFirstHourOfDay(timestamp uint64) bool {
|
||||
return (timestamp/3600)%24 == 0
|
||||
}
|
||||
|
||||
// TimeRange is time range.
|
||||
type TimeRange struct {
|
||||
MinTimestamp int64
|
||||
|
||||
@@ -203,3 +203,29 @@ func TestTimeRange_fromPartitionTimestamp(t *testing.T) {
|
||||
MaxTimestamp: time.Date(2025, 3, 31, 23, 59, 59, 999_000_000, time.UTC).UnixMilli(),
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsFirstHourOfDay(t *testing.T) {
|
||||
f := func(tt time.Time, want bool) {
|
||||
got := isFirstHourOfDay(uint64(tt.Unix()))
|
||||
if got != want {
|
||||
t.Fatalf("isFirstHourOfDay(%v) unexpected result: got %t, want %t", tt, got, want)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
firstHourOfDay := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
f(firstHourOfDay, true)
|
||||
firstHourOfDay = time.Date(2000, 1, 1, 0, 12, 34, 56789, time.UTC)
|
||||
f(firstHourOfDay, true)
|
||||
firstHourOfDay = time.Date(2000, 1, 1, 0, 59, 59, 999_999_999, time.UTC)
|
||||
f(firstHourOfDay, true)
|
||||
|
||||
secondHourOfDay := time.Date(2000, 1, 1, 1, 0, 0, 0, time.UTC)
|
||||
f(secondHourOfDay, false)
|
||||
|
||||
sixthHourOfDay := time.Date(2000, 1, 1, 5, 0, 0, 0, time.UTC)
|
||||
f(sixthHourOfDay, false)
|
||||
|
||||
lastHourOfDay := time.Date(2000, 1, 1, 23, 59, 59, 999_999_999, time.UTC)
|
||||
f(lastHourOfDay, false)
|
||||
}
|
||||
|
||||
8
vendor/cloud.google.com/go/auth/CHANGES.md
generated
vendored
@@ -1,5 +1,13 @@
|
||||
# Changes
|
||||
|
||||
## [0.20.0](https://github.com/googleapis/google-cloud-go/releases/tag/auth%2Fv0.20.0) (2026-04-06)
|
||||
|
||||
## [0.19.0](https://github.com/googleapis/google-cloud-go/releases/tag/auth%2Fv0.19.0) (2026-03-23)
|
||||
|
||||
### Features
|
||||
|
||||
* add OpenTelemetry gRPC and HTTP wrappers for T4 tracing (#14133) ([d38abf9](https://github.com/googleapis/google-cloud-go/commit/d38abf988d4017b4832434abae9a90874bec5ce9))
|
||||
|
||||
## [0.18.2](https://github.com/googleapis/google-cloud-go/releases/tag/auth%2Fv0.18.2) (2026-02-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
249
vendor/cloud.google.com/go/auth/grpctransport/grpctransport.go
generated
vendored
@@ -22,19 +22,27 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
"cloud.google.com/go/auth/credentials"
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"cloud.google.com/go/auth/internal/transport"
|
||||
"cloud.google.com/go/auth/internal/transport/headers"
|
||||
"github.com/googleapis/gax-go/v2"
|
||||
"github.com/googleapis/gax-go/v2/callctx"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"google.golang.org/grpc"
|
||||
grpccreds "google.golang.org/grpc/credentials"
|
||||
grpcinsecure "google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/stats"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -47,6 +55,30 @@ const (
|
||||
quotaProjectHeaderKey = "X-goog-user-project"
|
||||
)
|
||||
|
||||
// codeToStr is a reversal of the `strToCode` map in
|
||||
// https://github.com/grpc/grpc-go/blob/master/codes/codes.go
|
||||
// The gRPC specification has exactly 17 status codes, defined
|
||||
// as a contiguous block of integers from 0 to 16.
|
||||
var codeToStr = [...]string{
|
||||
"OK", // codes.OK = 0
|
||||
"CANCELED", // codes.Canceled = 1
|
||||
"UNKNOWN", // codes.Unknown = 2
|
||||
"INVALID_ARGUMENT", // codes.InvalidArgument = 3
|
||||
"DEADLINE_EXCEEDED", // codes.DeadlineExceeded = 4
|
||||
"NOT_FOUND", // codes.NotFound = 5
|
||||
"ALREADY_EXISTS", // codes.AlreadyExists = 6
|
||||
"PERMISSION_DENIED", // codes.PermissionDenied = 7
|
||||
"RESOURCE_EXHAUSTED", // codes.ResourceExhausted = 8
|
||||
"FAILED_PRECONDITION", // codes.FailedPrecondition = 9
|
||||
"ABORTED", // codes.Aborted = 10
|
||||
"OUT_OF_RANGE", // codes.OutOfRange = 11
|
||||
"UNIMPLEMENTED", // codes.Unimplemented = 12
|
||||
"INTERNAL", // codes.Internal = 13
|
||||
"UNAVAILABLE", // codes.Unavailable = 14
|
||||
"DATA_LOSS", // codes.DataLoss = 15
|
||||
"UNAUTHENTICATED", // codes.Unauthenticated = 16
|
||||
}
|
||||
|
||||
var (
|
||||
// Set at init time by dial_socketopt.go. If nil, socketopt is not supported.
|
||||
timeoutDialerOption grpc.DialOption
|
||||
@@ -198,7 +230,7 @@ type InternalOptions struct {
|
||||
// service.
|
||||
DefaultScopes []string
|
||||
// SkipValidation bypasses validation on Options. It should only be used
|
||||
// internally for clients that needs more control over their transport.
|
||||
// internally for clients that need more control over their transport.
|
||||
SkipValidation bool
|
||||
// TelemetryAttributes specifies a map of telemetry attributes to be added
|
||||
// to all OpenTelemetry signals, such as tracing and metrics, for purposes
|
||||
@@ -338,7 +370,7 @@ func dial(ctx context.Context, secure bool, opts *Options) (*grpc.ClientConn, er
|
||||
// Add tracing, but before the other options, so that clients can override the
|
||||
// gRPC stats handler.
|
||||
// This assumes that gRPC options are processed in order, left to right.
|
||||
grpcOpts = addOpenTelemetryStatsHandler(grpcOpts, opts)
|
||||
grpcOpts = addOpenTelemetryStatsHandler(grpcOpts, opts, transportCreds.Endpoint)
|
||||
grpcOpts = append(grpcOpts, opts.GRPCDialOpts...)
|
||||
|
||||
return grpc.DialContext(ctx, transportCreds.Endpoint, grpcOpts...)
|
||||
@@ -426,9 +458,218 @@ func (c *grpcCredentialsProvider) RequireTransportSecurity() bool {
|
||||
return c.secure
|
||||
}
|
||||
|
||||
func addOpenTelemetryStatsHandler(dialOpts []grpc.DialOption, opts *Options) []grpc.DialOption {
|
||||
func addOpenTelemetryStatsHandler(dialOpts []grpc.DialOption, opts *Options, endpoint string) []grpc.DialOption {
|
||||
if opts.DisableTelemetry {
|
||||
return dialOpts
|
||||
}
|
||||
return append(dialOpts, grpc.WithStatsHandler(otelgrpc.NewClientHandler()))
|
||||
if gax.IsFeatureEnabled("METRICS") {
|
||||
host, port := extractHostPort(endpoint)
|
||||
dialOpts = append(dialOpts, grpc.WithChainUnaryInterceptor(openTelemetryUnaryClientInterceptor(host, port)))
|
||||
}
|
||||
if !gax.IsFeatureEnabled("TRACING") && !gax.IsFeatureEnabled("LOGGING") {
|
||||
return append(dialOpts, grpc.WithStatsHandler(otelgrpc.NewClientHandler()))
|
||||
}
|
||||
var staticAttrs []attribute.KeyValue
|
||||
var scopedLogger *slog.Logger
|
||||
|
||||
if gax.IsFeatureEnabled("LOGGING") && opts.Logger != nil {
|
||||
scopedLogger = opts.Logger
|
||||
}
|
||||
|
||||
if opts.InternalOptions != nil {
|
||||
staticAttrs = transport.StaticTelemetryAttributes(opts.InternalOptions.TelemetryAttributes)
|
||||
if scopedLogger != nil {
|
||||
var staticLogAttrs []any
|
||||
for _, attr := range staticAttrs {
|
||||
staticLogAttrs = append(staticLogAttrs, slog.String(string(attr.Key), attr.Value.AsString()))
|
||||
}
|
||||
scopedLogger = scopedLogger.With(staticLogAttrs...)
|
||||
}
|
||||
}
|
||||
var otelOpts []otelgrpc.Option
|
||||
if gax.IsFeatureEnabled("TRACING") {
|
||||
otelOpts = append(otelOpts, otelgrpc.WithSpanAttributes(staticAttrs...))
|
||||
}
|
||||
return append(dialOpts, grpc.WithStatsHandler(&otelHandler{
|
||||
Handler: otelgrpc.NewClientHandler(otelOpts...),
|
||||
logger: scopedLogger,
|
||||
}))
|
||||
}
|
||||
|
||||
// Extract the host and port from a target address
|
||||
func extractHostPort(target string) (string, int) {
|
||||
if idx := strings.Index(target, "://"); idx != -1 {
|
||||
target = target[idx+3:]
|
||||
// Ensure any leading authorities (like 8.8.8.8 in dns://8.8.8.8/foo) are stripped
|
||||
if slashIdx := strings.Index(target, "/"); slashIdx != -1 {
|
||||
target = target[slashIdx+1:]
|
||||
}
|
||||
}
|
||||
host, portStr, err := net.SplitHostPort(target)
|
||||
if err != nil {
|
||||
return target, 0
|
||||
}
|
||||
port, err := strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
return host, 0
|
||||
}
|
||||
return host, port
|
||||
}
|
||||
|
||||
// openTelemetryUnaryClientInterceptor returns an interceptor that populates
|
||||
// TransportTelemetryData with the server peer address.
|
||||
func openTelemetryUnaryClientInterceptor(host string, port int) grpc.UnaryClientInterceptor {
|
||||
return func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
|
||||
transportData := gax.ExtractTransportTelemetry(ctx)
|
||||
if transportData != nil {
|
||||
if host != "" {
|
||||
transportData.SetServerAddress(host)
|
||||
}
|
||||
if port != 0 {
|
||||
transportData.SetServerPort(port)
|
||||
}
|
||||
}
|
||||
|
||||
err := invoker(ctx, method, req, reply, cc, opts...)
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// otelHandler is a wrapper around the OpenTelemetry gRPC client handler that
|
||||
// adds custom Google Cloud-specific attributes to spans and metrics.
|
||||
type otelHandler struct {
|
||||
stats.Handler
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
// TagRPC intercepts the RPC start to extract dynamic attributes like resource
|
||||
// name and retry count from the outgoing context metadata and attach them to
|
||||
// the current span.
|
||||
func (h *otelHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context {
|
||||
ctx = h.Handler.TagRPC(ctx, info)
|
||||
|
||||
var span trace.Span
|
||||
if gax.IsFeatureEnabled("TRACING") {
|
||||
if s := trace.SpanFromContext(ctx); s != nil && s.IsRecording() {
|
||||
span = s
|
||||
}
|
||||
}
|
||||
|
||||
if span == nil {
|
||||
return ctx
|
||||
}
|
||||
var attrs []attribute.KeyValue
|
||||
if resName, ok := callctx.TelemetryFromContext(ctx, "resource_name"); ok {
|
||||
attrs = append(attrs, attribute.String("gcp.resource.destination.id", resName))
|
||||
}
|
||||
if resendCountStr, ok := callctx.TelemetryFromContext(ctx, "resend_count"); ok {
|
||||
if count, err := strconv.Atoi(resendCountStr); err == nil {
|
||||
attrs = append(attrs, attribute.Int("gcp.grpc.resend_count", count))
|
||||
}
|
||||
}
|
||||
if len(attrs) > 0 {
|
||||
span.SetAttributes(attrs...)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
// HandleRPC intercepts the RPC completion to capture and format error-related
|
||||
// attributes ensuring they conform to Google Cloud observability standards.
|
||||
func (h *otelHandler) HandleRPC(ctx context.Context, s stats.RPCStats) {
|
||||
end, ok := s.(*stats.End)
|
||||
if !ok {
|
||||
h.Handler.HandleRPC(ctx, s)
|
||||
return
|
||||
}
|
||||
|
||||
var span trace.Span
|
||||
if gax.IsFeatureEnabled("TRACING") {
|
||||
if s := trace.SpanFromContext(ctx); s != nil && s.IsRecording() {
|
||||
span = s
|
||||
}
|
||||
}
|
||||
|
||||
var logger *slog.Logger
|
||||
if gax.IsFeatureEnabled("LOGGING") {
|
||||
if l := h.logger; l != nil && l.Enabled(ctx, slog.LevelDebug) {
|
||||
logger = l
|
||||
}
|
||||
}
|
||||
|
||||
if span == nil && logger == nil {
|
||||
h.Handler.HandleRPC(ctx, s)
|
||||
return
|
||||
}
|
||||
|
||||
if end.Error != nil {
|
||||
h.handleRPCError(ctx, span, logger, end)
|
||||
} else {
|
||||
h.handleRPCSuccess(span)
|
||||
}
|
||||
h.Handler.HandleRPC(ctx, s)
|
||||
}
|
||||
|
||||
func (h *otelHandler) handleRPCError(ctx context.Context, span trace.Span, logger *slog.Logger, end *stats.End) {
|
||||
info := gax.ExtractTelemetryErrorInfo(ctx, end.Error)
|
||||
|
||||
if logger != nil {
|
||||
logActionableError(ctx, logger, info)
|
||||
}
|
||||
|
||||
if span != nil {
|
||||
attrs := []attribute.KeyValue{
|
||||
attribute.String("error.type", info.ErrorType),
|
||||
attribute.String("status.message", info.StatusMessage),
|
||||
attribute.String("rpc.response.status_code", info.StatusCode),
|
||||
attribute.String("exception.type", fmt.Sprintf("%T", end.Error)),
|
||||
}
|
||||
span.SetAttributes(attrs...)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *otelHandler) handleRPCSuccess(span trace.Span) {
|
||||
if span != nil {
|
||||
attrs := []attribute.KeyValue{
|
||||
attribute.String("rpc.response.status_code", "OK"),
|
||||
}
|
||||
span.SetAttributes(attrs...)
|
||||
}
|
||||
}
|
||||
|
||||
func logActionableError(ctx context.Context, logger *slog.Logger, info gax.TelemetryErrorInfo) {
|
||||
baseLogAttrs := []slog.Attr{
|
||||
slog.String("rpc.system.name", "grpc"),
|
||||
slog.String("rpc.response.status_code", info.StatusCode),
|
||||
}
|
||||
|
||||
if resendCountStr, ok := callctx.TelemetryFromContext(ctx, "resend_count"); ok {
|
||||
if count, e := strconv.Atoi(resendCountStr); e == nil {
|
||||
baseLogAttrs = append(baseLogAttrs, slog.Int64("gcp.grpc.resend_count", int64(count)))
|
||||
}
|
||||
}
|
||||
|
||||
msg := info.StatusMessage
|
||||
if msg == "" {
|
||||
msg = "API call failed"
|
||||
}
|
||||
|
||||
if rpcMethod, ok := callctx.TelemetryFromContext(ctx, "rpc_method"); ok {
|
||||
baseLogAttrs = append(baseLogAttrs, slog.String("rpc.method", rpcMethod))
|
||||
}
|
||||
|
||||
if resName, ok := callctx.TelemetryFromContext(ctx, "resource_name"); ok {
|
||||
baseLogAttrs = append(baseLogAttrs, slog.String("gcp.resource.destination.id", resName))
|
||||
}
|
||||
|
||||
if info.Domain != "" {
|
||||
baseLogAttrs = append(baseLogAttrs, slog.String("gcp.errors.domain", info.Domain))
|
||||
}
|
||||
for k, v := range info.Metadata {
|
||||
baseLogAttrs = append(baseLogAttrs, slog.String("gcp.errors.metadata."+k, v))
|
||||
}
|
||||
|
||||
baseLogAttrs = append(baseLogAttrs, slog.String("error.type", info.ErrorType))
|
||||
|
||||
logger.LogAttrs(ctx, slog.LevelDebug, msg, baseLogAttrs...)
|
||||
}
|
||||
|
||||
315
vendor/cloud.google.com/go/auth/httptransport/transport.go
generated
vendored
@@ -15,11 +15,17 @@
|
||||
package httptransport
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
@@ -28,12 +34,18 @@ import (
|
||||
"cloud.google.com/go/auth/internal/transport"
|
||||
"cloud.google.com/go/auth/internal/transport/cert"
|
||||
"cloud.google.com/go/auth/internal/transport/headers"
|
||||
"github.com/googleapis/gax-go/v2"
|
||||
"github.com/googleapis/gax-go/v2/callctx"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"golang.org/x/net/http2"
|
||||
"google.golang.org/api/googleapi"
|
||||
)
|
||||
|
||||
const (
|
||||
quotaProjectHeaderKey = "X-goog-user-project"
|
||||
maxErrorReadBytes = int64(8192) // 8KB
|
||||
)
|
||||
|
||||
func newTransport(base http.RoundTripper, opts *Options) (http.RoundTripper, error) {
|
||||
@@ -173,7 +185,308 @@ func addOpenTelemetryTransport(trans http.RoundTripper, opts *Options) http.Roun
|
||||
if opts.DisableTelemetry {
|
||||
return trans
|
||||
}
|
||||
return otelhttp.NewTransport(trans)
|
||||
|
||||
var traceAttrs []attribute.KeyValue
|
||||
var scopedLogger *slog.Logger
|
||||
|
||||
if gax.IsFeatureEnabled("LOGGING") && opts.Logger != nil {
|
||||
scopedLogger = opts.Logger
|
||||
}
|
||||
|
||||
if opts.InternalOptions != nil {
|
||||
attrs := transport.StaticTelemetryAttributes(opts.InternalOptions.TelemetryAttributes)
|
||||
if gax.IsFeatureEnabled("TRACING") {
|
||||
traceAttrs = attrs
|
||||
}
|
||||
if scopedLogger != nil {
|
||||
var logAttrs []any
|
||||
for _, attr := range attrs {
|
||||
logAttrs = append(logAttrs, slog.String(string(attr.Key), attr.Value.AsString()))
|
||||
}
|
||||
scopedLogger = scopedLogger.With(logAttrs...)
|
||||
}
|
||||
}
|
||||
|
||||
if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
|
||||
trans = &otelAttributeTransport{
|
||||
base: trans,
|
||||
logger: scopedLogger,
|
||||
}
|
||||
}
|
||||
|
||||
if !gax.IsFeatureEnabled("TRACING") && !gax.IsFeatureEnabled("LOGGING") {
|
||||
return otelhttp.NewTransport(trans)
|
||||
}
|
||||
|
||||
var otelOpts []otelhttp.Option
|
||||
if len(traceAttrs) > 0 {
|
||||
otelOpts = append(otelOpts, otelhttp.WithSpanOptions(trace.WithAttributes(traceAttrs...)))
|
||||
}
|
||||
return otelhttp.NewTransport(trans, otelOpts...)
|
||||
}
|
||||
|
||||
// otelAttributeTransport is a wrapper around an http.RoundTripper that adds
|
||||
// custom Google Cloud-specific attributes to OpenTelemetry spans.
|
||||
type otelAttributeTransport struct {
|
||||
base http.RoundTripper
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
// RoundTrip intercepts the HTTP request and response to enrich the active
|
||||
// OpenTelemetry span with static and dynamic attributes, as well as detailed
|
||||
// error information.
|
||||
func (t *otelAttributeTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
var span trace.Span
|
||||
if gax.IsFeatureEnabled("TRACING") {
|
||||
if s := trace.SpanFromContext(req.Context()); s != nil && s.IsRecording() {
|
||||
span = s
|
||||
}
|
||||
}
|
||||
|
||||
if span != nil {
|
||||
var attrs []attribute.KeyValue
|
||||
attrs = append(attrs, attribute.String("rpc.system.name", "http"))
|
||||
if resName, ok := callctx.TelemetryFromContext(req.Context(), "resource_name"); ok {
|
||||
attrs = append(attrs, attribute.String("gcp.resource.destination.id", resName))
|
||||
}
|
||||
if resendCountStr, ok := callctx.TelemetryFromContext(req.Context(), "resend_count"); ok {
|
||||
if count, err := strconv.Atoi(resendCountStr); err == nil {
|
||||
attrs = append(attrs, attribute.Int("http.request.resend_count", count))
|
||||
}
|
||||
}
|
||||
if urlTemplate, ok := callctx.TelemetryFromContext(req.Context(), "url_template"); ok {
|
||||
attrs = append(attrs, attribute.String("url.template", urlTemplate))
|
||||
span.SetName(fmt.Sprintf("%s %s", req.Method, urlTemplate))
|
||||
}
|
||||
span.SetAttributes(attrs...)
|
||||
}
|
||||
|
||||
var data *gax.TransportTelemetryData
|
||||
if gax.IsFeatureEnabled("METRICS") {
|
||||
data = gax.ExtractTransportTelemetry(req.Context())
|
||||
if data != nil && req.URL != nil {
|
||||
host := req.URL.Hostname()
|
||||
if host != "" {
|
||||
data.SetServerAddress(host)
|
||||
}
|
||||
portStr := req.URL.Port()
|
||||
if portStr == "" {
|
||||
if req.URL.Scheme == "https" {
|
||||
portStr = "443"
|
||||
} else if req.URL.Scheme == "http" {
|
||||
portStr = "80"
|
||||
}
|
||||
}
|
||||
if port, pErr := strconv.Atoi(portStr); pErr == nil {
|
||||
data.SetServerPort(port)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := t.base.RoundTrip(req)
|
||||
|
||||
var logger *slog.Logger
|
||||
if gax.IsFeatureEnabled("LOGGING") {
|
||||
if l := t.logger; l != nil && l.Enabled(req.Context(), slog.LevelDebug) {
|
||||
logger = l
|
||||
}
|
||||
}
|
||||
|
||||
if span == nil && logger == nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.logAndSpanError(req, resp, err, err, span, logger)
|
||||
} else if resp.StatusCode >= 400 {
|
||||
if resp.Body != nil && resp.Body != http.NoBody && (resp.ContentLength < 0 || resp.ContentLength <= maxErrorReadBytes) {
|
||||
resp.Body = &errorTrackingBody{
|
||||
ReadCloser: resp.Body,
|
||||
req: req,
|
||||
resp: resp,
|
||||
span: span,
|
||||
logger: logger,
|
||||
t: t,
|
||||
}
|
||||
} else {
|
||||
t.logAndSpanError(req, resp, &googleapi.Error{
|
||||
Code: resp.StatusCode,
|
||||
Message: resp.Status,
|
||||
}, nil, span, logger)
|
||||
}
|
||||
} else {
|
||||
if span != nil {
|
||||
span.SetAttributes(attribute.Int("http.response.status_code", resp.StatusCode))
|
||||
}
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (t *otelAttributeTransport) logAndSpanError(req *http.Request, resp *http.Response, errToParse error, netErr error, span trace.Span, logger *slog.Logger) {
|
||||
var httpStatusCode int
|
||||
if resp != nil {
|
||||
httpStatusCode = resp.StatusCode
|
||||
}
|
||||
|
||||
info := gax.ExtractTelemetryErrorInfo(req.Context(), errToParse)
|
||||
|
||||
if netErr == nil && resp != nil && resp.StatusCode >= 400 {
|
||||
if info.ErrorType == "*googleapi.Error" {
|
||||
info.ErrorType = strconv.Itoa(resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
if logger != nil {
|
||||
logAttrs := []slog.Attr{
|
||||
slog.String("rpc.system.name", "http"),
|
||||
}
|
||||
if httpStatusCode > 0 {
|
||||
logAttrs = append(logAttrs, slog.Int64("http.response.status_code", int64(httpStatusCode)))
|
||||
}
|
||||
|
||||
ctx := req.Context()
|
||||
if resendCountStr, ok := callctx.TelemetryFromContext(ctx, "resend_count"); ok {
|
||||
if count, e := strconv.Atoi(resendCountStr); e == nil {
|
||||
logAttrs = append(logAttrs, slog.Int64("http.request.resend_count", int64(count)))
|
||||
}
|
||||
}
|
||||
if urlTemplate, ok := callctx.TelemetryFromContext(ctx, "url_template"); ok {
|
||||
logAttrs = append(logAttrs, slog.String("url.template", urlTemplate))
|
||||
}
|
||||
logAttrs = append(logAttrs, slog.String("http.request.method", req.Method))
|
||||
|
||||
msg := info.StatusMessage
|
||||
if msg == "" {
|
||||
msg = "API call failed"
|
||||
}
|
||||
|
||||
if rpcMethod, ok := callctx.TelemetryFromContext(ctx, "rpc_method"); ok {
|
||||
logAttrs = append(logAttrs, slog.String("rpc.method", rpcMethod))
|
||||
}
|
||||
|
||||
if resName, ok := callctx.TelemetryFromContext(ctx, "resource_name"); ok {
|
||||
logAttrs = append(logAttrs, slog.String("gcp.resource.destination.id", resName))
|
||||
}
|
||||
|
||||
if info.Domain != "" {
|
||||
logAttrs = append(logAttrs, slog.String("gcp.errors.domain", info.Domain))
|
||||
}
|
||||
for k, v := range info.Metadata {
|
||||
logAttrs = append(logAttrs, slog.String("gcp.errors.metadata."+k, v))
|
||||
}
|
||||
|
||||
logAttrs = append(logAttrs, slog.String("error.type", info.ErrorType))
|
||||
if info.StatusCode != "" {
|
||||
logAttrs = append(logAttrs, slog.String("rpc.response.status_code", info.StatusCode))
|
||||
}
|
||||
|
||||
logger.LogAttrs(ctx, slog.LevelDebug, msg, logAttrs...)
|
||||
}
|
||||
|
||||
if span != nil {
|
||||
if netErr != nil {
|
||||
span.SetAttributes(
|
||||
attribute.String("error.type", info.ErrorType),
|
||||
attribute.String("status.message", info.StatusMessage),
|
||||
attribute.String("exception.type", fmt.Sprintf("%T", netErr)),
|
||||
)
|
||||
} else {
|
||||
span.SetAttributes(
|
||||
attribute.Int("http.response.status_code", httpStatusCode),
|
||||
attribute.String("error.type", info.ErrorType),
|
||||
attribute.String("status.message", info.StatusMessage),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type errorTrackingBody struct {
|
||||
io.ReadCloser
|
||||
req *http.Request
|
||||
resp *http.Response
|
||||
span trace.Span
|
||||
logger *slog.Logger
|
||||
t *otelAttributeTransport
|
||||
|
||||
mu sync.Mutex
|
||||
buf bytes.Buffer
|
||||
recorded bool
|
||||
}
|
||||
|
||||
func (b *errorTrackingBody) Read(p []byte) (n int, err error) {
|
||||
n, err = b.ReadCloser.Read(p)
|
||||
|
||||
b.mu.Lock()
|
||||
shouldRecord := false
|
||||
if !b.recorded {
|
||||
if n > 0 {
|
||||
remaining := maxErrorReadBytes - int64(b.buf.Len())
|
||||
if remaining > 0 {
|
||||
if int64(n) > remaining {
|
||||
b.buf.Write(p[:remaining])
|
||||
} else {
|
||||
b.buf.Write(p[:n])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err == io.EOF || int64(b.buf.Len()) >= maxErrorReadBytes {
|
||||
shouldRecord = true
|
||||
b.recorded = true
|
||||
}
|
||||
}
|
||||
b.mu.Unlock()
|
||||
|
||||
if shouldRecord {
|
||||
b.recordError()
|
||||
}
|
||||
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (b *errorTrackingBody) Close() error {
|
||||
b.mu.Lock()
|
||||
shouldRecord := !b.recorded
|
||||
b.recorded = true
|
||||
b.mu.Unlock()
|
||||
|
||||
// We can close the network stream immediately.
|
||||
err := b.ReadCloser.Close()
|
||||
|
||||
// Do heavy in-memory telemetry parsing without holding the lock
|
||||
if shouldRecord {
|
||||
b.recordError() // If this panics here, the socket is already released
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *errorTrackingBody) recordError() {
|
||||
errToParse := &googleapi.Error{
|
||||
Code: b.resp.StatusCode,
|
||||
Message: b.resp.Status,
|
||||
}
|
||||
|
||||
if b.buf.Len() > 0 {
|
||||
clone := *b.resp
|
||||
clone.Body = io.NopCloser(bytes.NewReader(b.buf.Bytes()))
|
||||
if errResp := googleapi.CheckResponse(&clone); errResp != nil {
|
||||
if gErr, ok := errResp.(*googleapi.Error); ok {
|
||||
if gErr.Message == "" {
|
||||
gErr.Message = b.resp.Status
|
||||
}
|
||||
errToParse = gErr
|
||||
} else {
|
||||
errToParse = &googleapi.Error{
|
||||
Code: b.resp.StatusCode,
|
||||
Message: errResp.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b.t.logAndSpanError(b.req, b.resp, errToParse, nil, b.span, b.logger)
|
||||
}
|
||||
|
||||
type authTransport struct {
|
||||
|
||||
30
vendor/cloud.google.com/go/auth/internal/transport/transport.go
generated
vendored
@@ -24,8 +24,38 @@ import (
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/auth/credentials"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
// knownKeys provides keys for reading telemetry attributes from Context.
|
||||
// It provides an implicit contract with generated client library code
|
||||
// using the same keys. The keys in this collection should not be removed
|
||||
// or modified. New keys may be added, but they will need to be explicitly
|
||||
// used in code referencing this collection in order to appear in telemetry.
|
||||
var knownKeys = []string{
|
||||
"gcp.client.service",
|
||||
"gcp.client.version",
|
||||
"gcp.client.repo",
|
||||
"gcp.client.artifact",
|
||||
"gcp.client.language",
|
||||
"url.domain",
|
||||
}
|
||||
|
||||
// StaticTelemetryAttributes selectively converts known keys from a map of
|
||||
// strings to Open Telemetry attributes.
|
||||
func StaticTelemetryAttributes(m map[string]string) []attribute.KeyValue {
|
||||
var staticAttrs []attribute.KeyValue
|
||||
if m == nil {
|
||||
return staticAttrs
|
||||
}
|
||||
for _, k := range knownKeys {
|
||||
if v, ok := m[k]; ok {
|
||||
staticAttrs = append(staticAttrs, attribute.String(k, v))
|
||||
}
|
||||
}
|
||||
return staticAttrs
|
||||
}
|
||||
|
||||
// CloneDetectOptions clones a user set detect option into some new memory that
|
||||
// we can internally manipulate before sending onto the detect package.
|
||||
func CloneDetectOptions(oldDo *credentials.DetectOptions) *credentials.DetectOptions {
|
||||
|
||||
4
vendor/cloud.google.com/go/auth/internal/version.go
generated
vendored
@@ -4,7 +4,7 @@
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -17,4 +17,4 @@
|
||||
package internal
|
||||
|
||||
// Version is the current tagged release of the library.
|
||||
const Version = "0.18.2"
|
||||
const Version = "0.20.0"
|
||||
|
||||
10
vendor/cloud.google.com/go/iam/.repo-metadata.json
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"api_shortname": "iam",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/iam/latest",
|
||||
"client_library_type": "manual",
|
||||
"description": "Cloud IAM",
|
||||
"distribution_name": "cloud.google.com/go/iam",
|
||||
"language": "go",
|
||||
"library_type": "CORE",
|
||||
"release_level": "stable"
|
||||
}
|
||||
8
vendor/cloud.google.com/go/iam/CHANGES.md
generated
vendored
@@ -1,6 +1,14 @@
|
||||
# Changes
|
||||
|
||||
|
||||
## [1.7.0](https://github.com/googleapis/google-cloud-go/releases/tag/iam%2Fv1.7.0) (2026-04-02)
|
||||
|
||||
## [1.6.0](https://github.com/googleapis/google-cloud-go/releases/tag/iam%2Fv1.6.0) (2026-03-26)
|
||||
|
||||
### Features
|
||||
|
||||
* update image to us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/librarian-go@sha256:f9f9065a893591ad505df3384f409e9d404132d8c83b5d4bcbb8ae1650553b3b ([9a2be95](https://github.com/googleapis/google-cloud-go/commit/9a2be95cffe44aa7e6d68c08fff6d85a3a13a9b7))
|
||||
|
||||
## [1.5.3](https://github.com/googleapis/google-cloud-go/compare/iam/v1.5.2...iam/v1.5.3) (2025-10-08)
|
||||
|
||||
|
||||
|
||||
19
vendor/cloud.google.com/go/iam/README.md
generated
vendored
@@ -1,8 +1,8 @@
|
||||
# IAM API
|
||||
# Identity and Access Management (IAM) API
|
||||
|
||||
[](https://pkg.go.dev/cloud.google.com/go/iam)
|
||||
|
||||
Go Client Library for IAM API.
|
||||
Go Client Library for Identity and Access Management (IAM) API.
|
||||
|
||||
## Install
|
||||
|
||||
@@ -19,6 +19,21 @@ However, a `v1+` module may have breaking changes in two scenarios:
|
||||
* Packages with `alpha` or `beta` in the import path
|
||||
* The GoDoc has an explicit stability disclaimer (for example, for an experimental feature).
|
||||
|
||||
### Which package to use?
|
||||
|
||||
Generated client library surfaces can be found in packages whose import path
|
||||
ends in `.../apivXXX`. The `XXX` could be something like `1` or `2` in the case
|
||||
of a stable service backend or may be like `1beta2` or `2beta` in the case of a
|
||||
more experimental service backend. Because of this fact, a given module can have
|
||||
multiple clients for different service backends. In these cases it is generally
|
||||
recommended to use clients with stable service backends, with import suffixes like
|
||||
`apiv1`, unless you need to use features that are only present in a beta backend
|
||||
or there is not yet a stable backend available.
|
||||
|
||||
## Google Cloud Samples
|
||||
|
||||
To browse ready to use code samples check [Google Cloud Samples](https://cloud.google.com/docs/samples?l=go).
|
||||
|
||||
## Go Version Support
|
||||
|
||||
See the [Go Versions Supported](https://github.com/googleapis/google-cloud-go#go-versions-supported)
|
||||
|
||||
158
vendor/cloud.google.com/go/iam/apiv1/iampb/iam_policy.pb.go
generated
vendored
@@ -14,19 +14,21 @@
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.35.2
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v4.25.7
|
||||
// source: google/iam/v1/iam_policy.proto
|
||||
|
||||
package iampb
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -38,10 +40,7 @@ const (
|
||||
|
||||
// Request message for `SetIamPolicy` method.
|
||||
type SetIamPolicyRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// REQUIRED: The resource for which the policy is being specified.
|
||||
// See the operation documentation for the appropriate value for this field.
|
||||
Resource string `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"`
|
||||
@@ -55,7 +54,9 @@ type SetIamPolicyRequest struct {
|
||||
// following default mask is used:
|
||||
//
|
||||
// `paths: "bindings, etag"`
|
||||
UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,3,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
|
||||
UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,3,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetIamPolicyRequest) Reset() {
|
||||
@@ -111,16 +112,15 @@ func (x *SetIamPolicyRequest) GetUpdateMask() *fieldmaskpb.FieldMask {
|
||||
|
||||
// Request message for `GetIamPolicy` method.
|
||||
type GetIamPolicyRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// REQUIRED: The resource for which the policy is being requested.
|
||||
// See the operation documentation for the appropriate value for this field.
|
||||
Resource string `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"`
|
||||
// OPTIONAL: A `GetPolicyOptions` object for specifying options to
|
||||
// `GetIamPolicy`.
|
||||
Options *GetPolicyOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
|
||||
Options *GetPolicyOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetIamPolicyRequest) Reset() {
|
||||
@@ -169,10 +169,7 @@ func (x *GetIamPolicyRequest) GetOptions() *GetPolicyOptions {
|
||||
|
||||
// Request message for `TestIamPermissions` method.
|
||||
type TestIamPermissionsRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// REQUIRED: The resource for which the policy detail is being requested.
|
||||
// See the operation documentation for the appropriate value for this field.
|
||||
Resource string `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"`
|
||||
@@ -180,7 +177,9 @@ type TestIamPermissionsRequest struct {
|
||||
// wildcards (such as '*' or 'storage.*') are not allowed. For more
|
||||
// information see
|
||||
// [IAM Overview](https://cloud.google.com/iam/docs/overview#permissions).
|
||||
Permissions []string `protobuf:"bytes,2,rep,name=permissions,proto3" json:"permissions,omitempty"`
|
||||
Permissions []string `protobuf:"bytes,2,rep,name=permissions,proto3" json:"permissions,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *TestIamPermissionsRequest) Reset() {
|
||||
@@ -229,13 +228,12 @@ func (x *TestIamPermissionsRequest) GetPermissions() []string {
|
||||
|
||||
// Response message for `TestIamPermissions` method.
|
||||
type TestIamPermissionsResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// A subset of `TestPermissionsRequest.permissions` that the caller is
|
||||
// allowed.
|
||||
Permissions []string `protobuf:"bytes,1,rep,name=permissions,proto3" json:"permissions,omitempty"`
|
||||
Permissions []string `protobuf:"bytes,1,rep,name=permissions,proto3" json:"permissions,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *TestIamPermissionsResponse) Reset() {
|
||||
@@ -277,98 +275,39 @@ func (x *TestIamPermissionsResponse) GetPermissions() []string {
|
||||
|
||||
var File_google_iam_v1_iam_policy_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_google_iam_v1_iam_policy_proto_rawDesc = []byte{
|
||||
0x0a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x69, 0x61, 0x6d, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x12, 0x0d, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x1a,
|
||||
0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f,
|
||||
0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f,
|
||||
0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
|
||||
0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x76,
|
||||
0x31, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
|
||||
0x1a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x70,
|
||||
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65,
|
||||
0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xad, 0x01,
|
||||
0x0a, 0x13, 0x53, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x03, 0x0a,
|
||||
0x01, 0x2a, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x0a, 0x06,
|
||||
0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c,
|
||||
0x69, 0x63, 0x79, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79,
|
||||
0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73,
|
||||
0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x77, 0x0a,
|
||||
0x13, 0x47, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x03, 0x0a, 0x01,
|
||||
0x2a, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x6f,
|
||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f,
|
||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x69, 0x0a, 0x19, 0x54, 0x65, 0x73, 0x74, 0x49, 0x61,
|
||||
0x6d, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x03, 0x0a, 0x01, 0x2a,
|
||||
0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0b, 0x70, 0x65,
|
||||
0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42,
|
||||
0x03, 0xe0, 0x41, 0x02, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x22, 0x3e, 0x0a, 0x1a, 0x54, 0x65, 0x73, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x65, 0x72, 0x6d,
|
||||
0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x20, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x32, 0xb4, 0x03, 0x0a, 0x09, 0x49, 0x41, 0x4d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12,
|
||||
0x74, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12,
|
||||
0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x53, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x29, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x23, 0x3a, 0x01, 0x2a, 0x22, 0x1e, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x3d, 0x2a, 0x2a, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50,
|
||||
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x74, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50,
|
||||
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69,
|
||||
0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69,
|
||||
0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79,
|
||||
0x22, 0x29, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, 0x3a, 0x01, 0x2a, 0x22, 0x1e, 0x2f, 0x76, 0x31,
|
||||
0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3d, 0x2a, 0x2a, 0x7d, 0x3a, 0x67,
|
||||
0x65, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x9a, 0x01, 0x0a, 0x12,
|
||||
0x54, 0x65, 0x73, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x12, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73,
|
||||
0x74, 0x49, 0x61, 0x6d, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a,
|
||||
0x01, 0x2a, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x3d, 0x2a, 0x2a, 0x7d, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x49, 0x61, 0x6d, 0x50, 0x65, 0x72,
|
||||
0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x1e, 0xca, 0x41, 0x1b, 0x69, 0x61, 0x6d,
|
||||
0x2d, 0x6d, 0x65, 0x74, 0x61, 0x2d, 0x61, 0x70, 0x69, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x42, 0x7c, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x42, 0x0e, 0x49,
|
||||
0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
|
||||
0x29, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2f, 0x69,
|
||||
0x61, 0x6d, 0x70, 0x62, 0x3b, 0x69, 0x61, 0x6d, 0x70, 0x62, 0xaa, 0x02, 0x13, 0x47, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x49, 0x61, 0x6d, 0x2e, 0x56, 0x31,
|
||||
0xca, 0x02, 0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c,
|
||||
0x49, 0x61, 0x6d, 0x5c, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
const file_google_iam_v1_iam_policy_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x1egoogle/iam/v1/iam_policy.proto\x12\rgoogle.iam.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a\x1bgoogle/iam/v1/options.proto\x1a\x1agoogle/iam/v1/policy.proto\x1a google/protobuf/field_mask.proto\"\xad\x01\n" +
|
||||
"\x13SetIamPolicyRequest\x12%\n" +
|
||||
"\bresource\x18\x01 \x01(\tB\t\xe0A\x02\xfaA\x03\n" +
|
||||
"\x01*R\bresource\x122\n" +
|
||||
"\x06policy\x18\x02 \x01(\v2\x15.google.iam.v1.PolicyB\x03\xe0A\x02R\x06policy\x12;\n" +
|
||||
"\vupdate_mask\x18\x03 \x01(\v2\x1a.google.protobuf.FieldMaskR\n" +
|
||||
"updateMask\"w\n" +
|
||||
"\x13GetIamPolicyRequest\x12%\n" +
|
||||
"\bresource\x18\x01 \x01(\tB\t\xe0A\x02\xfaA\x03\n" +
|
||||
"\x01*R\bresource\x129\n" +
|
||||
"\aoptions\x18\x02 \x01(\v2\x1f.google.iam.v1.GetPolicyOptionsR\aoptions\"i\n" +
|
||||
"\x19TestIamPermissionsRequest\x12%\n" +
|
||||
"\bresource\x18\x01 \x01(\tB\t\xe0A\x02\xfaA\x03\n" +
|
||||
"\x01*R\bresource\x12%\n" +
|
||||
"\vpermissions\x18\x02 \x03(\tB\x03\xe0A\x02R\vpermissions\">\n" +
|
||||
"\x1aTestIamPermissionsResponse\x12 \n" +
|
||||
"\vpermissions\x18\x01 \x03(\tR\vpermissions2\xb4\x03\n" +
|
||||
"\tIAMPolicy\x12t\n" +
|
||||
"\fSetIamPolicy\x12\".google.iam.v1.SetIamPolicyRequest\x1a\x15.google.iam.v1.Policy\")\x82\xd3\xe4\x93\x02#:\x01*\"\x1e/v1/{resource=**}:setIamPolicy\x12t\n" +
|
||||
"\fGetIamPolicy\x12\".google.iam.v1.GetIamPolicyRequest\x1a\x15.google.iam.v1.Policy\")\x82\xd3\xe4\x93\x02#:\x01*\"\x1e/v1/{resource=**}:getIamPolicy\x12\x9a\x01\n" +
|
||||
"\x12TestIamPermissions\x12(.google.iam.v1.TestIamPermissionsRequest\x1a).google.iam.v1.TestIamPermissionsResponse\"/\x82\xd3\xe4\x93\x02):\x01*\"$/v1/{resource=**}:testIamPermissions\x1a\x1e\xcaA\x1biam-meta-api.googleapis.comB|\n" +
|
||||
"\x11com.google.iam.v1B\x0eIamPolicyProtoP\x01Z)cloud.google.com/go/iam/apiv1/iampb;iampb\xaa\x02\x13Google.Cloud.Iam.V1\xca\x02\x13Google\\Cloud\\Iam\\V1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_google_iam_v1_iam_policy_proto_rawDescOnce sync.Once
|
||||
file_google_iam_v1_iam_policy_proto_rawDescData = file_google_iam_v1_iam_policy_proto_rawDesc
|
||||
file_google_iam_v1_iam_policy_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_google_iam_v1_iam_policy_proto_rawDescGZIP() []byte {
|
||||
file_google_iam_v1_iam_policy_proto_rawDescOnce.Do(func() {
|
||||
file_google_iam_v1_iam_policy_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_iam_v1_iam_policy_proto_rawDescData)
|
||||
file_google_iam_v1_iam_policy_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_iam_v1_iam_policy_proto_rawDesc), len(file_google_iam_v1_iam_policy_proto_rawDesc)))
|
||||
})
|
||||
return file_google_iam_v1_iam_policy_proto_rawDescData
|
||||
}
|
||||
@@ -411,7 +350,7 @@ func file_google_iam_v1_iam_policy_proto_init() {
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_google_iam_v1_iam_policy_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_iam_v1_iam_policy_proto_rawDesc), len(file_google_iam_v1_iam_policy_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
@@ -422,7 +361,6 @@ func file_google_iam_v1_iam_policy_proto_init() {
|
||||
MessageInfos: file_google_iam_v1_iam_policy_proto_msgTypes,
|
||||
}.Build()
|
||||
File_google_iam_v1_iam_policy_proto = out.File
|
||||
file_google_iam_v1_iam_policy_proto_rawDesc = nil
|
||||
file_google_iam_v1_iam_policy_proto_goTypes = nil
|
||||
file_google_iam_v1_iam_policy_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
1
vendor/cloud.google.com/go/iam/apiv1/iampb/iam_policy_grpc.pb.go
generated
vendored
@@ -22,6 +22,7 @@ package iampb
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
|
||||
47
vendor/cloud.google.com/go/iam/apiv1/iampb/options.pb.go
generated
vendored
@@ -14,17 +14,19 @@
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.35.2
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v4.25.7
|
||||
// source: google/iam/v1/options.proto
|
||||
|
||||
package iampb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -36,10 +38,7 @@ const (
|
||||
|
||||
// Encapsulates settings provided to GetIamPolicy.
|
||||
type GetPolicyOptions struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// Optional. The maximum policy version that will be used to format the
|
||||
// policy.
|
||||
//
|
||||
@@ -59,6 +58,8 @@ type GetPolicyOptions struct {
|
||||
// [IAM
|
||||
// documentation](https://cloud.google.com/iam/help/conditions/resource-policies).
|
||||
RequestedPolicyVersion int32 `protobuf:"varint,1,opt,name=requested_policy_version,json=requestedPolicyVersion,proto3" json:"requested_policy_version,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetPolicyOptions) Reset() {
|
||||
@@ -100,34 +101,21 @@ func (x *GetPolicyOptions) GetRequestedPolicyVersion() int32 {
|
||||
|
||||
var File_google_iam_v1_options_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_google_iam_v1_options_proto_rawDesc = []byte{
|
||||
0x0a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x22, 0x4c, 0x0a, 0x10,
|
||||
0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x12, 0x38, 0x0a, 0x18, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x6f,
|
||||
0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x16, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x6c,
|
||||
0x69, 0x63, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x7d, 0x0a, 0x11, 0x63, 0x6f,
|
||||
0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x42,
|
||||
0x0c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
|
||||
0x29, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2f, 0x69,
|
||||
0x61, 0x6d, 0x70, 0x62, 0x3b, 0x69, 0x61, 0x6d, 0x70, 0x62, 0xf8, 0x01, 0x01, 0xaa, 0x02, 0x13,
|
||||
0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x49, 0x61, 0x6d,
|
||||
0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f,
|
||||
0x75, 0x64, 0x5c, 0x49, 0x61, 0x6d, 0x5c, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
}
|
||||
const file_google_iam_v1_options_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x1bgoogle/iam/v1/options.proto\x12\rgoogle.iam.v1\"L\n" +
|
||||
"\x10GetPolicyOptions\x128\n" +
|
||||
"\x18requested_policy_version\x18\x01 \x01(\x05R\x16requestedPolicyVersionB}\n" +
|
||||
"\x11com.google.iam.v1B\fOptionsProtoP\x01Z)cloud.google.com/go/iam/apiv1/iampb;iampb\xf8\x01\x01\xaa\x02\x13Google.Cloud.Iam.V1\xca\x02\x13Google\\Cloud\\Iam\\V1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_google_iam_v1_options_proto_rawDescOnce sync.Once
|
||||
file_google_iam_v1_options_proto_rawDescData = file_google_iam_v1_options_proto_rawDesc
|
||||
file_google_iam_v1_options_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_google_iam_v1_options_proto_rawDescGZIP() []byte {
|
||||
file_google_iam_v1_options_proto_rawDescOnce.Do(func() {
|
||||
file_google_iam_v1_options_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_iam_v1_options_proto_rawDescData)
|
||||
file_google_iam_v1_options_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_iam_v1_options_proto_rawDesc), len(file_google_iam_v1_options_proto_rawDesc)))
|
||||
})
|
||||
return file_google_iam_v1_options_proto_rawDescData
|
||||
}
|
||||
@@ -153,7 +141,7 @@ func file_google_iam_v1_options_proto_init() {
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_google_iam_v1_options_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_iam_v1_options_proto_rawDesc), len(file_google_iam_v1_options_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
@@ -164,7 +152,6 @@ func file_google_iam_v1_options_proto_init() {
|
||||
MessageInfos: file_google_iam_v1_options_proto_msgTypes,
|
||||
}.Build()
|
||||
File_google_iam_v1_options_proto = out.File
|
||||
file_google_iam_v1_options_proto_rawDesc = nil
|
||||
file_google_iam_v1_options_proto_goTypes = nil
|
||||
file_google_iam_v1_options_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
213
vendor/cloud.google.com/go/iam/apiv1/iampb/policy.pb.go
generated
vendored
@@ -14,18 +14,20 @@
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.35.2
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v4.25.7
|
||||
// source: google/iam/v1/policy.proto
|
||||
|
||||
package iampb
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
|
||||
expr "google.golang.org/genproto/googleapis/type/expr"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -276,10 +278,7 @@ func (AuditConfigDelta_Action) EnumDescriptor() ([]byte, []int) {
|
||||
// For a description of IAM and its features, see the
|
||||
// [IAM documentation](https://cloud.google.com/iam/docs/).
|
||||
type Policy struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// Specifies the format of the policy.
|
||||
//
|
||||
// Valid values are `0`, `1`, and `3`. Requests that specify an invalid value
|
||||
@@ -331,7 +330,9 @@ type Policy struct {
|
||||
// whenever you call `setIamPolicy`. If you omit this field, then IAM allows
|
||||
// you to overwrite a version `3` policy with a version `1` policy, and all of
|
||||
// the conditions in the version `3` policy are lost.
|
||||
Etag []byte `protobuf:"bytes,3,opt,name=etag,proto3" json:"etag,omitempty"`
|
||||
Etag []byte `protobuf:"bytes,3,opt,name=etag,proto3" json:"etag,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Policy) Reset() {
|
||||
@@ -394,10 +395,7 @@ func (x *Policy) GetEtag() []byte {
|
||||
|
||||
// Associates `members`, or principals, with a `role`.
|
||||
type Binding struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// Role that is assigned to the list of `members`, or principals.
|
||||
// For example, `roles/viewer`, `roles/editor`, or `roles/owner`.
|
||||
Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"`
|
||||
@@ -454,7 +452,9 @@ type Binding struct {
|
||||
// To learn which resources support conditions in their IAM policies, see the
|
||||
// [IAM
|
||||
// documentation](https://cloud.google.com/iam/help/conditions/resource-policies).
|
||||
Condition *expr.Expr `protobuf:"bytes,3,opt,name=condition,proto3" json:"condition,omitempty"`
|
||||
Condition *expr.Expr `protobuf:"bytes,3,opt,name=condition,proto3" json:"condition,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Binding) Reset() {
|
||||
@@ -560,16 +560,15 @@ func (x *Binding) GetCondition() *expr.Expr {
|
||||
// logging. It also exempts `jose@example.com` from DATA_READ logging, and
|
||||
// `aliya@example.com` from DATA_WRITE logging.
|
||||
type AuditConfig struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// Specifies a service that will be enabled for audit logging.
|
||||
// For example, `storage.googleapis.com`, `cloudsql.googleapis.com`.
|
||||
// `allServices` is a special value that covers all services.
|
||||
Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
|
||||
// The configuration for logging of each type of permission.
|
||||
AuditLogConfigs []*AuditLogConfig `protobuf:"bytes,3,rep,name=audit_log_configs,json=auditLogConfigs,proto3" json:"audit_log_configs,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuditConfig) Reset() {
|
||||
@@ -636,10 +635,7 @@ func (x *AuditConfig) GetAuditLogConfigs() []*AuditLogConfig {
|
||||
// This enables 'DATA_READ' and 'DATA_WRITE' logging, while exempting
|
||||
// jose@example.com from DATA_READ logging.
|
||||
type AuditLogConfig struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The log type that this config enables.
|
||||
LogType AuditLogConfig_LogType `protobuf:"varint,1,opt,name=log_type,json=logType,proto3,enum=google.iam.v1.AuditLogConfig_LogType" json:"log_type,omitempty"`
|
||||
// Specifies the identities that do not cause logging for this type of
|
||||
@@ -647,6 +643,8 @@ type AuditLogConfig struct {
|
||||
// Follows the same format of
|
||||
// [Binding.members][google.iam.v1.Binding.members].
|
||||
ExemptedMembers []string `protobuf:"bytes,2,rep,name=exempted_members,json=exemptedMembers,proto3" json:"exempted_members,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuditLogConfig) Reset() {
|
||||
@@ -695,14 +693,13 @@ func (x *AuditLogConfig) GetExemptedMembers() []string {
|
||||
|
||||
// The difference delta between two policies.
|
||||
type PolicyDelta struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The delta for Bindings between two policies.
|
||||
BindingDeltas []*BindingDelta `protobuf:"bytes,1,rep,name=binding_deltas,json=bindingDeltas,proto3" json:"binding_deltas,omitempty"`
|
||||
// The delta for AuditConfigs between two policies.
|
||||
AuditConfigDeltas []*AuditConfigDelta `protobuf:"bytes,2,rep,name=audit_config_deltas,json=auditConfigDeltas,proto3" json:"audit_config_deltas,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PolicyDelta) Reset() {
|
||||
@@ -752,10 +749,7 @@ func (x *PolicyDelta) GetAuditConfigDeltas() []*AuditConfigDelta {
|
||||
// One delta entry for Binding. Each individual change (only one member in each
|
||||
// entry) to a binding will be a separate entry.
|
||||
type BindingDelta struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The action that was performed on a Binding.
|
||||
// Required
|
||||
Action BindingDelta_Action `protobuf:"varint,1,opt,name=action,proto3,enum=google.iam.v1.BindingDelta_Action" json:"action,omitempty"`
|
||||
@@ -768,7 +762,9 @@ type BindingDelta struct {
|
||||
// Required
|
||||
Member string `protobuf:"bytes,3,opt,name=member,proto3" json:"member,omitempty"`
|
||||
// The condition that is associated with this binding.
|
||||
Condition *expr.Expr `protobuf:"bytes,4,opt,name=condition,proto3" json:"condition,omitempty"`
|
||||
Condition *expr.Expr `protobuf:"bytes,4,opt,name=condition,proto3" json:"condition,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *BindingDelta) Reset() {
|
||||
@@ -832,10 +828,7 @@ func (x *BindingDelta) GetCondition() *expr.Expr {
|
||||
// One delta entry for AuditConfig. Each individual change (only one
|
||||
// exempted_member in each entry) to a AuditConfig will be a separate entry.
|
||||
type AuditConfigDelta struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The action that was performed on an audit configuration in a policy.
|
||||
// Required
|
||||
Action AuditConfigDelta_Action `protobuf:"varint,1,opt,name=action,proto3,enum=google.iam.v1.AuditConfigDelta_Action" json:"action,omitempty"`
|
||||
@@ -851,7 +844,9 @@ type AuditConfigDelta struct {
|
||||
// Specifies the log_type that was be enabled. ADMIN_ACTIVITY is always
|
||||
// enabled, and cannot be configured.
|
||||
// Required
|
||||
LogType string `protobuf:"bytes,4,opt,name=log_type,json=logType,proto3" json:"log_type,omitempty"`
|
||||
LogType string `protobuf:"bytes,4,opt,name=log_type,json=logType,proto3" json:"log_type,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuditConfigDelta) Reset() {
|
||||
@@ -914,107 +909,64 @@ func (x *AuditConfigDelta) GetLogType() string {
|
||||
|
||||
var File_google_iam_v1_policy_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_google_iam_v1_policy_proto_rawDesc = []byte{
|
||||
0x0a, 0x1a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x1a, 0x16, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x22, 0xab, 0x01, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x08, 0x62, 0x69, 0x6e, 0x64,
|
||||
0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x6e, 0x64, 0x69,
|
||||
0x6e, 0x67, 0x52, 0x08, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3f, 0x0a, 0x0d,
|
||||
0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x06, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
|
||||
0x0c, 0x61, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x65, 0x74, 0x61, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x65, 0x74, 0x61,
|
||||
0x67, 0x22, 0x68, 0x0a, 0x07, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x72, 0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x6f,
|
||||
0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x72,
|
||||
0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x72, 0x0a, 0x0b, 0x41,
|
||||
0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x12, 0x49, 0x0a, 0x11, 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x6c, 0x6f,
|
||||
0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0f,
|
||||
0x61, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22,
|
||||
0xd1, 0x01, 0x0a, 0x0e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x12, 0x40, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61,
|
||||
0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x2e, 0x4c, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x6c, 0x6f, 0x67,
|
||||
0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x74, 0x65, 0x64,
|
||||
0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f,
|
||||
0x65, 0x78, 0x65, 0x6d, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22,
|
||||
0x52, 0x0a, 0x07, 0x4c, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x4c, 0x4f,
|
||||
0x47, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
|
||||
0x45, 0x44, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x5f, 0x52, 0x45,
|
||||
0x41, 0x44, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x57, 0x52, 0x49,
|
||||
0x54, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x45, 0x41,
|
||||
0x44, 0x10, 0x03, 0x22, 0xa2, 0x01, 0x0a, 0x0b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x44, 0x65,
|
||||
0x6c, 0x74, 0x61, 0x12, 0x42, 0x0a, 0x0e, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x64,
|
||||
0x65, 0x6c, 0x74, 0x61, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x6e, 0x64,
|
||||
0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x52, 0x0d, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e,
|
||||
0x67, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x73, 0x12, 0x4f, 0x0a, 0x13, 0x61, 0x75, 0x64, 0x69, 0x74,
|
||||
0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x73, 0x18, 0x02,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61,
|
||||
0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x44, 0x65, 0x6c, 0x74, 0x61, 0x52, 0x11, 0x61, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x73, 0x22, 0xde, 0x01, 0x0a, 0x0c, 0x42, 0x69, 0x6e,
|
||||
0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x3a, 0x0a, 0x06, 0x61, 0x63, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e,
|
||||
0x67, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61,
|
||||
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x6d,
|
||||
0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x62, 0x65,
|
||||
0x72, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x74, 0x79,
|
||||
0x70, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x22, 0x35, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x12,
|
||||
0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
|
||||
0x45, 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x44, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a,
|
||||
0x06, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x10, 0x02, 0x22, 0xe7, 0x01, 0x0a, 0x10, 0x41, 0x75,
|
||||
0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x3e,
|
||||
0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26,
|
||||
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x41,
|
||||
0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x2e,
|
||||
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x78, 0x65, 0x6d,
|
||||
0x70, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0e, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65,
|
||||
0x72, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x22, 0x35, 0x0a, 0x06,
|
||||
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e,
|
||||
0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x07,
|
||||
0x0a, 0x03, 0x41, 0x44, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x45, 0x4d, 0x4f, 0x56,
|
||||
0x45, 0x10, 0x02, 0x42, 0x7c, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79,
|
||||
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x69, 0x61, 0x6d,
|
||||
0x2f, 0x61, 0x70, 0x69, 0x76, 0x31, 0x2f, 0x69, 0x61, 0x6d, 0x70, 0x62, 0x3b, 0x69, 0x61, 0x6d,
|
||||
0x70, 0x62, 0xf8, 0x01, 0x01, 0xaa, 0x02, 0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43,
|
||||
0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x49, 0x61, 0x6d, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x47, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x49, 0x61, 0x6d, 0x5c, 0x56,
|
||||
0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
const file_google_iam_v1_policy_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x1agoogle/iam/v1/policy.proto\x12\rgoogle.iam.v1\x1a\x16google/type/expr.proto\"\xab\x01\n" +
|
||||
"\x06Policy\x12\x18\n" +
|
||||
"\aversion\x18\x01 \x01(\x05R\aversion\x122\n" +
|
||||
"\bbindings\x18\x04 \x03(\v2\x16.google.iam.v1.BindingR\bbindings\x12?\n" +
|
||||
"\raudit_configs\x18\x06 \x03(\v2\x1a.google.iam.v1.AuditConfigR\fauditConfigs\x12\x12\n" +
|
||||
"\x04etag\x18\x03 \x01(\fR\x04etag\"h\n" +
|
||||
"\aBinding\x12\x12\n" +
|
||||
"\x04role\x18\x01 \x01(\tR\x04role\x12\x18\n" +
|
||||
"\amembers\x18\x02 \x03(\tR\amembers\x12/\n" +
|
||||
"\tcondition\x18\x03 \x01(\v2\x11.google.type.ExprR\tcondition\"r\n" +
|
||||
"\vAuditConfig\x12\x18\n" +
|
||||
"\aservice\x18\x01 \x01(\tR\aservice\x12I\n" +
|
||||
"\x11audit_log_configs\x18\x03 \x03(\v2\x1d.google.iam.v1.AuditLogConfigR\x0fauditLogConfigs\"\xd1\x01\n" +
|
||||
"\x0eAuditLogConfig\x12@\n" +
|
||||
"\blog_type\x18\x01 \x01(\x0e2%.google.iam.v1.AuditLogConfig.LogTypeR\alogType\x12)\n" +
|
||||
"\x10exempted_members\x18\x02 \x03(\tR\x0fexemptedMembers\"R\n" +
|
||||
"\aLogType\x12\x18\n" +
|
||||
"\x14LOG_TYPE_UNSPECIFIED\x10\x00\x12\x0e\n" +
|
||||
"\n" +
|
||||
"ADMIN_READ\x10\x01\x12\x0e\n" +
|
||||
"\n" +
|
||||
"DATA_WRITE\x10\x02\x12\r\n" +
|
||||
"\tDATA_READ\x10\x03\"\xa2\x01\n" +
|
||||
"\vPolicyDelta\x12B\n" +
|
||||
"\x0ebinding_deltas\x18\x01 \x03(\v2\x1b.google.iam.v1.BindingDeltaR\rbindingDeltas\x12O\n" +
|
||||
"\x13audit_config_deltas\x18\x02 \x03(\v2\x1f.google.iam.v1.AuditConfigDeltaR\x11auditConfigDeltas\"\xde\x01\n" +
|
||||
"\fBindingDelta\x12:\n" +
|
||||
"\x06action\x18\x01 \x01(\x0e2\".google.iam.v1.BindingDelta.ActionR\x06action\x12\x12\n" +
|
||||
"\x04role\x18\x02 \x01(\tR\x04role\x12\x16\n" +
|
||||
"\x06member\x18\x03 \x01(\tR\x06member\x12/\n" +
|
||||
"\tcondition\x18\x04 \x01(\v2\x11.google.type.ExprR\tcondition\"5\n" +
|
||||
"\x06Action\x12\x16\n" +
|
||||
"\x12ACTION_UNSPECIFIED\x10\x00\x12\a\n" +
|
||||
"\x03ADD\x10\x01\x12\n" +
|
||||
"\n" +
|
||||
"\x06REMOVE\x10\x02\"\xe7\x01\n" +
|
||||
"\x10AuditConfigDelta\x12>\n" +
|
||||
"\x06action\x18\x01 \x01(\x0e2&.google.iam.v1.AuditConfigDelta.ActionR\x06action\x12\x18\n" +
|
||||
"\aservice\x18\x02 \x01(\tR\aservice\x12'\n" +
|
||||
"\x0fexempted_member\x18\x03 \x01(\tR\x0eexemptedMember\x12\x19\n" +
|
||||
"\blog_type\x18\x04 \x01(\tR\alogType\"5\n" +
|
||||
"\x06Action\x12\x16\n" +
|
||||
"\x12ACTION_UNSPECIFIED\x10\x00\x12\a\n" +
|
||||
"\x03ADD\x10\x01\x12\n" +
|
||||
"\n" +
|
||||
"\x06REMOVE\x10\x02B|\n" +
|
||||
"\x11com.google.iam.v1B\vPolicyProtoP\x01Z)cloud.google.com/go/iam/apiv1/iampb;iampb\xf8\x01\x01\xaa\x02\x13Google.Cloud.Iam.V1\xca\x02\x13Google\\Cloud\\Iam\\V1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_google_iam_v1_policy_proto_rawDescOnce sync.Once
|
||||
file_google_iam_v1_policy_proto_rawDescData = file_google_iam_v1_policy_proto_rawDesc
|
||||
file_google_iam_v1_policy_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_google_iam_v1_policy_proto_rawDescGZIP() []byte {
|
||||
file_google_iam_v1_policy_proto_rawDescOnce.Do(func() {
|
||||
file_google_iam_v1_policy_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_iam_v1_policy_proto_rawDescData)
|
||||
file_google_iam_v1_policy_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_iam_v1_policy_proto_rawDesc), len(file_google_iam_v1_policy_proto_rawDesc)))
|
||||
})
|
||||
return file_google_iam_v1_policy_proto_rawDescData
|
||||
}
|
||||
@@ -1061,7 +1013,7 @@ func file_google_iam_v1_policy_proto_init() {
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_google_iam_v1_policy_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_iam_v1_policy_proto_rawDesc), len(file_google_iam_v1_policy_proto_rawDesc)),
|
||||
NumEnums: 3,
|
||||
NumMessages: 7,
|
||||
NumExtensions: 0,
|
||||
@@ -1073,7 +1025,6 @@ func file_google_iam_v1_policy_proto_init() {
|
||||
MessageInfos: file_google_iam_v1_policy_proto_msgTypes,
|
||||
}.Build()
|
||||
File_google_iam_v1_policy_proto = out.File
|
||||
file_google_iam_v1_policy_proto_rawDesc = nil
|
||||
file_google_iam_v1_policy_proto_goTypes = nil
|
||||
file_google_iam_v1_policy_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
56
vendor/cloud.google.com/go/iam/apiv1/iampb/resource_policy_member.pb.go
generated
vendored
@@ -14,18 +14,20 @@
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.35.2
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v4.25.7
|
||||
// source: google/iam/v1/resource_policy_member.proto
|
||||
|
||||
package iampb
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -38,10 +40,7 @@ const (
|
||||
// Output-only policy member strings of a Google Cloud resource's built-in
|
||||
// identity.
|
||||
type ResourcePolicyMember struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// IAM policy binding member referring to a Google Cloud resource by
|
||||
// user-assigned name (https://google.aip.dev/122). If a resource is deleted
|
||||
// and recreated with the same name, the binding will be applicable to the new
|
||||
@@ -58,6 +57,8 @@ type ResourcePolicyMember struct {
|
||||
// Example:
|
||||
// `principal://parametermanager.googleapis.com/projects/12345/uid/locations/us-central1-a/parameters/a918fed5`
|
||||
IamPolicyUidPrincipal string `protobuf:"bytes,2,opt,name=iam_policy_uid_principal,json=iamPolicyUidPrincipal,proto3" json:"iam_policy_uid_principal,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ResourcePolicyMember) Reset() {
|
||||
@@ -106,42 +107,22 @@ func (x *ResourcePolicyMember) GetIamPolicyUidPrincipal() string {
|
||||
|
||||
var File_google_iam_v1_resource_policy_member_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_google_iam_v1_resource_policy_member_proto_rawDesc = []byte{
|
||||
0x0a, 0x2a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x69, 0x61, 0x6d, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f,
|
||||
0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65,
|
||||
0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x94, 0x01, 0x0a,
|
||||
0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d,
|
||||
0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x19, 0x69, 0x61, 0x6d, 0x5f, 0x70, 0x6f, 0x6c,
|
||||
0x69, 0x63, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70,
|
||||
0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x16, 0x69,
|
||||
0x61, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x69, 0x6e,
|
||||
0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x3c, 0x0a, 0x18, 0x69, 0x61, 0x6d, 0x5f, 0x70, 0x6f, 0x6c,
|
||||
0x69, 0x63, 0x79, 0x5f, 0x75, 0x69, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61,
|
||||
0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x15, 0x69, 0x61,
|
||||
0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x69, 0x64, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69,
|
||||
0x70, 0x61, 0x6c, 0x42, 0x87, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x76, 0x31, 0x42, 0x19, 0x52, 0x65, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x50,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x69, 0x61, 0x6d, 0x2f,
|
||||
0x61, 0x70, 0x69, 0x76, 0x31, 0x2f, 0x69, 0x61, 0x6d, 0x70, 0x62, 0x3b, 0x69, 0x61, 0x6d, 0x70,
|
||||
0x62, 0xaa, 0x02, 0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64,
|
||||
0x2e, 0x49, 0x61, 0x6d, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x49, 0x61, 0x6d, 0x5c, 0x56, 0x31, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
const file_google_iam_v1_resource_policy_member_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"*google/iam/v1/resource_policy_member.proto\x12\rgoogle.iam.v1\x1a\x1fgoogle/api/field_behavior.proto\"\x94\x01\n" +
|
||||
"\x14ResourcePolicyMember\x12>\n" +
|
||||
"\x19iam_policy_name_principal\x18\x01 \x01(\tB\x03\xe0A\x03R\x16iamPolicyNamePrincipal\x12<\n" +
|
||||
"\x18iam_policy_uid_principal\x18\x02 \x01(\tB\x03\xe0A\x03R\x15iamPolicyUidPrincipalB\x87\x01\n" +
|
||||
"\x11com.google.iam.v1B\x19ResourcePolicyMemberProtoP\x01Z)cloud.google.com/go/iam/apiv1/iampb;iampb\xaa\x02\x13Google.Cloud.Iam.V1\xca\x02\x13Google\\Cloud\\Iam\\V1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_google_iam_v1_resource_policy_member_proto_rawDescOnce sync.Once
|
||||
file_google_iam_v1_resource_policy_member_proto_rawDescData = file_google_iam_v1_resource_policy_member_proto_rawDesc
|
||||
file_google_iam_v1_resource_policy_member_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_google_iam_v1_resource_policy_member_proto_rawDescGZIP() []byte {
|
||||
file_google_iam_v1_resource_policy_member_proto_rawDescOnce.Do(func() {
|
||||
file_google_iam_v1_resource_policy_member_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_iam_v1_resource_policy_member_proto_rawDescData)
|
||||
file_google_iam_v1_resource_policy_member_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_iam_v1_resource_policy_member_proto_rawDesc), len(file_google_iam_v1_resource_policy_member_proto_rawDesc)))
|
||||
})
|
||||
return file_google_iam_v1_resource_policy_member_proto_rawDescData
|
||||
}
|
||||
@@ -167,7 +148,7 @@ func file_google_iam_v1_resource_policy_member_proto_init() {
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_google_iam_v1_resource_policy_member_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_iam_v1_resource_policy_member_proto_rawDesc), len(file_google_iam_v1_resource_policy_member_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
@@ -178,7 +159,6 @@ func file_google_iam_v1_resource_policy_member_proto_init() {
|
||||
MessageInfos: file_google_iam_v1_resource_policy_member_proto_msgTypes,
|
||||
}.Build()
|
||||
File_google_iam_v1_resource_policy_member_proto = out.File
|
||||
file_google_iam_v1_resource_policy_member_proto_rawDesc = nil
|
||||
file_google_iam_v1_resource_policy_member_proto_goTypes = nil
|
||||
file_google_iam_v1_resource_policy_member_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
10
vendor/cloud.google.com/go/monitoring/apiv3/v2/.repo-metadata.json
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"api_shortname": "monitoring",
|
||||
"client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/monitoring/latest/apiv3/v2",
|
||||
"client_library_type": "generated",
|
||||
"description": "Cloud Monitoring API",
|
||||
"distribution_name": "cloud.google.com/go/monitoring/apiv3/v2",
|
||||
"language": "go",
|
||||
"library_type": "GAPIC_AUTO",
|
||||
"release_level": "preview"
|
||||
}
|
||||
3
vendor/cloud.google.com/go/monitoring/apiv3/v2/alert_policy_client.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2025 Google LLC
|
||||
// Copyright 2026 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -55,6 +55,7 @@ func defaultAlertPolicyGRPCClientOptions() []option.ClientOption {
|
||||
internaloption.WithDefaultAudience("https://monitoring.googleapis.com/"),
|
||||
internaloption.WithDefaultScopes(DefaultAuthScopes()...),
|
||||
internaloption.EnableJwtWithScope(),
|
||||
internaloption.AllowHardBoundTokens("MTLS_S2A"),
|
||||
internaloption.EnableNewAuthLibrary(),
|
||||
option.WithGRPCDialOption(grpc.WithDefaultCallOptions(
|
||||
grpc.MaxCallRecvMsgSize(math.MaxInt32))),
|
||||
|
||||
2
vendor/cloud.google.com/go/monitoring/apiv3/v2/auxiliary.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2025 Google LLC
|
||||
// Copyright 2026 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||
2
vendor/cloud.google.com/go/monitoring/apiv3/v2/auxiliary_go123.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2025 Google LLC
|
||||
// Copyright 2026 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
||||