From 8ab0a6e2add1a9e40350a32b6e709bdc87eb4080 Mon Sep 17 00:00:00 2001 From: Jerome Meyer Date: Thu, 30 Jan 2020 11:41:57 -0500 Subject: [PATCH 01/42] Added externalURL and pathPrefix functions to Template reference documentation Signed-off-by: Jerome Meyer --- docs/configuration/template_reference.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/configuration/template_reference.md b/docs/configuration/template_reference.md index fe2b60b233..475946923b 100644 --- a/docs/configuration/template_reference.md +++ b/docs/configuration/template_reference.md @@ -82,6 +82,8 @@ versions. | args | []interface{} | map[string]interface{} | This converts a list of objects to a map with keys arg0, arg1 etc. This is intended to allow multiple arguments to be passed to templates. | | tmpl | string, []interface{} | nothing | Like the built-in `template`, but allows non-literals as the template name. Note that the result is assumed to be safe, and will not be auto-escaped. Only available in consoles. | | safeHtml | string | string | Marks string as HTML not requiring auto-escaping. | +| externalURL | none | string | The URL under which Prometheus is externally reachable (set with `--web.external-url`). | +| pathPrefix | none | string | Path portion of the external URL. | ## Template type differences From c7c7847b6f12fa11821ab2927ba4b8d8888d9f07 Mon Sep 17 00:00:00 2001 From: Jinwook Jeong Date: Sat, 9 Apr 2022 01:03:54 +0900 Subject: [PATCH 02/42] Fix discovery managers to be properly cancelled Signed-off-by: Jinwook Jeong --- discovery/legacymanager/manager.go | 8 +++----- discovery/manager.go | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/discovery/legacymanager/manager.go b/discovery/legacymanager/manager.go index 7a3d6b3b82..2c8ba18a03 100644 --- a/discovery/legacymanager/manager.go +++ b/discovery/legacymanager/manager.go @@ -140,11 +140,9 @@ type Manager struct { // Run starts the background processing func (m *Manager) Run() error { go m.sender() - for range m.ctx.Done() { - m.cancelDiscoverers() - return m.ctx.Err() - } - return nil + <-m.ctx.Done() + m.cancelDiscoverers() + return m.ctx.Err() } // SyncCh returns a read only channel used by all the clients to receive target updates. diff --git a/discovery/manager.go b/discovery/manager.go index 088b9722cb..6747c56908 100644 --- a/discovery/manager.go +++ b/discovery/manager.go @@ -166,11 +166,9 @@ type Manager struct { // Run starts the background processing. func (m *Manager) Run() error { go m.sender() - for range m.ctx.Done() { - m.cancelDiscoverers() - return m.ctx.Err() - } - return nil + <-m.ctx.Done() + m.cancelDiscoverers() + return m.ctx.Err() } // SyncCh returns a read only channel used by all the clients to receive target updates. From a018a7ef5379cd8969dee4f36b091d0088286502 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 17 Aug 2023 07:42:18 +0100 Subject: [PATCH 03/42] storage: simplify Seek on BufferedSeriesIterator Small tweak to call a simpler method Signed-off-by: Bryan Boreham --- storage/buffer.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/storage/buffer.go b/storage/buffer.go index 38f5591039..50810b8189 100644 --- a/storage/buffer.go +++ b/storage/buffer.go @@ -92,12 +92,8 @@ func (b *BufferedSeriesIterator) Seek(t int64) chunkenc.ValueType { switch b.valueType { case chunkenc.ValNone: return chunkenc.ValNone - case chunkenc.ValFloat: - b.lastTime, _ = b.At() - case chunkenc.ValHistogram: - b.lastTime, _ = b.AtHistogram() - case chunkenc.ValFloatHistogram: - b.lastTime, _ = b.AtFloatHistogram() + case chunkenc.ValFloat, chunkenc.ValHistogram, chunkenc.ValFloatHistogram: + b.lastTime = b.AtT() default: panic(fmt.Errorf("BufferedSeriesIterator: unknown value type %v", b.valueType)) } From bdc7983956310b4ea75b645ea4dd96ed99ef3a69 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Sat, 26 Aug 2023 14:01:15 +0000 Subject: [PATCH 04/42] TSDB: re-use iterator when moving between series Signed-off-by: Bryan Boreham --- tsdb/querier.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsdb/querier.go b/tsdb/querier.go index 965707547e..5d37497b30 100644 --- a/tsdb/querier.go +++ b/tsdb/querier.go @@ -622,7 +622,7 @@ func (p *populateWithDelGenericSeriesIterator) reset(blockID ulid.ULID, cr Chunk p.chks = chks p.i = -1 p.err = nil - p.bufIter.Iter = nil + // Note we don't touch p.bufIter.Iter; it is holding on to an iterator we might reuse in next(). p.bufIter.Intervals = p.bufIter.Intervals[:0] p.intervals = intervals p.currDelIter = nil From 86729d4d7b8659e2b90fa65ae2d42ecddc3657bc Mon Sep 17 00:00:00 2001 From: Goutham Veeramachaneni Date: Thu, 21 Sep 2023 22:53:51 +0200 Subject: [PATCH 05/42] Update exp package (#12650) --- cmd/promtool/tsdb.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- model/labels/labels.go | 9 +++++---- model/labels/labels_stringlabels.go | 7 ++++--- promql/quantile.go | 11 +++++++++-- rules/manager.go | 21 ++++++++++++++------- scrape/scrape.go | 4 ++-- storage/remote/codec.go | 4 ++-- storage/remote/read_handler.go | 5 +++-- tsdb/compact.go | 8 ++++---- tsdb/db.go | 12 ++++++------ tsdb/exemplar.go | 4 ++-- tsdb/head_read.go | 4 ++-- tsdb/index/postings.go | 12 ++++++++---- tsdb/index/postingsstats.go | 4 +--- tsdb/ooo_head_read.go | 12 ++++++------ tsdb/querier.go | 8 ++++++-- tsdb/wlog/checkpoint.go | 4 ++-- tsdb/wlog/wlog.go | 4 ++-- util/stats/timer.go | 4 +--- web/federate.go | 5 +++-- 22 files changed, 86 insertions(+), 64 deletions(-) diff --git a/cmd/promtool/tsdb.go b/cmd/promtool/tsdb.go index 5aa7e9bfe7..85aeacc11e 100644 --- a/cmd/promtool/tsdb.go +++ b/cmd/promtool/tsdb.go @@ -459,7 +459,7 @@ func analyzeBlock(ctx context.Context, path, blockID string, limit int, runExten postingInfos := []postingInfo{} printInfo := func(postingInfos []postingInfo) { - slices.SortFunc(postingInfos, func(a, b postingInfo) bool { return a.metric > b.metric }) + slices.SortFunc(postingInfos, func(a, b postingInfo) int { return int(b.metric) - int(a.metric) }) for i, pc := range postingInfos { if i >= limit { diff --git a/go.mod b/go.mod index ada0572684..1cdca0f989 100644 --- a/go.mod +++ b/go.mod @@ -185,7 +185,7 @@ require ( go.opentelemetry.io/otel/metric v1.16.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect golang.org/x/crypto v0.11.0 // indirect - golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 + golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b golang.org/x/mod v0.12.0 // indirect golang.org/x/term v0.10.0 // indirect golang.org/x/text v0.11.0 // indirect diff --git a/go.sum b/go.sum index 04824f3c29..bdf4f59477 100644 --- a/go.sum +++ b/go.sum @@ -853,8 +853,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= -golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b h1:r+vk0EmXNmekl0S0BascoeeoHk/L7wmaW2QF90K+kYI= +golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/model/labels/labels.go b/model/labels/labels.go index 0c27e15c72..3dc3049b1c 100644 --- a/model/labels/labels.go +++ b/model/labels/labels.go @@ -19,6 +19,7 @@ import ( "bytes" "encoding/json" "strconv" + "strings" "github.com/cespare/xxhash/v2" "github.com/prometheus/common/model" @@ -362,7 +363,7 @@ func EmptyLabels() Labels { func New(ls ...Label) Labels { set := make(Labels, 0, len(ls)) set = append(set, ls...) - slices.SortFunc(set, func(a, b Label) bool { return a.Name < b.Name }) + slices.SortFunc(set, func(a, b Label) int { return strings.Compare(a.Name, b.Name) }) return set } @@ -386,7 +387,7 @@ func FromStrings(ss ...string) Labels { res = append(res, Label{Name: ss[i], Value: ss[i+1]}) } - slices.SortFunc(res, func(a, b Label) bool { return a.Name < b.Name }) + slices.SortFunc(res, func(a, b Label) int { return strings.Compare(a.Name, b.Name) }) return res } @@ -591,7 +592,7 @@ func (b *Builder) Labels() Labels { } if len(b.add) > 0 { // Base is already in order, so we only need to sort if we add to it. res = append(res, b.add...) - slices.SortFunc(res, func(a, b Label) bool { return a.Name < b.Name }) + slices.SortFunc(res, func(a, b Label) int { return strings.Compare(a.Name, b.Name) }) } return res } @@ -618,7 +619,7 @@ func (b *ScratchBuilder) Add(name, value string) { // Sort the labels added so far by name. func (b *ScratchBuilder) Sort() { - slices.SortFunc(b.add, func(a, b Label) bool { return a.Name < b.Name }) + slices.SortFunc(b.add, func(a, b Label) int { return strings.Compare(a.Name, b.Name) }) } // Assign is for when you already have a Labels which you want this ScratchBuilder to return. diff --git a/model/labels/labels_stringlabels.go b/model/labels/labels_stringlabels.go index a87545a26b..cc6bfcc700 100644 --- a/model/labels/labels_stringlabels.go +++ b/model/labels/labels_stringlabels.go @@ -20,6 +20,7 @@ import ( "encoding/json" "reflect" "strconv" + "strings" "unsafe" "github.com/cespare/xxhash/v2" @@ -412,7 +413,7 @@ func yoloBytes(s string) (b []byte) { // New returns a sorted Labels from the given labels. // The caller has to guarantee that all label names are unique. func New(ls ...Label) Labels { - slices.SortFunc(ls, func(a, b Label) bool { return a.Name < b.Name }) + slices.SortFunc(ls, func(a, b Label) int { return strings.Compare(a.Name, b.Name) }) size := labelsSize(ls) buf := make([]byte, size) marshalLabelsToSizedBuffer(ls, buf) @@ -671,7 +672,7 @@ func (b *Builder) Labels() Labels { return b.base } - slices.SortFunc(b.add, func(a, b Label) bool { return a.Name < b.Name }) + slices.SortFunc(b.add, func(a, b Label) int { return strings.Compare(a.Name, b.Name) }) slices.Sort(b.del) a, d := 0, 0 @@ -830,7 +831,7 @@ func (b *ScratchBuilder) Add(name, value string) { // Sort the labels added so far by name. func (b *ScratchBuilder) Sort() { - slices.SortFunc(b.add, func(a, b Label) bool { return a.Name < b.Name }) + slices.SortFunc(b.add, func(a, b Label) int { return strings.Compare(a.Name, b.Name) }) } // Assign is for when you already have a Labels which you want this ScratchBuilder to return. diff --git a/promql/quantile.go b/promql/quantile.go index 7f48b5945c..06a02a8d42 100644 --- a/promql/quantile.go +++ b/promql/quantile.go @@ -81,8 +81,15 @@ func bucketQuantile(q float64, buckets buckets) float64 { if q > 1 { return math.Inf(+1) } - slices.SortFunc(buckets, func(a, b bucket) bool { - return a.upperBound < b.upperBound + slices.SortFunc(buckets, func(a, b bucket) int { + // We don't expect the bucket boundary to be a NaN. + if a.upperBound < b.upperBound { + return -1 + } + if a.upperBound > b.upperBound { + return +1 + } + return 0 }) if !math.IsInf(buckets[len(buckets)-1].upperBound, +1) { return math.NaN() diff --git a/rules/manager.go b/rules/manager.go index e5e248cded..4e10d39c7d 100644 --- a/rules/manager.go +++ b/rules/manager.go @@ -19,6 +19,7 @@ import ( "fmt" "math" "net/url" + "strings" "sync" "time" @@ -490,9 +491,11 @@ func (g *Group) AlertingRules() []*AlertingRule { alerts = append(alerts, alertingRule) } } - slices.SortFunc(alerts, func(a, b *AlertingRule) bool { - return a.State() > b.State() || - (a.State() == b.State() && a.Name() < b.Name()) + slices.SortFunc(alerts, func(a, b *AlertingRule) int { + if a.State() == b.State() { + return strings.Compare(a.Name(), b.Name()) + } + return int(b.State() - a.State()) }) return alerts } @@ -1203,11 +1206,15 @@ func (m *Manager) RuleGroups() []*Group { rgs = append(rgs, g) } - slices.SortFunc(rgs, func(a, b *Group) bool { - if a.file != b.file { - return a.file < b.file + slices.SortFunc(rgs, func(a, b *Group) int { + fileCompare := strings.Compare(a.file, b.file) + + // If its 0, then the file names are the same. + // Lets look at the group names in that case. + if fileCompare != 0 { + return fileCompare } - return a.name < b.name + return strings.Compare(a.name, b.name) }) return rgs diff --git a/scrape/scrape.go b/scrape/scrape.go index b52616a01a..4d13d7f6b1 100644 --- a/scrape/scrape.go +++ b/scrape/scrape.go @@ -732,8 +732,8 @@ func mutateSampleLabels(lset labels.Labels, target *Target, honor bool, rc []*re } func resolveConflictingExposedLabels(lb *labels.Builder, conflictingExposedLabels []labels.Label) { - slices.SortStableFunc(conflictingExposedLabels, func(a, b labels.Label) bool { - return len(a.Name) < len(b.Name) + slices.SortStableFunc(conflictingExposedLabels, func(a, b labels.Label) int { + return len(a.Name) - len(b.Name) }) for _, l := range conflictingExposedLabels { diff --git a/storage/remote/codec.go b/storage/remote/codec.go index 4e0166d17e..4c190f2a4e 100644 --- a/storage/remote/codec.go +++ b/storage/remote/codec.go @@ -187,8 +187,8 @@ func FromQueryResult(sortSeries bool, res *prompb.QueryResult) storage.SeriesSet } if sortSeries { - slices.SortFunc(series, func(a, b storage.Series) bool { - return labels.Compare(a.Labels(), b.Labels()) < 0 + slices.SortFunc(series, func(a, b storage.Series) int { + return labels.Compare(a.Labels(), b.Labels()) }) } return &concreteSeriesSet{ diff --git a/storage/remote/read_handler.go b/storage/remote/read_handler.go index 5cb4d39774..e2702c9f77 100644 --- a/storage/remote/read_handler.go +++ b/storage/remote/read_handler.go @@ -16,6 +16,7 @@ package remote import ( "context" "net/http" + "strings" "sync" "github.com/go-kit/log" @@ -93,8 +94,8 @@ func (h *readHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { Value: value, }) } - slices.SortFunc(sortedExternalLabels, func(a, b prompb.Label) bool { - return a.Name < b.Name + slices.SortFunc(sortedExternalLabels, func(a, b prompb.Label) int { + return strings.Compare(a.Name, b.Name) }) responseType, err := NegotiateResponseType(req.AcceptedResponseTypes) diff --git a/tsdb/compact.go b/tsdb/compact.go index 7f5c307638..ca3a950960 100644 --- a/tsdb/compact.go +++ b/tsdb/compact.go @@ -200,8 +200,8 @@ func (c *LeveledCompactor) Plan(dir string) ([]string, error) { } func (c *LeveledCompactor) plan(dms []dirMeta) ([]string, error) { - slices.SortFunc(dms, func(a, b dirMeta) bool { - return a.meta.MinTime < b.meta.MinTime + slices.SortFunc(dms, func(a, b dirMeta) int { + return int(a.meta.MinTime - b.meta.MinTime) }) res := c.selectOverlappingDirs(dms) @@ -380,8 +380,8 @@ func CompactBlockMetas(uid ulid.ULID, blocks ...*BlockMeta) *BlockMeta { for s := range sources { res.Compaction.Sources = append(res.Compaction.Sources, s) } - slices.SortFunc(res.Compaction.Sources, func(a, b ulid.ULID) bool { - return a.Compare(b) < 0 + slices.SortFunc(res.Compaction.Sources, func(a, b ulid.ULID) int { + return a.Compare(b) }) res.MinTime = mint diff --git a/tsdb/db.go b/tsdb/db.go index 8a1c084f20..5c7040703a 100644 --- a/tsdb/db.go +++ b/tsdb/db.go @@ -579,8 +579,8 @@ func (db *DBReadOnly) Blocks() ([]BlockReader, error) { return nil, nil } - slices.SortFunc(loadable, func(a, b *Block) bool { - return a.Meta().MinTime < b.Meta().MinTime + slices.SortFunc(loadable, func(a, b *Block) int { + return int(a.Meta().MinTime - b.Meta().MinTime) }) blockMetas := make([]BlockMeta, 0, len(loadable)) @@ -1447,8 +1447,8 @@ func (db *DB) reloadBlocks() (err error) { } db.metrics.blocksBytes.Set(float64(blocksSize)) - slices.SortFunc(toLoad, func(a, b *Block) bool { - return a.Meta().MinTime < b.Meta().MinTime + slices.SortFunc(toLoad, func(a, b *Block) int { + return int(a.Meta().MinTime - b.Meta().MinTime) }) // Swap new blocks first for subsequently created readers to be seen. @@ -1517,8 +1517,8 @@ func deletableBlocks(db *DB, blocks []*Block) map[ulid.ULID]struct{} { // Sort the blocks by time - newest to oldest (largest to smallest timestamp). // This ensures that the retentions will remove the oldest blocks. - slices.SortFunc(blocks, func(a, b *Block) bool { - return a.Meta().MaxTime > b.Meta().MaxTime + slices.SortFunc(blocks, func(a, b *Block) int { + return int(b.Meta().MaxTime - a.Meta().MaxTime) }) for _, block := range blocks { diff --git a/tsdb/exemplar.go b/tsdb/exemplar.go index d4c0505cc1..904fc7c2bd 100644 --- a/tsdb/exemplar.go +++ b/tsdb/exemplar.go @@ -185,8 +185,8 @@ func (ce *CircularExemplarStorage) Select(start, end int64, matchers ...[]*label } } - slices.SortFunc(ret, func(a, b exemplar.QueryResult) bool { - return labels.Compare(a.SeriesLabels, b.SeriesLabels) < 0 + slices.SortFunc(ret, func(a, b exemplar.QueryResult) int { + return labels.Compare(a.SeriesLabels, b.SeriesLabels) }) return ret, nil diff --git a/tsdb/head_read.go b/tsdb/head_read.go index f7c04991ad..6964d5472b 100644 --- a/tsdb/head_read.go +++ b/tsdb/head_read.go @@ -136,8 +136,8 @@ func (h *headIndexReader) SortedPostings(p index.Postings) index.Postings { return index.ErrPostings(errors.Wrap(err, "expand postings")) } - slices.SortFunc(series, func(a, b *memSeries) bool { - return labels.Compare(a.lset, b.lset) < 0 + slices.SortFunc(series, func(a, b *memSeries) int { + return labels.Compare(a.lset, b.lset) }) // Convert back to list. diff --git a/tsdb/index/postings.go b/tsdb/index/postings.go index 97fc04d4f1..e5fa5fc540 100644 --- a/tsdb/index/postings.go +++ b/tsdb/index/postings.go @@ -19,6 +19,7 @@ import ( "encoding/binary" "runtime" "sort" + "strings" "sync" "github.com/pkg/errors" @@ -108,11 +109,14 @@ func (p *MemPostings) SortedKeys() []labels.Label { } p.mtx.RUnlock() - slices.SortFunc(keys, func(a, b labels.Label) bool { - if a.Name != b.Name { - return a.Name < b.Name + slices.SortFunc(keys, func(a, b labels.Label) int { + nameCompare := strings.Compare(a.Name, b.Name) + // If names are the same, compare values. + if nameCompare != 0 { + return nameCompare } - return a.Value < b.Value + + return strings.Compare(a.Value, b.Value) }) return keys } diff --git a/tsdb/index/postingsstats.go b/tsdb/index/postingsstats.go index 8e5f62dbac..70622b3d27 100644 --- a/tsdb/index/postingsstats.go +++ b/tsdb/index/postingsstats.go @@ -63,8 +63,6 @@ func (m *maxHeap) push(item Stat) { } func (m *maxHeap) get() []Stat { - slices.SortFunc(m.Items, func(a, b Stat) bool { - return a.Count > b.Count - }) + slices.SortFunc(m.Items, func(a, b Stat) int { return int(b.Count - a.Count) }) return m.Items } diff --git a/tsdb/ooo_head_read.go b/tsdb/ooo_head_read.go index 792fc4c8be..198bc4f2f4 100644 --- a/tsdb/ooo_head_read.go +++ b/tsdb/ooo_head_read.go @@ -177,18 +177,18 @@ type chunkMetaAndChunkDiskMapperRef struct { origMaxT int64 } -func refLessByMinTimeAndMinRef(a, b chunkMetaAndChunkDiskMapperRef) bool { +func refLessByMinTimeAndMinRef(a, b chunkMetaAndChunkDiskMapperRef) int { if a.meta.MinTime == b.meta.MinTime { - return a.meta.Ref < b.meta.Ref + return int(a.meta.Ref - b.meta.Ref) } - return a.meta.MinTime < b.meta.MinTime + return int(a.meta.MinTime - b.meta.MinTime) } -func lessByMinTimeAndMinRef(a, b chunks.Meta) bool { +func lessByMinTimeAndMinRef(a, b chunks.Meta) int { if a.MinTime == b.MinTime { - return a.Ref < b.Ref + return int(a.Ref - b.Ref) } - return a.MinTime < b.MinTime + return int(a.MinTime - b.MinTime) } func (oh *OOOHeadIndexReader) Postings(ctx context.Context, name string, values ...string) (index.Postings, error) { diff --git a/tsdb/querier.go b/tsdb/querier.go index f957ad2536..96406f1bdf 100644 --- a/tsdb/querier.go +++ b/tsdb/querier.go @@ -279,8 +279,12 @@ func PostingsForMatchers(ctx context.Context, ix IndexReader, ms ...*labels.Matc // there is no chance that the set we subtract from // contains postings of series that didn't exist when // we constructed the set we subtract by. - slices.SortStableFunc(ms, func(i, j *labels.Matcher) bool { - return !isSubtractingMatcher(i) && isSubtractingMatcher(j) + slices.SortStableFunc(ms, func(i, j *labels.Matcher) int { + if !isSubtractingMatcher(i) && isSubtractingMatcher(j) { + return -1 + } + + return +1 }) for _, m := range ms { diff --git a/tsdb/wlog/checkpoint.go b/tsdb/wlog/checkpoint.go index dd52ea2e3d..d64599c276 100644 --- a/tsdb/wlog/checkpoint.go +++ b/tsdb/wlog/checkpoint.go @@ -374,8 +374,8 @@ func listCheckpoints(dir string) (refs []checkpointRef, err error) { refs = append(refs, checkpointRef{name: fi.Name(), index: idx}) } - slices.SortFunc(refs, func(a, b checkpointRef) bool { - return a.index < b.index + slices.SortFunc(refs, func(a, b checkpointRef) int { + return a.index - b.index }) return refs, nil diff --git a/tsdb/wlog/wlog.go b/tsdb/wlog/wlog.go index d898ebd7ac..fd65fca07a 100644 --- a/tsdb/wlog/wlog.go +++ b/tsdb/wlog/wlog.go @@ -909,8 +909,8 @@ func listSegments(dir string) (refs []segmentRef, err error) { } refs = append(refs, segmentRef{name: fn, index: k}) } - slices.SortFunc(refs, func(a, b segmentRef) bool { - return a.index < b.index + slices.SortFunc(refs, func(a, b segmentRef) int { + return a.index - b.index }) for i := 0; i < len(refs)-1; i++ { if refs[i].index+1 != refs[i+1].index { diff --git a/util/stats/timer.go b/util/stats/timer.go index df1e2f931c..b7d79f4121 100644 --- a/util/stats/timer.go +++ b/util/stats/timer.go @@ -85,9 +85,7 @@ func (t *TimerGroup) String() string { for _, timer := range t.timers { timers = append(timers, timer) } - slices.SortFunc(timers, func(a, b *Timer) bool { - return a.created < b.created - }) + slices.SortFunc(timers, func(a, b *Timer) int { return a.created - b.created }) result := &bytes.Buffer{} for _, timer := range timers { fmt.Fprintf(result, "%s\n", timer) diff --git a/web/federate.go b/web/federate.go index fde1942bb2..babc97e55d 100644 --- a/web/federate.go +++ b/web/federate.go @@ -17,6 +17,7 @@ import ( "fmt" "net/http" "sort" + "strings" "github.com/go-kit/log/level" "github.com/gogo/protobuf/proto" @@ -169,10 +170,10 @@ Loop: return } - slices.SortFunc(vec, func(a, b promql.Sample) bool { + slices.SortFunc(vec, func(a, b promql.Sample) int { ni := a.Metric.Get(labels.MetricName) nj := b.Metric.Get(labels.MetricName) - return ni < nj + return strings.Compare(ni, nj) }) externalLabels := h.config.GlobalConfig.ExternalLabels.Map() From 5d233df7ef392ff0883ee7c962a0087b3de116cb Mon Sep 17 00:00:00 2001 From: ouyang1204 Date: Mon, 25 Sep 2023 15:48:05 +0800 Subject: [PATCH 06/42] Fix rule check broken (#12715) Signed-off-by: DrAuYueng --- cmd/promtool/main.go | 72 +++++++++++++++--------- cmd/promtool/main_test.go | 85 +++++++++++++++++++++++++++++ cmd/promtool/testdata/rules-bad.yml | 28 ++++++++++ 3 files changed, 160 insertions(+), 25 deletions(-) create mode 100644 cmd/promtool/testdata/rules-bad.yml diff --git a/cmd/promtool/main.go b/cmd/promtool/main.go index d539ce08f9..4ff48ce25c 100644 --- a/cmd/promtool/main.go +++ b/cmd/promtool/main.go @@ -733,30 +733,7 @@ func CheckRules(ls lintConfig, files ...string) int { failed := false hasErrors := false if len(files) == 0 { - fmt.Println("Checking standard input") - data, err := io.ReadAll(os.Stdin) - if err != nil { - fmt.Fprintln(os.Stderr, " FAILED:", err) - return failureExitCode - } - rgs, errs := rulefmt.Parse(data) - for _, e := range errs { - fmt.Fprintln(os.Stderr, e.Error()) - return failureExitCode - } - if n, errs := checkRuleGroups(rgs, ls); errs != nil { - fmt.Fprintln(os.Stderr, " FAILED:") - for _, e := range errs { - fmt.Fprintln(os.Stderr, e.Error()) - } - failed = true - for _, err := range errs { - hasErrors = hasErrors || !errors.Is(err, lintError) - } - } else { - fmt.Printf(" SUCCESS: %d rules found\n", n) - } - fmt.Println() + failed, hasErrors = checkRulesFromStdin(ls) } else { failed, hasErrors = checkRules(files, ls) } @@ -771,6 +748,44 @@ func CheckRules(ls lintConfig, files ...string) int { return successExitCode } +// checkRulesFromStdin validates rule from stdin. +func checkRulesFromStdin(ls lintConfig) (bool, bool) { + failed := false + hasErrors := false + fmt.Println("Checking standard input") + data, err := io.ReadAll(os.Stdin) + if err != nil { + fmt.Fprintln(os.Stderr, " FAILED:", err) + return true, true + } + rgs, errs := rulefmt.Parse(data) + if errs != nil { + failed = true + fmt.Fprintln(os.Stderr, " FAILED:") + for _, e := range errs { + fmt.Fprintln(os.Stderr, e.Error()) + hasErrors = hasErrors || !errors.Is(e, lintError) + } + if hasErrors { + return failed, hasErrors + } + } + if n, errs := checkRuleGroups(rgs, ls); errs != nil { + fmt.Fprintln(os.Stderr, " FAILED:") + for _, e := range errs { + fmt.Fprintln(os.Stderr, e.Error()) + } + failed = true + for _, err := range errs { + hasErrors = hasErrors || !errors.Is(err, lintError) + } + } else { + fmt.Printf(" SUCCESS: %d rules found\n", n) + } + fmt.Println() + return failed, hasErrors +} + // checkRules validates rule files. func checkRules(files []string, ls lintConfig) (bool, bool) { failed := false @@ -780,7 +795,14 @@ func checkRules(files []string, ls lintConfig) (bool, bool) { rgs, errs := rulefmt.ParseFile(f) if errs != nil { failed = true - continue + fmt.Fprintln(os.Stderr, " FAILED:") + for _, e := range errs { + fmt.Fprintln(os.Stderr, e.Error()) + hasErrors = hasErrors || !errors.Is(e, lintError) + } + if hasErrors { + continue + } } if n, errs := checkRuleGroups(rgs, ls); errs != nil { fmt.Fprintln(os.Stderr, " FAILED:") diff --git a/cmd/promtool/main_test.go b/cmd/promtool/main_test.go index 6cfa48798e..5ba08bdc18 100644 --- a/cmd/promtool/main_test.go +++ b/cmd/promtool/main_test.go @@ -464,3 +464,88 @@ func TestDocumentation(t *testing.T) { require.Equal(t, string(expectedContent), generatedContent, "Generated content does not match documentation. Hint: run `make cli-documentation`.") } + +func TestCheckRules(t *testing.T) { + t.Run("rules-good", func(t *testing.T) { + data, err := os.ReadFile("./testdata/rules.yml") + require.NoError(t, err) + r, w, err := os.Pipe() + if err != nil { + t.Fatal(err) + } + + _, err = w.Write(data) + if err != nil { + t.Error(err) + } + w.Close() + + // Restore stdin right after the test. + defer func(v *os.File) { os.Stdin = v }(os.Stdin) + os.Stdin = r + + exitCode := CheckRules(newLintConfig(lintOptionDuplicateRules, false)) + require.Equal(t, successExitCode, exitCode, "") + }) + + t.Run("rules-bad", func(t *testing.T) { + data, err := os.ReadFile("./testdata/rules-bad.yml") + require.NoError(t, err) + r, w, err := os.Pipe() + if err != nil { + t.Fatal(err) + } + + _, err = w.Write(data) + if err != nil { + t.Error(err) + } + w.Close() + + // Restore stdin right after the test. + defer func(v *os.File) { os.Stdin = v }(os.Stdin) + os.Stdin = r + + exitCode := CheckRules(newLintConfig(lintOptionDuplicateRules, false)) + require.Equal(t, failureExitCode, exitCode, "") + }) + + t.Run("rules-lint-fatal", func(t *testing.T) { + data, err := os.ReadFile("./testdata/prometheus-rules.lint.yml") + require.NoError(t, err) + r, w, err := os.Pipe() + if err != nil { + t.Fatal(err) + } + + _, err = w.Write(data) + if err != nil { + t.Error(err) + } + w.Close() + + // Restore stdin right after the test. + defer func(v *os.File) { os.Stdin = v }(os.Stdin) + os.Stdin = r + + exitCode := CheckRules(newLintConfig(lintOptionDuplicateRules, true)) + require.Equal(t, lintErrExitCode, exitCode, "") + }) +} + +func TestCheckRulesWithRuleFiles(t *testing.T) { + t.Run("rules-good", func(t *testing.T) { + exitCode := CheckRules(newLintConfig(lintOptionDuplicateRules, false), "./testdata/rules.yml") + require.Equal(t, successExitCode, exitCode, "") + }) + + t.Run("rules-bad", func(t *testing.T) { + exitCode := CheckRules(newLintConfig(lintOptionDuplicateRules, false), "./testdata/rules-bad.yml") + require.Equal(t, failureExitCode, exitCode, "") + }) + + t.Run("rules-lint-fatal", func(t *testing.T) { + exitCode := CheckRules(newLintConfig(lintOptionDuplicateRules, true), "./testdata/prometheus-rules.lint.yml") + require.Equal(t, lintErrExitCode, exitCode, "") + }) +} diff --git a/cmd/promtool/testdata/rules-bad.yml b/cmd/promtool/testdata/rules-bad.yml new file mode 100644 index 0000000000..9548a3a67b --- /dev/null +++ b/cmd/promtool/testdata/rules-bad.yml @@ -0,0 +1,28 @@ +# This is the rules file. + +groups: + - name: alerts + rules: + - alert: InstanceDown + expr: up == 0 + for: 5m + labels: + severity: page + annotations: + summary: "Instance {{ $label.foo }} down" + description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes." + - alert: AlwaysFiring + expr: 1 + + - name: rules + rules: + - record: job:test:count_over_time1m + expr: sum without(instance) (count_over_time(test[1m])) + + # A recording rule that doesn't depend on input series. + - record: fixed_data + expr: 1 + + # Subquery with default resolution test. + - record: suquery_interval_test + expr: count_over_time(up[5m:]) From a15e884e7a925a3af5cbef7129ecb97a642b89c1 Mon Sep 17 00:00:00 2001 From: Alan Protasio Date: Mon, 25 Sep 2023 12:15:41 -0700 Subject: [PATCH 07/42] Prevent Prometheus from overallocating memory on subquery with large amount of steps. (#12734) * change initial points slice size Signed-off-by: Alan Protasio * refactor on the steps calculation and moving the getXPoint/putXPoint method to the evaluator Signed-off-by: Alan Protasio * prevent potential panic Signed-off-by: Alan Protasio * Update promql/engine.go Co-authored-by: Bartlomiej Plotka Signed-off-by: Alan Protasio * Update promql/engine.go Co-authored-by: Bartlomiej Plotka Signed-off-by: Alan Protasio * Update promql/engine.go Co-authored-by: Bartlomiej Plotka Signed-off-by: Alan Protasio * Update promql/engine.go Co-authored-by: Bartlomiej Plotka Signed-off-by: Alan Protasio * Allocating slice with maximum size of 5k Signed-off-by: Alan Protasio * adding comments Signed-off-by: Alan Protasio --------- Signed-off-by: Alan Protasio Co-authored-by: Bartlomiej Plotka --- promql/engine.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/promql/engine.go b/promql/engine.go index 4a894fe72d..161aa85acb 100644 --- a/promql/engine.go +++ b/promql/engine.go @@ -60,6 +60,11 @@ const ( maxInt64 = 9223372036854774784 // The smallest SampleValue that can be converted to an int64 without underflow. minInt64 = -9223372036854775808 + + // Max initial size for the pooled points slices. + // The getHPointSlice and getFPointSlice functions are called with an estimated size which often can be + // over-estimated. + maxPointsSliceSize = 5000 ) type engineMetrics struct { @@ -1910,19 +1915,33 @@ func getFPointSlice(sz int) []FPoint { if p := fPointPool.Get(); p != nil { return p } + + if sz > maxPointsSliceSize { + sz = maxPointsSliceSize + } + return make([]FPoint, 0, sz) } +// putFPointSlice will return a FPoint slice of size max(maxPointsSliceSize, sz). +// This function is called with an estimated size which often can be over-estimated. func putFPointSlice(p []FPoint) { if p != nil { fPointPool.Put(p[:0]) } } +// getHPointSlice will return a HPoint slice of size max(maxPointsSliceSize, sz). +// This function is called with an estimated size which often can be over-estimated. func getHPointSlice(sz int) []HPoint { if p := hPointPool.Get(); p != nil { return p } + + if sz > maxPointsSliceSize { + sz = maxPointsSliceSize + } + return make([]HPoint, 0, sz) } From 6dcbd653e9a62304db603d2aaa7a0d317231ca7b Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Mon, 25 Sep 2023 13:57:08 -0700 Subject: [PATCH 08/42] tsdb: register metrics after Head is initialized (#12876) This avoids situations where metrics are scraped before the data they are trying to look at is initialized. Signed-off-by: Bryan Boreham --- tsdb/head.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsdb/head.go b/tsdb/head.go index f66a686e60..ea71b27181 100644 --- a/tsdb/head.go +++ b/tsdb/head.go @@ -258,7 +258,6 @@ func NewHead(r prometheus.Registerer, l log.Logger, wal, wbl *wlog.WL, opts *Hea if err := h.resetInMemoryState(); err != nil { return nil, err } - h.metrics = newHeadMetrics(h, r) if opts.ChunkPool == nil { opts.ChunkPool = chunkenc.NewPool() @@ -278,6 +277,7 @@ func NewHead(r prometheus.Registerer, l log.Logger, wal, wbl *wlog.WL, opts *Hea if err != nil { return nil, err } + h.metrics = newHeadMetrics(h, r) return h, nil } From 1aad4004c32b117979532345a49ef83f3f99a872 Mon Sep 17 00:00:00 2001 From: Linas Medziunas Date: Wed, 27 Sep 2023 09:34:43 +0300 Subject: [PATCH 09/42] Additional test case for ValidateHistogram Signed-off-by: Linas Medziunas --- tsdb/head_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tsdb/head_test.go b/tsdb/head_test.go index 3d271e93bb..a9179af62c 100644 --- a/tsdb/head_test.go +++ b/tsdb/head_test.go @@ -4836,6 +4836,16 @@ func TestHistogramValidation(t *testing.T) { "valid histogram": { h: tsdbutil.GenerateTestHistograms(1)[0], }, + "valid histogram that has its Count (4) higher than the actual total of buckets (2 + 1)": { + // This case is possible if NaN values (which do not fall into any bucket) are observed. + h: &histogram.Histogram{ + ZeroCount: 2, + Count: 4, + Sum: math.NaN(), + PositiveSpans: []histogram.Span{{Offset: 0, Length: 1}}, + PositiveBuckets: []int64{1}, + }, + }, "rejects histogram that has too few negative buckets": { h: &histogram.Histogram{ NegativeSpans: []histogram.Span{{Offset: 0, Length: 1}}, From 67dcca500505452ab8a3e4547198c996bcf050da Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Wed, 27 Sep 2023 23:34:18 +0200 Subject: [PATCH 10/42] ci(lint): enable errorlint linter on cmd Signed-off-by: Matthieu MOREL --- .github/workflows/ci.yml | 1 + .golangci.yml | 22 ++++++++++++++++++++++ cmd/prometheus/main_test.go | 7 +++---- cmd/promtool/main_test.go | 7 +++---- cmd/promtool/unittest.go | 2 +- 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ab12876674..768efe195c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -142,6 +142,7 @@ jobs: - name: Install Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: + cache: false go-version: 1.20.x - name: Install snmp_exporter/generator dependencies run: sudo apt-get update && sudo apt-get -y install libsnmp-dev diff --git a/.golangci.yml b/.golangci.yml index 5aa01e48aa..57c6895b95 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -13,6 +13,7 @@ output: linters: enable: - depguard + - errorlint - gocritic - gofumpt - goimports @@ -31,6 +32,27 @@ issues: - path: _test.go linters: - errcheck + - path: discovery/ + linters: + - errorlint + - path: model/ + linters: + - errorlint + - path: scrape/ + linters: + - errorlint + - path: storage/ + linters: + - errorlint + - path: tsdb/ + linters: + - errorlint + - path: util/ + linters: + - errorlint + - path: web/ + linters: + - errorlint linters-settings: depguard: diff --git a/cmd/prometheus/main_test.go b/cmd/prometheus/main_test.go index 21447d0369..e4f831939f 100644 --- a/cmd/prometheus/main_test.go +++ b/cmd/prometheus/main_test.go @@ -498,10 +498,9 @@ func TestDocumentation(t *testing.T) { cmd.Stdout = &stdout if err := cmd.Run(); err != nil { - if exitError, ok := err.(*exec.ExitError); ok { - if exitError.ExitCode() != 0 { - fmt.Println("Command failed with non-zero exit code") - } + var exitError *exec.ExitError + if errors.As(err, &exitError) && exitError.ExitCode() != 0 { + fmt.Println("Command failed with non-zero exit code") } } diff --git a/cmd/promtool/main_test.go b/cmd/promtool/main_test.go index 5ba08bdc18..09c91f92a5 100644 --- a/cmd/promtool/main_test.go +++ b/cmd/promtool/main_test.go @@ -450,10 +450,9 @@ func TestDocumentation(t *testing.T) { cmd.Stdout = &stdout if err := cmd.Run(); err != nil { - if exitError, ok := err.(*exec.ExitError); ok { - if exitError.ExitCode() != 0 { - fmt.Println("Command failed with non-zero exit code") - } + var exitError *exec.ExitError + if errors.As(err, &exitError) && exitError.ExitCode() != 0 { + fmt.Println("Command failed with non-zero exit code") } } diff --git a/cmd/promtool/unittest.go b/cmd/promtool/unittest.go index 575480b032..5bec5c60b0 100644 --- a/cmd/promtool/unittest.go +++ b/cmd/promtool/unittest.go @@ -241,7 +241,7 @@ func (tg *testGroup) test(evalInterval time.Duration, groupOrderMap map[string]i g.Eval(suite.Context(), ts) for _, r := range g.Rules() { if r.LastError() != nil { - evalErrs = append(evalErrs, fmt.Errorf(" rule: %s, time: %s, err: %v", + evalErrs = append(evalErrs, fmt.Errorf(" rule: %s, time: %s, err: %w", r.Name(), ts.Sub(time.Unix(0, 0).UTC()), r.LastError())) } } From f15f0ac16a295b448e65c17e742375f702fd3aba Mon Sep 17 00:00:00 2001 From: lasea75 Date: Thu, 28 Sep 2023 12:26:46 -0500 Subject: [PATCH 11/42] Update functions.md Signed-off-by: lasea75 --- docs/querying/functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/querying/functions.md b/docs/querying/functions.md index 6b3a77e973..68036d882f 100644 --- a/docs/querying/functions.md +++ b/docs/querying/functions.md @@ -14,7 +14,7 @@ vector, which if not provided it will default to the value of the expression _Notes about the experimental native histograms:_ * Ingesting native histograms has to be enabled via a [feature - flag](../../feature_flags.md#native-histograms). As long as no native histograms + flag](https://prometheus.io/docs/prometheus/latest/feature_flags/). As long as no native histograms have been ingested into the TSDB, all functions will behave as usual. * Functions that do not explicitly mention native histograms in their documentation (see below) will ignore histogram samples. From 5d68ebb2076f2776e5c553b56f92b57e99a8fe61 Mon Sep 17 00:00:00 2001 From: johncming Date: Sat, 21 Mar 2020 21:34:00 +0800 Subject: [PATCH 12/42] pkg/rulefmt: fix bug of validate. Signed-off-by: johncming --- model/rulefmt/rulefmt.go | 18 +- .../record_and_alert.both_set.bad.yaml | 6 + .../record_and_alert.both_unset.bad.yaml | 4 + pkg/rulefmt/rulefmt_test.go | 175 ++++++++++++++++++ 4 files changed, 191 insertions(+), 12 deletions(-) create mode 100644 model/rulefmt/testdata/record_and_alert.both_set.bad.yaml create mode 100644 model/rulefmt/testdata/record_and_alert.both_unset.bad.yaml create mode 100644 pkg/rulefmt/rulefmt_test.go diff --git a/model/rulefmt/rulefmt.go b/model/rulefmt/rulefmt.go index 30b3face0d..6be93f6428 100644 --- a/model/rulefmt/rulefmt.go +++ b/model/rulefmt/rulefmt.go @@ -173,17 +173,11 @@ func (r *RuleNode) Validate() (nodes []WrappedError) { }) } if r.Record.Value == "" && r.Alert.Value == "" { - if r.Record.Value == "0" { - nodes = append(nodes, WrappedError{ - err: fmt.Errorf("one of 'record' or 'alert' must be set"), - node: &r.Alert, - }) - } else { - nodes = append(nodes, WrappedError{ - err: fmt.Errorf("one of 'record' or 'alert' must be set"), - node: &r.Record, - }) - } + nodes = append(nodes, WrappedError{ + err: fmt.Errorf("one of 'record' or 'alert' must be set"), + node: &r.Record, + nodeAlt: &r.Alert, + }) } if r.Expr.Value == "" { @@ -250,7 +244,7 @@ func (r *RuleNode) Validate() (nodes []WrappedError) { nodes = append(nodes, WrappedError{err: err}) } - return + return nodes } // testTemplateParsing checks if the templates used in labels and annotations diff --git a/model/rulefmt/testdata/record_and_alert.both_set.bad.yaml b/model/rulefmt/testdata/record_and_alert.both_set.bad.yaml new file mode 100644 index 0000000000..0ba81b7423 --- /dev/null +++ b/model/rulefmt/testdata/record_and_alert.both_set.bad.yaml @@ -0,0 +1,6 @@ +groups: +- name: yolo + rules: + - record: Hi + alert: Hello + expr: 1 diff --git a/model/rulefmt/testdata/record_and_alert.both_unset.bad.yaml b/model/rulefmt/testdata/record_and_alert.both_unset.bad.yaml new file mode 100644 index 0000000000..64d2e8f20d --- /dev/null +++ b/model/rulefmt/testdata/record_and_alert.both_unset.bad.yaml @@ -0,0 +1,4 @@ +groups: + - name: yolo + rules: + - expr: 1 diff --git a/pkg/rulefmt/rulefmt_test.go b/pkg/rulefmt/rulefmt_test.go new file mode 100644 index 0000000000..58b5d5ad36 --- /dev/null +++ b/pkg/rulefmt/rulefmt_test.go @@ -0,0 +1,175 @@ +// Copyright 2017 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// 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 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package rulefmt + +import ( + "path/filepath" + "strings" + "testing" + + "github.com/prometheus/prometheus/util/testutil" +) + +func TestParseFileSuccess(t *testing.T) { + if _, errs := ParseFile("testdata/test.yaml"); len(errs) > 0 { + t.Errorf("unexpected errors parsing file") + for _, err := range errs { + t.Error(err) + } + } +} + +func TestParseFileFailure(t *testing.T) { + table := []struct { + filename string + errMsg string + }{ + { + filename: "duplicate_grp.bad.yaml", + errMsg: "groupname: \"yolo\" is repeated in the same file", + }, + { + filename: "bad_expr.bad.yaml", + errMsg: "parse error", + }, + { + filename: "record_and_alert.both_set.bad.yaml", + errMsg: "'alert' and 'record' cannot be set at the same time", + }, + { + filename: "record_and_alert.both_unset.bad.yaml", + errMsg: "one of 'record' or 'alert' must be set", + }, + { + filename: "no_rec_alert.bad.yaml", + errMsg: "one of 'record' or 'alert' must be set", + }, + { + filename: "noexpr.bad.yaml", + errMsg: "field 'expr' must be set in rule", + }, + { + filename: "bad_lname.bad.yaml", + errMsg: "invalid label name", + }, + { + filename: "bad_annotation.bad.yaml", + errMsg: "invalid annotation name", + }, + { + filename: "invalid_record_name.bad.yaml", + errMsg: "invalid recording rule name", + }, + { + filename: "bad_field.bad.yaml", + errMsg: "field annotation not found", + }, + { + filename: "invalid_label_name.bad.yaml", + errMsg: "invalid label name", + }, + } + + for _, c := range table { + _, errs := ParseFile(filepath.Join("testdata", c.filename)) + if errs == nil { + t.Errorf("Expected error parsing %s but got none", c.filename) + continue + } + if !strings.Contains(errs[0].Error(), c.errMsg) { + t.Errorf("Expected error for %s to contain %q but got: %s", c.filename, c.errMsg, errs) + } + } + +} + +func TestTemplateParsing(t *testing.T) { + tests := []struct { + ruleString string + shouldPass bool + }{ + { + ruleString: ` +groups: +- name: example + rules: + - alert: InstanceDown + expr: up == 0 + for: 5m + labels: + severity: "page" + annotations: + summary: "Instance {{ $labels.instance }} down" +`, + shouldPass: true, + }, + { + // `$label` instead of `$labels`. + ruleString: ` +groups: +- name: example + rules: + - alert: InstanceDown + expr: up == 0 + for: 5m + labels: + severity: "page" + annotations: + summary: "Instance {{ $label.instance }} down" +`, + shouldPass: false, + }, + { + // `$this_is_wrong`. + ruleString: ` +groups: +- name: example + rules: + - alert: InstanceDown + expr: up == 0 + for: 5m + labels: + severity: "{{$this_is_wrong}}" + annotations: + summary: "Instance {{ $labels.instance }} down" +`, + shouldPass: false, + }, + { + // `$labels.quantile * 100`. + ruleString: ` +groups: +- name: example + rules: + - alert: InstanceDown + expr: up == 0 + for: 5m + labels: + severity: "page" + annotations: + summary: "Instance {{ $labels.instance }} down" + description: "{{$labels.quantile * 100}}" +`, + shouldPass: false, + }, + } + + for _, tst := range tests { + rgs, errs := Parse([]byte(tst.ruleString)) + testutil.Assert(t, rgs != nil, "Rule parsing, rule=\n"+tst.ruleString) + passed := (tst.shouldPass && len(errs) == 0) || (!tst.shouldPass && len(errs) > 0) + testutil.Assert(t, passed, "Rule validation failed, rule=\n"+tst.ruleString) + } + +} From c52db2b196238e376dba6d580d95373ba794a226 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Fri, 29 Sep 2023 10:38:10 +0200 Subject: [PATCH 13/42] Remove duplicate tests Signed-off-by: Julien Pivotto --- model/rulefmt/rulefmt.go | 2 +- .../record_and_alert.both_set.bad.yaml | 6 - .../record_and_alert.both_unset.bad.yaml | 4 - pkg/rulefmt/rulefmt_test.go | 175 ------------------ 4 files changed, 1 insertion(+), 186 deletions(-) delete mode 100644 model/rulefmt/testdata/record_and_alert.both_set.bad.yaml delete mode 100644 model/rulefmt/testdata/record_and_alert.both_unset.bad.yaml delete mode 100644 pkg/rulefmt/rulefmt_test.go diff --git a/model/rulefmt/rulefmt.go b/model/rulefmt/rulefmt.go index 6be93f6428..03cbd8849c 100644 --- a/model/rulefmt/rulefmt.go +++ b/model/rulefmt/rulefmt.go @@ -244,7 +244,7 @@ func (r *RuleNode) Validate() (nodes []WrappedError) { nodes = append(nodes, WrappedError{err: err}) } - return nodes + return } // testTemplateParsing checks if the templates used in labels and annotations diff --git a/model/rulefmt/testdata/record_and_alert.both_set.bad.yaml b/model/rulefmt/testdata/record_and_alert.both_set.bad.yaml deleted file mode 100644 index 0ba81b7423..0000000000 --- a/model/rulefmt/testdata/record_and_alert.both_set.bad.yaml +++ /dev/null @@ -1,6 +0,0 @@ -groups: -- name: yolo - rules: - - record: Hi - alert: Hello - expr: 1 diff --git a/model/rulefmt/testdata/record_and_alert.both_unset.bad.yaml b/model/rulefmt/testdata/record_and_alert.both_unset.bad.yaml deleted file mode 100644 index 64d2e8f20d..0000000000 --- a/model/rulefmt/testdata/record_and_alert.both_unset.bad.yaml +++ /dev/null @@ -1,4 +0,0 @@ -groups: - - name: yolo - rules: - - expr: 1 diff --git a/pkg/rulefmt/rulefmt_test.go b/pkg/rulefmt/rulefmt_test.go deleted file mode 100644 index 58b5d5ad36..0000000000 --- a/pkg/rulefmt/rulefmt_test.go +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright 2017 The Prometheus Authors -// Licensed under the Apache License, Version 2.0 (the "License"); -// 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 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package rulefmt - -import ( - "path/filepath" - "strings" - "testing" - - "github.com/prometheus/prometheus/util/testutil" -) - -func TestParseFileSuccess(t *testing.T) { - if _, errs := ParseFile("testdata/test.yaml"); len(errs) > 0 { - t.Errorf("unexpected errors parsing file") - for _, err := range errs { - t.Error(err) - } - } -} - -func TestParseFileFailure(t *testing.T) { - table := []struct { - filename string - errMsg string - }{ - { - filename: "duplicate_grp.bad.yaml", - errMsg: "groupname: \"yolo\" is repeated in the same file", - }, - { - filename: "bad_expr.bad.yaml", - errMsg: "parse error", - }, - { - filename: "record_and_alert.both_set.bad.yaml", - errMsg: "'alert' and 'record' cannot be set at the same time", - }, - { - filename: "record_and_alert.both_unset.bad.yaml", - errMsg: "one of 'record' or 'alert' must be set", - }, - { - filename: "no_rec_alert.bad.yaml", - errMsg: "one of 'record' or 'alert' must be set", - }, - { - filename: "noexpr.bad.yaml", - errMsg: "field 'expr' must be set in rule", - }, - { - filename: "bad_lname.bad.yaml", - errMsg: "invalid label name", - }, - { - filename: "bad_annotation.bad.yaml", - errMsg: "invalid annotation name", - }, - { - filename: "invalid_record_name.bad.yaml", - errMsg: "invalid recording rule name", - }, - { - filename: "bad_field.bad.yaml", - errMsg: "field annotation not found", - }, - { - filename: "invalid_label_name.bad.yaml", - errMsg: "invalid label name", - }, - } - - for _, c := range table { - _, errs := ParseFile(filepath.Join("testdata", c.filename)) - if errs == nil { - t.Errorf("Expected error parsing %s but got none", c.filename) - continue - } - if !strings.Contains(errs[0].Error(), c.errMsg) { - t.Errorf("Expected error for %s to contain %q but got: %s", c.filename, c.errMsg, errs) - } - } - -} - -func TestTemplateParsing(t *testing.T) { - tests := []struct { - ruleString string - shouldPass bool - }{ - { - ruleString: ` -groups: -- name: example - rules: - - alert: InstanceDown - expr: up == 0 - for: 5m - labels: - severity: "page" - annotations: - summary: "Instance {{ $labels.instance }} down" -`, - shouldPass: true, - }, - { - // `$label` instead of `$labels`. - ruleString: ` -groups: -- name: example - rules: - - alert: InstanceDown - expr: up == 0 - for: 5m - labels: - severity: "page" - annotations: - summary: "Instance {{ $label.instance }} down" -`, - shouldPass: false, - }, - { - // `$this_is_wrong`. - ruleString: ` -groups: -- name: example - rules: - - alert: InstanceDown - expr: up == 0 - for: 5m - labels: - severity: "{{$this_is_wrong}}" - annotations: - summary: "Instance {{ $labels.instance }} down" -`, - shouldPass: false, - }, - { - // `$labels.quantile * 100`. - ruleString: ` -groups: -- name: example - rules: - - alert: InstanceDown - expr: up == 0 - for: 5m - labels: - severity: "page" - annotations: - summary: "Instance {{ $labels.instance }} down" - description: "{{$labels.quantile * 100}}" -`, - shouldPass: false, - }, - } - - for _, tst := range tests { - rgs, errs := Parse([]byte(tst.ruleString)) - testutil.Assert(t, rgs != nil, "Rule parsing, rule=\n"+tst.ruleString) - passed := (tst.shouldPass && len(errs) == 0) || (!tst.shouldPass && len(errs) > 0) - testutil.Assert(t, passed, "Rule validation failed, rule=\n"+tst.ruleString) - } - -} From a1c1fc8244364114e6f21d08a94c17a31bad9044 Mon Sep 17 00:00:00 2001 From: Gabriela Gutierrez Date: Fri, 23 Sep 2022 15:42:20 -0300 Subject: [PATCH 14/42] Create scorecards.yml Signed-off-by: Gabriela Gutierrez --- .github/workflows/scorecards.yml | 51 ++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/scorecards.yml diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml new file mode 100644 index 0000000000..fb7acf66af --- /dev/null +++ b/.github/workflows/scorecards.yml @@ -0,0 +1,51 @@ +name: Scorecards supply-chain security +on: + # Only the default branch is supported. + branch_protection_rule: + schedule: + - cron: '25 18 * * 5' + push: + branches: [ "main" ] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecards analysis + runs-on: ubuntu-latest + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Used to receive a badge. + id-token: write + + steps: + - name: "Checkout code" + uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 # tag=v3.0.0 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@865b4092859256271290c77adbd10a43f4779972 # tag=v2.0.3 + with: + results_file: results.sarif + results_format: sarif + # Publish the results for public repositories to enable scorecard badges. For more details, see + # https://github.com/ossf/scorecard-action#publishing-results. + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + - name: "Upload artifact" + uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # tag=v3.0.0 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@5f532563584d71fdef14ee64d17bafb34f751ce5 # tag=v1.0.26 + with: + sarif_file: results.sarif From 9a628bb1c8511fc166ac102f25209b1931e1a1b6 Mon Sep 17 00:00:00 2001 From: Gabriela Gutierrez Date: Fri, 23 Sep 2022 17:07:46 -0300 Subject: [PATCH 15/42] Add OpenSSF Scorecard badge to README.md Signed-off-by: Gabriela Gutierrez --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8b89bb01e5..5fa6cc49e5 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ examples and guides.

[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/486/badge)](https://bestpractices.coreinfrastructure.org/projects/486) [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/prometheus/prometheus) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/prometheus.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:prometheus) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/prometheus/prometheus/badge)](https://api.securityscorecards.dev/projects/github.com/prometheus/prometheus) From 17caa505b1b6caff26b17d11ddbfb90c6763a54a Mon Sep 17 00:00:00 2001 From: Gabriela Gutierrez Date: Fri, 23 Sep 2022 17:28:30 -0300 Subject: [PATCH 16/42] Add Google copyright notice Signed-off-by: Gabriela Gutierrez --- .github/workflows/scorecards.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index fb7acf66af..66ef760e8b 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -1,3 +1,5 @@ +# Copyright 2022 Google LLC + name: Scorecards supply-chain security on: # Only the default branch is supported. From 6237aba7c4d79c793530bf119078f60cd96fec97 Mon Sep 17 00:00:00 2001 From: Gabriela Gutierrez Date: Fri, 23 Sep 2022 17:49:51 -0300 Subject: [PATCH 17/42] Fix trailing spaces Signed-off-by: Gabriela Gutierrez --- .github/workflows/scorecards.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 66ef760e8b..ef784e1fbe 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -21,7 +21,7 @@ jobs: security-events: write # Used to receive a badge. id-token: write - + steps: - name: "Checkout code" uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 # tag=v3.0.0 @@ -34,7 +34,7 @@ jobs: results_file: results.sarif results_format: sarif # Publish the results for public repositories to enable scorecard badges. For more details, see - # https://github.com/ossf/scorecard-action#publishing-results. + # https://github.com/ossf/scorecard-action#publishing-results. publish_results: true # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF @@ -45,7 +45,7 @@ jobs: name: SARIF file path: results.sarif retention-days: 5 - + # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" uses: github/codeql-action/upload-sarif@5f532563584d71fdef14ee64d17bafb34f751ce5 # tag=v1.0.26 From 19b4cb2f48d585c8d6371f1e5f9579035eac978c Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Fri, 29 Sep 2023 13:20:32 +0200 Subject: [PATCH 18/42] OpenSSF: Run on main and PR's Signed-off-by: Julien Pivotto --- .github/workflows/scorecards.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index ef784e1fbe..716555e8a9 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -2,10 +2,7 @@ name: Scorecards supply-chain security on: - # Only the default branch is supported. - branch_protection_rule: - schedule: - - cron: '25 18 * * 5' + pull_request: push: branches: [ "main" ] @@ -29,13 +26,13 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@865b4092859256271290c77adbd10a43f4779972 # tag=v2.0.3 + uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031 # tag=v2.2.0 with: results_file: results.sarif results_format: sarif # Publish the results for public repositories to enable scorecard badges. For more details, see # https://github.com/ossf/scorecard-action#publishing-results. - publish_results: true + publish_results: ${{ github.event_name != 'pull_request' }} # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. From b6fbda0c8a1f62688a26b87ba899d5e1b0587660 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Fri, 29 Sep 2023 13:47:06 +0200 Subject: [PATCH 19/42] UI: Update Webpack (GHSA-hc6q-2mpp-qw7j) Signed-off-by: Julien Pivotto --- web/ui/package-lock.json | 528 +++++++++++++++++++-------------------- 1 file changed, 258 insertions(+), 270 deletions(-) diff --git a/web/ui/package-lock.json b/web/ui/package-lock.json index 04c1a3eddc..a9e9e3d165 100644 --- a/web/ui/package-lock.json +++ b/web/ui/package-lock.json @@ -3464,9 +3464,9 @@ } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", @@ -3474,9 +3474,9 @@ } }, "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", @@ -3494,13 +3494,13 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@leichtgewicht/ip-codec": { @@ -4899,148 +4899,148 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" } }, @@ -5116,9 +5116,9 @@ } }, "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -5150,9 +5150,9 @@ } }, "node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, "peerDependencies": { "acorn": "^8" @@ -7647,9 +7647,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -7802,9 +7802,9 @@ "dev": true }, "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz", + "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==", "dev": true }, "node_modules/es-shim-unscopables": { @@ -18146,9 +18146,9 @@ } }, "node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -18236,9 +18236,9 @@ "dev": true }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", "dev": true, "dependencies": { "randombytes": "^2.1.0" @@ -19194,13 +19194,13 @@ } }, "node_modules/terser": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", - "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.20.0.tgz", + "integrity": "sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==", "dev": true, "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -19212,16 +19212,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", - "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.14", + "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" }, "engines": { "node": ">= 10.13.0" @@ -19886,22 +19886,22 @@ } }, "node_modules/webpack": { - "version": "5.74.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", - "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "version": "5.88.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", + "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", + "acorn-import-assertions": "^1.9.0", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -19910,9 +19910,9 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", + "terser-webpack-plugin": "^5.3.7", "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, @@ -20175,12 +20175,6 @@ "node": ">=10.13.0" } }, - "node_modules/webpack/node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true - }, "node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -23243,9 +23237,9 @@ "dev": true }, "@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, "requires": { "@jridgewell/gen-mapping": "^0.3.0", @@ -23253,9 +23247,9 @@ }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "requires": { "@jridgewell/set-array": "^1.0.1", @@ -23272,13 +23266,13 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@leichtgewicht/ip-codec": { @@ -24450,148 +24444,148 @@ } }, "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", "dev": true }, "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" } }, "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" } }, "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" } }, "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" } }, @@ -24650,9 +24644,9 @@ } }, "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true }, "acorn-globals": { @@ -24674,9 +24668,9 @@ } }, "acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, "requires": {} }, @@ -26542,9 +26536,9 @@ "dev": true }, "enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -26672,9 +26666,9 @@ "dev": true }, "es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz", + "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==", "dev": true }, "es-shim-unscopables": { @@ -34379,9 +34373,9 @@ } }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "requires": { "@types/json-schema": "^7.0.8", @@ -34457,9 +34451,9 @@ } }, "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -35207,13 +35201,13 @@ } }, "terser": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", - "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.20.0.tgz", + "integrity": "sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==", "dev": true, "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -35227,16 +35221,16 @@ } }, "terser-webpack-plugin": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", - "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.14", + "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" } }, "test-exclude": { @@ -35719,22 +35713,22 @@ "dev": true }, "webpack": { - "version": "5.74.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", - "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "version": "5.88.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", + "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", + "acorn-import-assertions": "^1.9.0", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -35743,19 +35737,13 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", + "terser-webpack-plugin": "^5.3.7", "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, "dependencies": { - "@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true - }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", From ca12cb8909936fbc2000dd7849672efcca7fa3ff Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Fri, 29 Sep 2023 13:47:31 +0200 Subject: [PATCH 20/42] UI: Update tough-cookie (GHSA-72xf-g2v4-qvf3 GHSA-76p3-8jx3-jpfq) Signed-off-by: Julien Pivotto --- web/ui/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web/ui/package-lock.json b/web/ui/package-lock.json index a9e9e3d165..7c60c12087 100644 --- a/web/ui/package-lock.json +++ b/web/ui/package-lock.json @@ -19342,9 +19342,9 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", - "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", "dev": true, "dependencies": { "psl": "^1.1.33", @@ -35309,9 +35309,9 @@ "dev": true }, "tough-cookie": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", - "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", "dev": true, "requires": { "psl": "^1.1.33", From f24dc17fcc0c7943b3edeffa36f8dba77fda0db7 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Fri, 29 Sep 2023 13:48:29 +0200 Subject: [PATCH 21/42] UI: Update semver (GHSA-c2qf-rxjj-qqgw) Signed-off-by: Julien Pivotto --- web/ui/package-lock.json | 120 +++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/web/ui/package-lock.json b/web/ui/package-lock.json index 7c60c12087..64c3febca4 100644 --- a/web/ui/package-lock.json +++ b/web/ui/package-lock.json @@ -4676,9 +4676,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -4821,9 +4821,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -6819,9 +6819,9 @@ } }, "node_modules/css-loader/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -9149,9 +9149,9 @@ } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -11714,9 +11714,9 @@ } }, "node_modules/jest-jasmine2/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -12646,9 +12646,9 @@ "peer": true }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "peer": true, "dependencies": { @@ -14924,9 +14924,9 @@ } }, "node_modules/postcss-loader/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -17358,9 +17358,9 @@ "dev": true }, "node_modules/react-scripts/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -18182,9 +18182,9 @@ } }, "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -19444,9 +19444,9 @@ } }, "node_modules/ts-jest/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -24316,9 +24316,9 @@ }, "dependencies": { "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -24391,9 +24391,9 @@ }, "dependencies": { "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -25918,9 +25918,9 @@ }, "dependencies": { "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -27666,9 +27666,9 @@ } }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -29623,9 +29623,9 @@ } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -30369,9 +30369,9 @@ "peer": true }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "peer": true, "requires": { @@ -32005,9 +32005,9 @@ }, "dependencies": { "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -33790,9 +33790,9 @@ "dev": true }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -34399,9 +34399,9 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true }, "send": { @@ -35374,9 +35374,9 @@ } }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" From d50c7d3bfc466d144db0666c7d5efa0a17a6be69 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Fri, 29 Sep 2023 13:49:10 +0200 Subject: [PATCH 22/42] UI: Update loader-utils (GHSA-hhq3-ff78-jv3g GHSA-3rfm-jhwj-7488) Signed-off-by: Julien Pivotto --- web/ui/package-lock.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/web/ui/package-lock.json b/web/ui/package-lock.json index 64c3febca4..ab37a977c6 100644 --- a/web/ui/package-lock.json +++ b/web/ui/package-lock.json @@ -13108,9 +13108,9 @@ } }, "node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "dependencies": { "big.js": "^5.2.2", @@ -16105,9 +16105,9 @@ } }, "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", - "integrity": "sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", "dev": true, "engines": { "node": ">= 12.13.0" @@ -30743,9 +30743,9 @@ "dev": true }, "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -32811,9 +32811,9 @@ }, "dependencies": { "loader-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", - "integrity": "sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", "dev": true } } From 3d80cb1325f47898ea55abc08390886565531561 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Fri, 29 Sep 2023 13:49:55 +0200 Subject: [PATCH 23/42] UI: Update json5 (GHSA-9c47-m6qq-7p4h) Signed-off-by: Julien Pivotto --- web/ui/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web/ui/package-lock.json b/web/ui/package-lock.json index ab37a977c6..18af99c40b 100644 --- a/web/ui/package-lock.json +++ b/web/ui/package-lock.json @@ -19471,9 +19471,9 @@ } }, "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -35397,9 +35397,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" From 76ebd621d688a96cfe663b56cc66b58a2d7be666 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Fri, 29 Sep 2023 13:54:30 +0200 Subject: [PATCH 24/42] UI: Update word-wrap (GHSA-j8xg-fqg3-53r7) Signed-off-by: Julien Pivotto --- web/ui/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web/ui/package-lock.json b/web/ui/package-lock.json index 18af99c40b..eabb75cb1f 100644 --- a/web/ui/package-lock.json +++ b/web/ui/package-lock.json @@ -20299,9 +20299,9 @@ } }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -36012,9 +36012,9 @@ } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "workbox-background-sync": { From ac0919d48cd59e6b1d53b72a122c36a895de37d9 Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Fri, 29 Sep 2023 19:10:41 +0200 Subject: [PATCH 25/42] Update docs/querying/functions.md Signed-off-by: Julien Pivotto --- docs/querying/functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/querying/functions.md b/docs/querying/functions.md index 68036d882f..6838bb72b6 100644 --- a/docs/querying/functions.md +++ b/docs/querying/functions.md @@ -14,7 +14,7 @@ vector, which if not provided it will default to the value of the expression _Notes about the experimental native histograms:_ * Ingesting native histograms has to be enabled via a [feature - flag](https://prometheus.io/docs/prometheus/latest/feature_flags/). As long as no native histograms + flag](../feature_flags.md#native-histograms). As long as no native histograms have been ingested into the TSDB, all functions will behave as usual. * Functions that do not explicitly mention native histograms in their documentation (see below) will ignore histogram samples. From 0a513f827d31c769736f41d45535176d65c33194 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Fri, 29 Sep 2023 22:50:30 +0200 Subject: [PATCH 26/42] ci(lint): enable errorlint linter on model Signed-off-by: Matthieu MOREL --- .golangci.yml | 3 --- model/textparse/openmetricsparse.go | 6 +++--- model/textparse/promparse.go | 4 ++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 57c6895b95..6e46812c8f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -35,9 +35,6 @@ issues: - path: discovery/ linters: - errorlint - - path: model/ - linters: - - errorlint - path: scrape/ linters: - errorlint diff --git a/model/textparse/openmetricsparse.go b/model/textparse/openmetricsparse.go index e0833636f1..5623e6833f 100644 --- a/model/textparse/openmetricsparse.go +++ b/model/textparse/openmetricsparse.go @@ -338,7 +338,7 @@ func (p *OpenMetricsParser) Next() (Entry, error) { var ts float64 // A float is enough to hold what we need for millisecond resolution. if ts, err = parseFloat(yoloString(p.l.buf()[1:])); err != nil { - return EntryInvalid, fmt.Errorf("%v while parsing: %q", err, p.l.b[p.start:p.l.i]) + return EntryInvalid, fmt.Errorf("%w while parsing: %q", err, p.l.b[p.start:p.l.i]) } if math.IsNaN(ts) || math.IsInf(ts, 0) { return EntryInvalid, fmt.Errorf("invalid timestamp %f", ts) @@ -391,7 +391,7 @@ func (p *OpenMetricsParser) parseComment() error { var ts float64 // A float is enough to hold what we need for millisecond resolution. if ts, err = parseFloat(yoloString(p.l.buf()[1:])); err != nil { - return fmt.Errorf("%v while parsing: %q", err, p.l.b[p.start:p.l.i]) + return fmt.Errorf("%w while parsing: %q", err, p.l.b[p.start:p.l.i]) } if math.IsNaN(ts) || math.IsInf(ts, 0) { return fmt.Errorf("invalid exemplar timestamp %f", ts) @@ -461,7 +461,7 @@ func (p *OpenMetricsParser) getFloatValue(t token, after string) (float64, error } val, err := parseFloat(yoloString(p.l.buf()[1:])) if err != nil { - return 0, fmt.Errorf("%v while parsing: %q", err, p.l.b[p.start:p.l.i]) + return 0, fmt.Errorf("%w while parsing: %q", err, p.l.b[p.start:p.l.i]) } // Ensure canonical NaN value. if math.IsNaN(p.exemplarVal) { diff --git a/model/textparse/promparse.go b/model/textparse/promparse.go index 94338a6660..04c295dd00 100644 --- a/model/textparse/promparse.go +++ b/model/textparse/promparse.go @@ -348,7 +348,7 @@ func (p *PromParser) Next() (Entry, error) { return EntryInvalid, p.parseError("expected value after metric", t2) } if p.val, err = parseFloat(yoloString(p.l.buf())); err != nil { - return EntryInvalid, fmt.Errorf("%v while parsing: %q", err, p.l.b[p.start:p.l.i]) + return EntryInvalid, fmt.Errorf("%w while parsing: %q", err, p.l.b[p.start:p.l.i]) } // Ensure canonical NaN value. if math.IsNaN(p.val) { @@ -361,7 +361,7 @@ func (p *PromParser) Next() (Entry, error) { case tTimestamp: p.hasTS = true if p.ts, err = strconv.ParseInt(yoloString(p.l.buf()), 10, 64); err != nil { - return EntryInvalid, fmt.Errorf("%v while parsing: %q", err, p.l.b[p.start:p.l.i]) + return EntryInvalid, fmt.Errorf("%w while parsing: %q", err, p.l.b[p.start:p.l.i]) } if t2 := p.nextToken(); t2 != tLinebreak { return EntryInvalid, p.parseError("expected next entry after timestamp", t2) From 5027863c40d318ae68894c0908aacb2a476ac338 Mon Sep 17 00:00:00 2001 From: Jennifer Villa Date: Sat, 30 Sep 2023 10:23:54 -0400 Subject: [PATCH 27/42] Clarify what happens when a rule group takes too long to execute Namely, call out that all subsequent evaluations will be skipped until the initial evaluation completes. Signed-off-by: Jennifer Villa --- docs/configuration/recording_rules.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/configuration/recording_rules.md b/docs/configuration/recording_rules.md index eda0214b35..6ccde040d8 100644 --- a/docs/configuration/recording_rules.md +++ b/docs/configuration/recording_rules.md @@ -147,3 +147,7 @@ by the rule are discarded, and if it's an alerting rule, _all_ alerts for the rule, active, pending, or inactive, are cleared as well. The event will be recorded as an error in the evaluation, and as such no stale markers are written. + +# Failed rule evaluations due to slow evaluation + +If a rule group hasn't finished evaluating before the next evaluation is supposed to start, the next evaluation will be skipped. Subsequent evaluations of the rule group will continue to be skipped until the initial evaluation either completes or times out. When this happens, there will be a gap in the recording rule metric. The `rule_group_iterations_missed_total` metric will be incremented for each missed iteration. From 601e5b902844f9fb02c422ec516dee642277c6a0 Mon Sep 17 00:00:00 2001 From: Jennifer Villa Date: Sat, 30 Sep 2023 10:26:29 -0400 Subject: [PATCH 28/42] Update recording_rules.md specified the evaluation interval defines when the next evaluation should start. Signed-off-by: Jennifer Villa --- docs/configuration/recording_rules.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/recording_rules.md b/docs/configuration/recording_rules.md index 6ccde040d8..0c8aef6377 100644 --- a/docs/configuration/recording_rules.md +++ b/docs/configuration/recording_rules.md @@ -150,4 +150,4 @@ written. # Failed rule evaluations due to slow evaluation -If a rule group hasn't finished evaluating before the next evaluation is supposed to start, the next evaluation will be skipped. Subsequent evaluations of the rule group will continue to be skipped until the initial evaluation either completes or times out. When this happens, there will be a gap in the recording rule metric. The `rule_group_iterations_missed_total` metric will be incremented for each missed iteration. +If a rule group hasn't finished evaluating before its next evaluation is supposed to start (as defined by the `evaluation_interval`), the next evaluation will be skipped. Subsequent evaluations of the rule group will continue to be skipped until the initial evaluation either completes or times out. When this happens, there will be a gap in the recording rule metric. The `rule_group_iterations_missed_total` metric will be incremented for each missed iteration. From 216cf6046ea61194d691be31443ed26de7f6968a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 23:43:34 +0000 Subject: [PATCH 29/42] build(deps): bump actions/checkout from 4.0.0 to 4.1.0 in /scripts Bumps [actions/checkout](https://github.com/actions/checkout) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/3df4ab11eba7bda6032a0b82a6bb43b11571feac...8ade135a41bc03ea155e62e844d188df1ea18608) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- scripts/golangci-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/golangci-lint.yml b/scripts/golangci-lint.yml index 8ace97bde1..15cf547be1 100644 --- a/scripts/golangci-lint.yml +++ b/scripts/golangci-lint.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 - name: install Go uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 with: From 5d8f0e0582abb03624c1fd3a0bde0d04a8d360a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 23:48:39 +0000 Subject: [PATCH 30/42] build(deps): bump github.com/hashicorp/consul/api from 1.22.0 to 1.25.1 Bumps [github.com/hashicorp/consul/api](https://github.com/hashicorp/consul) from 1.22.0 to 1.25.1. - [Release notes](https://github.com/hashicorp/consul/releases) - [Changelog](https://github.com/hashicorp/consul/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/consul/compare/api/v1.22.0...api/v1.25.1) --- updated-dependencies: - dependency-name: github.com/hashicorp/consul/api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 1cdca0f989..3fb42ceaa6 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/gophercloud/gophercloud v1.5.0 github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/hashicorp/consul/api v1.22.0 + github.com/hashicorp/consul/api v1.25.1 github.com/hashicorp/nomad/api v0.0.0-20230718173136-3a687930bd3e github.com/hetznercloud/hcloud-go/v2 v2.0.0 github.com/ionos-cloud/sdk-go/v6 v6.1.8 diff --git a/go.sum b/go.sum index bdf4f59477..2f837a09de 100644 --- a/go.sum +++ b/go.sum @@ -403,10 +403,10 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/api v1.22.0 h1:ydEvDooB/A0c/xpsBd8GSt7P2/zYPBui4KrNip0xGjE= -github.com/hashicorp/consul/api v1.22.0/go.mod h1:zHpYgZ7TeYqS6zaszjwSt128OwESRpnhU9aGa6ue3Eg= +github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE= +github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.14.0 h1:Hly+BMNMssVzoWddbBnBFi3W+Fzytvm0haSkihhj3GU= +github.com/hashicorp/consul/sdk v0.14.1 h1:ZiwE2bKb+zro68sWzZ1SgHF3kRMBZ94TwOCFRF4ylPs= github.com/hashicorp/cronexpr v1.1.2 h1:wG/ZYIKT+RT3QkOdgYc+xsKWVRgnxJ1OJtjjy84fJ9A= github.com/hashicorp/cronexpr v1.1.2/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= From 754fcc265e47700fe4788e21bbe19c77bb5ef000 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 23:53:21 +0000 Subject: [PATCH 31/42] build(deps): bump github.com/prometheus/client_golang Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- documentation/examples/remote_storage/go.mod | 10 ++++----- documentation/examples/remote_storage/go.sum | 22 ++++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/documentation/examples/remote_storage/go.mod b/documentation/examples/remote_storage/go.mod index b4c8e077d6..1800dfef25 100644 --- a/documentation/examples/remote_storage/go.mod +++ b/documentation/examples/remote_storage/go.mod @@ -8,7 +8,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/golang/snappy v0.0.4 github.com/influxdata/influxdb v1.11.2 - github.com/prometheus/client_golang v1.16.0 + github.com/prometheus/client_golang v1.17.0 github.com/prometheus/common v0.44.0 github.com/prometheus/prometheus v0.45.0 github.com/stretchr/testify v1.8.4 @@ -42,9 +42,9 @@ require ( github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect + github.com/prometheus/procfs v0.11.1 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 // indirect go.opentelemetry.io/otel v1.16.0 // indirect @@ -56,11 +56,11 @@ require ( golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sys v0.8.0 // indirect + golang.org/x/sys v0.11.0 // indirect golang.org/x/text v0.9.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/documentation/examples/remote_storage/go.sum b/documentation/examples/remote_storage/go.sum index 2ade3a1b7c..e0070d9663 100644 --- a/documentation/examples/remote_storage/go.sum +++ b/documentation/examples/remote_storage/go.sum @@ -194,13 +194,13 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM= +github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= @@ -213,8 +213,8 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= +github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/prometheus/prometheus v0.45.0 h1:O/uG+Nw4kNxx/jDPxmjsSDd+9Ohql6E7ZSY1x5x/0KI= github.com/prometheus/prometheus v0.45.0/go.mod h1:jC5hyO8ItJBnDWGecbEucMyXjzxGv9cxsxsjS9u5s1w= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -292,7 +292,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -312,8 +312,8 @@ golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -352,8 +352,8 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 4ba8430299cae194f7579d1adb5bb724f90cbce4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 23:57:36 +0000 Subject: [PATCH 32/42] build(deps): bump actions/upload-artifact from 3.0.0 to 3.1.3 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3.0.0 to 3.1.3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3...a8a3f3ad30e3422c9c7b888a15615d19a852ae32) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 716555e8a9..84f732ee66 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -37,7 +37,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # tag=v3.0.0 + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # tag=v3.1.3 with: name: SARIF file path: results.sarif From de7e057d3c8f21d31bd98fd1499ccb2d392fe9e9 Mon Sep 17 00:00:00 2001 From: Arve Knudsen Date: Mon, 2 Oct 2023 12:16:37 +0200 Subject: [PATCH 33/42] tsdb: Tighten up sub-benchmark scope in BenchmarkQuerier (#12718) Signed-off-by: Arve Knudsen --- tsdb/querier_bench_test.go | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/tsdb/querier_bench_test.go b/tsdb/querier_bench_test.go index 206b41fde8..e2e281db8b 100644 --- a/tsdb/querier_bench_test.go +++ b/tsdb/querier_bench_test.go @@ -31,10 +31,9 @@ const ( ) func BenchmarkQuerier(b *testing.B) { - chunkDir := b.TempDir() opts := DefaultHeadOptions() opts.ChunkRange = 1000 - opts.ChunkDirRoot = chunkDir + opts.ChunkDirRoot = b.TempDir() h, err := NewHead(nil, nil, nil, nil, opts, nil) require.NoError(b, err) defer func() { @@ -58,9 +57,13 @@ func BenchmarkQuerier(b *testing.B) { } require.NoError(b, app.Commit()) - ir, err := h.Index() - require.NoError(b, err) b.Run("Head", func(b *testing.B) { + ir, err := h.Index() + require.NoError(b, err) + defer func() { + require.NoError(b, ir.Close()) + }() + b.Run("PostingsForMatchers", func(b *testing.B) { benchmarkPostingsForMatchers(b, ir) }) @@ -69,18 +72,20 @@ func BenchmarkQuerier(b *testing.B) { }) }) - tmpdir := b.TempDir() - - blockdir := createBlockFromHead(b, tmpdir, h) - block, err := OpenBlock(nil, blockdir, nil) - require.NoError(b, err) - defer func() { - require.NoError(b, block.Close()) - }() - ir, err = block.Index() - require.NoError(b, err) - defer ir.Close() b.Run("Block", func(b *testing.B) { + blockdir := createBlockFromHead(b, b.TempDir(), h) + block, err := OpenBlock(nil, blockdir, nil) + require.NoError(b, err) + defer func() { + require.NoError(b, block.Close()) + }() + + ir, err := block.Index() + require.NoError(b, err) + defer func() { + require.NoError(b, ir.Close()) + }() + b.Run("PostingsForMatchers", func(b *testing.B) { benchmarkPostingsForMatchers(b, ir) }) @@ -239,10 +244,9 @@ func BenchmarkMergedStringIter(b *testing.B) { } func BenchmarkQuerierSelect(b *testing.B) { - chunkDir := b.TempDir() opts := DefaultHeadOptions() opts.ChunkRange = 1000 - opts.ChunkDirRoot = chunkDir + opts.ChunkDirRoot = b.TempDir() h, err := NewHead(nil, nil, nil, nil, opts, nil) require.NoError(b, err) defer h.Close() From 1492031ef2e04e94bf1d50a7d46eb881aa2b0c0a Mon Sep 17 00:00:00 2001 From: Oleg Zaytsev Date: Mon, 2 Oct 2023 16:24:25 +0200 Subject: [PATCH 34/42] Optimize ListPostings Next() (#12906) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Next() call of ListPostings() was updating two values, while we can just update the position. This is up to 30% faster for high number of Postings. goos: linux goarch: amd64 pkg: github.com/prometheus/prometheus/tsdb/index cpu: 11th Gen Intel(R) Core(TM) i7-11700K @ 3.60GHz │ old │ new │ │ sec/op │ sec/op vs base │ ListPostings/count=100-16 819.2n ± 0% 732.6n ± 0% -10.58% (p=0.000 n=20) ListPostings/count=1000-16 2.685µ ± 1% 2.017µ ± 0% -24.88% (p=0.000 n=20) ListPostings/count=10000-16 21.43µ ± 1% 14.81µ ± 0% -30.91% (p=0.000 n=20) ListPostings/count=100000-16 209.4µ ± 1% 143.3µ ± 0% -31.55% (p=0.000 n=20) ListPostings/count=1000000-16 2.086m ± 1% 1.436m ± 1% -31.18% (p=0.000 n=20) geomean 29.02µ 21.41µ -26.22% We're talking about microseconds here, but they just keep adding. Signed-off-by: Oleg Zaytsev --- tsdb/index/postings.go | 35 ++++----- tsdb/index/postings_test.go | 144 ++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+), 20 deletions(-) diff --git a/tsdb/index/postings.go b/tsdb/index/postings.go index e5fa5fc540..5f24dbfe1a 100644 --- a/tsdb/index/postings.go +++ b/tsdb/index/postings.go @@ -747,7 +747,7 @@ func (rp *removedPostings) Err() error { // ListPostings implements the Postings interface over a plain list. type ListPostings struct { list []storage.SeriesRef - cur storage.SeriesRef + pos int } func NewListPostings(list []storage.SeriesRef) Postings { @@ -759,39 +759,34 @@ func newListPostings(list ...storage.SeriesRef) *ListPostings { } func (it *ListPostings) At() storage.SeriesRef { - return it.cur + return it.list[it.pos-1] } func (it *ListPostings) Next() bool { - if len(it.list) > 0 { - it.cur = it.list[0] - it.list = it.list[1:] + if it.pos < len(it.list) { + it.pos++ return true } - it.cur = 0 return false } func (it *ListPostings) Seek(x storage.SeriesRef) bool { - // If the current value satisfies, then return. - if it.cur >= x { - return true + if it.pos == 0 { + it.pos++ } - if len(it.list) == 0 { + if it.pos > len(it.list) { return false } + // If the current value satisfies, then return. + if it.list[it.pos-1] >= x { + return true + } // Do binary search between current position and end. - i := sort.Search(len(it.list), func(i int) bool { - return it.list[i] >= x - }) - if i < len(it.list) { - it.cur = it.list[i] - it.list = it.list[i+1:] - return true - } - it.list = nil - return false + it.pos = sort.Search(len(it.list[it.pos-1:]), func(i int) bool { + return it.list[i+it.pos-1] >= x + }) + it.pos + return it.pos-1 < len(it.list) } func (it *ListPostings) Err() error { diff --git a/tsdb/index/postings_test.go b/tsdb/index/postings_test.go index b2ed1064d2..f0f3bb75a8 100644 --- a/tsdb/index/postings_test.go +++ b/tsdb/index/postings_test.go @@ -1118,3 +1118,147 @@ func TestPostingsWithIndexHeap(t *testing.T) { require.Equal(t, storage.SeriesRef(25), node.p.At()) }) } + +func TestListPostings(t *testing.T) { + t.Run("empty list", func(t *testing.T) { + p := NewListPostings(nil) + require.False(t, p.Next()) + require.False(t, p.Seek(10)) + require.False(t, p.Next()) + require.NoError(t, p.Err()) + }) + + t.Run("one posting", func(t *testing.T) { + t.Run("next", func(t *testing.T) { + p := NewListPostings([]storage.SeriesRef{10}) + require.True(t, p.Next()) + require.Equal(t, storage.SeriesRef(10), p.At()) + require.False(t, p.Next()) + require.NoError(t, p.Err()) + }) + t.Run("seek less", func(t *testing.T) { + p := NewListPostings([]storage.SeriesRef{10}) + require.True(t, p.Seek(5)) + require.Equal(t, storage.SeriesRef(10), p.At()) + require.True(t, p.Seek(5)) + require.Equal(t, storage.SeriesRef(10), p.At()) + require.False(t, p.Next()) + require.NoError(t, p.Err()) + }) + t.Run("seek equal", func(t *testing.T) { + p := NewListPostings([]storage.SeriesRef{10}) + require.True(t, p.Seek(10)) + require.Equal(t, storage.SeriesRef(10), p.At()) + require.False(t, p.Next()) + require.NoError(t, p.Err()) + }) + t.Run("seek more", func(t *testing.T) { + p := NewListPostings([]storage.SeriesRef{10}) + require.False(t, p.Seek(15)) + require.False(t, p.Next()) + require.NoError(t, p.Err()) + }) + t.Run("seek after next", func(t *testing.T) { + p := NewListPostings([]storage.SeriesRef{10}) + require.True(t, p.Next()) + require.False(t, p.Seek(15)) + require.False(t, p.Next()) + require.NoError(t, p.Err()) + }) + }) + + t.Run("multiple postings", func(t *testing.T) { + t.Run("next", func(t *testing.T) { + p := NewListPostings([]storage.SeriesRef{10, 20}) + require.True(t, p.Next()) + require.Equal(t, storage.SeriesRef(10), p.At()) + require.True(t, p.Next()) + require.Equal(t, storage.SeriesRef(20), p.At()) + require.False(t, p.Next()) + require.NoError(t, p.Err()) + }) + t.Run("seek", func(t *testing.T) { + p := NewListPostings([]storage.SeriesRef{10, 20}) + require.True(t, p.Seek(5)) + require.Equal(t, storage.SeriesRef(10), p.At()) + require.True(t, p.Seek(5)) + require.Equal(t, storage.SeriesRef(10), p.At()) + require.True(t, p.Seek(10)) + require.Equal(t, storage.SeriesRef(10), p.At()) + require.True(t, p.Next()) + require.Equal(t, storage.SeriesRef(20), p.At()) + require.True(t, p.Seek(10)) + require.Equal(t, storage.SeriesRef(20), p.At()) + require.True(t, p.Seek(20)) + require.Equal(t, storage.SeriesRef(20), p.At()) + require.False(t, p.Next()) + require.NoError(t, p.Err()) + }) + t.Run("seek lest than last", func(t *testing.T) { + p := NewListPostings([]storage.SeriesRef{10, 20, 30, 40, 50}) + require.True(t, p.Seek(45)) + require.Equal(t, storage.SeriesRef(50), p.At()) + require.False(t, p.Next()) + }) + t.Run("seek exactly last", func(t *testing.T) { + p := NewListPostings([]storage.SeriesRef{10, 20, 30, 40, 50}) + require.True(t, p.Seek(50)) + require.Equal(t, storage.SeriesRef(50), p.At()) + require.False(t, p.Next()) + }) + t.Run("seek more than last", func(t *testing.T) { + p := NewListPostings([]storage.SeriesRef{10, 20, 30, 40, 50}) + require.False(t, p.Seek(60)) + require.False(t, p.Next()) + }) + }) + + t.Run("seek", func(t *testing.T) { + for _, c := range []int{2, 8, 9, 10} { + t.Run(fmt.Sprintf("count=%d", c), func(t *testing.T) { + list := make([]storage.SeriesRef, c) + for i := 0; i < c; i++ { + list[i] = storage.SeriesRef(i * 10) + } + + t.Run("all one by one", func(t *testing.T) { + p := NewListPostings(list) + for i := 0; i < c; i++ { + require.True(t, p.Seek(storage.SeriesRef(i*10))) + require.Equal(t, storage.SeriesRef(i*10), p.At()) + } + require.False(t, p.Seek(storage.SeriesRef(c*10))) + }) + + t.Run("each one", func(t *testing.T) { + for _, ref := range list { + p := NewListPostings(list) + require.True(t, p.Seek(ref)) + require.Equal(t, ref, p.At()) + } + }) + }) + } + }) +} + +func BenchmarkListPostings(b *testing.B) { + const maxCount = 1e6 + input := make([]storage.SeriesRef, maxCount) + for i := 0; i < maxCount; i++ { + input[i] = storage.SeriesRef(i << 2) + } + + for _, count := range []int{100, 1e3, 10e3, 100e3, maxCount} { + b.Run(fmt.Sprintf("count=%d", count), func(b *testing.B) { + for i := 0; i < b.N; i++ { + p := NewListPostings(input[:count]) + var sum storage.SeriesRef + for p.Next() { + sum += p.At() + } + require.NotZero(b, sum) + } + }) + } +} From 65ffa0c511f3eef8c813680b7e43740bb8a1705d Mon Sep 17 00:00:00 2001 From: Jennifer Villa Date: Mon, 2 Oct 2023 21:37:29 -0400 Subject: [PATCH 35/42] Update recording_rules.md adding Josh's suggestion Signed-off-by: Jennifer Villa --- docs/configuration/recording_rules.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/recording_rules.md b/docs/configuration/recording_rules.md index 0c8aef6377..90bd3df730 100644 --- a/docs/configuration/recording_rules.md +++ b/docs/configuration/recording_rules.md @@ -150,4 +150,4 @@ written. # Failed rule evaluations due to slow evaluation -If a rule group hasn't finished evaluating before its next evaluation is supposed to start (as defined by the `evaluation_interval`), the next evaluation will be skipped. Subsequent evaluations of the rule group will continue to be skipped until the initial evaluation either completes or times out. When this happens, there will be a gap in the recording rule metric. The `rule_group_iterations_missed_total` metric will be incremented for each missed iteration. +If a rule group hasn't finished evaluating before its next evaluation is supposed to start (as defined by the `evaluation_interval`), the next evaluation will be skipped. Subsequent evaluations of the rule group will continue to be skipped until the initial evaluation either completes or times out. When this happens, there will be a gap in the recording rule metric. The `rule_group_iterations_missed_total` metric will be incremented for each missed iteration of the rule group. From ea7bec4cc7dd8984d86996e7e711e6884c38425b Mon Sep 17 00:00:00 2001 From: Jennifer Villa Date: Mon, 2 Oct 2023 21:44:54 -0400 Subject: [PATCH 36/42] Update recording_rules.md updated language to be a bit more clear Signed-off-by: Jennifer Villa --- docs/configuration/recording_rules.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/recording_rules.md b/docs/configuration/recording_rules.md index 90bd3df730..48ab951f94 100644 --- a/docs/configuration/recording_rules.md +++ b/docs/configuration/recording_rules.md @@ -150,4 +150,4 @@ written. # Failed rule evaluations due to slow evaluation -If a rule group hasn't finished evaluating before its next evaluation is supposed to start (as defined by the `evaluation_interval`), the next evaluation will be skipped. Subsequent evaluations of the rule group will continue to be skipped until the initial evaluation either completes or times out. When this happens, there will be a gap in the recording rule metric. The `rule_group_iterations_missed_total` metric will be incremented for each missed iteration of the rule group. +If a rule group hasn't finished evaluating before its next evaluation is supposed to start (as defined by the `evaluation_interval`), the next evaluation will be skipped. Subsequent evaluations of the rule group will continue to be skipped until the initial evaluation either completes or times out. When this happens, there will be a gap in the metric produced by the recording rule. The `rule_group_iterations_missed_total` metric will be incremented for each missed iteration of the rule group. From ec9170b8bf6dd8595c42b57d211f3567aa3bd0c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Rabenstein?= Date: Wed, 20 Sep 2023 18:01:21 +0200 Subject: [PATCH 37/42] Merge pull request #12874 from krajorama/outof-order-chunks Fix duplicate sample detection at chunk size limit Signed-off-by: SuperQ --- tsdb/head_append.go | 9 ++++++--- tsdb/head_test.go | 46 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/tsdb/head_append.go b/tsdb/head_append.go index 9016943756..d1f4d3035e 100644 --- a/tsdb/head_append.go +++ b/tsdb/head_append.go @@ -1282,9 +1282,6 @@ func (s *memSeries) appendPreprocessor(t int64, e chunkenc.Encoding, o chunkOpts // There is no head chunk in this series yet, create the first chunk for the sample. c = s.cutNewHeadChunk(t, e, o.chunkRange) chunkCreated = true - } else if len(c.chunk.Bytes()) > maxBytesPerXORChunk { - c = s.cutNewHeadChunk(t, e, o.chunkRange) - chunkCreated = true } // Out of order sample. @@ -1292,6 +1289,12 @@ func (s *memSeries) appendPreprocessor(t int64, e chunkenc.Encoding, o chunkOpts return c, false, chunkCreated } + // Check the chunk size, unless we just created it and if the chunk is too large, cut a new one. + if !chunkCreated && len(c.chunk.Bytes()) > maxBytesPerXORChunk { + c = s.cutNewHeadChunk(t, e, o.chunkRange) + chunkCreated = true + } + if c.chunk.Encoding() != e { // The chunk encoding expected by this append is different than the head chunk's // encoding. So we cut a new chunk with the expected encoding. diff --git a/tsdb/head_test.go b/tsdb/head_test.go index b501f5f3f3..cd9ab65108 100644 --- a/tsdb/head_test.go +++ b/tsdb/head_test.go @@ -5399,3 +5399,49 @@ func TestCuttingNewHeadChunks(t *testing.T) { }) } } + +// TestHeadDetectsDuplcateSampleAtSizeLimit tests a regression where a duplicate sample +// is appended to the head, right when the head chunk is at the size limit. +// The test adds all samples as duplicate, thus expecting that the result has +// exactly half of the samples. +func TestHeadDetectsDuplicateSampleAtSizeLimit(t *testing.T) { + numSamples := 1000 + baseTS := int64(1695209650) + + h, _ := newTestHead(t, DefaultBlockDuration, wlog.CompressionNone, false) + defer func() { + require.NoError(t, h.Close()) + }() + + a := h.Appender(context.Background()) + var err error + vals := []float64{math.MaxFloat64, 0x00} // Use the worst case scenario for the XOR encoding. Otherwise we hit the sample limit before the size limit. + for i := 0; i < numSamples; i++ { + ts := baseTS + int64(i/2)*10000 + a.Append(0, labels.FromStrings("foo", "bar"), ts, vals[(i/2)%len(vals)]) + err = a.Commit() + require.NoError(t, err) + a = h.Appender(context.Background()) + } + + indexReader, err := h.Index() + require.NoError(t, err) + + var ( + chunks []chunks.Meta + builder labels.ScratchBuilder + ) + require.NoError(t, indexReader.Series(1, &builder, &chunks)) + + chunkReader, err := h.Chunks() + require.NoError(t, err) + + storedSampleCount := 0 + for _, chunkMeta := range chunks { + chunk, err := chunkReader.Chunk(chunkMeta) + require.NoError(t, err) + storedSampleCount += chunk.NumSamples() + } + + require.Equal(t, numSamples/2, storedSampleCount) +} From 64130d7909e2ce5a2e35f2fbb39eb5bc5e09fc92 Mon Sep 17 00:00:00 2001 From: SuperQ Date: Wed, 4 Oct 2023 09:46:57 +0200 Subject: [PATCH 38/42] Release 2.47.1 * [BUGFIX] Fix duplicate sample detection at chunk size limit #12874 Signed-off-by: SuperQ --- CHANGELOG.md | 4 ++++ VERSION | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a9d4521a1..7ad9c69dc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 2.47.1 / 2023-10-04 + +* [BUGFIX] Fix duplicate sample detection at chunk size limit #12874 + ## 2.47.0 / 2023-09-06 This release adds an experimental OpenTelemetry (OTLP) Ingestion feature, diff --git a/VERSION b/VERSION index bb13a7e354..24c6ede7ad 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.47.0 +2.47.1 From b43358fd43cda5e19fc138a557b11bcf5bc7e408 Mon Sep 17 00:00:00 2001 From: Arve Knudsen Date: Wed, 4 Oct 2023 10:36:55 +0200 Subject: [PATCH 39/42] API: Add tests for query timeout parameter (#12927) Add unit tests for Web API's query endpoint (GET/POST). Also modify the endpoint handler to use context.WithDeadline instead of context.WithTimeout, so the deadline is deterministic for the tests. Signed-off-by: Arve Knudsen --- web/api/v1/api.go | 2 +- web/api/v1/api_test.go | 106 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/web/api/v1/api.go b/web/api/v1/api.go index 62a376b0ba..1a54f23a61 100644 --- a/web/api/v1/api.go +++ b/web/api/v1/api.go @@ -436,7 +436,7 @@ func (api *API) query(r *http.Request) (result apiFuncResult) { return invalidParamError(err, "timeout") } - ctx, cancel = context.WithTimeout(ctx, timeout) + ctx, cancel = context.WithDeadline(ctx, api.now().Add(timeout)) defer cancel() } diff --git a/web/api/v1/api_test.go b/web/api/v1/api_test.go index c86165b780..475b4bab54 100644 --- a/web/api/v1/api_test.go +++ b/web/api/v1/api_test.go @@ -404,7 +404,7 @@ func TestEndpoints(t *testing.T) { testEndpoints(t, api, testTargetRetriever, storage, true) }) - // Run all the API tests against a API that is wired to forward queries via + // Run all the API tests against an API that is wired to forward queries via // the remote read client to a test server, which in turn sends them to the // data from the test storage. t.Run("remote", func(t *testing.T) { @@ -3660,3 +3660,107 @@ func TestExtractQueryOpts(t *testing.T) { }) } } + +// Test query timeout parameter. +func TestQueryTimeout(t *testing.T) { + storage := promql.LoadedStorage(t, ` + load 1m + test_metric1{foo="bar"} 0+100x100 + `) + t.Cleanup(func() { + _ = storage.Close() + }) + + now := time.Now() + + for _, tc := range []struct { + name string + method string + }{ + { + name: "GET method", + method: http.MethodGet, + }, + { + name: "POST method", + method: http.MethodPost, + }, + } { + t.Run(tc.name, func(t *testing.T) { + engine := &fakeEngine{} + api := &API{ + Queryable: storage, + QueryEngine: engine, + ExemplarQueryable: storage.ExemplarQueryable(), + alertmanagerRetriever: testAlertmanagerRetriever{}.toFactory(), + flagsMap: sampleFlagMap, + now: func() time.Time { return now }, + config: func() config.Config { return samplePrometheusCfg }, + ready: func(f http.HandlerFunc) http.HandlerFunc { return f }, + } + + query := url.Values{ + "query": []string{"2"}, + "timeout": []string{"1s"}, + } + ctx := context.Background() + req, err := http.NewRequest(tc.method, fmt.Sprintf("http://example.com?%s", query.Encode()), nil) + require.NoError(t, err) + req.RemoteAddr = "127.0.0.1:20201" + + res := api.query(req.WithContext(ctx)) + assertAPIError(t, res.err, errorNone) + + require.Len(t, engine.query.execCalls, 1) + deadline, ok := engine.query.execCalls[0].Deadline() + require.True(t, ok) + require.Equal(t, now.Add(time.Second), deadline) + }) + } +} + +// fakeEngine is a fake QueryEngine implementation. +type fakeEngine struct { + query fakeQuery +} + +func (e *fakeEngine) SetQueryLogger(promql.QueryLogger) {} + +func (e *fakeEngine) NewInstantQuery(ctx context.Context, q storage.Queryable, opts promql.QueryOpts, qs string, ts time.Time) (promql.Query, error) { + return &e.query, nil +} + +func (e *fakeEngine) NewRangeQuery(ctx context.Context, q storage.Queryable, opts promql.QueryOpts, qs string, start, end time.Time, interval time.Duration) (promql.Query, error) { + return &e.query, nil +} + +// fakeQuery is a fake Query implementation. +type fakeQuery struct { + query string + execCalls []context.Context +} + +func (q *fakeQuery) Exec(ctx context.Context) *promql.Result { + q.execCalls = append(q.execCalls, ctx) + return &promql.Result{ + Value: &parser.StringLiteral{ + Val: "test", + }, + } +} + +func (q *fakeQuery) Close() {} + +func (q *fakeQuery) Statement() parser.Statement { + return nil +} + +func (q *fakeQuery) Stats() *stats.Statistics { + return nil +} + +func (q *fakeQuery) Cancel() {} + +func (q *fakeQuery) String() string { + return q.query +} From cdad64002a41aadbb821ce39e1b396cf5154dd7e Mon Sep 17 00:00:00 2001 From: rakshith210 <56937390+rakshith210@users.noreply.github.com> Date: Wed, 4 Oct 2023 19:16:36 -0700 Subject: [PATCH 40/42] Added Azure OAuth support (#12572) * Added Azure OAuth support Signed-off-by: rakshith210 * Added missing comment Signed-off-by: rakshith210 * Addressing comment Signed-off-by: rakshith210 * Fixed lint issue Signed-off-by: rakshith210 * Fix test Signed-off-by: rakshith210 * Addressing comments Signed-off-by: rakshith210 * Added documentation and updated unit tests Signed-off-by: rakshith210 * Addressing comments Signed-off-by: rakshith210 --------- Signed-off-by: rakshith210 --- docs/configuration/configuration.md | 8 +- storage/remote/azuread/azuread.go | 116 +++++- storage/remote/azuread/azuread_test.go | 333 ++++++++++-------- ...ng.yaml => azuread_bad_configmissing.yaml} | 0 .../azuread_bad_invalidoauthconfig.yaml | 4 + .../testdata/azuread_bad_twoconfig.yaml | 7 + ...yaml => azuread_good_managedidentity.yaml} | 0 .../azuread/testdata/azuread_good_oauth.yaml | 5 + 8 files changed, 318 insertions(+), 155 deletions(-) rename storage/remote/azuread/testdata/{azuread_bad_clientidmissing.yaml => azuread_bad_configmissing.yaml} (100%) create mode 100644 storage/remote/azuread/testdata/azuread_bad_invalidoauthconfig.yaml create mode 100644 storage/remote/azuread/testdata/azuread_bad_twoconfig.yaml rename storage/remote/azuread/testdata/{azuread_good.yaml => azuread_good_managedidentity.yaml} (100%) create mode 100644 storage/remote/azuread/testdata/azuread_good_oauth.yaml diff --git a/docs/configuration/configuration.md b/docs/configuration/configuration.md index c9e9415490..b55bb7d721 100644 --- a/docs/configuration/configuration.md +++ b/docs/configuration/configuration.md @@ -3537,7 +3537,13 @@ azuread: # Azure User-assigned Managed identity. [ managed_identity: - [ client_id: ] + [ client_id: ] ] + + # Azure OAuth. + [ oauth: + [ client_id: ] + [ client_secret: ] + [ tenant_id: ] ] # Configures the remote write request's TLS settings. tls_config: diff --git a/storage/remote/azuread/azuread.go b/storage/remote/azuread/azuread.go index 94b6144da1..cb4587b02a 100644 --- a/storage/remote/azuread/azuread.go +++ b/storage/remote/azuread/azuread.go @@ -22,7 +22,10 @@ import ( "sync" "time" + "github.com/grafana/regexp" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/google/uuid" @@ -46,11 +49,26 @@ type ManagedIdentityConfig struct { ClientID string `yaml:"client_id,omitempty"` } +// OAuthConfig is used to store azure oauth config values. +type OAuthConfig struct { + // ClientID is the clientId of the azure active directory application that is being used to authenticate. + ClientID string `yaml:"client_id,omitempty"` + + // ClientSecret is the clientSecret of the azure active directory application that is being used to authenticate. + ClientSecret string `yaml:"client_secret,omitempty"` + + // TenantID is the tenantId of the azure active directory application that is being used to authenticate. + TenantID string `yaml:"tenant_id,omitempty"` +} + // AzureADConfig is used to store the config values. type AzureADConfig struct { // nolint:revive // ManagedIdentity is the managed identity that is being used to authenticate. ManagedIdentity *ManagedIdentityConfig `yaml:"managed_identity,omitempty"` + // OAuth is the oauth config that is being used to authenticate. + OAuth *OAuthConfig `yaml:"oauth,omitempty"` + // Cloud is the Azure cloud in which the service is running. Example: AzurePublic/AzureGovernment/AzureChina. Cloud string `yaml:"cloud,omitempty"` } @@ -84,18 +102,47 @@ func (c *AzureADConfig) Validate() error { return fmt.Errorf("must provide a cloud in the Azure AD config") } - if c.ManagedIdentity == nil { - return fmt.Errorf("must provide an Azure Managed Identity in the Azure AD config") + if c.ManagedIdentity == nil && c.OAuth == nil { + return fmt.Errorf("must provide an Azure Managed Identity or Azure OAuth in the Azure AD config") } - if c.ManagedIdentity.ClientID == "" { - return fmt.Errorf("must provide an Azure Managed Identity client_id in the Azure AD config") + if c.ManagedIdentity != nil && c.OAuth != nil { + return fmt.Errorf("cannot provide both Azure Managed Identity and Azure OAuth in the Azure AD config") } - _, err := uuid.Parse(c.ManagedIdentity.ClientID) - if err != nil { - return fmt.Errorf("the provided Azure Managed Identity client_id provided is invalid") + if c.ManagedIdentity != nil { + if c.ManagedIdentity.ClientID == "" { + return fmt.Errorf("must provide an Azure Managed Identity client_id in the Azure AD config") + } + + _, err := uuid.Parse(c.ManagedIdentity.ClientID) + if err != nil { + return fmt.Errorf("the provided Azure Managed Identity client_id is invalid") + } } + + if c.OAuth != nil { + if c.OAuth.ClientID == "" { + return fmt.Errorf("must provide an Azure OAuth client_id in the Azure AD config") + } + if c.OAuth.ClientSecret == "" { + return fmt.Errorf("must provide an Azure OAuth client_secret in the Azure AD config") + } + if c.OAuth.TenantID == "" { + return fmt.Errorf("must provide an Azure OAuth tenant_id in the Azure AD config") + } + + var err error + _, err = uuid.Parse(c.OAuth.ClientID) + if err != nil { + return fmt.Errorf("the provided Azure OAuth client_id is invalid") + } + _, err = regexp.MatchString("^[0-9a-zA-Z-.]+$", c.OAuth.TenantID) + if err != nil { + return fmt.Errorf("the provided Azure OAuth tenant_id is invalid") + } + } + return nil } @@ -146,21 +193,54 @@ func (rt *azureADRoundTripper) RoundTrip(req *http.Request) (*http.Response, err // newTokenCredential returns a TokenCredential of different kinds like Azure Managed Identity and Azure AD application. func newTokenCredential(cfg *AzureADConfig) (azcore.TokenCredential, error) { - cred, err := newManagedIdentityTokenCredential(cfg.ManagedIdentity.ClientID) + var cred azcore.TokenCredential + var err error + cloudConfiguration, err := getCloudConfiguration(cfg.Cloud) if err != nil { return nil, err } + clientOpts := &azcore.ClientOptions{ + Cloud: cloudConfiguration, + } + + if cfg.ManagedIdentity != nil { + managedIdentityConfig := &ManagedIdentityConfig{ + ClientID: cfg.ManagedIdentity.ClientID, + } + cred, err = newManagedIdentityTokenCredential(clientOpts, managedIdentityConfig) + if err != nil { + return nil, err + } + } + + if cfg.OAuth != nil { + oAuthConfig := &OAuthConfig{ + ClientID: cfg.OAuth.ClientID, + ClientSecret: cfg.OAuth.ClientSecret, + TenantID: cfg.OAuth.TenantID, + } + cred, err = newOAuthTokenCredential(clientOpts, oAuthConfig) + if err != nil { + return nil, err + } + } return cred, nil } // newManagedIdentityTokenCredential returns new Managed Identity token credential. -func newManagedIdentityTokenCredential(managedIdentityClientID string) (azcore.TokenCredential, error) { - clientID := azidentity.ClientID(managedIdentityClientID) - opts := &azidentity.ManagedIdentityCredentialOptions{ID: clientID} +func newManagedIdentityTokenCredential(clientOpts *azcore.ClientOptions, managedIdentityConfig *ManagedIdentityConfig) (azcore.TokenCredential, error) { + clientID := azidentity.ClientID(managedIdentityConfig.ClientID) + opts := &azidentity.ManagedIdentityCredentialOptions{ClientOptions: *clientOpts, ID: clientID} return azidentity.NewManagedIdentityCredential(opts) } +// newOAuthTokenCredential returns new OAuth token credential +func newOAuthTokenCredential(clientOpts *azcore.ClientOptions, oAuthConfig *OAuthConfig) (azcore.TokenCredential, error) { + opts := &azidentity.ClientSecretCredentialOptions{ClientOptions: *clientOpts} + return azidentity.NewClientSecretCredential(oAuthConfig.TenantID, oAuthConfig.ClientID, oAuthConfig.ClientSecret, opts) +} + // newTokenProvider helps to fetch accessToken for different types of credential. This also takes care of // refreshing the accessToken before expiry. This accessToken is attached to the Authorization header while making requests. func newTokenProvider(cfg *AzureADConfig, cred azcore.TokenCredential) (*tokenProvider, error) { @@ -245,3 +325,17 @@ func getAudience(cloud string) (string, error) { return "", errors.New("Cloud is not specified or is incorrect: " + cloud) } } + +// getCloudConfiguration returns the cloud Configuration which contains AAD endpoint for different clouds +func getCloudConfiguration(c string) (cloud.Configuration, error) { + switch strings.ToLower(c) { + case strings.ToLower(AzureChina): + return cloud.AzureChina, nil + case strings.ToLower(AzureGovernment): + return cloud.AzureGovernment, nil + case strings.ToLower(AzurePublic): + return cloud.AzurePublic, nil + default: + return cloud.Configuration{}, errors.New("Cloud is not specified or is incorrect: " + c) + } +} diff --git a/storage/remote/azuread/azuread_test.go b/storage/remote/azuread/azuread_test.go index ebbd98958c..1143b71da7 100644 --- a/storage/remote/azuread/azuread_test.go +++ b/storage/remote/azuread/azuread_test.go @@ -26,17 +26,20 @@ import ( "github.com/google/uuid" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" "gopkg.in/yaml.v2" ) const ( - dummyAudience = "dummyAudience" - dummyClientID = "00000000-0000-0000-0000-000000000000" - testTokenString = "testTokenString" + dummyAudience = "dummyAudience" + dummyClientID = "00000000-0000-0000-0000-000000000000" + dummyClientSecret = "Cl1ent$ecret!" + dummyTenantID = "00000000-a12b-3cd4-e56f-000000000000" + testTokenString = "testTokenString" ) -var testTokenExpiry = time.Now().Add(10 * time.Second) +var testTokenExpiry = time.Now().Add(5 * time.Second) type AzureAdTestSuite struct { suite.Suite @@ -62,47 +65,64 @@ func TestAzureAd(t *testing.T) { } func (ad *AzureAdTestSuite) TestAzureAdRoundTripper() { - var gotReq *http.Request - - testToken := &azcore.AccessToken{ - Token: testTokenString, - ExpiresOn: testTokenExpiry, + cases := []struct { + cfg *AzureADConfig + }{ + // AzureAd roundtripper with Managedidentity. + { + cfg: &AzureADConfig{ + Cloud: "AzurePublic", + ManagedIdentity: &ManagedIdentityConfig{ + ClientID: dummyClientID, + }, + }, + }, + // AzureAd roundtripper with OAuth. + { + cfg: &AzureADConfig{ + Cloud: "AzurePublic", + OAuth: &OAuthConfig{ + ClientID: dummyClientID, + ClientSecret: dummyClientSecret, + TenantID: dummyTenantID, + }, + }, + }, } + for _, c := range cases { + var gotReq *http.Request - managedIdentityConfig := &ManagedIdentityConfig{ - ClientID: dummyClientID, + testToken := &azcore.AccessToken{ + Token: testTokenString, + ExpiresOn: testTokenExpiry, + } + + ad.mockCredential.On("GetToken", mock.Anything, mock.Anything).Return(*testToken, nil) + + tokenProvider, err := newTokenProvider(c.cfg, ad.mockCredential) + ad.Assert().NoError(err) + + rt := &azureADRoundTripper{ + next: promhttp.RoundTripperFunc(func(req *http.Request) (*http.Response, error) { + gotReq = req + return &http.Response{StatusCode: http.StatusOK}, nil + }), + tokenProvider: tokenProvider, + } + + cli := &http.Client{Transport: rt} + + req, err := http.NewRequest(http.MethodPost, "https://example.com", strings.NewReader("Hello, world!")) + ad.Assert().NoError(err) + + _, err = cli.Do(req) + ad.Assert().NoError(err) + ad.Assert().NotNil(gotReq) + + origReq := gotReq + ad.Assert().NotEmpty(origReq.Header.Get("Authorization")) + ad.Assert().Equal("Bearer "+testTokenString, origReq.Header.Get("Authorization")) } - - azureAdConfig := &AzureADConfig{ - Cloud: "AzurePublic", - ManagedIdentity: managedIdentityConfig, - } - - ad.mockCredential.On("GetToken", mock.Anything, mock.Anything).Return(*testToken, nil) - - tokenProvider, err := newTokenProvider(azureAdConfig, ad.mockCredential) - ad.Assert().NoError(err) - - rt := &azureADRoundTripper{ - next: promhttp.RoundTripperFunc(func(req *http.Request) (*http.Response, error) { - gotReq = req - return &http.Response{StatusCode: http.StatusOK}, nil - }), - tokenProvider: tokenProvider, - } - - cli := &http.Client{Transport: rt} - - req, err := http.NewRequest(http.MethodPost, "https://example.com", strings.NewReader("Hello, world!")) - ad.Assert().NoError(err) - - _, err = cli.Do(req) - ad.Assert().NoError(err) - ad.Assert().NotNil(gotReq) - - origReq := gotReq - ad.Assert().NotEmpty(origReq.Header.Get("Authorization")) - ad.Assert().Equal("Bearer "+testTokenString, origReq.Header.Get("Authorization")) } func loadAzureAdConfig(filename string) (*AzureADConfig, error) { @@ -117,42 +137,54 @@ func loadAzureAdConfig(filename string) (*AzureADConfig, error) { return &cfg, nil } -func testGoodConfig(t *testing.T, filename string) { - _, err := loadAzureAdConfig(filename) - if err != nil { - t.Fatalf("Unexpected error parsing %s: %s", filename, err) +func TestAzureAdConfig(t *testing.T) { + cases := []struct { + filename string + err string + }{ + // Missing managedidentiy or oauth field. + { + filename: "testdata/azuread_bad_configmissing.yaml", + err: "must provide an Azure Managed Identity or Azure OAuth in the Azure AD config", + }, + // Invalid managedidentity client id. + { + filename: "testdata/azuread_bad_invalidclientid.yaml", + err: "the provided Azure Managed Identity client_id is invalid", + }, + // Missing tenant id in oauth config. + { + filename: "testdata/azuread_bad_invalidoauthconfig.yaml", + err: "must provide an Azure OAuth tenant_id in the Azure AD config", + }, + // Invalid config when both managedidentity and oauth is provided. + { + filename: "testdata/azuread_bad_twoconfig.yaml", + err: "cannot provide both Azure Managed Identity and Azure OAuth in the Azure AD config", + }, + // Valid config with missing optionally cloud field. + { + filename: "testdata/azuread_good_cloudmissing.yaml", + }, + // Valid managed identity config. + { + filename: "testdata/azuread_good_managedidentity.yaml", + }, + // Valid Oauth config. + { + filename: "testdata/azuread_good_oauth.yaml", + }, } -} - -func TestGoodAzureAdConfig(t *testing.T) { - filename := "testdata/azuread_good.yaml" - testGoodConfig(t, filename) -} - -func TestGoodCloudMissingAzureAdConfig(t *testing.T) { - filename := "testdata/azuread_good_cloudmissing.yaml" - testGoodConfig(t, filename) -} - -func TestBadClientIdMissingAzureAdConfig(t *testing.T) { - filename := "testdata/azuread_bad_clientidmissing.yaml" - _, err := loadAzureAdConfig(filename) - if err == nil { - t.Fatalf("Did not receive expected error unmarshaling bad azuread config") - } - if !strings.Contains(err.Error(), "must provide an Azure Managed Identity in the Azure AD config") { - t.Errorf("Received unexpected error from unmarshal of %s: %s", filename, err.Error()) - } -} - -func TestBadInvalidClientIdAzureAdConfig(t *testing.T) { - filename := "testdata/azuread_bad_invalidclientid.yaml" - _, err := loadAzureAdConfig(filename) - if err == nil { - t.Fatalf("Did not receive expected error unmarshaling bad azuread config") - } - if !strings.Contains(err.Error(), "the provided Azure Managed Identity client_id provided is invalid") { - t.Errorf("Received unexpected error from unmarshal of %s: %s", filename, err.Error()) + for _, c := range cases { + _, err := loadAzureAdConfig(c.filename) + if c.err != "" { + if err == nil { + t.Fatalf("Did not receive expected error unmarshaling bad azuread config") + } + require.EqualError(t, err, c.err) + } else { + require.NoError(t, err) + } } } @@ -173,75 +205,90 @@ func TestTokenProvider(t *testing.T) { suite.Run(t, new(TokenProviderTestSuite)) } -func (s *TokenProviderTestSuite) TestNewTokenProvider_NilAudience_Fail() { - managedIdentityConfig := &ManagedIdentityConfig{ - ClientID: dummyClientID, +func (s *TokenProviderTestSuite) TestNewTokenProvider() { + cases := []struct { + cfg *AzureADConfig + err string + }{ + // Invalid tokenProvider for managedidentity. + { + cfg: &AzureADConfig{ + Cloud: "PublicAzure", + ManagedIdentity: &ManagedIdentityConfig{ + ClientID: dummyClientID, + }, + }, + err: "Cloud is not specified or is incorrect: ", + }, + // Invalid tokenProvider for oauth. + { + cfg: &AzureADConfig{ + Cloud: "PublicAzure", + OAuth: &OAuthConfig{ + ClientID: dummyClientID, + ClientSecret: dummyClientSecret, + TenantID: dummyTenantID, + }, + }, + err: "Cloud is not specified or is incorrect: ", + }, + // Valid tokenProvider for managedidentity. + { + cfg: &AzureADConfig{ + Cloud: "AzurePublic", + ManagedIdentity: &ManagedIdentityConfig{ + ClientID: dummyClientID, + }, + }, + }, + // Valid tokenProvider for oauth. + { + cfg: &AzureADConfig{ + Cloud: "AzurePublic", + OAuth: &OAuthConfig{ + ClientID: dummyClientID, + ClientSecret: dummyClientSecret, + TenantID: dummyTenantID, + }, + }, + }, } + mockGetTokenCallCounter := 1 + for _, c := range cases { + if c.err != "" { + actualTokenProvider, actualErr := newTokenProvider(c.cfg, s.mockCredential) - azureAdConfig := &AzureADConfig{ - Cloud: "PublicAzure", - ManagedIdentity: managedIdentityConfig, + s.Assert().Nil(actualTokenProvider) + s.Assert().NotNil(actualErr) + s.Assert().ErrorContains(actualErr, c.err) + } else { + testToken := &azcore.AccessToken{ + Token: testTokenString, + ExpiresOn: testTokenExpiry, + } + + s.mockCredential.On("GetToken", mock.Anything, mock.Anything).Return(*testToken, nil).Once(). + On("GetToken", mock.Anything, mock.Anything).Return(getToken(), nil) + + actualTokenProvider, actualErr := newTokenProvider(c.cfg, s.mockCredential) + + s.Assert().NotNil(actualTokenProvider) + s.Assert().Nil(actualErr) + s.Assert().NotNil(actualTokenProvider.getAccessToken(context.Background())) + + // Token set to refresh at half of the expiry time. The test tokens are set to expiry in 5s. + // Hence, the 4 seconds wait to check if the token is refreshed. + time.Sleep(4 * time.Second) + + s.Assert().NotNil(actualTokenProvider.getAccessToken(context.Background())) + + s.mockCredential.AssertNumberOfCalls(s.T(), "GetToken", 2*mockGetTokenCallCounter) + mockGetTokenCallCounter += 1 + accessToken, err := actualTokenProvider.getAccessToken(context.Background()) + s.Assert().Nil(err) + s.Assert().NotEqual(accessToken, testTokenString) + } } - - actualTokenProvider, actualErr := newTokenProvider(azureAdConfig, s.mockCredential) - - s.Assert().Nil(actualTokenProvider) - s.Assert().NotNil(actualErr) - s.Assert().Equal("Cloud is not specified or is incorrect: "+azureAdConfig.Cloud, actualErr.Error()) -} - -func (s *TokenProviderTestSuite) TestNewTokenProvider_Success() { - managedIdentityConfig := &ManagedIdentityConfig{ - ClientID: dummyClientID, - } - - azureAdConfig := &AzureADConfig{ - Cloud: "AzurePublic", - ManagedIdentity: managedIdentityConfig, - } - s.mockCredential.On("GetToken", mock.Anything, mock.Anything).Return(getToken(), nil) - - actualTokenProvider, actualErr := newTokenProvider(azureAdConfig, s.mockCredential) - - s.Assert().NotNil(actualTokenProvider) - s.Assert().Nil(actualErr) - s.Assert().NotNil(actualTokenProvider.getAccessToken(context.Background())) -} - -func (s *TokenProviderTestSuite) TestPeriodicTokenRefresh_Success() { - // setup - managedIdentityConfig := &ManagedIdentityConfig{ - ClientID: dummyClientID, - } - - azureAdConfig := &AzureADConfig{ - Cloud: "AzurePublic", - ManagedIdentity: managedIdentityConfig, - } - testToken := &azcore.AccessToken{ - Token: testTokenString, - ExpiresOn: testTokenExpiry, - } - - s.mockCredential.On("GetToken", mock.Anything, mock.Anything).Return(*testToken, nil).Once(). - On("GetToken", mock.Anything, mock.Anything).Return(getToken(), nil) - - actualTokenProvider, actualErr := newTokenProvider(azureAdConfig, s.mockCredential) - - s.Assert().NotNil(actualTokenProvider) - s.Assert().Nil(actualErr) - s.Assert().NotNil(actualTokenProvider.getAccessToken(context.Background())) - - // Token set to refresh at half of the expiry time. The test tokens are set to expiry in 10s. - // Hence, the 6 seconds wait to check if the token is refreshed. - time.Sleep(6 * time.Second) - - s.Assert().NotNil(actualTokenProvider.getAccessToken(context.Background())) - - s.mockCredential.AssertNumberOfCalls(s.T(), "GetToken", 2) - accessToken, err := actualTokenProvider.getAccessToken(context.Background()) - s.Assert().Nil(err) - s.Assert().NotEqual(accessToken, testTokenString) } func getToken() azcore.AccessToken { diff --git a/storage/remote/azuread/testdata/azuread_bad_clientidmissing.yaml b/storage/remote/azuread/testdata/azuread_bad_configmissing.yaml similarity index 100% rename from storage/remote/azuread/testdata/azuread_bad_clientidmissing.yaml rename to storage/remote/azuread/testdata/azuread_bad_configmissing.yaml diff --git a/storage/remote/azuread/testdata/azuread_bad_invalidoauthconfig.yaml b/storage/remote/azuread/testdata/azuread_bad_invalidoauthconfig.yaml new file mode 100644 index 0000000000..1b01dc2e6f --- /dev/null +++ b/storage/remote/azuread/testdata/azuread_bad_invalidoauthconfig.yaml @@ -0,0 +1,4 @@ +cloud: AzurePublic +oauth: + client_id: 00000000-0000-0000-0000-000000000000 + client_secret: Cl1ent$ecret! diff --git a/storage/remote/azuread/testdata/azuread_bad_twoconfig.yaml b/storage/remote/azuread/testdata/azuread_bad_twoconfig.yaml new file mode 100644 index 0000000000..710f6d3535 --- /dev/null +++ b/storage/remote/azuread/testdata/azuread_bad_twoconfig.yaml @@ -0,0 +1,7 @@ +cloud: AzurePublic +managed_identity: + client_id: 00000000-0000-0000-0000-000000000000 +oauth: + client_id: 00000000-0000-0000-0000-000000000000 + client_secret: Cl1ent$ecret! + tenant_id: 00000000-a12b-3cd4-e56f-000000000000 diff --git a/storage/remote/azuread/testdata/azuread_good.yaml b/storage/remote/azuread/testdata/azuread_good_managedidentity.yaml similarity index 100% rename from storage/remote/azuread/testdata/azuread_good.yaml rename to storage/remote/azuread/testdata/azuread_good_managedidentity.yaml diff --git a/storage/remote/azuread/testdata/azuread_good_oauth.yaml b/storage/remote/azuread/testdata/azuread_good_oauth.yaml new file mode 100644 index 0000000000..473297f99b --- /dev/null +++ b/storage/remote/azuread/testdata/azuread_good_oauth.yaml @@ -0,0 +1,5 @@ +cloud: AzurePublic +oauth: + client_id: 00000000-0000-0000-0000-000000000000 + client_secret: Cl1ent$ecret! + tenant_id: 00000000-a12b-3cd4-e56f-000000000000 From 7c934ae18cd02d600d2d4f40b4a42b9b53126b74 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 5 Oct 2023 11:04:59 +0000 Subject: [PATCH 41/42] scraping: hoist labels variable to save garbage `lset` escapes to heap due to being passed through the text-parser interface, so we can reduce garbage by hoisting it out of the loop so only one allocation is done for every series in a scrape. Signed-off-by: Bryan Boreham --- scrape/scrape.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scrape/scrape.go b/scrape/scrape.go index 4d13d7f6b1..e40ae81d28 100644 --- a/scrape/scrape.go +++ b/scrape/scrape.go @@ -1525,6 +1525,7 @@ func (sl *scrapeLoop) append(app storage.Appender, b []byte, contentType string, appErrs = appendErrors{} sampleLimitErr error bucketLimitErr error + lset labels.Labels // escapes to heap so hoisted out of loop e exemplar.Exemplar // escapes to heap so hoisted out of loop meta metadata.Metadata metadataChanged bool @@ -1622,7 +1623,6 @@ loop: ce, ok := sl.cache.get(met) var ( ref storage.SeriesRef - lset labels.Labels hash uint64 ) From a5a4eab679ccf2d432ab34b5143ef9e1c6482839 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 6 Oct 2023 12:28:07 +0100 Subject: [PATCH 42/42] Storage: reduce memory allocations when merging series sets (#12938) Instead of setting to nil and allocating a new slice every time the merge is advanced, re-use the previous slice. This is safe because the `currentSets` member is only used inside member functions, and explicitly copied in `At()`, the only place it leaves the struct. Signed-off-by: Bryan Boreham --- storage/merge.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/merge.go b/storage/merge.go index f7a88738c3..1e29374e53 100644 --- a/storage/merge.go +++ b/storage/merge.go @@ -347,7 +347,7 @@ func (c *genericMergeSeriesSet) Next() bool { } // Now, pop items of the heap that have equal label sets. - c.currentSets = nil + c.currentSets = c.currentSets[:0] c.currentLabels = c.heap[0].At().Labels() for len(c.heap) > 0 && labels.Equal(c.currentLabels, c.heap[0].At().Labels()) { set := heap.Pop(&c.heap).(genericSeriesSet)