mirror of
https://github.com/prometheus/prometheus.git
synced 2025-01-23 11:41:54 -08:00
Merge branch 'main' into sparsehistogram
This commit is contained in:
commit
6f33ab2b35
|
@ -2,7 +2,7 @@
|
|||
version: 2.1
|
||||
|
||||
orbs:
|
||||
prometheus: prometheus/prometheus@0.14.0
|
||||
prometheus: prometheus/prometheus@0.15.0
|
||||
go: circleci/go@1.7.0
|
||||
win: circleci/windows@2.3.0
|
||||
|
||||
|
|
1
.github/dependabot.yml
vendored
1
.github/dependabot.yml
vendored
|
@ -6,6 +6,7 @@ updates:
|
|||
interval: "weekly"
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/web/ui"
|
||||
open-pull-requests-limit: 0
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "github-actions"
|
||||
|
|
2
.github/workflows/fuzzing.yml
vendored
2
.github/workflows/fuzzing.yml
vendored
|
@ -22,7 +22,7 @@ jobs:
|
|||
fuzz-seconds: 600
|
||||
dry-run: false
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@v2.2.4
|
||||
uses: actions/upload-artifact@v2.3.0
|
||||
if: failure() && steps.build.outcome == 'success'
|
||||
with:
|
||||
name: artifacts
|
||||
|
|
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -1,6 +1,6 @@
|
|||
## 2.32.0-beta.0 / 2021-11-16
|
||||
## 2.32.0 / 2021-12-09
|
||||
|
||||
This beta release introduces the Prometheus Agent, a new mode of operation for
|
||||
This release introduces the Prometheus Agent, a new mode of operation for
|
||||
Prometheus optimized for remote-write only scenarios. In this mode, Prometheus
|
||||
does not generate blocks on the local filesystem and is not queryable locally.
|
||||
Enable with `--enable-feature=agent`.
|
||||
|
@ -8,7 +8,7 @@ Enable with `--enable-feature=agent`.
|
|||
Learn more about the Prometheus Agent in our [blog post](https://prometheus.io/blog/2021/11/16/agent/).
|
||||
|
||||
* [CHANGE] remote-write: Change default max retry time from 100ms to 5 seconds. #9634
|
||||
* [FEATURE] Agent: New mode of operation optimized for remote-write only scenarios, without local storage. Enable with `--enable-feature=agent`. #8785
|
||||
* [FEATURE] Agent: New mode of operation optimized for remote-write only scenarios, without local storage. Enable with `--enable-feature=agent`. #8785 #9851 #9664 #9939 #9941 #9943
|
||||
* [FEATURE] Promtool: Add `promtool check service-discovery` command. #8970
|
||||
* [FEATURE] UI: Add search in metrics dropdown. #9629
|
||||
* [FEATURE] Templates: Add parseDuration to template functions. #8817
|
||||
|
@ -20,8 +20,15 @@ Learn more about the Prometheus Agent in our [blog post](https://prometheus.io/b
|
|||
* [ENHANCEMENT] TSDB: Optimize query by skipping unneeded sorting in TSDB. #9673
|
||||
* [ENHANCEMENT] Templates: Support int and uint as datatypes for template formatting. #9680
|
||||
* [ENHANCEMENT] UI: Prefer `rate` over `rad`, `delta` over `deg`, and `count` over `cos` in autocomplete. #9688
|
||||
* [ENHANCEMENT] Linode SD: Tune API request page sizes. #9779
|
||||
* [BUGFIX] TSDB: Add more size checks when writing individual sections in the index. #9710
|
||||
* [BUGFIX] PromQL: Make `deriv()` return zero values for constant series. #9728
|
||||
* [BUGFIX] TSDB: Fix panic when checkpoint directory is empty. #9687
|
||||
* [BUGFIX] TSDB: Fix panic, out of order chunks, and race warning during WAL replay. #9856
|
||||
* [BUGFIX] UI: Correctly render links for targets with IPv6 addresses that contain a Zone ID. #9853
|
||||
* [BUGFIX] Promtool: Fix checking of `authorization.credentials_file` and `bearer_token_file` fields. #9883
|
||||
* [BUGFIX] Uyuni SD: Fix null pointer exception during initialization. #9924 #9950
|
||||
* [BUGFIX] TSDB: Fix queries after a failed snapshot replay. #9980
|
||||
|
||||
## 2.31.1 / 2021-11-05
|
||||
|
||||
|
|
5
NOTICE
5
NOTICE
|
@ -91,6 +91,11 @@ https://github.com/dgryski/go-tsz
|
|||
Copyright (c) 2015,2016 Damian Gryski <damian@gryski.com>
|
||||
See https://github.com/dgryski/go-tsz/blob/master/LICENSE for license details.
|
||||
|
||||
The Go programming language
|
||||
https://go.dev/
|
||||
Copyright (c) 2009 The Go Authors
|
||||
See https://go.dev/LICENSE for license details.
|
||||
|
||||
The Codicon icon font from Microsoft
|
||||
https://github.com/microsoft/vscode-codicons
|
||||
Copyright (c) Microsoft Corporation and other contributors
|
||||
|
|
|
@ -382,7 +382,7 @@ func main() {
|
|||
serverOnlyFlag(a, "query.max-samples", "Maximum number of samples a single query can load into memory. Note that queries will fail if they try to load more samples than this into memory, so this also limits the number of samples a query can return.").
|
||||
Default("50000000").IntVar(&cfg.queryMaxSamples)
|
||||
|
||||
a.Flag("enable-feature", "Comma separated feature names to enable. Valid options: exemplar-storage, expand-external-labels, memory-snapshot-on-shutdown, promql-at-modifier, promql-negative-offset, remote-write-receiver, extra-scrape-metrics, new-service-discovery-manager. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details.").
|
||||
a.Flag("enable-feature", "Comma separated feature names to enable. Valid options: agent, exemplar-storage, expand-external-labels, memory-snapshot-on-shutdown, promql-at-modifier, promql-negative-offset, remote-write-receiver, extra-scrape-metrics, new-service-discovery-manager. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details.").
|
||||
Default("").StringsVar(&cfg.featureList)
|
||||
|
||||
promlogflag.AddFlags(a, &cfg.promlogConfig)
|
||||
|
|
|
@ -73,6 +73,7 @@ func main() {
|
|||
"config-files",
|
||||
"The config files to check.",
|
||||
).Required().ExistingFiles()
|
||||
checkConfigSyntaxOnly := checkConfigCmd.Flag("syntax-only", "Only check the config file syntax, ignoring file and content validation referenced in the config").Bool()
|
||||
|
||||
checkWebConfigCmd := checkCmd.Command("web-config", "Check if the web config files are valid or not.")
|
||||
webConfigFiles := checkWebConfigCmd.Arg(
|
||||
|
@ -211,7 +212,7 @@ func main() {
|
|||
os.Exit(CheckSD(*sdConfigFile, *sdJobName, *sdTimeout))
|
||||
|
||||
case checkConfigCmd.FullCommand():
|
||||
os.Exit(CheckConfig(*agentMode, *configFiles...))
|
||||
os.Exit(CheckConfig(*agentMode, *checkConfigSyntaxOnly, *configFiles...))
|
||||
|
||||
case checkWebConfigCmd.FullCommand():
|
||||
os.Exit(CheckWebConfig(*webConfigFiles...))
|
||||
|
@ -267,16 +268,19 @@ func main() {
|
|||
}
|
||||
|
||||
// CheckConfig validates configuration files.
|
||||
func CheckConfig(agentMode bool, files ...string) int {
|
||||
func CheckConfig(agentMode, checkSyntaxOnly bool, files ...string) int {
|
||||
failed := false
|
||||
|
||||
for _, f := range files {
|
||||
ruleFiles, err := checkConfig(agentMode, f)
|
||||
ruleFiles, err := checkConfig(agentMode, f, checkSyntaxOnly)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, " FAILED:", err)
|
||||
failed = true
|
||||
} else {
|
||||
fmt.Printf(" SUCCESS: %d rule files found\n", len(ruleFiles))
|
||||
if len(ruleFiles) > 0 {
|
||||
fmt.Printf(" SUCCESS: %d rule files found\n", len(ruleFiles))
|
||||
}
|
||||
fmt.Printf(" SUCCESS: %s is valid prometheus config file syntax\n", f)
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
|
@ -326,7 +330,7 @@ func checkFileExists(fn string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func checkConfig(agentMode bool, filename string) ([]string, error) {
|
||||
func checkConfig(agentMode bool, filename string, checkSyntaxOnly bool) ([]string, error) {
|
||||
fmt.Println("Checking", filename)
|
||||
|
||||
cfg, err := config.LoadFile(filename, agentMode, false, log.NewNopLogger())
|
||||
|
@ -335,41 +339,46 @@ func checkConfig(agentMode bool, filename string) ([]string, error) {
|
|||
}
|
||||
|
||||
var ruleFiles []string
|
||||
for _, rf := range cfg.RuleFiles {
|
||||
rfs, err := filepath.Glob(rf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// If an explicit file was given, error if it is not accessible.
|
||||
if !strings.Contains(rf, "*") {
|
||||
if len(rfs) == 0 {
|
||||
return nil, errors.Errorf("%q does not point to an existing file", rf)
|
||||
if !checkSyntaxOnly {
|
||||
for _, rf := range cfg.RuleFiles {
|
||||
rfs, err := filepath.Glob(rf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := checkFileExists(rfs[0]); err != nil {
|
||||
return nil, errors.Wrapf(err, "error checking rule file %q", rfs[0])
|
||||
// If an explicit file was given, error if it is not accessible.
|
||||
if !strings.Contains(rf, "*") {
|
||||
if len(rfs) == 0 {
|
||||
return nil, errors.Errorf("%q does not point to an existing file", rf)
|
||||
}
|
||||
if err := checkFileExists(rfs[0]); err != nil {
|
||||
return nil, errors.Wrapf(err, "error checking rule file %q", rfs[0])
|
||||
}
|
||||
}
|
||||
ruleFiles = append(ruleFiles, rfs...)
|
||||
}
|
||||
ruleFiles = append(ruleFiles, rfs...)
|
||||
}
|
||||
|
||||
for _, scfg := range cfg.ScrapeConfigs {
|
||||
if scfg.HTTPClientConfig.Authorization != nil {
|
||||
if !checkSyntaxOnly && scfg.HTTPClientConfig.Authorization != nil {
|
||||
if err := checkFileExists(scfg.HTTPClientConfig.Authorization.CredentialsFile); err != nil {
|
||||
return nil, errors.Wrapf(err, "error checking authorization credentials or bearer token file %q", scfg.HTTPClientConfig.Authorization.CredentialsFile)
|
||||
}
|
||||
}
|
||||
|
||||
if err := checkTLSConfig(scfg.HTTPClientConfig.TLSConfig); err != nil {
|
||||
if err := checkTLSConfig(scfg.HTTPClientConfig.TLSConfig, checkSyntaxOnly); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, c := range scfg.ServiceDiscoveryConfigs {
|
||||
switch c := c.(type) {
|
||||
case *kubernetes.SDConfig:
|
||||
if err := checkTLSConfig(c.HTTPClientConfig.TLSConfig); err != nil {
|
||||
if err := checkTLSConfig(c.HTTPClientConfig.TLSConfig, checkSyntaxOnly); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case *file.SDConfig:
|
||||
if checkSyntaxOnly {
|
||||
break
|
||||
}
|
||||
for _, file := range c.Files {
|
||||
files, err := filepath.Glob(file)
|
||||
if err != nil {
|
||||
|
@ -403,6 +412,9 @@ func checkConfig(agentMode bool, filename string) ([]string, error) {
|
|||
for _, c := range amcfg.ServiceDiscoveryConfigs {
|
||||
switch c := c.(type) {
|
||||
case *file.SDConfig:
|
||||
if checkSyntaxOnly {
|
||||
break
|
||||
}
|
||||
for _, file := range c.Files {
|
||||
files, err := filepath.Glob(file)
|
||||
if err != nil {
|
||||
|
@ -434,14 +446,7 @@ func checkConfig(agentMode bool, filename string) ([]string, error) {
|
|||
return ruleFiles, nil
|
||||
}
|
||||
|
||||
func checkTLSConfig(tlsConfig config_util.TLSConfig) error {
|
||||
if err := checkFileExists(tlsConfig.CertFile); err != nil {
|
||||
return errors.Wrapf(err, "error checking client cert file %q", tlsConfig.CertFile)
|
||||
}
|
||||
if err := checkFileExists(tlsConfig.KeyFile); err != nil {
|
||||
return errors.Wrapf(err, "error checking client key file %q", tlsConfig.KeyFile)
|
||||
}
|
||||
|
||||
func checkTLSConfig(tlsConfig config_util.TLSConfig, checkSyntaxOnly bool) error {
|
||||
if len(tlsConfig.CertFile) > 0 && len(tlsConfig.KeyFile) == 0 {
|
||||
return errors.Errorf("client cert file %q specified without client key file", tlsConfig.CertFile)
|
||||
}
|
||||
|
@ -449,6 +454,17 @@ func checkTLSConfig(tlsConfig config_util.TLSConfig) error {
|
|||
return errors.Errorf("client key file %q specified without client cert file", tlsConfig.KeyFile)
|
||||
}
|
||||
|
||||
if checkSyntaxOnly {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := checkFileExists(tlsConfig.CertFile); err != nil {
|
||||
return errors.Wrapf(err, "error checking client cert file %q", tlsConfig.CertFile)
|
||||
}
|
||||
if err := checkFileExists(tlsConfig.KeyFile); err != nil {
|
||||
return errors.Wrapf(err, "error checking client key file %q", tlsConfig.KeyFile)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ import (
|
|||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -194,7 +196,7 @@ func TestCheckTargetConfig(t *testing.T) {
|
|||
}
|
||||
for _, test := range cases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
_, err := checkConfig(false, "testdata/"+test.file)
|
||||
_, err := checkConfig(false, "testdata/"+test.file, false)
|
||||
if test.err != "" {
|
||||
require.Equalf(t, test.err, err.Error(), "Expected error %q, got %q", test.err, err.Error())
|
||||
return
|
||||
|
@ -204,6 +206,93 @@ func TestCheckTargetConfig(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCheckConfigSyntax(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
file string
|
||||
syntaxOnly bool
|
||||
err string
|
||||
errWindows string
|
||||
}{
|
||||
{
|
||||
name: "check with syntax only succeeds with nonexistent rule files",
|
||||
file: "config_with_rule_files.yml",
|
||||
syntaxOnly: true,
|
||||
err: "",
|
||||
errWindows: "",
|
||||
},
|
||||
{
|
||||
name: "check without syntax only fails with nonexistent rule files",
|
||||
file: "config_with_rule_files.yml",
|
||||
syntaxOnly: false,
|
||||
err: "\"testdata/non-existent-file.yml\" does not point to an existing file",
|
||||
errWindows: "\"testdata\\\\non-existent-file.yml\" does not point to an existing file",
|
||||
},
|
||||
{
|
||||
name: "check with syntax only succeeds with nonexistent service discovery files",
|
||||
file: "config_with_service_discovery_files.yml",
|
||||
syntaxOnly: true,
|
||||
err: "",
|
||||
errWindows: "",
|
||||
},
|
||||
// The test below doesn't fail because the file verification for ServiceDiscoveryConfigs doesn't fail the check if
|
||||
// file isn't found; it only outputs a warning message.
|
||||
{
|
||||
name: "check without syntax only succeeds with nonexistent service discovery files",
|
||||
file: "config_with_service_discovery_files.yml",
|
||||
syntaxOnly: false,
|
||||
err: "",
|
||||
errWindows: "",
|
||||
},
|
||||
{
|
||||
name: "check with syntax only succeeds with nonexistent TLS files",
|
||||
file: "config_with_tls_files.yml",
|
||||
syntaxOnly: true,
|
||||
err: "",
|
||||
errWindows: "",
|
||||
},
|
||||
{
|
||||
name: "check without syntax only fails with nonexistent TLS files",
|
||||
file: "config_with_tls_files.yml",
|
||||
syntaxOnly: false,
|
||||
err: "error checking client cert file \"testdata/nonexistent_cert_file.yml\": " +
|
||||
"stat testdata/nonexistent_cert_file.yml: no such file or directory",
|
||||
errWindows: "error checking client cert file \"testdata\\\\nonexistent_cert_file.yml\": " +
|
||||
"CreateFile testdata\\nonexistent_cert_file.yml: The system cannot find the file specified.",
|
||||
},
|
||||
{
|
||||
name: "check with syntax only succeeds with nonexistent credentials file",
|
||||
file: "authorization_credentials_file.bad.yml",
|
||||
syntaxOnly: true,
|
||||
err: "",
|
||||
errWindows: "",
|
||||
},
|
||||
{
|
||||
name: "check without syntax only fails with nonexistent credentials file",
|
||||
file: "authorization_credentials_file.bad.yml",
|
||||
syntaxOnly: false,
|
||||
err: "error checking authorization credentials or bearer token file \"/random/file/which/does/not/exist.yml\": " +
|
||||
"stat /random/file/which/does/not/exist.yml: no such file or directory",
|
||||
errWindows: "error checking authorization credentials or bearer token file \"testdata\\\\random\\\\file\\\\which\\\\does\\\\not\\\\exist.yml\": " +
|
||||
"CreateFile testdata\\random\\file\\which\\does\\not\\exist.yml: The system cannot find the path specified.",
|
||||
},
|
||||
}
|
||||
for _, test := range cases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
_, err := checkConfig(false, "testdata/"+test.file, test.syntaxOnly)
|
||||
expectedErrMsg := test.err
|
||||
if strings.Contains(runtime.GOOS, "windows") {
|
||||
expectedErrMsg = test.errWindows
|
||||
}
|
||||
if expectedErrMsg != "" {
|
||||
require.Equalf(t, expectedErrMsg, err.Error(), "Expected error %q, got %q", test.err, err.Error())
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizationConfig(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
|
@ -224,7 +313,7 @@ func TestAuthorizationConfig(t *testing.T) {
|
|||
|
||||
for _, test := range cases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
_, err := checkConfig(false, "testdata/"+test.file)
|
||||
_, err := checkConfig(false, "testdata/"+test.file, false)
|
||||
if test.err != "" {
|
||||
require.Contains(t, err.Error(), test.err, "Expected error to contain %q, got %q", test.err, err.Error())
|
||||
return
|
||||
|
|
3
cmd/promtool/testdata/config_with_rule_files.yml
vendored
Normal file
3
cmd/promtool/testdata/config_with_rule_files.yml
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
rule_files:
|
||||
- non-existent-file.yml
|
||||
- /etc/non/existent/file.yml
|
12
cmd/promtool/testdata/config_with_service_discovery_files.yml
vendored
Normal file
12
cmd/promtool/testdata/config_with_service_discovery_files.yml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
scrape_configs:
|
||||
- job_name: prometheus
|
||||
file_sd_configs:
|
||||
- files:
|
||||
- nonexistent_file.yml
|
||||
alerting:
|
||||
alertmanagers:
|
||||
- scheme: http
|
||||
api_version: v1
|
||||
file_sd_configs:
|
||||
- files:
|
||||
- nonexistent_file.yml
|
5
cmd/promtool/testdata/config_with_tls_files.yml
vendored
Normal file
5
cmd/promtool/testdata/config_with_tls_files.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
scrape_configs:
|
||||
- job_name: "some job"
|
||||
tls_config:
|
||||
cert_file: nonexistent_cert_file.yml
|
||||
key_file: nonexistent_key_file.yml
|
|
@ -227,7 +227,6 @@ var expectedConf = &Config{
|
|||
},
|
||||
},
|
||||
{
|
||||
|
||||
JobName: "service-x",
|
||||
|
||||
HonorTimestamps: true,
|
||||
|
@ -954,7 +953,7 @@ var expectedConf = &Config{
|
|||
Scheme: DefaultScrapeConfig.Scheme,
|
||||
ServiceDiscoveryConfigs: discovery.Configs{
|
||||
&uyuni.SDConfig{
|
||||
Server: kubernetesSDHostURL(),
|
||||
Server: "https://localhost:1234",
|
||||
Username: "gopher",
|
||||
Password: "hole",
|
||||
Entitlement: "monitoring_entitled",
|
||||
|
@ -1434,6 +1433,10 @@ var expectedErrors = []struct {
|
|||
filename: "empty_scrape_config_action.bad.yml",
|
||||
errMsg: "relabel action cannot be empty",
|
||||
},
|
||||
{
|
||||
filename: "uyuni_no_server.bad.yml",
|
||||
errMsg: "Uyuni SD configuration requires server host",
|
||||
},
|
||||
}
|
||||
|
||||
func TestBadConfigs(t *testing.T) {
|
||||
|
|
4
config/testdata/uyuni_no_server.bad.yml
vendored
Normal file
4
config/testdata/uyuni_no_server.bad.yml
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
scrape_configs:
|
||||
- job_name: uyuni
|
||||
uyuni_sd_configs:
|
||||
- server:
|
|
@ -615,3 +615,86 @@ func TestEndpointsDiscoveryNamespaces(t *testing.T) {
|
|||
},
|
||||
}.Run(t)
|
||||
}
|
||||
|
||||
func TestEndpointsDiscoveryOwnNamespace(t *testing.T) {
|
||||
epOne := makeEndpoints()
|
||||
epOne.Namespace = "own-ns"
|
||||
|
||||
epTwo := makeEndpoints()
|
||||
epTwo.Namespace = "non-own-ns"
|
||||
|
||||
podOne := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "testpod",
|
||||
Namespace: "own-ns",
|
||||
UID: types.UID("deadbeef"),
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
NodeName: "testnode",
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "p1",
|
||||
Ports: []v1.ContainerPort{
|
||||
{
|
||||
Name: "mainport",
|
||||
ContainerPort: 9000,
|
||||
Protocol: v1.ProtocolTCP,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
HostIP: "2.3.4.5",
|
||||
PodIP: "4.3.2.1",
|
||||
},
|
||||
}
|
||||
|
||||
podTwo := podOne.DeepCopy()
|
||||
podTwo.Namespace = "non-own-ns"
|
||||
|
||||
objs := []runtime.Object{
|
||||
epOne,
|
||||
epTwo,
|
||||
podOne,
|
||||
podTwo,
|
||||
}
|
||||
|
||||
n, _ := makeDiscovery(RoleEndpoint, NamespaceDiscovery{IncludeOwnNamespace: true}, objs...)
|
||||
|
||||
k8sDiscoveryTest{
|
||||
discovery: n,
|
||||
expectedMaxItems: 1,
|
||||
expectedRes: map[string]*targetgroup.Group{
|
||||
"endpoints/own-ns/testendpoints": {
|
||||
Targets: []model.LabelSet{
|
||||
{
|
||||
"__address__": "1.2.3.4:9000",
|
||||
"__meta_kubernetes_endpoint_hostname": "testendpoint1",
|
||||
"__meta_kubernetes_endpoint_node_name": "foobar",
|
||||
"__meta_kubernetes_endpoint_port_name": "testport",
|
||||
"__meta_kubernetes_endpoint_port_protocol": "TCP",
|
||||
"__meta_kubernetes_endpoint_ready": "true",
|
||||
},
|
||||
{
|
||||
"__address__": "2.3.4.5:9001",
|
||||
"__meta_kubernetes_endpoint_port_name": "testport",
|
||||
"__meta_kubernetes_endpoint_port_protocol": "TCP",
|
||||
"__meta_kubernetes_endpoint_ready": "true",
|
||||
},
|
||||
{
|
||||
"__address__": "2.3.4.5:9001",
|
||||
"__meta_kubernetes_endpoint_port_name": "testport",
|
||||
"__meta_kubernetes_endpoint_port_protocol": "TCP",
|
||||
"__meta_kubernetes_endpoint_ready": "false",
|
||||
},
|
||||
},
|
||||
Labels: model.LabelSet{
|
||||
"__meta_kubernetes_namespace": "own-ns",
|
||||
"__meta_kubernetes_endpoints_name": "testendpoints",
|
||||
},
|
||||
Source: "endpoints/own-ns/testendpoints",
|
||||
},
|
||||
},
|
||||
}.Run(t)
|
||||
}
|
||||
|
|
|
@ -630,3 +630,87 @@ func TestEndpointSliceDiscoveryNamespaces(t *testing.T) {
|
|||
},
|
||||
}.Run(t)
|
||||
}
|
||||
|
||||
func TestEndpointSliceDiscoveryOwnNamespace(t *testing.T) {
|
||||
epOne := makeEndpointSlice()
|
||||
epOne.Namespace = "own-ns"
|
||||
|
||||
epTwo := makeEndpointSlice()
|
||||
epTwo.Namespace = "non-own-ns"
|
||||
|
||||
podOne := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "testpod",
|
||||
Namespace: "own-ns",
|
||||
UID: types.UID("deadbeef"),
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
NodeName: "testnode",
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "p1",
|
||||
Ports: []v1.ContainerPort{
|
||||
{
|
||||
Name: "mainport",
|
||||
ContainerPort: 9000,
|
||||
Protocol: v1.ProtocolTCP,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
HostIP: "2.3.4.5",
|
||||
PodIP: "4.3.2.1",
|
||||
},
|
||||
}
|
||||
|
||||
podTwo := podOne.DeepCopy()
|
||||
podTwo.Namespace = "non-own-ns"
|
||||
|
||||
objs := []runtime.Object{
|
||||
epOne,
|
||||
epTwo,
|
||||
podOne,
|
||||
podTwo,
|
||||
}
|
||||
n, _ := makeDiscovery(RoleEndpointSlice, NamespaceDiscovery{IncludeOwnNamespace: true}, objs...)
|
||||
|
||||
k8sDiscoveryTest{
|
||||
discovery: n,
|
||||
expectedMaxItems: 1,
|
||||
expectedRes: map[string]*targetgroup.Group{
|
||||
"endpointslice/own-ns/testendpoints": {
|
||||
Targets: []model.LabelSet{
|
||||
{
|
||||
"__address__": "1.2.3.4:9000",
|
||||
"__meta_kubernetes_endpointslice_endpoint_hostname": "testendpoint1",
|
||||
"__meta_kubernetes_endpointslice_port": "9000",
|
||||
"__meta_kubernetes_endpointslice_port_name": "testport",
|
||||
"__meta_kubernetes_endpointslice_port_protocol": "TCP",
|
||||
},
|
||||
{
|
||||
"__address__": "2.3.4.5:9000",
|
||||
"__meta_kubernetes_endpointslice_endpoint_conditions_ready": "true",
|
||||
"__meta_kubernetes_endpointslice_port": "9000",
|
||||
"__meta_kubernetes_endpointslice_port_name": "testport",
|
||||
"__meta_kubernetes_endpointslice_port_protocol": "TCP",
|
||||
},
|
||||
{
|
||||
"__address__": "3.4.5.6:9000",
|
||||
"__meta_kubernetes_endpointslice_endpoint_conditions_ready": "false",
|
||||
"__meta_kubernetes_endpointslice_port": "9000",
|
||||
"__meta_kubernetes_endpointslice_port_name": "testport",
|
||||
"__meta_kubernetes_endpointslice_port_protocol": "TCP",
|
||||
},
|
||||
},
|
||||
Labels: model.LabelSet{
|
||||
"__meta_kubernetes_endpointslice_address_type": "IPv4",
|
||||
"__meta_kubernetes_endpointslice_name": "testendpoints",
|
||||
"__meta_kubernetes_namespace": "own-ns",
|
||||
},
|
||||
Source: "endpointslice/own-ns/testendpoints",
|
||||
},
|
||||
},
|
||||
}.Run(t)
|
||||
}
|
||||
|
|
|
@ -323,3 +323,21 @@ func TestIngressDiscoveryNamespacesV1beta1(t *testing.T) {
|
|||
expectedRes: expected,
|
||||
}.Run(t)
|
||||
}
|
||||
|
||||
func TestIngressDiscoveryOwnNamespace(t *testing.T) {
|
||||
n, c := makeDiscovery(RoleIngress, NamespaceDiscovery{IncludeOwnNamespace: true})
|
||||
|
||||
expected := expectedTargetGroups("own-ns", TLSNo)
|
||||
k8sDiscoveryTest{
|
||||
discovery: n,
|
||||
afterStart: func() {
|
||||
for _, ns := range []string{"own-ns", "non-own-ns"} {
|
||||
obj := makeIngress(TLSNo)
|
||||
obj.Namespace = ns
|
||||
c.NetworkingV1().Ingresses(obj.Namespace).Create(context.Background(), obj, metav1.CreateOptions{})
|
||||
}
|
||||
},
|
||||
expectedMaxItems: 1,
|
||||
expectedRes: expected,
|
||||
}.Run(t)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ package kubernetes
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -48,7 +49,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// kubernetesMetaLabelPrefix is the meta prefix used for all meta labels.
|
||||
// metaLabelPrefix is the meta prefix used for all meta labels.
|
||||
// in this discovery.
|
||||
metaLabelPrefix = model.MetaLabelPrefix + "kubernetes_"
|
||||
namespaceLabel = metaLabelPrefix + "namespace"
|
||||
|
@ -230,7 +231,8 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
// NamespaceDiscovery is the configuration for discovering
|
||||
// Kubernetes namespaces.
|
||||
type NamespaceDiscovery struct {
|
||||
Names []string `yaml:"names"`
|
||||
IncludeOwnNamespace bool `yaml:"own_namespace"`
|
||||
Names []string `yaml:"names"`
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
||||
|
@ -250,13 +252,21 @@ type Discovery struct {
|
|||
namespaceDiscovery *NamespaceDiscovery
|
||||
discoverers []discovery.Discoverer
|
||||
selectors roleSelector
|
||||
ownNamespace string
|
||||
}
|
||||
|
||||
func (d *Discovery) getNamespaces() []string {
|
||||
namespaces := d.namespaceDiscovery.Names
|
||||
if len(namespaces) == 0 {
|
||||
namespaces = []string{apiv1.NamespaceAll}
|
||||
includeOwnNamespace := d.namespaceDiscovery.IncludeOwnNamespace
|
||||
|
||||
if len(namespaces) == 0 && !includeOwnNamespace {
|
||||
return []string{apiv1.NamespaceAll}
|
||||
}
|
||||
|
||||
if includeOwnNamespace {
|
||||
return append(namespaces, d.ownNamespace)
|
||||
}
|
||||
|
||||
return namespaces
|
||||
}
|
||||
|
||||
|
@ -299,6 +309,12 @@ func New(l log.Logger, conf *SDConfig) (*Discovery, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ownNamespace, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not determine the pod's namespace: %w", err)
|
||||
}
|
||||
|
||||
return &Discovery{
|
||||
client: c,
|
||||
logger: l,
|
||||
|
@ -306,6 +322,7 @@ func New(l log.Logger, conf *SDConfig) (*Discovery, error) {
|
|||
namespaceDiscovery: &conf.NamespaceDiscovery,
|
||||
discoverers: make([]discovery.Discoverer, 0),
|
||||
selectors: mapSelector(conf.Selectors),
|
||||
ownNamespace: string(ownNamespace),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ func makeDiscoveryWithVersion(role Role, nsDiscovery NamespaceDiscovery, k8sVer
|
|||
logger: log.NewNopLogger(),
|
||||
role: role,
|
||||
namespaceDiscovery: &nsDiscovery,
|
||||
ownNamespace: "own-ns",
|
||||
}, clientset
|
||||
}
|
||||
|
||||
|
|
|
@ -149,6 +149,7 @@ func nodeSourceFromName(name string) string {
|
|||
|
||||
const (
|
||||
nodeNameLabel = metaLabelPrefix + "node_name"
|
||||
nodeProviderIDLabel = metaLabelPrefix + "node_provider_id"
|
||||
nodeLabelPrefix = metaLabelPrefix + "node_label_"
|
||||
nodeLabelPresentPrefix = metaLabelPrefix + "node_labelpresent_"
|
||||
nodeAnnotationPrefix = metaLabelPrefix + "node_annotation_"
|
||||
|
@ -161,6 +162,7 @@ func nodeLabels(n *apiv1.Node) model.LabelSet {
|
|||
ls := make(model.LabelSet, 2*(len(n.Labels)+len(n.Annotations))+1)
|
||||
|
||||
ls[nodeNameLabel] = lv(n.Name)
|
||||
ls[nodeProviderIDLabel] = lv(n.Spec.ProviderID)
|
||||
|
||||
for k, v := range n.Labels {
|
||||
ln := strutil.SanitizeLabelName(k)
|
||||
|
|
|
@ -25,13 +25,16 @@ import (
|
|||
"github.com/prometheus/prometheus/discovery/targetgroup"
|
||||
)
|
||||
|
||||
func makeNode(name, address string, labels, annotations map[string]string) *v1.Node {
|
||||
func makeNode(name, address, providerID string, labels, annotations map[string]string) *v1.Node {
|
||||
return &v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Labels: labels,
|
||||
Annotations: annotations,
|
||||
},
|
||||
Spec: v1.NodeSpec{
|
||||
ProviderID: providerID,
|
||||
},
|
||||
Status: v1.NodeStatus{
|
||||
Addresses: []v1.NodeAddress{
|
||||
{
|
||||
|
@ -49,7 +52,7 @@ func makeNode(name, address string, labels, annotations map[string]string) *v1.N
|
|||
}
|
||||
|
||||
func makeEnumeratedNode(i int) *v1.Node {
|
||||
return makeNode(fmt.Sprintf("test%d", i), "1.2.3.4", map[string]string{}, map[string]string{})
|
||||
return makeNode(fmt.Sprintf("test%d", i), "1.2.3.4", fmt.Sprintf("aws:///de-west-3a/i-%d", i), map[string]string{}, map[string]string{})
|
||||
}
|
||||
|
||||
func TestNodeDiscoveryBeforeStart(t *testing.T) {
|
||||
|
@ -61,6 +64,7 @@ func TestNodeDiscoveryBeforeStart(t *testing.T) {
|
|||
obj := makeNode(
|
||||
"test",
|
||||
"1.2.3.4",
|
||||
"aws:///nl-north-7b/i-03149834983492827",
|
||||
map[string]string{"test-label": "testvalue"},
|
||||
map[string]string{"test-annotation": "testannotationvalue"},
|
||||
)
|
||||
|
@ -78,6 +82,7 @@ func TestNodeDiscoveryBeforeStart(t *testing.T) {
|
|||
},
|
||||
Labels: model.LabelSet{
|
||||
"__meta_kubernetes_node_name": "test",
|
||||
"__meta_kubernetes_node_provider_id": "aws:///nl-north-7b/i-03149834983492827",
|
||||
"__meta_kubernetes_node_label_test_label": "testvalue",
|
||||
"__meta_kubernetes_node_labelpresent_test_label": "true",
|
||||
"__meta_kubernetes_node_annotation_test_annotation": "testannotationvalue",
|
||||
|
@ -109,7 +114,8 @@ func TestNodeDiscoveryAdd(t *testing.T) {
|
|||
},
|
||||
},
|
||||
Labels: model.LabelSet{
|
||||
"__meta_kubernetes_node_name": "test1",
|
||||
"__meta_kubernetes_node_name": "test1",
|
||||
"__meta_kubernetes_node_provider_id": "aws:///de-west-3a/i-1",
|
||||
},
|
||||
Source: "node/test1",
|
||||
},
|
||||
|
@ -146,6 +152,7 @@ func TestNodeDiscoveryUpdate(t *testing.T) {
|
|||
obj2 := makeNode(
|
||||
"test0",
|
||||
"1.2.3.4",
|
||||
"aws:///fr-south-1c/i-49508290343823952",
|
||||
map[string]string{"Unschedulable": "true"},
|
||||
map[string]string{},
|
||||
)
|
||||
|
@ -165,6 +172,7 @@ func TestNodeDiscoveryUpdate(t *testing.T) {
|
|||
"__meta_kubernetes_node_label_Unschedulable": "true",
|
||||
"__meta_kubernetes_node_labelpresent_Unschedulable": "true",
|
||||
"__meta_kubernetes_node_name": "test0",
|
||||
"__meta_kubernetes_node_provider_id": "aws:///fr-south-1c/i-49508290343823952",
|
||||
},
|
||||
Source: "node/test0",
|
||||
},
|
||||
|
|
|
@ -389,3 +389,21 @@ func TestPodDiscoveryNamespaces(t *testing.T) {
|
|||
expectedRes: expected,
|
||||
}.Run(t)
|
||||
}
|
||||
|
||||
func TestPodDiscoveryOwnNamespace(t *testing.T) {
|
||||
n, c := makeDiscovery(RolePod, NamespaceDiscovery{IncludeOwnNamespace: true})
|
||||
|
||||
expected := expectedPodTargetGroups("own-ns")
|
||||
k8sDiscoveryTest{
|
||||
discovery: n,
|
||||
beforeRun: func() {
|
||||
for _, ns := range []string{"own-ns", "non-own-ns"} {
|
||||
pod := makePods()
|
||||
pod.Namespace = ns
|
||||
c.CoreV1().Pods(pod.Namespace).Create(context.Background(), pod, metav1.CreateOptions{})
|
||||
}
|
||||
},
|
||||
expectedMaxItems: 1,
|
||||
expectedRes: expected,
|
||||
}.Run(t)
|
||||
}
|
||||
|
|
|
@ -254,3 +254,87 @@ func TestServiceDiscoveryNamespaces(t *testing.T) {
|
|||
},
|
||||
}.Run(t)
|
||||
}
|
||||
|
||||
func TestServiceDiscoveryOwnNamespace(t *testing.T) {
|
||||
n, c := makeDiscovery(RoleService, NamespaceDiscovery{IncludeOwnNamespace: true})
|
||||
|
||||
k8sDiscoveryTest{
|
||||
discovery: n,
|
||||
afterStart: func() {
|
||||
for _, ns := range []string{"own-ns", "non-own-ns"} {
|
||||
obj := makeService()
|
||||
obj.Namespace = ns
|
||||
c.CoreV1().Services(obj.Namespace).Create(context.Background(), obj, metav1.CreateOptions{})
|
||||
}
|
||||
},
|
||||
expectedMaxItems: 1,
|
||||
expectedRes: map[string]*targetgroup.Group{
|
||||
"svc/own-ns/testservice": {
|
||||
Targets: []model.LabelSet{
|
||||
{
|
||||
"__meta_kubernetes_service_port_protocol": "TCP",
|
||||
"__address__": "testservice.own-ns.svc:30900",
|
||||
"__meta_kubernetes_service_type": "ClusterIP",
|
||||
"__meta_kubernetes_service_cluster_ip": "10.0.0.1",
|
||||
"__meta_kubernetes_service_port_name": "testport",
|
||||
},
|
||||
},
|
||||
Labels: model.LabelSet{
|
||||
"__meta_kubernetes_service_name": "testservice",
|
||||
"__meta_kubernetes_namespace": "own-ns",
|
||||
},
|
||||
Source: "svc/own-ns/testservice",
|
||||
},
|
||||
},
|
||||
}.Run(t)
|
||||
}
|
||||
|
||||
func TestServiceDiscoveryAllNamespaces(t *testing.T) {
|
||||
n, c := makeDiscovery(RoleService, NamespaceDiscovery{})
|
||||
|
||||
k8sDiscoveryTest{
|
||||
discovery: n,
|
||||
afterStart: func() {
|
||||
for _, ns := range []string{"own-ns", "non-own-ns"} {
|
||||
obj := makeService()
|
||||
obj.Namespace = ns
|
||||
c.CoreV1().Services(obj.Namespace).Create(context.Background(), obj, metav1.CreateOptions{})
|
||||
}
|
||||
},
|
||||
expectedMaxItems: 2,
|
||||
expectedRes: map[string]*targetgroup.Group{
|
||||
"svc/own-ns/testservice": {
|
||||
Targets: []model.LabelSet{
|
||||
{
|
||||
"__meta_kubernetes_service_port_protocol": "TCP",
|
||||
"__address__": "testservice.own-ns.svc:30900",
|
||||
"__meta_kubernetes_service_type": "ClusterIP",
|
||||
"__meta_kubernetes_service_cluster_ip": "10.0.0.1",
|
||||
"__meta_kubernetes_service_port_name": "testport",
|
||||
},
|
||||
},
|
||||
Labels: model.LabelSet{
|
||||
"__meta_kubernetes_service_name": "testservice",
|
||||
"__meta_kubernetes_namespace": "own-ns",
|
||||
},
|
||||
Source: "svc/own-ns/testservice",
|
||||
},
|
||||
"svc/non-own-ns/testservice": {
|
||||
Targets: []model.LabelSet{
|
||||
{
|
||||
"__meta_kubernetes_service_port_protocol": "TCP",
|
||||
"__address__": "testservice.non-own-ns.svc:30900",
|
||||
"__meta_kubernetes_service_type": "ClusterIP",
|
||||
"__meta_kubernetes_service_cluster_ip": "10.0.0.1",
|
||||
"__meta_kubernetes_service_port_name": "testport",
|
||||
},
|
||||
},
|
||||
Labels: model.LabelSet{
|
||||
"__meta_kubernetes_service_name": "testservice",
|
||||
"__meta_kubernetes_namespace": "non-own-ns",
|
||||
},
|
||||
Source: "svc/non-own-ns/testservice",
|
||||
},
|
||||
},
|
||||
}.Run(t)
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ func init() {
|
|||
|
||||
// SDConfig is the configuration for Uyuni based service discovery.
|
||||
type SDConfig struct {
|
||||
Server config.URL `yaml:"server"`
|
||||
Server string `yaml:"server"`
|
||||
Username string `yaml:"username"`
|
||||
Password config.Secret `yaml:"password"`
|
||||
HTTPClientConfig config.HTTPClientConfig `yaml:",inline"`
|
||||
|
@ -122,11 +122,11 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if c.Server.URL == nil {
|
||||
if c.Server == "" {
|
||||
return errors.New("Uyuni SD configuration requires server host")
|
||||
}
|
||||
|
||||
_, err = url.Parse(c.Server.String())
|
||||
_, err = url.Parse(c.Server)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Uyuni Server URL is not valid")
|
||||
}
|
||||
|
@ -199,8 +199,10 @@ func getEndpointInfoForSystems(
|
|||
|
||||
// NewDiscovery returns a uyuni discovery for the given configuration.
|
||||
func NewDiscovery(conf *SDConfig, logger log.Logger) (*Discovery, error) {
|
||||
var apiURL *url.URL
|
||||
*apiURL = *conf.Server.URL
|
||||
apiURL, err := url.Parse(conf.Server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
apiURL.Path = path.Join(apiURL.Path, uyuniXMLRPCAPIPath)
|
||||
|
||||
rt, err := config.NewRoundTripperFromConfig(conf.HTTPClientConfig, "uyuni_sd")
|
||||
|
|
58
discovery/uyuni/uyuni_test.go
Normal file
58
discovery/uyuni/uyuni_test.go
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright 2020 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 uyuni
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/prometheus/prometheus/discovery/targetgroup"
|
||||
)
|
||||
|
||||
func testUpdateServices(respHandler http.HandlerFunc) ([]*targetgroup.Group, error) {
|
||||
// Create a test server with mock HTTP handler.
|
||||
ts := httptest.NewServer(respHandler)
|
||||
defer ts.Close()
|
||||
|
||||
conf := SDConfig{
|
||||
Server: ts.URL,
|
||||
}
|
||||
|
||||
md, err := NewDiscovery(&conf, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return md.refresh(context.Background())
|
||||
}
|
||||
|
||||
func TestUyuniSDHandleError(t *testing.T) {
|
||||
var (
|
||||
errTesting = "unable to login to Uyuni API: request error: bad status code - 500"
|
||||
respHandler = func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Header().Set("Content-Type", "application/xml")
|
||||
io.WriteString(w, ``)
|
||||
}
|
||||
)
|
||||
tgs, err := testUpdateServices(respHandler)
|
||||
|
||||
require.EqualError(t, err, errTesting)
|
||||
require.Equal(t, len(tgs), 0)
|
||||
}
|
|
@ -95,6 +95,10 @@ remote_write:
|
|||
# Settings related to the remote read feature.
|
||||
remote_read:
|
||||
[ - <remote_read> ... ]
|
||||
|
||||
# Storage related settings that are runtime reloadable.
|
||||
storage:
|
||||
[ - <exemplars> ... ]
|
||||
```
|
||||
|
||||
### `<scrape_config>`
|
||||
|
@ -1509,6 +1513,7 @@ node object in the address type order of `NodeInternalIP`, `NodeExternalIP`,
|
|||
Available meta labels:
|
||||
|
||||
* `__meta_kubernetes_node_name`: The name of the node object.
|
||||
* `__meta_kubernetes_node_provider_id`: The cloud provider's name for the node object.
|
||||
* `__meta_kubernetes_node_label_<labelname>`: Each label from the node object.
|
||||
* `__meta_kubernetes_node_labelpresent_<labelname>`: `true` for each label from the node object.
|
||||
* `__meta_kubernetes_node_annotation_<annotationname>`: Each annotation from the node object.
|
||||
|
@ -1597,19 +1602,20 @@ address referenced in the endpointslice object one target is discovered. If the
|
|||
additional container ports of the pod, not bound to an endpoint port, are discovered as targets as well.
|
||||
|
||||
Available meta labels:
|
||||
|
||||
* `__meta_kubernetes_namespace`: The namespace of the endpoints object.
|
||||
* `__meta_kubernetes_endpointslice_name`: The name of endpointslice object.
|
||||
* For all targets discovered directly from the endpointslice list (those not additionally inferred
|
||||
from underlying pods), the following labels are attached:
|
||||
* `__meta_kubernetes_endpointslice_address_target_kind`: Kind of the referenced object.
|
||||
* `__meta_kubernetes_endpointslice_address_target_name`: Name of referenced object.
|
||||
* `__meta_kubernetes_endpointslice_address_type`: The ip protocol family of the address of the target.
|
||||
* `__meta_kubernetes_endpointslice_endpoint_conditions_ready`: Set to `true` or `false` for the referenced endpoint's ready state.
|
||||
* `__meta_kubernetes_endpointslice_endpoint_topology_kubernetes_io_hostname`: Name of the node hosting the referenced endpoint.
|
||||
* `__meta_kubernetes_endpointslice_endpoint_topology_present_kubernetes_io_hostname`: Flag that shows if the referenced object has a kubernetes.io/hostname annotation.
|
||||
* `__meta_kubernetes_endpointslice_port`: Port of the referenced endpoint.
|
||||
* `__meta_kubernetes_endpointslice_port_name`: Named port of the referenced endpoint.
|
||||
* `__meta_kubernetes_endpointslice_port_protocol`: Protocol of the referenced endpoint.
|
||||
* `__meta_kubernetes_endpointslice_address_target_kind`: Kind of the referenced object.
|
||||
* `__meta_kubernetes_endpointslice_address_target_name`: Name of referenced object.
|
||||
* `__meta_kubernetes_endpointslice_address_type`: The ip protocol family of the address of the target.
|
||||
* `__meta_kubernetes_endpointslice_endpoint_conditions_ready`: Set to `true` or `false` for the referenced endpoint's ready state.
|
||||
* `__meta_kubernetes_endpointslice_endpoint_topology_kubernetes_io_hostname`: Name of the node hosting the referenced endpoint.
|
||||
* `__meta_kubernetes_endpointslice_endpoint_topology_present_kubernetes_io_hostname`: Flag that shows if the referenced object has a kubernetes.io/hostname annotation.
|
||||
* `__meta_kubernetes_endpointslice_port`: Port of the referenced endpoint.
|
||||
* `__meta_kubernetes_endpointslice_port_name`: Named port of the referenced endpoint.
|
||||
* `__meta_kubernetes_endpointslice_port_protocol`: Protocol of the referenced endpoint.
|
||||
* If the endpoints belong to a service, all labels of the `role: service` discovery are attached.
|
||||
* For all targets backed by a pod, all labels of the `role: pod` discovery are attached.
|
||||
|
||||
|
@ -1688,6 +1694,7 @@ tls_config:
|
|||
|
||||
# Optional namespace discovery. If omitted, all namespaces are used.
|
||||
namespaces:
|
||||
own_namespace: <bool>
|
||||
names:
|
||||
[ - <string> ]
|
||||
|
||||
|
@ -2839,3 +2846,12 @@ tls_config:
|
|||
There is a list of
|
||||
[integrations](https://prometheus.io/docs/operating/integrations/#remote-endpoints-and-storage)
|
||||
with this feature.
|
||||
|
||||
### `<exemplars>`
|
||||
|
||||
Note that exemplar storage is still considered experimental and must be enabled via `--enable-feature=exemplar-storage`.
|
||||
|
||||
```yaml
|
||||
# Configures the maximum size of the circular buffer used to store exemplars for all series. Resizable during runtime.
|
||||
[ max_exemplars: <int> | default = 100000 ]
|
||||
```
|
||||
|
|
|
@ -52,7 +52,7 @@ The remote write receiver allows Prometheus to accept remote write requests from
|
|||
|
||||
[OpenMetrics](https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#exemplars) introduces the ability for scrape targets to add exemplars to certain metrics. Exemplars are references to data outside of the MetricSet. A common use case are IDs of program traces.
|
||||
|
||||
Exemplar storage is implemented as a fixed size circular buffer that stores exemplars in memory for all series. Enabling this feature will enable the storage of exemplars scraped by Prometheus. The flag `storage.exemplars.exemplars-limit` can be used to control the size of circular buffer by # of exemplars. An exemplar with just a `traceID=<jaeger-trace-id>` uses roughly 100 bytes of memory via the in-memory exemplar storage. If the exemplar storage is enabled, we will also append the exemplars to WAL for local persistence (for WAL duration).
|
||||
Exemplar storage is implemented as a fixed size circular buffer that stores exemplars in memory for all series. Enabling this feature will enable the storage of exemplars scraped by Prometheus. The config file block [storage](configuration/configuration.md#configuration-file)/[exemplars](configuration/configuration.md#exemplars) can be used to control the size of circular buffer by # of exemplars. An exemplar with just a `traceID=<jaeger-trace-id>` uses roughly 100 bytes of memory via the in-memory exemplar storage. If the exemplar storage is enabled, we will also append the exemplars to WAL for local persistence (for WAL duration).
|
||||
|
||||
## Memory snapshot on shutdown
|
||||
|
||||
|
|
38
go.mod
38
go.mod
|
@ -3,19 +3,19 @@ module github.com/prometheus/prometheus
|
|||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go v59.4.0+incompatible
|
||||
github.com/Azure/go-autorest/autorest v0.11.22
|
||||
github.com/Azure/azure-sdk-for-go v60.1.0+incompatible
|
||||
github.com/Azure/go-autorest/autorest v0.11.23
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.17
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a
|
||||
github.com/aws/aws-sdk-go v1.42.15
|
||||
github.com/aws/aws-sdk-go v1.42.23
|
||||
github.com/cespare/xxhash/v2 v2.1.2
|
||||
github.com/containerd/containerd v1.5.7 // indirect
|
||||
github.com/dennwc/varint v1.0.0
|
||||
github.com/dgryski/go-sip13 v0.0.0-20200911182023-62edffca9245
|
||||
github.com/digitalocean/godo v1.71.0
|
||||
github.com/docker/docker v20.10.11+incompatible
|
||||
github.com/digitalocean/godo v1.73.0
|
||||
github.com/docker/docker v20.10.12+incompatible
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/edsrzf/mmap-go v1.0.0
|
||||
github.com/envoyproxy/go-control-plane v0.10.1
|
||||
|
@ -27,8 +27,8 @@ require (
|
|||
github.com/go-zookeeper/zk v1.0.2
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang/snappy v0.0.4
|
||||
github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0
|
||||
github.com/gophercloud/gophercloud v0.23.0
|
||||
github.com/google/pprof v0.0.0-20211122183932-1daafda22083
|
||||
github.com/gophercloud/gophercloud v0.24.0
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||
github.com/hashicorp/consul/api v1.11.0
|
||||
github.com/hetznercloud/hcloud-go v1.33.1
|
||||
|
@ -50,7 +50,7 @@ require (
|
|||
github.com/prometheus/client_model v0.2.0
|
||||
github.com/prometheus/common v0.32.1
|
||||
github.com/prometheus/common/sigv4 v0.1.0
|
||||
github.com/prometheus/exporter-toolkit v0.7.0
|
||||
github.com/prometheus/exporter-toolkit v0.7.1
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210223165440-c65ae3540d44
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
|
||||
|
@ -59,23 +59,23 @@ require (
|
|||
github.com/uber/jaeger-lib v2.4.1+incompatible
|
||||
go.uber.org/atomic v1.9.0
|
||||
go.uber.org/goleak v1.1.12
|
||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309
|
||||
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac
|
||||
golang.org/x/tools v0.1.7
|
||||
google.golang.org/api v0.60.0
|
||||
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c
|
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486
|
||||
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11
|
||||
golang.org/x/tools v0.1.8
|
||||
google.golang.org/api v0.63.0
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa
|
||||
google.golang.org/protobuf v1.27.1
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
k8s.io/api v0.22.4
|
||||
k8s.io/apimachinery v0.22.4
|
||||
k8s.io/client-go v0.22.4
|
||||
k8s.io/api v0.23.0
|
||||
k8s.io/apimachinery v0.23.0
|
||||
k8s.io/client-go v0.23.0
|
||||
k8s.io/klog v1.0.0
|
||||
k8s.io/klog/v2 v2.20.0
|
||||
k8s.io/klog/v2 v2.30.0
|
||||
)
|
||||
|
||||
replace (
|
||||
|
|
120
go.sum
120
go.sum
|
@ -26,8 +26,9 @@ cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWc
|
|||
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
|
||||
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
|
||||
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
|
||||
cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8=
|
||||
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
|
||||
cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY=
|
||||
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
|
@ -51,8 +52,8 @@ collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE=
|
|||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v41.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v59.4.0+incompatible h1:gDA8odnngdNd3KYHL2NoK1j9vpWBgEnFSjKKLpkC8Aw=
|
||||
github.com/Azure/azure-sdk-for-go v59.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v60.1.0+incompatible h1:j6y8ddurcaiyLfwBwPmJFaunp6BDzyQTuAgMrm1r++o=
|
||||
github.com/Azure/azure-sdk-for-go v60.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
|
@ -64,8 +65,8 @@ github.com/Azure/go-autorest/autorest v0.10.0/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUd
|
|||
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
|
||||
github.com/Azure/go-autorest/autorest v0.11.9/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
||||
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
|
||||
github.com/Azure/go-autorest/autorest v0.11.22 h1:bXiQwDjrRmBQOE67bwlvUKAC1EU1yZTPQ38c+bstZws=
|
||||
github.com/Azure/go-autorest/autorest v0.11.22/go.mod h1:BAWYUWGPEtKPzjVkp0Q6an0MJcJDsoh5Z1BFAEFs4Xs=
|
||||
github.com/Azure/go-autorest/autorest v0.11.23 h1:bRQWsW25/YkoxnIqXMPF94JW33qWDcrPMZ3bINaAruU=
|
||||
github.com/Azure/go-autorest/autorest v0.11.23/go.mod h1:BAWYUWGPEtKPzjVkp0Q6an0MJcJDsoh5Z1BFAEFs4Xs=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
|
@ -187,8 +188,8 @@ github.com/aws/aws-sdk-go v1.30.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZve
|
|||
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
||||
github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/aws/aws-sdk-go v1.40.11/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
|
||||
github.com/aws/aws-sdk-go v1.42.15 h1:RcUChuF7KzrrTqx9LAzJbLBX00LkUY7cH9T1VdxNdqk=
|
||||
github.com/aws/aws-sdk-go v1.42.15/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
|
||||
github.com/aws/aws-sdk-go v1.42.23 h1:V0V5hqMEyVelgpu1e4gMPVCJ+KhmscdNxP/NWP1iCOA=
|
||||
github.com/aws/aws-sdk-go v1.42.23/go.mod h1:gyRszuZ/icHmHAVE4gc/r+cfCmhA1AD+vqfWbgI+eHs=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/benbjohnson/immutable v0.2.1/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI=
|
||||
github.com/benbjohnson/tmpl v1.0.0/go.mod h1:igT620JFIi44B6awvU9IsDhR77IXWtFigTLil/RPdps=
|
||||
|
@ -372,8 +373,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8
|
|||
github.com/dgryski/go-sip13 v0.0.0-20190329191031-25c5027a8c7b/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20200911182023-62edffca9245 h1:9cOfvEwjQxdwKuNDTQSaMKNRvwKwgZG+U4HrjeRKHso=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20200911182023-62edffca9245/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/digitalocean/godo v1.71.0 h1:a4UZCG1kr8eQ3MmsGoPzcAwkEtJG2Lc7eelzEkfZwtA=
|
||||
github.com/digitalocean/godo v1.71.0/go.mod h1:GBmu8MkjZmNARE7IXRPmkbbnocNN8+uBm0xbEVw2LCs=
|
||||
github.com/digitalocean/godo v1.73.0 h1:VEPb2YIgvbG5WP9+2Yin6ty+1s01mTUrSEW4CO6alVc=
|
||||
github.com/digitalocean/godo v1.73.0/go.mod h1:GBmu8MkjZmNARE7IXRPmkbbnocNN8+uBm0xbEVw2LCs=
|
||||
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
||||
github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
|
@ -381,8 +382,8 @@ github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TT
|
|||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v20.10.11+incompatible h1:OqzI/g/W54LczvhnccGqniFoQghHx3pklbLuhfXpqGo=
|
||||
github.com/docker/docker v20.10.11+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.12+incompatible h1:CEeNmFM0QZIsJCZKMkZx0ZcahTiewkrgiwfYD+dfl1U=
|
||||
github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
|
@ -422,8 +423,8 @@ github.com/envoyproxy/protoc-gen-validate v0.6.2 h1:JiO+kJTpmYGjEodY7O1Zk8oZcNz1
|
|||
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
|
@ -441,6 +442,7 @@ github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5
|
|||
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
|
||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
|
||||
github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
|
@ -718,8 +720,8 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe
|
|||
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0 h1:zHs+jv3LO743/zFGcByu2KmpbliCU2AhjcGgrdTwSG4=
|
||||
github.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
||||
github.com/google/pprof v0.0.0-20211122183932-1daafda22083 h1:c8EUapQFi+kjzedr4c6WqbwMdmB95+oDBWZ5XFHFYxY=
|
||||
github.com/google/pprof v0.0.0-20211122183932-1daafda22083/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
|
@ -739,8 +741,8 @@ github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9
|
|||
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gophercloud/gophercloud v0.10.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss=
|
||||
github.com/gophercloud/gophercloud v0.23.0 h1:I3P10oKlGu3DHP9PrEWMr1ya+/+3Rc9uRHNkRZ9wO7g=
|
||||
github.com/gophercloud/gophercloud v0.23.0/go.mod h1:MRw6uyLj8uCGbIvBlqL7QW67t0QtNZnzydUzewo1Ioc=
|
||||
github.com/gophercloud/gophercloud v0.24.0 h1:jDsIMGJ1KZpAjYfQgGI2coNQj5Q83oPzuiGJRFWgMzw=
|
||||
github.com/gophercloud/gophercloud v0.24.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
|
@ -1168,8 +1170,8 @@ github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+
|
|||
github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4=
|
||||
github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI=
|
||||
github.com/prometheus/exporter-toolkit v0.6.1/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g=
|
||||
github.com/prometheus/exporter-toolkit v0.7.0 h1:XtYeVeeC5daG4txbc9+mieKq+/AK4gtIBLl9Mulrjnk=
|
||||
github.com/prometheus/exporter-toolkit v0.7.0/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g=
|
||||
github.com/prometheus/exporter-toolkit v0.7.1 h1:c6RXaK8xBVercEeUQ4tRNL8UGWzDHfvj9dseo1FcK1Y=
|
||||
github.com/prometheus/exporter-toolkit v0.7.1/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g=
|
||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
|
@ -1332,7 +1334,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||
|
@ -1414,11 +1416,12 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh
|
|||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e h1:MUP6MR3rJ7Gk9LEia0LP2ytiH6MuCfs7qYz+47jGdD8=
|
||||
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -1460,8 +1463,9 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q=
|
||||
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -1526,10 +1530,12 @@ golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qx
|
|||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309 h1:A0lJIi+hcTR6aajJH4YqKWwohY4aW9RO7oRMcdv+HKI=
|
||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -1545,8 +1551,8 @@ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ
|
|||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1 h1:B333XXssMuKQeBwiNODx4TupZy7bf4sxFZnN2ZOcvUE=
|
||||
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -1666,17 +1672,19 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 h1:2B5p2L5IfGiD7+b9BOoRMC6DgObAVZV+Fsp050NqXik=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 h1:5hpz5aRr+W1erYCL5JRhSUBJRph7l9XkNveoExlrKYk=
|
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -1696,8 +1704,9 @@ golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 h1:GZokNIeuVkl3aZHJchRrr13WCsols02MLUcz1U9is6M=
|
||||
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -1757,6 +1766,7 @@ golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjs
|
|||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200422205258-72e4a01eba43/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
|
@ -1775,8 +1785,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
|||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
|
||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -1820,8 +1830,9 @@ google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6
|
|||
google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
|
||||
google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
|
||||
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
|
||||
google.golang.org/api v0.60.0 h1:eq/zs5WPH4J9undYM9IP1O7dSr7Yh8Y0GtSCpzGzIUk=
|
||||
google.golang.org/api v0.60.0/go.mod h1:d7rl65NZAkEQ90JFzqBjcRq1TVeG5ZoGV3sSpEnnVb4=
|
||||
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
|
||||
google.golang.org/api v0.63.0 h1:n2bqqK895ygnBpdPDYetfy23K7fJ22wsrZKCyfuRkkA=
|
||||
google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
@ -1895,8 +1906,10 @@ google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEc
|
|||
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c h1:FqrtZMB5Wr+/RecOM3uPJNPfWR8Upb5hAPnt7PU6i4k=
|
||||
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0=
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
|
@ -1929,8 +1942,9 @@ google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ
|
|||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||
google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.40.1 h1:pnP7OclFFFgFi4VHQDQDaoXUVauOFyktqTsqqgzFKbc=
|
||||
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
|
@ -2006,14 +2020,14 @@ k8s.io/api v0.17.5/go.mod h1:0zV5/ungglgy2Rlm3QK8fbxkXVs+BSJWpJP/+8gUVLY=
|
|||
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
|
||||
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
|
||||
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
|
||||
k8s.io/api v0.22.4 h1:UvyHW0ezB2oIgHAxlYoo6UJQObYXU7awuNarwoHEOjw=
|
||||
k8s.io/api v0.22.4/go.mod h1:Rgs+9gIGYC5laXQSZZ9JqT5NevNgoGiOdVWi1BAB3qk=
|
||||
k8s.io/api v0.23.0 h1:WrL1gb73VSC8obi8cuYETJGXEoFNEh3LU0Pt+Sokgro=
|
||||
k8s.io/api v0.23.0/go.mod h1:8wmDdLBHBNxtOIytwLstXt5E9PddnZb0GaMcqsvDBpg=
|
||||
k8s.io/apimachinery v0.17.5/go.mod h1:ioIo1G/a+uONV7Tv+ZmCbMG1/a3kVw5YcDdncd8ugQ0=
|
||||
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
|
||||
k8s.io/apimachinery v0.22.4 h1:9uwcvPpukBw/Ri0EUmWz+49cnFtaoiyEhQTK+xOe7Ck=
|
||||
k8s.io/apimachinery v0.22.4/go.mod h1:yU6oA6Gnax9RrxGzVvPFFJ+mpnW6PBSqp0sx0I0HHW0=
|
||||
k8s.io/apimachinery v0.23.0 h1:mIfWRMjBuMdolAWJ3Fd+aPTMv3X9z+waiARMpvvb0HQ=
|
||||
k8s.io/apimachinery v0.23.0/go.mod h1:fFCTTBKvKcwTPFzjlcxp91uPFZr+JA0FubU4fLzzFYc=
|
||||
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
|
||||
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
|
||||
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
|
||||
|
@ -2021,8 +2035,8 @@ k8s.io/client-go v0.17.5/go.mod h1:S8uZpBpjJJdEH/fEyxcqg7Rn0P5jH+ilkgBHjriSmNo=
|
|||
k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
|
||||
k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
|
||||
k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
|
||||
k8s.io/client-go v0.22.4 h1:aAQ1Wk+I3bjCNk35YWUqbaueqrIonkfDPJSPDDe8Kfg=
|
||||
k8s.io/client-go v0.22.4/go.mod h1:Yzw4e5e7h1LNHA4uqnMVrpEpUs1hJOiuBsJKIlRCHDA=
|
||||
k8s.io/client-go v0.23.0 h1:vcsOqyPq7XV3QmQRCBH/t9BICJM9Q1M18qahjv+rebY=
|
||||
k8s.io/client-go v0.23.0/go.mod h1:hrDnpnK1mSr65lHHcUuIZIXDgEbzc7/683c6hyG4jTA=
|
||||
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
|
||||
k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
|
||||
k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
|
||||
|
@ -2032,22 +2046,26 @@ k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
|||
k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/kube-openapi v0.0.0-20200316234421-82d701f24f9d/go.mod h1:F+5wygcW0wmRTnM3cOgIqGivxkwSWIWT5YdsDbeAOaU=
|
||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
||||
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c h1:jvamsI1tn9V0S8jicyX82qaFC0H/NKxv2e5mbqsgR80=
|
||||
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
|
||||
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4=
|
||||
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=
|
||||
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
|
||||
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/utils v0.0.0-20200414100711-2df71ebbae66/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a h1:8dYfu/Fc9Gz2rNJKB9IQRGgQOh2clmRzNIPPY1xLY5g=
|
||||
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b h1:wxEMGetGMur3J1xuGLQY7GEQYg9bZxKn3tKo5k/eYcs=
|
||||
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s=
|
||||
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs=
|
||||
sigs.k8s.io/structured-merge-diff/v2 v2.0.1/go.mod h1:Wb7vfKAodbKgf6tn1Kl0VvGj7mRH6DGaRcixXEJXTsE=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
|
|
|
@ -85,7 +85,7 @@ func (b *BufferedSeriesIterator) Seek(t int64) chunkenc.ValueType {
|
|||
|
||||
// If the delta would cause us to seek backwards, preserve the buffer
|
||||
// and just continue regular advancement while filling the buffer on the way.
|
||||
if t0 > b.lastTime {
|
||||
if b.valueType != chunkenc.ValNone && t0 > b.lastTime {
|
||||
b.buf.reset()
|
||||
|
||||
b.valueType = b.it.Seek(t0)
|
||||
|
|
|
@ -152,6 +152,7 @@ func TestBufferedSeriesIterator(t *testing.T) {
|
|||
bufferEq([]sample{{t: 99, v: 8}, {t: 100, v: 9}})
|
||||
|
||||
require.Equal(t, chunkenc.ValNone, it.Next(), "next succeeded unexpectedly")
|
||||
require.Equal(t, chunkenc.ValNone, it.Seek(1024), "seek succeeded unexpectedly")
|
||||
}
|
||||
|
||||
// At() should not be called once Next() returns false.
|
||||
|
|
|
@ -77,7 +77,7 @@ func (b *MemoizedSeriesIterator) PeekPrev() (t int64, v float64, h *histogram.Hi
|
|||
func (b *MemoizedSeriesIterator) Seek(t int64) chunkenc.ValueType {
|
||||
t0 := t - b.delta
|
||||
|
||||
if t0 > b.lastTime {
|
||||
if b.valueType != chunkenc.ValNone && t0 > b.lastTime {
|
||||
// Reset the previously stored element because the seek advanced
|
||||
// more than the delta.
|
||||
b.prevTime = math.MinInt64
|
||||
|
|
|
@ -71,6 +71,7 @@ func TestMemoizedSeriesIterator(t *testing.T) {
|
|||
prevSampleEq(100, 9, true)
|
||||
|
||||
require.Equal(t, it.Next(), chunkenc.ValNone, "next succeeded unexpectedly")
|
||||
require.Equal(t, it.Seek(1024), chunkenc.ValNone, "seek succeeded unexpectedly")
|
||||
}
|
||||
|
||||
func BenchmarkMemoizedSeriesIterator(b *testing.B) {
|
||||
|
|
|
@ -507,7 +507,6 @@ func (t *QueueManager) sendMetadataWithBackoff(ctx context.Context, metadata []p
|
|||
// Append queues a sample to be sent to the remote storage. Blocks until all samples are
|
||||
// enqueued on their shards or a shutdown signal is received.
|
||||
func (t *QueueManager) Append(samples []record.RefSample) bool {
|
||||
var appendSample prompb.Sample
|
||||
outer:
|
||||
for _, s := range samples {
|
||||
t.seriesMtx.Lock()
|
||||
|
@ -530,9 +529,12 @@ outer:
|
|||
return false
|
||||
default:
|
||||
}
|
||||
appendSample.Value = s.V
|
||||
appendSample.Timestamp = s.T
|
||||
if t.shards.enqueue(s.Ref, writeSample{lbls, appendSample}) {
|
||||
if t.shards.enqueue(s.Ref, sampleOrExemplar{
|
||||
seriesLabels: lbls,
|
||||
timestamp: s.T,
|
||||
value: s.V,
|
||||
isSample: true,
|
||||
}) {
|
||||
continue outer
|
||||
}
|
||||
|
||||
|
@ -552,7 +554,6 @@ func (t *QueueManager) AppendExemplars(exemplars []record.RefExemplar) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
var appendExemplar prompb.Exemplar
|
||||
outer:
|
||||
for _, e := range exemplars {
|
||||
t.seriesMtx.Lock()
|
||||
|
@ -576,10 +577,12 @@ outer:
|
|||
return false
|
||||
default:
|
||||
}
|
||||
appendExemplar.Labels = labelsToLabelsProto(e.Labels, nil)
|
||||
appendExemplar.Timestamp = e.T
|
||||
appendExemplar.Value = e.V
|
||||
if t.shards.enqueue(e.Ref, writeExemplar{lbls, appendExemplar}) {
|
||||
if t.shards.enqueue(e.Ref, sampleOrExemplar{
|
||||
seriesLabels: lbls,
|
||||
timestamp: e.T,
|
||||
value: e.V,
|
||||
exemplarLabels: e.Labels,
|
||||
}) {
|
||||
continue outer
|
||||
}
|
||||
|
||||
|
@ -901,21 +904,11 @@ func (t *QueueManager) newShards() *shards {
|
|||
return s
|
||||
}
|
||||
|
||||
type writeSample struct {
|
||||
seriesLabels labels.Labels
|
||||
sample prompb.Sample
|
||||
}
|
||||
|
||||
type writeExemplar struct {
|
||||
seriesLabels labels.Labels
|
||||
exemplar prompb.Exemplar
|
||||
}
|
||||
|
||||
type shards struct {
|
||||
mtx sync.RWMutex // With the WAL, this is never actually contended.
|
||||
|
||||
qm *QueueManager
|
||||
queues []chan interface{}
|
||||
queues []*queue
|
||||
// So we can accurately track how many of each are lost during shard shutdowns.
|
||||
enqueuedSamples atomic.Int64
|
||||
enqueuedExemplars atomic.Int64
|
||||
|
@ -943,9 +936,9 @@ func (s *shards) start(n int) {
|
|||
s.qm.metrics.pendingSamples.Set(0)
|
||||
s.qm.metrics.numShards.Set(float64(n))
|
||||
|
||||
newQueues := make([]chan interface{}, n)
|
||||
newQueues := make([]*queue, n)
|
||||
for i := 0; i < n; i++ {
|
||||
newQueues[i] = make(chan interface{}, s.qm.cfg.Capacity)
|
||||
newQueues[i] = newQueue(s.qm.cfg.MaxSamplesPerSend, s.qm.cfg.Capacity)
|
||||
}
|
||||
|
||||
s.queues = newQueues
|
||||
|
@ -978,7 +971,7 @@ func (s *shards) stop() {
|
|||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
for _, queue := range s.queues {
|
||||
close(queue)
|
||||
go queue.FlushAndShutdown(s.done)
|
||||
}
|
||||
select {
|
||||
case <-s.done:
|
||||
|
@ -999,7 +992,7 @@ func (s *shards) stop() {
|
|||
|
||||
// enqueue data (sample or exemplar). If we are currently in the process of shutting down or resharding,
|
||||
// will return false; in this case, you should back off and retry.
|
||||
func (s *shards) enqueue(ref chunks.HeadSeriesRef, data interface{}) bool {
|
||||
func (s *shards) enqueue(ref chunks.HeadSeriesRef, data sampleOrExemplar) bool {
|
||||
s.mtx.RLock()
|
||||
defer s.mtx.RUnlock()
|
||||
|
||||
|
@ -1013,22 +1006,117 @@ func (s *shards) enqueue(ref chunks.HeadSeriesRef, data interface{}) bool {
|
|||
select {
|
||||
case <-s.softShutdown:
|
||||
return false
|
||||
case s.queues[shard] <- data:
|
||||
switch data.(type) {
|
||||
case writeSample:
|
||||
default:
|
||||
appended := s.queues[shard].Append(data, s.softShutdown)
|
||||
if !appended {
|
||||
return false
|
||||
}
|
||||
if data.isSample {
|
||||
s.qm.metrics.pendingSamples.Inc()
|
||||
s.enqueuedSamples.Inc()
|
||||
case writeExemplar:
|
||||
} else {
|
||||
s.qm.metrics.pendingExemplars.Inc()
|
||||
s.enqueuedExemplars.Inc()
|
||||
default:
|
||||
level.Warn(s.qm.logger).Log("msg", "Invalid object type in shards enqueue")
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func (s *shards) runShard(ctx context.Context, shardID int, queue chan interface{}) {
|
||||
type queue struct {
|
||||
batch []sampleOrExemplar
|
||||
batchQueue chan []sampleOrExemplar
|
||||
|
||||
// Since we know there are a limited number of batches out, using a stack
|
||||
// is easy and safe so a sync.Pool is not necessary.
|
||||
batchPool [][]sampleOrExemplar
|
||||
// This mutex covers adding and removing batches from the batchPool.
|
||||
poolMux sync.Mutex
|
||||
}
|
||||
|
||||
type sampleOrExemplar struct {
|
||||
seriesLabels labels.Labels
|
||||
value float64
|
||||
timestamp int64
|
||||
exemplarLabels labels.Labels
|
||||
isSample bool
|
||||
}
|
||||
|
||||
func newQueue(batchSize, capacity int) *queue {
|
||||
batches := capacity / batchSize
|
||||
return &queue{
|
||||
batch: make([]sampleOrExemplar, 0, batchSize),
|
||||
batchQueue: make(chan []sampleOrExemplar, batches),
|
||||
// batchPool should have capacity for everything in the channel + 1 for
|
||||
// the batch being processed.
|
||||
batchPool: make([][]sampleOrExemplar, 0, batches+1),
|
||||
}
|
||||
}
|
||||
|
||||
func (q *queue) Append(datum sampleOrExemplar, stop <-chan struct{}) bool {
|
||||
q.batch = append(q.batch, datum)
|
||||
if len(q.batch) == cap(q.batch) {
|
||||
select {
|
||||
case q.batchQueue <- q.batch:
|
||||
q.batch = q.newBatch(cap(q.batch))
|
||||
return true
|
||||
case <-stop:
|
||||
// Remove the sample we just appended. It will get retried.
|
||||
q.batch = q.batch[:len(q.batch)-1]
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (q *queue) Chan() <-chan []sampleOrExemplar {
|
||||
return q.batchQueue
|
||||
}
|
||||
|
||||
// Batch returns the current batch and allocates a new batch. Must not be
|
||||
// called concurrently with Append.
|
||||
func (q *queue) Batch() []sampleOrExemplar {
|
||||
batch := q.batch
|
||||
q.batch = q.newBatch(cap(batch))
|
||||
return batch
|
||||
}
|
||||
|
||||
// ReturnForReuse adds the batch buffer back to the internal pool.
|
||||
func (q *queue) ReturnForReuse(batch []sampleOrExemplar) {
|
||||
q.poolMux.Lock()
|
||||
defer q.poolMux.Unlock()
|
||||
if len(q.batchPool) < cap(q.batchPool) {
|
||||
q.batchPool = append(q.batchPool, batch[:0])
|
||||
}
|
||||
}
|
||||
|
||||
// FlushAndShutdown stops the queue and flushes any samples. No appends can be
|
||||
// made after this is called.
|
||||
func (q *queue) FlushAndShutdown(done <-chan struct{}) {
|
||||
if len(q.batch) > 0 {
|
||||
select {
|
||||
case q.batchQueue <- q.batch:
|
||||
case <-done:
|
||||
// The shard has been hard shut down, so no more samples can be
|
||||
// sent. Drop everything left in the queue.
|
||||
}
|
||||
}
|
||||
q.batch = nil
|
||||
close(q.batchQueue)
|
||||
}
|
||||
|
||||
func (q *queue) newBatch(capacity int) []sampleOrExemplar {
|
||||
q.poolMux.Lock()
|
||||
defer q.poolMux.Unlock()
|
||||
batches := len(q.batchPool)
|
||||
if batches > 0 {
|
||||
batch := q.batchPool[batches-1]
|
||||
q.batchPool = q.batchPool[:batches-1]
|
||||
return batch
|
||||
}
|
||||
return make([]sampleOrExemplar, 0, capacity)
|
||||
}
|
||||
|
||||
func (s *shards) runShard(ctx context.Context, shardID int, queue *queue) {
|
||||
defer func() {
|
||||
if s.running.Dec() == 0 {
|
||||
close(s.done)
|
||||
|
@ -1040,8 +1128,7 @@ func (s *shards) runShard(ctx context.Context, shardID int, queue chan interface
|
|||
// Send batches of at most MaxSamplesPerSend samples to the remote storage.
|
||||
// If we have fewer samples than that, flush them out after a deadline anyways.
|
||||
var (
|
||||
max = s.qm.cfg.MaxSamplesPerSend
|
||||
nPending, nPendingSamples, nPendingExemplars = 0, 0, 0
|
||||
max = s.qm.cfg.MaxSamplesPerSend
|
||||
|
||||
pBuf = proto.NewBuffer(nil)
|
||||
buf []byte
|
||||
|
@ -1050,6 +1137,7 @@ func (s *shards) runShard(ctx context.Context, shardID int, queue chan interface
|
|||
max += int(float64(max) * 0.1)
|
||||
}
|
||||
|
||||
batchQueue := queue.Chan()
|
||||
pendingData := make([]prompb.TimeSeries, max)
|
||||
for i := range pendingData {
|
||||
pendingData[i].Samples = []prompb.Sample{{}}
|
||||
|
@ -1074,8 +1162,8 @@ func (s *shards) runShard(ctx context.Context, shardID int, queue chan interface
|
|||
case <-ctx.Done():
|
||||
// In this case we drop all samples in the buffer and the queue.
|
||||
// Remove them from pending and mark them as failed.
|
||||
droppedSamples := nPendingSamples + int(s.enqueuedSamples.Load())
|
||||
droppedExemplars := nPendingExemplars + int(s.enqueuedExemplars.Load())
|
||||
droppedSamples := int(s.enqueuedSamples.Load())
|
||||
droppedExemplars := int(s.enqueuedExemplars.Load())
|
||||
s.qm.metrics.pendingSamples.Sub(float64(droppedSamples))
|
||||
s.qm.metrics.pendingExemplars.Sub(float64(droppedExemplars))
|
||||
s.qm.metrics.failedSamplesTotal.Add(float64(droppedSamples))
|
||||
|
@ -1084,66 +1172,73 @@ func (s *shards) runShard(ctx context.Context, shardID int, queue chan interface
|
|||
s.exemplarsDroppedOnHardShutdown.Add(uint32(droppedExemplars))
|
||||
return
|
||||
|
||||
case sample, ok := <-queue:
|
||||
case batch, ok := <-batchQueue:
|
||||
if !ok {
|
||||
if nPendingSamples > 0 || nPendingExemplars > 0 {
|
||||
level.Debug(s.qm.logger).Log("msg", "Flushing data to remote storage...", "samples", nPendingSamples, "exemplars", nPendingExemplars)
|
||||
s.sendSamples(ctx, pendingData[:nPending], nPendingSamples, nPendingExemplars, pBuf, &buf)
|
||||
s.qm.metrics.pendingSamples.Sub(float64(nPendingSamples))
|
||||
s.qm.metrics.pendingExemplars.Sub(float64(nPendingExemplars))
|
||||
level.Debug(s.qm.logger).Log("msg", "Done flushing.")
|
||||
}
|
||||
return
|
||||
}
|
||||
nPendingSamples, nPendingExemplars := s.populateTimeSeries(batch, pendingData)
|
||||
queue.ReturnForReuse(batch)
|
||||
n := nPendingSamples + nPendingExemplars
|
||||
s.sendSamples(ctx, pendingData[:n], nPendingSamples, nPendingExemplars, pBuf, &buf)
|
||||
|
||||
pendingData[nPending].Samples = pendingData[nPending].Samples[:0]
|
||||
if s.qm.sendExemplars {
|
||||
pendingData[nPending].Exemplars = pendingData[nPending].Exemplars[:0]
|
||||
}
|
||||
// Number of pending samples is limited by the fact that sendSamples (via sendSamplesWithBackoff)
|
||||
// retries endlessly, so once we reach max samples, if we can never send to the endpoint we'll
|
||||
// stop reading from the queue. This makes it safe to reference pendingSamples by index.
|
||||
switch d := sample.(type) {
|
||||
case writeSample:
|
||||
pendingData[nPending].Labels = labelsToLabelsProto(d.seriesLabels, pendingData[nPending].Labels)
|
||||
pendingData[nPending].Samples = append(pendingData[nPending].Samples, d.sample)
|
||||
nPendingSamples++
|
||||
nPending++
|
||||
|
||||
case writeExemplar:
|
||||
pendingData[nPending].Labels = labelsToLabelsProto(d.seriesLabels, pendingData[nPending].Labels)
|
||||
pendingData[nPending].Exemplars = append(pendingData[nPending].Exemplars, d.exemplar)
|
||||
nPendingExemplars++
|
||||
nPending++
|
||||
}
|
||||
|
||||
if nPending >= max {
|
||||
s.sendSamples(ctx, pendingData[:nPending], nPendingSamples, nPendingExemplars, pBuf, &buf)
|
||||
s.qm.metrics.pendingSamples.Sub(float64(nPendingSamples))
|
||||
s.qm.metrics.pendingExemplars.Sub(float64(nPendingExemplars))
|
||||
nPendingSamples = 0
|
||||
nPendingExemplars = 0
|
||||
nPending = 0
|
||||
|
||||
stop()
|
||||
timer.Reset(time.Duration(s.qm.cfg.BatchSendDeadline))
|
||||
}
|
||||
stop()
|
||||
timer.Reset(time.Duration(s.qm.cfg.BatchSendDeadline))
|
||||
|
||||
case <-timer.C:
|
||||
if nPendingSamples > 0 || nPendingExemplars > 0 {
|
||||
level.Debug(s.qm.logger).Log("msg", "runShard timer ticked, sending buffered data", "samples", nPendingSamples, "exemplars", nPendingExemplars, "shard", shardNum)
|
||||
s.sendSamples(ctx, pendingData[:nPending], nPendingSamples, nPendingExemplars, pBuf, &buf)
|
||||
s.qm.metrics.pendingSamples.Sub(float64(nPendingSamples))
|
||||
s.qm.metrics.pendingExemplars.Sub(float64(nPendingExemplars))
|
||||
nPendingSamples = 0
|
||||
nPendingExemplars = 0
|
||||
nPending = 0
|
||||
// We need to take the lock when getting a batch to avoid
|
||||
// concurrent Appends. Generally this will only happen on low
|
||||
// traffic instances.
|
||||
s.mtx.Lock()
|
||||
// First, we need to see if we can happen to get a batch from the queue if it filled while acquiring the lock.
|
||||
var batch []sampleOrExemplar
|
||||
select {
|
||||
case batch = <-batchQueue:
|
||||
default:
|
||||
batch = queue.Batch()
|
||||
}
|
||||
s.mtx.Unlock()
|
||||
if len(batch) > 0 {
|
||||
nPendingSamples, nPendingExemplars := s.populateTimeSeries(batch, pendingData)
|
||||
n := nPendingSamples + nPendingExemplars
|
||||
level.Debug(s.qm.logger).Log("msg", "runShard timer ticked, sending buffered data", "samples", nPendingSamples, "exemplars", nPendingExemplars, "shard", shardNum)
|
||||
s.sendSamples(ctx, pendingData[:n], nPendingSamples, nPendingExemplars, pBuf, &buf)
|
||||
}
|
||||
queue.ReturnForReuse(batch)
|
||||
timer.Reset(time.Duration(s.qm.cfg.BatchSendDeadline))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *shards) populateTimeSeries(batch []sampleOrExemplar, pendingData []prompb.TimeSeries) (int, int) {
|
||||
var nPendingSamples, nPendingExemplars int
|
||||
for nPending, d := range batch {
|
||||
pendingData[nPending].Samples = pendingData[nPending].Samples[:0]
|
||||
if s.qm.sendExemplars {
|
||||
pendingData[nPending].Exemplars = pendingData[nPending].Exemplars[:0]
|
||||
}
|
||||
// Number of pending samples is limited by the fact that sendSamples (via sendSamplesWithBackoff)
|
||||
// retries endlessly, so once we reach max samples, if we can never send to the endpoint we'll
|
||||
// stop reading from the queue. This makes it safe to reference pendingSamples by index.
|
||||
if d.isSample {
|
||||
pendingData[nPending].Labels = labelsToLabelsProto(d.seriesLabels, pendingData[nPending].Labels)
|
||||
pendingData[nPending].Samples = append(pendingData[nPending].Samples, prompb.Sample{
|
||||
Value: d.value,
|
||||
Timestamp: d.timestamp,
|
||||
})
|
||||
nPendingSamples++
|
||||
} else {
|
||||
pendingData[nPending].Labels = labelsToLabelsProto(d.seriesLabels, pendingData[nPending].Labels)
|
||||
pendingData[nPending].Exemplars = append(pendingData[nPending].Exemplars, prompb.Exemplar{
|
||||
Labels: labelsToLabelsProto(d.exemplarLabels, nil),
|
||||
Value: d.value,
|
||||
Timestamp: d.timestamp,
|
||||
})
|
||||
nPendingExemplars++
|
||||
}
|
||||
}
|
||||
return nPendingSamples, nPendingExemplars
|
||||
}
|
||||
|
||||
func (s *shards) sendSamples(ctx context.Context, samples []prompb.TimeSeries, sampleCount, exemplarCount int, pBuf *proto.Buffer, buf *[]byte) {
|
||||
begin := time.Now()
|
||||
err := s.sendSamplesWithBackoff(ctx, samples, sampleCount, exemplarCount, pBuf, buf)
|
||||
|
@ -1158,6 +1253,12 @@ func (s *shards) sendSamples(ctx context.Context, samples []prompb.TimeSeries, s
|
|||
s.qm.dataOut.incr(int64(len(samples)))
|
||||
s.qm.dataOutDuration.incr(int64(time.Since(begin)))
|
||||
s.qm.lastSendTimestamp.Store(time.Now().Unix())
|
||||
// Pending samples/exemplars also should be subtracted as an error means
|
||||
// they will not be retried.
|
||||
s.qm.metrics.pendingSamples.Sub(float64(sampleCount))
|
||||
s.qm.metrics.pendingExemplars.Sub(float64(exemplarCount))
|
||||
s.enqueuedSamples.Sub(int64(sampleCount))
|
||||
s.enqueuedExemplars.Sub(int64(exemplarCount))
|
||||
}
|
||||
|
||||
// sendSamples to the remote storage with backoff for recoverable errors.
|
||||
|
|
|
@ -578,22 +578,6 @@ func (c *TestWriteClient) waitForExpectedData(tb testing.TB) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *TestWriteClient) expectDataCount(numSamples int) {
|
||||
if !c.withWaitGroup {
|
||||
return
|
||||
}
|
||||
c.mtx.Lock()
|
||||
defer c.mtx.Unlock()
|
||||
c.wg.Add(numSamples)
|
||||
}
|
||||
|
||||
func (c *TestWriteClient) waitForExpectedDataCount() {
|
||||
if !c.withWaitGroup {
|
||||
return
|
||||
}
|
||||
c.wg.Wait()
|
||||
}
|
||||
|
||||
func (c *TestWriteClient) Store(_ context.Context, req []byte) error {
|
||||
c.mtx.Lock()
|
||||
defer c.mtx.Unlock()
|
||||
|
@ -682,7 +666,15 @@ func (c *TestBlockingWriteClient) Endpoint() string {
|
|||
return "http://test-remote-blocking.com/1234"
|
||||
}
|
||||
|
||||
func BenchmarkSampleDelivery(b *testing.B) {
|
||||
// For benchmarking the send and not the receive side.
|
||||
type NopWriteClient struct{}
|
||||
|
||||
func NewNopWriteClient() *NopWriteClient { return &NopWriteClient{} }
|
||||
func (c *NopWriteClient) Store(_ context.Context, req []byte) error { return nil }
|
||||
func (c *NopWriteClient) Name() string { return "nopwriteclient" }
|
||||
func (c *NopWriteClient) Endpoint() string { return "http://test-remote.com/1234" }
|
||||
|
||||
func BenchmarkSampleSend(b *testing.B) {
|
||||
// Send one sample per series, which is the typical remote_write case
|
||||
const numSamples = 1
|
||||
const numSeries = 10000
|
||||
|
@ -707,12 +699,13 @@ func BenchmarkSampleDelivery(b *testing.B) {
|
|||
}
|
||||
samples, series := createTimeseries(numSamples, numSeries, extraLabels...)
|
||||
|
||||
c := NewTestWriteClient()
|
||||
c := NewNopWriteClient()
|
||||
|
||||
cfg := config.DefaultQueueConfig
|
||||
mcfg := config.DefaultMetadataConfig
|
||||
cfg.BatchSendDeadline = model.Duration(100 * time.Millisecond)
|
||||
cfg.MaxShards = 1
|
||||
cfg.MinShards = 20
|
||||
cfg.MaxShards = 20
|
||||
|
||||
dir := b.TempDir()
|
||||
|
||||
|
@ -726,11 +719,9 @@ func BenchmarkSampleDelivery(b *testing.B) {
|
|||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
c.expectDataCount(len(samples))
|
||||
go m.Append(samples)
|
||||
m.Append(samples)
|
||||
m.UpdateSeriesSegment(series, i+1) // simulate what wal.Watcher.garbageCollectSeries does
|
||||
m.SeriesReset(i + 1)
|
||||
c.waitForExpectedDataCount()
|
||||
}
|
||||
// Do not include shutdown
|
||||
b.StopTimer()
|
||||
|
|
|
@ -54,7 +54,6 @@ func (h *writeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
case nil:
|
||||
case storage.ErrOutOfOrderSample, storage.ErrOutOfBounds, storage.ErrDuplicateSampleForTimestamp:
|
||||
// Indicated an out of order sample is a bad request to prevent retries.
|
||||
level.Error(h.logger).Log("msg", "Out of order sample from remote write", "err", err.Error())
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
default:
|
||||
|
@ -98,6 +97,10 @@ func (h *writeHandler) write(ctx context.Context, req *prompb.WriteRequest) (err
|
|||
for _, s := range ts.Samples {
|
||||
_, err = app.Append(0, labels, s.Timestamp, s.Value)
|
||||
if err != nil {
|
||||
switch errors.Cause(err) {
|
||||
case storage.ErrOutOfOrderSample, storage.ErrOutOfBounds, storage.ErrDuplicateSampleForTimestamp:
|
||||
level.Error(h.logger).Log("msg", "Out of order sample from remote write", "err", err.Error(), "series", labels.String(), "timestamp", s.Timestamp)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
13
tsdb/head.go
13
tsdb/head.go
|
@ -483,7 +483,9 @@ const cardinalityCacheExpirationTime = time.Duration(30) * time.Second
|
|||
// limits the ingested samples to the head min valid time.
|
||||
func (h *Head) Init(minValidTime int64) error {
|
||||
h.minValidTime.Store(minValidTime)
|
||||
defer h.postings.EnsureOrder()
|
||||
defer func() {
|
||||
h.postings.EnsureOrder()
|
||||
}()
|
||||
defer h.gc() // After loading the wal remove the obsolete data from the head.
|
||||
defer func() {
|
||||
// Loading of m-mapped chunks and snapshot can make the mint of the Head
|
||||
|
@ -696,17 +698,18 @@ func (h *Head) ApplyConfig(cfg *config.Config) error {
|
|||
}
|
||||
|
||||
// Head uses opts.MaxExemplars in combination with opts.EnableExemplarStorage
|
||||
// to decide if it should pass exemplars along to it's exemplar storage, so we
|
||||
// to decide if it should pass exemplars along to its exemplar storage, so we
|
||||
// need to update opts.MaxExemplars here.
|
||||
prevSize := h.opts.MaxExemplars.Load()
|
||||
h.opts.MaxExemplars.Store(cfg.StorageConfig.ExemplarsConfig.MaxExemplars)
|
||||
newSize := h.opts.MaxExemplars.Load()
|
||||
|
||||
if prevSize == h.opts.MaxExemplars.Load() {
|
||||
if prevSize == newSize {
|
||||
return nil
|
||||
}
|
||||
|
||||
migrated := h.exemplars.(*CircularExemplarStorage).Resize(h.opts.MaxExemplars.Load())
|
||||
level.Info(h.logger).Log("msg", "Exemplar storage resized", "from", prevSize, "to", h.opts.MaxExemplars, "migrated", migrated)
|
||||
migrated := h.exemplars.(*CircularExemplarStorage).Resize(newSize)
|
||||
level.Info(h.logger).Log("msg", "Exemplar storage resized", "from", prevSize, "to", newSize, "migrated", migrated)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -3307,3 +3307,107 @@ loop:
|
|||
require.Equal(t, len(expResult), expIdx)
|
||||
require.False(t, ss.Next()) // Only 1 series.
|
||||
}
|
||||
|
||||
// Tests https://github.com/prometheus/prometheus/issues/9725.
|
||||
func TestChunkSnapshotReplayBug(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
wlog, err := wal.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Write few series records and samples such that the series references are not in order in the WAL
|
||||
// for status_code="200".
|
||||
var buf []byte
|
||||
for i := 1; i <= 1000; i++ {
|
||||
var ref chunks.HeadSeriesRef
|
||||
if i <= 500 {
|
||||
ref = chunks.HeadSeriesRef(i * 100)
|
||||
} else {
|
||||
ref = chunks.HeadSeriesRef((i - 500) * 50)
|
||||
}
|
||||
seriesRec := record.RefSeries{
|
||||
Ref: ref,
|
||||
Labels: labels.Labels{
|
||||
{Name: "__name__", Value: "request_duration"},
|
||||
{Name: "status_code", Value: "200"},
|
||||
{Name: "foo", Value: fmt.Sprintf("baz%d", rand.Int())},
|
||||
},
|
||||
}
|
||||
// Add a sample so that the series is not garbage collected.
|
||||
samplesRec := record.RefSample{Ref: ref, T: 1000, V: 1000}
|
||||
var enc record.Encoder
|
||||
|
||||
rec := enc.Series([]record.RefSeries{seriesRec}, buf)
|
||||
buf = rec[:0]
|
||||
require.NoError(t, wlog.Log(rec))
|
||||
rec = enc.Samples([]record.RefSample{samplesRec}, buf)
|
||||
buf = rec[:0]
|
||||
require.NoError(t, wlog.Log(rec))
|
||||
}
|
||||
|
||||
// Write a corrupt snapshot to fail the replay on startup.
|
||||
snapshotName := chunkSnapshotDir(0, 100)
|
||||
cpdir := filepath.Join(dir, snapshotName)
|
||||
require.NoError(t, os.MkdirAll(cpdir, 0o777))
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(cpdir, "00000000"), []byte{1, 5, 3, 5, 6, 7, 4, 2, 2}, 0o777)
|
||||
require.NoError(t, err)
|
||||
|
||||
opts := DefaultHeadOptions()
|
||||
opts.ChunkDirRoot = dir
|
||||
opts.EnableMemorySnapshotOnShutdown = true
|
||||
head, err := NewHead(nil, nil, wlog, opts, nil)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, head.Init(math.MinInt64))
|
||||
defer func() {
|
||||
require.NoError(t, head.Close())
|
||||
}()
|
||||
|
||||
// Snapshot replay should error out.
|
||||
require.Equal(t, 1.0, prom_testutil.ToFloat64(head.metrics.snapshotReplayErrorTotal))
|
||||
|
||||
// Querying `request_duration{status_code!="200"}` should return no series since all of
|
||||
// them have status_code="200".
|
||||
q, err := NewBlockQuerier(head, math.MinInt64, math.MaxInt64)
|
||||
require.NoError(t, err)
|
||||
series := query(t, q,
|
||||
labels.MustNewMatcher(labels.MatchEqual, "__name__", "request_duration"),
|
||||
labels.MustNewMatcher(labels.MatchNotEqual, "status_code", "200"),
|
||||
)
|
||||
require.Len(t, series, 0, "there should be no series found")
|
||||
}
|
||||
|
||||
func TestChunkSnapshotTakenAfterIncompleteSnapshot(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
wlog, err := wal.NewSize(nil, nil, filepath.Join(dir, "wal"), 32768, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Write a snapshot with .tmp suffix. This used to fail taking any further snapshots or replay of snapshots.
|
||||
snapshotName := chunkSnapshotDir(0, 100) + ".tmp"
|
||||
cpdir := filepath.Join(dir, snapshotName)
|
||||
require.NoError(t, os.MkdirAll(cpdir, 0o777))
|
||||
|
||||
opts := DefaultHeadOptions()
|
||||
opts.ChunkDirRoot = dir
|
||||
opts.EnableMemorySnapshotOnShutdown = true
|
||||
head, err := NewHead(nil, nil, wlog, opts, nil)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, head.Init(math.MinInt64))
|
||||
|
||||
require.Equal(t, 0.0, prom_testutil.ToFloat64(head.metrics.snapshotReplayErrorTotal))
|
||||
|
||||
// Add some samples for the snapshot.
|
||||
app := head.Appender(context.Background())
|
||||
_, err = app.Append(0, labels.Labels{{Name: "foo", Value: "bar"}}, 10, 10)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, app.Commit())
|
||||
|
||||
// Should not return any error for a successful snapshot.
|
||||
require.NoError(t, head.Close())
|
||||
|
||||
// Verify the snapshot.
|
||||
name, idx, offset, err := LastChunkSnapshot(dir)
|
||||
require.NoError(t, err)
|
||||
require.True(t, name != "")
|
||||
require.Equal(t, 0, idx)
|
||||
require.Greater(t, offset, 0)
|
||||
}
|
||||
|
|
|
@ -880,7 +880,8 @@ func LastChunkSnapshot(dir string) (string, int, int, error) {
|
|||
|
||||
splits := strings.Split(fi.Name()[len(chunkSnapshotPrefix):], ".")
|
||||
if len(splits) != 2 {
|
||||
return "", 0, 0, errors.Errorf("chunk snapshot %s is not in the right format", fi.Name())
|
||||
// Chunk snapshots is not in the right format, we do not care about it.
|
||||
continue
|
||||
}
|
||||
|
||||
idx, err := strconv.Atoi(splits[0])
|
||||
|
|
|
@ -10,6 +10,45 @@
|
|||
// 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.
|
||||
//
|
||||
// NOTE: The functions in this file (Unquote, unquoteChar, contains, unhex)
|
||||
// have been adapted from the "strconv" package of the Go standard library
|
||||
// to work for Prometheus-style strings. Go's special-casing for single
|
||||
// quotes was removed and single quoted strings are now treated the same as
|
||||
// double-quoted ones.
|
||||
//
|
||||
// The original copyright notice from the Go project for these parts is
|
||||
// reproduced here:
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
// ========================================================================
|
||||
|
||||
package strutil
|
||||
|
||||
|
@ -24,13 +63,6 @@ var ErrSyntax = errors.New("invalid syntax")
|
|||
// Unquote interprets s as a single-quoted, double-quoted, or backquoted
|
||||
// Prometheus query language string literal, returning the string value that s
|
||||
// quotes.
|
||||
//
|
||||
// NOTE: This function as well as the necessary helper functions below
|
||||
// (unquoteChar, contains, unhex) and associated tests have been adapted from
|
||||
// the corresponding functions in the "strconv" package of the Go standard
|
||||
// library to work for Prometheus-style strings. Go's special-casing for single
|
||||
// quotes was removed and single quoted strings are now treated the same as
|
||||
// double quoted ones.
|
||||
func Unquote(s string) (t string, err error) {
|
||||
n := len(s)
|
||||
if n < 2 {
|
||||
|
|
|
@ -10,6 +10,42 @@
|
|||
// 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.
|
||||
//
|
||||
// NOTE: The test code in this file has been adapted from the "strconv"
|
||||
// package of the Go standard library to work for Prometheus-style strings.
|
||||
//
|
||||
// The original copyright notice from the Go project for these parts is
|
||||
// reproduced here:
|
||||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
// ========================================================================
|
||||
|
||||
package strutil
|
||||
|
||||
|
|
|
@ -407,9 +407,7 @@ func TestEndpoints(t *testing.T) {
|
|||
Format: &af,
|
||||
}
|
||||
|
||||
dbDir, err := ioutil.TempDir("", "tsdb-api-ready")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(dbDir)
|
||||
dbDir := t.TempDir()
|
||||
|
||||
remote := remote.NewStorage(promlog.New(&promlogConfig), prometheus.DefaultRegisterer, func() (int64, error) {
|
||||
return 0, nil
|
||||
|
@ -2344,8 +2342,7 @@ func TestAdminEndpoints(t *testing.T) {
|
|||
} {
|
||||
tc := tc
|
||||
t.Run("", func(t *testing.T) {
|
||||
dir, _ := ioutil.TempDir("", "fakeDB")
|
||||
defer func() { require.NoError(t, os.RemoveAll(dir)) }()
|
||||
dir := t.TempDir()
|
||||
|
||||
api := &API{
|
||||
db: tc.db,
|
||||
|
|
|
@ -29,29 +29,29 @@
|
|||
"bugs": {
|
||||
"url": "https://github.com/prometheus/codemirror-promql/issues"
|
||||
},
|
||||
"homepage": "https://github.com/prometheus/codemirror-promql/blob/master/README.md",
|
||||
"homepage": "https://github.com/prometheus/codemirror-promql/blob/main/README.md",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@codemirror/autocomplete": "^0.19.8",
|
||||
"@codemirror/autocomplete": "^0.19.9",
|
||||
"@codemirror/basic-setup": "^0.19.0",
|
||||
"@codemirror/highlight": "^0.19.6",
|
||||
"@codemirror/language": "^0.19.5",
|
||||
"@codemirror/language": "^0.19.7",
|
||||
"@codemirror/lint": "^0.19.3",
|
||||
"@codemirror/state": "^0.19.6",
|
||||
"@codemirror/view": "^0.19.20",
|
||||
"@lezer/common": "^0.15.8",
|
||||
"@codemirror/view": "^0.19.27",
|
||||
"@lezer/common": "^0.15.10",
|
||||
"@lezer/generator": "^0.15.2",
|
||||
"@types/chai": "^4.2.22",
|
||||
"@types/lru-cache": "^5.1.0",
|
||||
"@types/lru-cache": "^5.1.1",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"@types/node": "^16.11.10",
|
||||
"@typescript-eslint/eslint-plugin": "^5.3.1",
|
||||
"@typescript-eslint/parser": "^5.3.1",
|
||||
"@types/node": "^16.11.12",
|
||||
"@typescript-eslint/eslint-plugin": "^5.5.0",
|
||||
"@typescript-eslint/parser": "^5.5.0",
|
||||
"chai": "^4.2.0",
|
||||
"codecov": "^3.8.1",
|
||||
"eslint": "^8.3.0",
|
||||
"codecov": "^3.8.3",
|
||||
"eslint": "^8.4.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-flowtype": "^8.0.3",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
|
@ -60,20 +60,20 @@
|
|||
"mocha": "^8.4.0",
|
||||
"nock": "^13.2.1",
|
||||
"nyc": "^15.1.0",
|
||||
"prettier": "^2.4.1",
|
||||
"ts-loader": "^7.0.4",
|
||||
"prettier": "^2.5.1",
|
||||
"ts-loader": "^7.0.5",
|
||||
"ts-mocha": "^8.0.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typescript": "^4.5.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@codemirror/autocomplete": "^0.19.8",
|
||||
"@codemirror/autocomplete": "^0.19.9",
|
||||
"@codemirror/highlight": "^0.19.6",
|
||||
"@codemirror/language": "^0.19.5",
|
||||
"@codemirror/language": "^0.19.7",
|
||||
"@codemirror/lint": "^0.19.3",
|
||||
"@codemirror/state": "^0.19.6",
|
||||
"@codemirror/view": "^0.19.20",
|
||||
"@lezer/common": "^0.15.8"
|
||||
"@codemirror/view": "^0.19.27",
|
||||
"@lezer/common": "^0.15.10"
|
||||
},
|
||||
"prettier": {
|
||||
"singleQuote": true,
|
||||
|
|
|
@ -47,7 +47,7 @@ export interface CacheConfig {
|
|||
}
|
||||
|
||||
export interface PrometheusConfig {
|
||||
url: string;
|
||||
url?: string;
|
||||
lookbackInterval?: number;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
httpErrorHandler?: (error: any) => void;
|
||||
|
@ -84,7 +84,7 @@ export class HTTPPrometheusClient implements PrometheusClient {
|
|||
private readonly fetchFn: FetchFn = (input: RequestInfo, init?: RequestInit): Promise<Response> => fetch(input, init);
|
||||
|
||||
constructor(config: PrometheusConfig) {
|
||||
this.url = config.url;
|
||||
this.url = config.url ? config.url : '';
|
||||
this.errorHandler = config.httpErrorHandler;
|
||||
if (config.lookbackInterval) {
|
||||
this.lookbackInterval = config.lookbackInterval;
|
||||
|
@ -242,12 +242,15 @@ export class HTTPPrometheusClient implements PrometheusClient {
|
|||
private labelsEndpoint(): string {
|
||||
return `${this.apiPrefix}/labels`;
|
||||
}
|
||||
|
||||
private labelValuesEndpoint(): string {
|
||||
return `${this.apiPrefix}/label/:name/values`;
|
||||
}
|
||||
|
||||
private seriesEndpoint(): string {
|
||||
return `${this.apiPrefix}/series`;
|
||||
}
|
||||
|
||||
private metricMetadataEndpoint(): string {
|
||||
return `${this.apiPrefix}/metadata`;
|
||||
}
|
||||
|
|
|
@ -1247,6 +1247,37 @@ describe('autocomplete promQL test', () => {
|
|||
span: /^[a-zA-Z0-9_:]+$/,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'online autocomplete with initial metric list',
|
||||
expr: 'rat',
|
||||
pos: 3,
|
||||
conf: { remote: { cache: { initialMetricList: ['metric1', 'metric2', 'rat'] } } },
|
||||
expectedResult: {
|
||||
options: ([] as Completion[]).concat(
|
||||
[
|
||||
{
|
||||
label: 'metric1',
|
||||
type: 'constant',
|
||||
},
|
||||
{
|
||||
label: 'metric2',
|
||||
type: 'constant',
|
||||
},
|
||||
{
|
||||
label: 'rat',
|
||||
type: 'constant',
|
||||
},
|
||||
],
|
||||
functionIdentifierTerms,
|
||||
aggregateOpTerms,
|
||||
numberTerms,
|
||||
snippets
|
||||
),
|
||||
from: 0,
|
||||
to: 3,
|
||||
span: /^[a-zA-Z0-9_:]+$/,
|
||||
},
|
||||
},
|
||||
];
|
||||
testCases.forEach((value) => {
|
||||
it(value.title, async () => {
|
||||
|
|
|
@ -32,7 +32,16 @@ export interface CompleteConfiguration {
|
|||
}
|
||||
|
||||
function isPrometheusConfig(remoteConfig: PrometheusConfig | PrometheusClient): remoteConfig is PrometheusConfig {
|
||||
return (remoteConfig as PrometheusConfig).url !== undefined;
|
||||
const cfg = remoteConfig as PrometheusConfig;
|
||||
return (
|
||||
cfg.url !== undefined ||
|
||||
cfg.lookbackInterval !== undefined ||
|
||||
cfg.httpErrorHandler !== undefined ||
|
||||
cfg.fetchFn !== undefined ||
|
||||
cfg.cache !== undefined ||
|
||||
cfg.httpMethod !== undefined ||
|
||||
cfg.apiPrefix !== undefined
|
||||
);
|
||||
}
|
||||
|
||||
export function newCompleteStrategy(conf?: CompleteConfiguration): CompleteStrategy {
|
||||
|
|
383
web/ui/package-lock.json
generated
383
web/ui/package-lock.json
generated
|
@ -20,24 +20,24 @@
|
|||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@codemirror/autocomplete": "^0.19.8",
|
||||
"@codemirror/autocomplete": "^0.19.9",
|
||||
"@codemirror/basic-setup": "^0.19.0",
|
||||
"@codemirror/highlight": "^0.19.6",
|
||||
"@codemirror/language": "^0.19.5",
|
||||
"@codemirror/language": "^0.19.7",
|
||||
"@codemirror/lint": "^0.19.3",
|
||||
"@codemirror/state": "^0.19.6",
|
||||
"@codemirror/view": "^0.19.20",
|
||||
"@lezer/common": "^0.15.8",
|
||||
"@codemirror/view": "^0.19.27",
|
||||
"@lezer/common": "^0.15.10",
|
||||
"@lezer/generator": "^0.15.2",
|
||||
"@types/chai": "^4.2.22",
|
||||
"@types/lru-cache": "^5.1.0",
|
||||
"@types/lru-cache": "^5.1.1",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"@types/node": "^16.11.10",
|
||||
"@typescript-eslint/eslint-plugin": "^5.3.1",
|
||||
"@typescript-eslint/parser": "^5.3.1",
|
||||
"@types/node": "^16.11.12",
|
||||
"@typescript-eslint/eslint-plugin": "^5.5.0",
|
||||
"@typescript-eslint/parser": "^5.5.0",
|
||||
"chai": "^4.2.0",
|
||||
"codecov": "^3.8.1",
|
||||
"eslint": "^8.3.0",
|
||||
"codecov": "^3.8.3",
|
||||
"eslint": "^8.4.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-flowtype": "^8.0.3",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
|
@ -46,8 +46,8 @@
|
|||
"mocha": "^8.4.0",
|
||||
"nock": "^13.2.1",
|
||||
"nyc": "^15.1.0",
|
||||
"prettier": "^2.4.1",
|
||||
"ts-loader": "^7.0.4",
|
||||
"prettier": "^2.5.1",
|
||||
"ts-loader": "^7.0.5",
|
||||
"ts-mocha": "^8.0.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typescript": "^4.5.2"
|
||||
|
@ -56,23 +56,24 @@
|
|||
"node": ">=12.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@codemirror/autocomplete": "^0.19.8",
|
||||
"@codemirror/autocomplete": "^0.19.9",
|
||||
"@codemirror/highlight": "^0.19.6",
|
||||
"@codemirror/language": "^0.19.5",
|
||||
"@codemirror/language": "^0.19.7",
|
||||
"@codemirror/lint": "^0.19.3",
|
||||
"@codemirror/state": "^0.19.6",
|
||||
"@codemirror/view": "^0.19.20",
|
||||
"@lezer/common": "^0.15.8"
|
||||
"@codemirror/view": "^0.19.27",
|
||||
"@lezer/common": "^0.15.10"
|
||||
}
|
||||
},
|
||||
"module/codemirror-promql/node_modules/@eslint/eslintrc": {
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz",
|
||||
"integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.0.0",
|
||||
"espree": "^9.2.0",
|
||||
"globals": "^13.9.0",
|
||||
"ignore": "^4.0.6",
|
||||
"import-fresh": "^3.2.1",
|
||||
|
@ -85,11 +86,12 @@
|
|||
}
|
||||
},
|
||||
"module/codemirror-promql/node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.6.0",
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz",
|
||||
"integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@humanwhocodes/object-schema": "^1.2.0",
|
||||
"@humanwhocodes/object-schema": "^1.2.1",
|
||||
"debug": "^4.1.1",
|
||||
"minimatch": "^3.0.4"
|
||||
},
|
||||
|
@ -98,12 +100,13 @@
|
|||
}
|
||||
},
|
||||
"module/codemirror-promql/node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.5.0.tgz",
|
||||
"integrity": "sha512-4bV6fulqbuaO9UMXU0Ia0o6z6if+kmMRW8rMRyfqXj/eGrZZRGedS4n0adeGNnjr8LKAM495hrQ7Tea52UWmQA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/experimental-utils": "5.4.0",
|
||||
"@typescript-eslint/scope-manager": "5.4.0",
|
||||
"@typescript-eslint/experimental-utils": "5.5.0",
|
||||
"@typescript-eslint/scope-manager": "5.5.0",
|
||||
"debug": "^4.3.2",
|
||||
"functional-red-black-tree": "^1.0.1",
|
||||
"ignore": "^5.1.8",
|
||||
|
@ -137,14 +140,15 @@
|
|||
}
|
||||
},
|
||||
"module/codemirror-promql/node_modules/@typescript-eslint/experimental-utils": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.5.0.tgz",
|
||||
"integrity": "sha512-kjWeeVU+4lQ1SLYErRKV5yDXbWDPkpbzTUUlfAUifPYvpX0qZlrcCZ96/6oWxt3QxtK5WVhXz+KsnwW9cIW+3A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"@typescript-eslint/scope-manager": "5.4.0",
|
||||
"@typescript-eslint/types": "5.4.0",
|
||||
"@typescript-eslint/typescript-estree": "5.4.0",
|
||||
"@typescript-eslint/scope-manager": "5.5.0",
|
||||
"@typescript-eslint/types": "5.5.0",
|
||||
"@typescript-eslint/typescript-estree": "5.5.0",
|
||||
"eslint-scope": "^5.1.1",
|
||||
"eslint-utils": "^3.0.0"
|
||||
},
|
||||
|
@ -160,13 +164,14 @@
|
|||
}
|
||||
},
|
||||
"module/codemirror-promql/node_modules/@typescript-eslint/parser": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz",
|
||||
"integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "5.4.0",
|
||||
"@typescript-eslint/types": "5.4.0",
|
||||
"@typescript-eslint/typescript-estree": "5.4.0",
|
||||
"@typescript-eslint/scope-manager": "5.5.0",
|
||||
"@typescript-eslint/types": "5.5.0",
|
||||
"@typescript-eslint/typescript-estree": "5.5.0",
|
||||
"debug": "^4.3.2"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -186,12 +191,13 @@
|
|||
}
|
||||
},
|
||||
"module/codemirror-promql/node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz",
|
||||
"integrity": "sha512-0/r656RmRLo7CbN4Mdd+xZyPJ/fPCKhYdU6mnZx+8msAD8nJSP8EyCFkzbd6vNVZzZvWlMYrSNekqGrCBqFQhg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.4.0",
|
||||
"@typescript-eslint/visitor-keys": "5.4.0"
|
||||
"@typescript-eslint/types": "5.5.0",
|
||||
"@typescript-eslint/visitor-keys": "5.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
|
@ -202,9 +208,10 @@
|
|||
}
|
||||
},
|
||||
"module/codemirror-promql/node_modules/@typescript-eslint/types": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.5.0.tgz",
|
||||
"integrity": "sha512-OaYTqkW3GnuHxqsxxJ6KypIKd5Uw7bFiQJZRyNi1jbMJnK3Hc/DR4KwB6KJj6PBRkJJoaNwzMNv9vtTk87JhOg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
|
@ -214,12 +221,13 @@
|
|||
}
|
||||
},
|
||||
"module/codemirror-promql/node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.5.0.tgz",
|
||||
"integrity": "sha512-pVn8btYUiYrjonhMAO0yG8lm7RApzy2L4RC7Td/mC/qFkyf6vRbGyZozoA94+w6D2Y2GRqpMoCWcwx/EUOzyoQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.4.0",
|
||||
"@typescript-eslint/visitor-keys": "5.4.0",
|
||||
"@typescript-eslint/types": "5.5.0",
|
||||
"@typescript-eslint/visitor-keys": "5.5.0",
|
||||
"debug": "^4.3.2",
|
||||
"globby": "^11.0.4",
|
||||
"is-glob": "^4.0.3",
|
||||
|
@ -240,11 +248,12 @@
|
|||
}
|
||||
},
|
||||
"module/codemirror-promql/node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.5.0.tgz",
|
||||
"integrity": "sha512-4GzJ1kRtsWzHhdM40tv0ZKHNSbkDhF0Woi/TDwVJX6UICwJItvP7ZTXbjTkCdrors7ww0sYe0t+cIKDAJwZ7Kw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.4.0",
|
||||
"@typescript-eslint/types": "5.5.0",
|
||||
"eslint-visitor-keys": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -304,13 +313,13 @@
|
|||
}
|
||||
},
|
||||
"module/codemirror-promql/node_modules/eslint": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.3.0.tgz",
|
||||
"integrity": "sha512-aIay56Ph6RxOTC7xyr59Kt3ewX185SaGnAr8eWukoPLeriCrvGjvAubxuvaXOfsxhtwV5g0uBOsyhAom4qJdww==",
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.1.tgz",
|
||||
"integrity": "sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint/eslintrc": "^1.0.4",
|
||||
"@humanwhocodes/config-array": "^0.6.0",
|
||||
"@eslint/eslintrc": "^1.0.5",
|
||||
"@humanwhocodes/config-array": "^0.9.2",
|
||||
"ajv": "^6.10.0",
|
||||
"chalk": "^4.0.0",
|
||||
"cross-spawn": "^7.0.2",
|
||||
|
@ -321,7 +330,7 @@
|
|||
"eslint-scope": "^7.1.0",
|
||||
"eslint-utils": "^3.0.0",
|
||||
"eslint-visitor-keys": "^3.1.0",
|
||||
"espree": "^9.1.0",
|
||||
"espree": "^9.2.0",
|
||||
"esquery": "^1.4.0",
|
||||
"esutils": "^2.0.2",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
|
@ -397,9 +406,9 @@
|
|||
}
|
||||
},
|
||||
"module/codemirror-promql/node_modules/espree": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.1.0.tgz",
|
||||
"integrity": "sha512-ZgYLvCS1wxOczBYGcQT9DDWgicXwJ4dbocr9uYN+/eresBAUuBu+O4WzB21ufQ/JqQT8gyp7hJ3z8SHii32mTQ==",
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz",
|
||||
"integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"acorn": "^8.6.0",
|
||||
|
@ -1138,9 +1147,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@codemirror/autocomplete": {
|
||||
"version": "0.19.8",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-0.19.8.tgz",
|
||||
"integrity": "sha512-o4I1pRlFjhBHOYab+QfpKcW0B8FqAH+2pdmCYrkTz3bm1djVwhlMEhv1s/aTKhdjLtkfZFUbdHBi+8xe22wUCA==",
|
||||
"version": "0.19.9",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-0.19.9.tgz",
|
||||
"integrity": "sha512-Ph1LWHtFFqNUIqEVrws6I263ihe5TH+TRBPwxQ78j7st7Q67FDAmgKX6mNbUPh02dxfqQrc9qxlo5JIqKeiVdg==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^0.19.0",
|
||||
"@codemirror/state": "^0.19.4",
|
||||
|
@ -1247,9 +1256,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@codemirror/language": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-0.19.5.tgz",
|
||||
"integrity": "sha512-FnIST07vaM99mv1mJaMMLvxiHSDGgP3wdlcEZzmidndWdbxjrYYYnJzVUOEkeZJNGOfrtPRMF62UCyrTjQMR3g==",
|
||||
"version": "0.19.7",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-0.19.7.tgz",
|
||||
"integrity": "sha512-pNNUtYWMIMG0lUSKyUXJr8U0rFiCKsKFXbA2Oj17PC+S1FY99hV0z1vcntW67ekAIZw9DMEUQnLsKBuIbAUX7Q==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^0.19.0",
|
||||
"@codemirror/text": "^0.19.0",
|
||||
|
@ -1343,9 +1352,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@codemirror/view": {
|
||||
"version": "0.19.20",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.19.20.tgz",
|
||||
"integrity": "sha512-j4cI/Egdhha77pMfKQQWZmpkcF7vhe21LqdZs8hsG09OtvsPVCHUXmfB0u7nMpcX1JR8aZ3ob9g6FMr+OVtjgA==",
|
||||
"version": "0.19.27",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.19.27.tgz",
|
||||
"integrity": "sha512-Uz/LecEf7CyvMWaQBlKtbJCYn0hRnEZ2yYvuZVy9YMhmvGmES6ec7FaKw7lDFFOMLwLbBThc9kfw4DCHreHN1w==",
|
||||
"dependencies": {
|
||||
"@codemirror/rangeset": "^0.19.0",
|
||||
"@codemirror/state": "^0.19.3",
|
||||
|
@ -1441,9 +1450,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/object-schema": {
|
||||
"version": "1.2.0",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause"
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
|
||||
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config": {
|
||||
"version": "1.1.0",
|
||||
|
@ -1557,8 +1567,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@lezer/common": {
|
||||
"version": "0.15.8",
|
||||
"license": "MIT"
|
||||
"version": "0.15.10",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.10.tgz",
|
||||
"integrity": "sha512-vlr+be73zTDoQBIknBVOh/633tmbQcjxUu9PIeVeYESeBK3V6TuBW96RRFg93Y2cyK9lglz241gOgSn452HFvA=="
|
||||
},
|
||||
"node_modules/@lezer/generator": {
|
||||
"version": "0.15.2",
|
||||
|
@ -1775,9 +1786,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "16.11.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.10.tgz",
|
||||
"integrity": "sha512-3aRnHa1KlOEEhJ6+CvyHKK5vE9BcLGjtUpwvqYLRvYNQKMfabu3BwfJaA/SLW8dxe28LsNDjtHwePTuzn3gmOA==",
|
||||
"version": "16.11.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.12.tgz",
|
||||
"integrity": "sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/prop-types": {
|
||||
|
@ -4141,6 +4152,11 @@
|
|||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/immutable": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
|
||||
"integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw=="
|
||||
},
|
||||
"node_modules/import-fresh": {
|
||||
"version": "3.3.0",
|
||||
"dev": true,
|
||||
|
@ -5754,9 +5770,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "2.4.1",
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
|
||||
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
},
|
||||
|
@ -6147,9 +6164,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sanitize-html": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.5.3.tgz",
|
||||
"integrity": "sha512-DGATXd1fs/Rm287/i5FBKVYSBBUL0iAaztOA1/RFhEs4yqo39/X52i/q/CwsfCUG5cilmXSBmnQmyWfnKhBlOg==",
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.6.0.tgz",
|
||||
"integrity": "sha512-qc+NqTeaOi/QVAVs5gOY9tqIVk4r1pcUbx1Q2N1a609Os3TNlm85zll2d8g8m/RM6RWg9llir0SpAcePQVIC1w==",
|
||||
"dependencies": {
|
||||
"deepmerge": "^4.2.2",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
|
@ -6160,10 +6177,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.43.4",
|
||||
"license": "MIT",
|
||||
"version": "1.44.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.44.0.tgz",
|
||||
"integrity": "sha512-0hLREbHFXGQqls/K8X+koeP+ogFRPF4ZqetVB19b7Cst9Er8cOR0rc6RU7MaI4W1JmUShd1BPgPoeqmmgMMYFw==",
|
||||
"dependencies": {
|
||||
"chokidar": ">=3.0.0 <4.0.0"
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"sass": "sass.js"
|
||||
|
@ -7207,21 +7226,21 @@
|
|||
"name": "graph",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^0.19.8",
|
||||
"@codemirror/autocomplete": "^0.19.9",
|
||||
"@codemirror/closebrackets": "^0.19.0",
|
||||
"@codemirror/commands": "^0.19.5",
|
||||
"@codemirror/comment": "^0.19.0",
|
||||
"@codemirror/highlight": "^0.19.6",
|
||||
"@codemirror/history": "^0.19.0",
|
||||
"@codemirror/language": "^0.19.5",
|
||||
"@codemirror/language": "^0.19.7",
|
||||
"@codemirror/lint": "^0.19.3",
|
||||
"@codemirror/matchbrackets": "^0.19.3",
|
||||
"@codemirror/search": "^0.19.3",
|
||||
"@codemirror/state": "^0.19.6",
|
||||
"@codemirror/view": "^0.19.20",
|
||||
"@codemirror/view": "^0.19.27",
|
||||
"@forevolve/bootstrap-dark": "^1.0.0",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.14",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.7.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.36",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.7.2",
|
||||
"@fortawesome/react-fontawesome": "^0.1.16",
|
||||
"@nexucis/fuzzy": "^0.3.0",
|
||||
"bootstrap": "^4.6.1",
|
||||
|
@ -7241,8 +7260,8 @@
|
|||
"react-router-dom": "^5.2.1",
|
||||
"react-test-renderer": "^17.0.2",
|
||||
"reactstrap": "^8.9.0",
|
||||
"sanitize-html": "^2.5.3",
|
||||
"sass": "1.43.4",
|
||||
"sanitize-html": "^2.6.0",
|
||||
"sass": "1.44.0",
|
||||
"tempusdominus-bootstrap-4": "^5.1.2",
|
||||
"tempusdominus-core": "^5.0.3"
|
||||
},
|
||||
|
@ -7252,7 +7271,7 @@
|
|||
"@types/flot": "0.0.32",
|
||||
"@types/jest": "^27.0.3",
|
||||
"@types/jquery": "^3.5.9",
|
||||
"@types/node": "^16.11.10",
|
||||
"@types/node": "^16.11.12",
|
||||
"@types/react": "^17.0.36",
|
||||
"@types/react-copy-to-clipboard": "^5.0.2",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
|
@ -7269,7 +7288,7 @@
|
|||
"jest-canvas-mock": "^2.3.1",
|
||||
"jest-fetch-mock": "^3.0.3",
|
||||
"mutationobserver-shim": "^0.3.7",
|
||||
"prettier": "^2.4.1",
|
||||
"prettier": "^2.5.1",
|
||||
"react-scripts": "4.0.3",
|
||||
"sinon": "^12.0.1",
|
||||
"typescript": "^4.5.2"
|
||||
|
@ -27282,9 +27301,9 @@
|
|||
}
|
||||
},
|
||||
"@codemirror/autocomplete": {
|
||||
"version": "0.19.8",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-0.19.8.tgz",
|
||||
"integrity": "sha512-o4I1pRlFjhBHOYab+QfpKcW0B8FqAH+2pdmCYrkTz3bm1djVwhlMEhv1s/aTKhdjLtkfZFUbdHBi+8xe22wUCA==",
|
||||
"version": "0.19.9",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-0.19.9.tgz",
|
||||
"integrity": "sha512-Ph1LWHtFFqNUIqEVrws6I263ihe5TH+TRBPwxQ78j7st7Q67FDAmgKX6mNbUPh02dxfqQrc9qxlo5JIqKeiVdg==",
|
||||
"requires": {
|
||||
"@codemirror/language": "^0.19.0",
|
||||
"@codemirror/state": "^0.19.4",
|
||||
|
@ -27384,9 +27403,9 @@
|
|||
}
|
||||
},
|
||||
"@codemirror/language": {
|
||||
"version": "0.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-0.19.5.tgz",
|
||||
"integrity": "sha512-FnIST07vaM99mv1mJaMMLvxiHSDGgP3wdlcEZzmidndWdbxjrYYYnJzVUOEkeZJNGOfrtPRMF62UCyrTjQMR3g==",
|
||||
"version": "0.19.7",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-0.19.7.tgz",
|
||||
"integrity": "sha512-pNNUtYWMIMG0lUSKyUXJr8U0rFiCKsKFXbA2Oj17PC+S1FY99hV0z1vcntW67ekAIZw9DMEUQnLsKBuIbAUX7Q==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^0.19.0",
|
||||
"@codemirror/text": "^0.19.0",
|
||||
|
@ -27476,9 +27495,9 @@
|
|||
}
|
||||
},
|
||||
"@codemirror/view": {
|
||||
"version": "0.19.20",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.19.20.tgz",
|
||||
"integrity": "sha512-j4cI/Egdhha77pMfKQQWZmpkcF7vhe21LqdZs8hsG09OtvsPVCHUXmfB0u7nMpcX1JR8aZ3ob9g6FMr+OVtjgA==",
|
||||
"version": "0.19.27",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.19.27.tgz",
|
||||
"integrity": "sha512-Uz/LecEf7CyvMWaQBlKtbJCYn0hRnEZ2yYvuZVy9YMhmvGmES6ec7FaKw7lDFFOMLwLbBThc9kfw4DCHreHN1w==",
|
||||
"requires": {
|
||||
"@codemirror/rangeset": "^0.19.0",
|
||||
"@codemirror/state": "^0.19.3",
|
||||
|
@ -27548,7 +27567,9 @@
|
|||
}
|
||||
},
|
||||
"@humanwhocodes/object-schema": {
|
||||
"version": "1.2.0",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
|
||||
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
|
||||
"dev": true
|
||||
},
|
||||
"@istanbuljs/load-nyc-config": {
|
||||
|
@ -27623,7 +27644,9 @@
|
|||
}
|
||||
},
|
||||
"@lezer/common": {
|
||||
"version": "0.15.8"
|
||||
"version": "0.15.10",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.10.tgz",
|
||||
"integrity": "sha512-vlr+be73zTDoQBIknBVOh/633tmbQcjxUu9PIeVeYESeBK3V6TuBW96RRFg93Y2cyK9lglz241gOgSn452HFvA=="
|
||||
},
|
||||
"@lezer/generator": {
|
||||
"version": "0.15.2",
|
||||
|
@ -27808,9 +27831,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "16.11.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.10.tgz",
|
||||
"integrity": "sha512-3aRnHa1KlOEEhJ6+CvyHKK5vE9BcLGjtUpwvqYLRvYNQKMfabu3BwfJaA/SLW8dxe28LsNDjtHwePTuzn3gmOA==",
|
||||
"version": "16.11.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.12.tgz",
|
||||
"integrity": "sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/prop-types": {
|
||||
|
@ -28401,24 +28424,24 @@
|
|||
"codemirror-promql": {
|
||||
"version": "file:module/codemirror-promql",
|
||||
"requires": {
|
||||
"@codemirror/autocomplete": "^0.19.8",
|
||||
"@codemirror/autocomplete": "^0.19.9",
|
||||
"@codemirror/basic-setup": "^0.19.0",
|
||||
"@codemirror/highlight": "^0.19.6",
|
||||
"@codemirror/language": "^0.19.5",
|
||||
"@codemirror/language": "^0.19.7",
|
||||
"@codemirror/lint": "^0.19.3",
|
||||
"@codemirror/state": "^0.19.6",
|
||||
"@codemirror/view": "^0.19.20",
|
||||
"@lezer/common": "^0.15.8",
|
||||
"@codemirror/view": "^0.19.27",
|
||||
"@lezer/common": "^0.15.10",
|
||||
"@lezer/generator": "^0.15.2",
|
||||
"@types/chai": "^4.2.22",
|
||||
"@types/lru-cache": "^5.1.0",
|
||||
"@types/lru-cache": "^5.1.1",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"@types/node": "^16.11.10",
|
||||
"@typescript-eslint/eslint-plugin": "^5.3.1",
|
||||
"@typescript-eslint/parser": "^5.3.1",
|
||||
"@types/node": "^16.11.12",
|
||||
"@typescript-eslint/eslint-plugin": "^5.5.0",
|
||||
"@typescript-eslint/parser": "^5.5.0",
|
||||
"chai": "^4.2.0",
|
||||
"codecov": "^3.8.1",
|
||||
"eslint": "^8.3.0",
|
||||
"codecov": "^3.8.3",
|
||||
"eslint": "^8.4.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-flowtype": "^8.0.3",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
|
@ -28428,20 +28451,22 @@
|
|||
"mocha": "^8.4.0",
|
||||
"nock": "^13.2.1",
|
||||
"nyc": "^15.1.0",
|
||||
"prettier": "^2.4.1",
|
||||
"ts-loader": "^7.0.4",
|
||||
"prettier": "^2.5.1",
|
||||
"ts-loader": "^7.0.5",
|
||||
"ts-mocha": "^8.0.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typescript": "^4.5.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@eslint/eslintrc": {
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz",
|
||||
"integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.0.0",
|
||||
"espree": "^9.2.0",
|
||||
"globals": "^13.9.0",
|
||||
"ignore": "^4.0.6",
|
||||
"import-fresh": "^3.2.1",
|
||||
|
@ -28451,20 +28476,24 @@
|
|||
}
|
||||
},
|
||||
"@humanwhocodes/config-array": {
|
||||
"version": "0.6.0",
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz",
|
||||
"integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@humanwhocodes/object-schema": "^1.2.0",
|
||||
"@humanwhocodes/object-schema": "^1.2.1",
|
||||
"debug": "^4.1.1",
|
||||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/eslint-plugin": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.5.0.tgz",
|
||||
"integrity": "sha512-4bV6fulqbuaO9UMXU0Ia0o6z6if+kmMRW8rMRyfqXj/eGrZZRGedS4n0adeGNnjr8LKAM495hrQ7Tea52UWmQA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/experimental-utils": "5.4.0",
|
||||
"@typescript-eslint/scope-manager": "5.4.0",
|
||||
"@typescript-eslint/experimental-utils": "5.5.0",
|
||||
"@typescript-eslint/scope-manager": "5.5.0",
|
||||
"debug": "^4.3.2",
|
||||
"functional-red-black-tree": "^1.0.1",
|
||||
"ignore": "^5.1.8",
|
||||
|
@ -28480,45 +28509,55 @@
|
|||
}
|
||||
},
|
||||
"@typescript-eslint/experimental-utils": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.5.0.tgz",
|
||||
"integrity": "sha512-kjWeeVU+4lQ1SLYErRKV5yDXbWDPkpbzTUUlfAUifPYvpX0qZlrcCZ96/6oWxt3QxtK5WVhXz+KsnwW9cIW+3A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"@typescript-eslint/scope-manager": "5.4.0",
|
||||
"@typescript-eslint/types": "5.4.0",
|
||||
"@typescript-eslint/typescript-estree": "5.4.0",
|
||||
"@typescript-eslint/scope-manager": "5.5.0",
|
||||
"@typescript-eslint/types": "5.5.0",
|
||||
"@typescript-eslint/typescript-estree": "5.5.0",
|
||||
"eslint-scope": "^5.1.1",
|
||||
"eslint-utils": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/parser": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.5.0.tgz",
|
||||
"integrity": "sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/scope-manager": "5.4.0",
|
||||
"@typescript-eslint/types": "5.4.0",
|
||||
"@typescript-eslint/typescript-estree": "5.4.0",
|
||||
"@typescript-eslint/scope-manager": "5.5.0",
|
||||
"@typescript-eslint/types": "5.5.0",
|
||||
"@typescript-eslint/typescript-estree": "5.5.0",
|
||||
"debug": "^4.3.2"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz",
|
||||
"integrity": "sha512-0/r656RmRLo7CbN4Mdd+xZyPJ/fPCKhYdU6mnZx+8msAD8nJSP8EyCFkzbd6vNVZzZvWlMYrSNekqGrCBqFQhg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.4.0",
|
||||
"@typescript-eslint/visitor-keys": "5.4.0"
|
||||
"@typescript-eslint/types": "5.5.0",
|
||||
"@typescript-eslint/visitor-keys": "5.5.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/types": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.5.0.tgz",
|
||||
"integrity": "sha512-OaYTqkW3GnuHxqsxxJ6KypIKd5Uw7bFiQJZRyNi1jbMJnK3Hc/DR4KwB6KJj6PBRkJJoaNwzMNv9vtTk87JhOg==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.5.0.tgz",
|
||||
"integrity": "sha512-pVn8btYUiYrjonhMAO0yG8lm7RApzy2L4RC7Td/mC/qFkyf6vRbGyZozoA94+w6D2Y2GRqpMoCWcwx/EUOzyoQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.4.0",
|
||||
"@typescript-eslint/visitor-keys": "5.4.0",
|
||||
"@typescript-eslint/types": "5.5.0",
|
||||
"@typescript-eslint/visitor-keys": "5.5.0",
|
||||
"debug": "^4.3.2",
|
||||
"globby": "^11.0.4",
|
||||
"is-glob": "^4.0.3",
|
||||
|
@ -28527,10 +28566,12 @@
|
|||
}
|
||||
},
|
||||
"@typescript-eslint/visitor-keys": {
|
||||
"version": "5.4.0",
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.5.0.tgz",
|
||||
"integrity": "sha512-4GzJ1kRtsWzHhdM40tv0ZKHNSbkDhF0Woi/TDwVJX6UICwJItvP7ZTXbjTkCdrors7ww0sYe0t+cIKDAJwZ7Kw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.4.0",
|
||||
"@typescript-eslint/types": "5.5.0",
|
||||
"eslint-visitor-keys": "^3.0.0"
|
||||
}
|
||||
},
|
||||
|
@ -28568,13 +28609,13 @@
|
|||
}
|
||||
},
|
||||
"eslint": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.3.0.tgz",
|
||||
"integrity": "sha512-aIay56Ph6RxOTC7xyr59Kt3ewX185SaGnAr8eWukoPLeriCrvGjvAubxuvaXOfsxhtwV5g0uBOsyhAom4qJdww==",
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.1.tgz",
|
||||
"integrity": "sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@eslint/eslintrc": "^1.0.4",
|
||||
"@humanwhocodes/config-array": "^0.6.0",
|
||||
"@eslint/eslintrc": "^1.0.5",
|
||||
"@humanwhocodes/config-array": "^0.9.2",
|
||||
"ajv": "^6.10.0",
|
||||
"chalk": "^4.0.0",
|
||||
"cross-spawn": "^7.0.2",
|
||||
|
@ -28585,7 +28626,7 @@
|
|||
"eslint-scope": "^7.1.0",
|
||||
"eslint-utils": "^3.0.0",
|
||||
"eslint-visitor-keys": "^3.1.0",
|
||||
"espree": "^9.1.0",
|
||||
"espree": "^9.2.0",
|
||||
"esquery": "^1.4.0",
|
||||
"esutils": "^2.0.2",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
|
@ -28638,9 +28679,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"espree": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.1.0.tgz",
|
||||
"integrity": "sha512-ZgYLvCS1wxOczBYGcQT9DDWgicXwJ4dbocr9uYN+/eresBAUuBu+O4WzB21ufQ/JqQT8gyp7hJ3z8SHii32mTQ==",
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz",
|
||||
"integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "^8.6.0",
|
||||
|
@ -29623,21 +29664,21 @@
|
|||
"graph": {
|
||||
"version": "file:react-app",
|
||||
"requires": {
|
||||
"@codemirror/autocomplete": "^0.19.8",
|
||||
"@codemirror/autocomplete": "^0.19.9",
|
||||
"@codemirror/closebrackets": "^0.19.0",
|
||||
"@codemirror/commands": "^0.19.5",
|
||||
"@codemirror/comment": "^0.19.0",
|
||||
"@codemirror/highlight": "^0.19.6",
|
||||
"@codemirror/history": "^0.19.0",
|
||||
"@codemirror/language": "^0.19.5",
|
||||
"@codemirror/language": "^0.19.7",
|
||||
"@codemirror/lint": "^0.19.3",
|
||||
"@codemirror/matchbrackets": "^0.19.3",
|
||||
"@codemirror/search": "^0.19.3",
|
||||
"@codemirror/state": "^0.19.6",
|
||||
"@codemirror/view": "^0.19.20",
|
||||
"@codemirror/view": "^0.19.27",
|
||||
"@forevolve/bootstrap-dark": "^1.0.0",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.14",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.7.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.36",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.7.2",
|
||||
"@fortawesome/react-fontawesome": "^0.1.16",
|
||||
"@nexucis/fuzzy": "^0.3.0",
|
||||
"@testing-library/react-hooks": "^7.0.1",
|
||||
|
@ -29645,7 +29686,7 @@
|
|||
"@types/flot": "0.0.32",
|
||||
"@types/jest": "^27.0.3",
|
||||
"@types/jquery": "^3.5.9",
|
||||
"@types/node": "^16.11.10",
|
||||
"@types/node": "^16.11.12",
|
||||
"@types/react": "^17.0.36",
|
||||
"@types/react-copy-to-clipboard": "^5.0.2",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
|
@ -29673,7 +29714,7 @@
|
|||
"moment-timezone": "^0.5.34",
|
||||
"mutationobserver-shim": "^0.3.7",
|
||||
"popper.js": "^1.14.3",
|
||||
"prettier": "^2.4.1",
|
||||
"prettier": "^2.5.1",
|
||||
"react": "^17.0.2",
|
||||
"react-copy-to-clipboard": "^5.0.4",
|
||||
"react-dom": "^17.0.2",
|
||||
|
@ -29682,8 +29723,8 @@
|
|||
"react-scripts": "4.0.3",
|
||||
"react-test-renderer": "^17.0.2",
|
||||
"reactstrap": "^8.9.0",
|
||||
"sanitize-html": "^2.5.3",
|
||||
"sass": "1.43.4",
|
||||
"sanitize-html": "^2.6.0",
|
||||
"sass": "1.44.0",
|
||||
"sinon": "^12.0.1",
|
||||
"tempusdominus-bootstrap-4": "^5.1.2",
|
||||
"tempusdominus-core": "^5.0.3",
|
||||
|
@ -43260,6 +43301,11 @@
|
|||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"immutable": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
|
||||
"integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw=="
|
||||
},
|
||||
"import-fresh": {
|
||||
"version": "3.3.0",
|
||||
"dev": true,
|
||||
|
@ -44324,7 +44370,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.4.1",
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
|
||||
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
|
||||
"dev": true
|
||||
},
|
||||
"prettier-linter-helpers": {
|
||||
|
@ -44576,9 +44624,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"sanitize-html": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.5.3.tgz",
|
||||
"integrity": "sha512-DGATXd1fs/Rm287/i5FBKVYSBBUL0iAaztOA1/RFhEs4yqo39/X52i/q/CwsfCUG5cilmXSBmnQmyWfnKhBlOg==",
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.6.0.tgz",
|
||||
"integrity": "sha512-qc+NqTeaOi/QVAVs5gOY9tqIVk4r1pcUbx1Q2N1a609Os3TNlm85zll2d8g8m/RM6RWg9llir0SpAcePQVIC1w==",
|
||||
"requires": {
|
||||
"deepmerge": "^4.2.2",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
|
@ -44589,9 +44637,12 @@
|
|||
}
|
||||
},
|
||||
"sass": {
|
||||
"version": "1.43.4",
|
||||
"version": "1.44.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.44.0.tgz",
|
||||
"integrity": "sha512-0hLREbHFXGQqls/K8X+koeP+ogFRPF4ZqetVB19b7Cst9Er8cOR0rc6RU7MaI4W1JmUShd1BPgPoeqmmgMMYFw==",
|
||||
"requires": {
|
||||
"chokidar": ">=3.0.0 <4.0.0"
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"scheduler": {
|
||||
|
|
|
@ -3,21 +3,21 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^0.19.8",
|
||||
"@codemirror/autocomplete": "^0.19.9",
|
||||
"@codemirror/closebrackets": "^0.19.0",
|
||||
"@codemirror/commands": "^0.19.5",
|
||||
"@codemirror/comment": "^0.19.0",
|
||||
"@codemirror/highlight": "^0.19.6",
|
||||
"@codemirror/history": "^0.19.0",
|
||||
"@codemirror/language": "^0.19.5",
|
||||
"@codemirror/language": "^0.19.7",
|
||||
"@codemirror/lint": "^0.19.3",
|
||||
"@codemirror/matchbrackets": "^0.19.3",
|
||||
"@codemirror/search": "^0.19.3",
|
||||
"@codemirror/state": "^0.19.6",
|
||||
"@codemirror/view": "^0.19.20",
|
||||
"@codemirror/view": "^0.19.27",
|
||||
"@forevolve/bootstrap-dark": "^1.0.0",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.14",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.7.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.36",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.7.2",
|
||||
"@fortawesome/react-fontawesome": "^0.1.16",
|
||||
"@nexucis/fuzzy": "^0.3.0",
|
||||
"bootstrap": "^4.6.1",
|
||||
|
@ -37,8 +37,8 @@
|
|||
"react-router-dom": "^5.2.1",
|
||||
"react-test-renderer": "^17.0.2",
|
||||
"reactstrap": "^8.9.0",
|
||||
"sanitize-html": "^2.5.3",
|
||||
"sass": "1.43.4",
|
||||
"sanitize-html": "^2.6.0",
|
||||
"sass": "1.44.0",
|
||||
"tempusdominus-bootstrap-4": "^5.1.2",
|
||||
"tempusdominus-core": "^5.0.3"
|
||||
},
|
||||
|
@ -69,7 +69,7 @@
|
|||
"@types/flot": "0.0.32",
|
||||
"@types/jest": "^27.0.3",
|
||||
"@types/jquery": "^3.5.9",
|
||||
"@types/node": "^16.11.10",
|
||||
"@types/node": "^16.11.12",
|
||||
"@types/react": "^17.0.36",
|
||||
"@types/react-copy-to-clipboard": "^5.0.2",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
|
@ -86,7 +86,7 @@
|
|||
"jest-canvas-mock": "^2.3.1",
|
||||
"jest-fetch-mock": "^3.0.3",
|
||||
"mutationobserver-shim": "^0.3.7",
|
||||
"prettier": "^2.4.1",
|
||||
"prettier": "^2.5.1",
|
||||
"react-scripts": "4.0.3",
|
||||
"sinon": "^12.0.1",
|
||||
"typescript": "^4.5.2"
|
||||
|
|
|
@ -103,7 +103,7 @@ const App: FC<AppProps> = ({ consolesLink, agentMode }) => {
|
|||
<ServiceDiscoveryPage />
|
||||
</Route>
|
||||
<Route path="/status">
|
||||
<StatusPage />
|
||||
<StatusPage agentMode={agentMode} />
|
||||
</Route>
|
||||
<Route path="/tsdb-status">
|
||||
<TSDBStatusPage />
|
||||
|
|
|
@ -6,7 +6,7 @@ const Agent: FC = () => {
|
|||
<h2>Prometheus Agent</h2>
|
||||
<p>
|
||||
This Prometheus instance is running in <strong>agent mode</strong>. In this mode, Prometheus is only used to scrape
|
||||
discovered targets and forward them to remote write endpoints.
|
||||
discovered targets and forward the scraped metrics to remote write endpoints.
|
||||
</p>
|
||||
<p>Some features are not available in this mode, such as querying and alerting.</p>
|
||||
</>
|
||||
|
|
|
@ -83,28 +83,35 @@ const StatusWithStatusIndicator = withStatusIndicator(StatusContent);
|
|||
|
||||
StatusContent.displayName = 'Status';
|
||||
|
||||
const Status: FC = () => {
|
||||
const StatusResult: FC<{ fetchPath: string; title: string }> = ({ fetchPath, title }) => {
|
||||
const { response, isLoading, error } = useFetch(fetchPath);
|
||||
return (
|
||||
<StatusWithStatusIndicator
|
||||
key={title}
|
||||
data={response.data}
|
||||
title={title}
|
||||
isLoading={isLoading}
|
||||
error={error}
|
||||
componentTitle={title}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const Status: FC<{ agentMode: boolean }> = ({ agentMode }) => {
|
||||
const pathPrefix = usePathPrefix();
|
||||
const path = `${pathPrefix}/${API_PATH}`;
|
||||
|
||||
return (
|
||||
<>
|
||||
{[
|
||||
{ fetchResult: useFetch<Record<string, string>>(`${path}/status/runtimeinfo`), title: 'Runtime Information' },
|
||||
{ fetchResult: useFetch<Record<string, string>>(`${path}/status/buildinfo`), title: 'Build Information' },
|
||||
{ fetchResult: useFetch<Record<string, string>>(`${path}/alertmanagers`), title: 'Alertmanagers' },
|
||||
].map(({ fetchResult, title }) => {
|
||||
const { response, isLoading, error } = fetchResult;
|
||||
return (
|
||||
<StatusWithStatusIndicator
|
||||
key={title}
|
||||
data={response.data}
|
||||
title={title}
|
||||
isLoading={isLoading}
|
||||
error={error}
|
||||
componentTitle={title}
|
||||
/>
|
||||
);
|
||||
{ fetchPath: `${path}/status/runtimeinfo`, title: 'Runtime Information' },
|
||||
{ fetchPath: `${path}/status/buildinfo`, title: 'Build Information' },
|
||||
{ fetchPath: `${path}/alertmanagers`, title: 'Alertmanagers' },
|
||||
].map(({ fetchPath, title }) => {
|
||||
if (agentMode && title === 'Alertmanagers') {
|
||||
return null;
|
||||
}
|
||||
return <StatusResult fetchPath={fetchPath} title={title} />;
|
||||
})}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -112,9 +112,7 @@ func (a *dbAdapter) WALReplayStatus() (tsdb.WALReplayStatus, error) {
|
|||
func TestReadyAndHealthy(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dbDir, err := ioutil.TempDir("", "tsdb-ready")
|
||||
require.NoError(t, err)
|
||||
defer func() { require.NoError(t, os.RemoveAll(dbDir)) }()
|
||||
dbDir := t.TempDir()
|
||||
|
||||
db, err := tsdb.Open(dbDir, nil, nil, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
@ -235,9 +233,7 @@ func TestReadyAndHealthy(t *testing.T) {
|
|||
|
||||
func TestRoutePrefix(t *testing.T) {
|
||||
t.Parallel()
|
||||
dbDir, err := ioutil.TempDir("", "tsdb-ready")
|
||||
require.NoError(t, err)
|
||||
defer func() { require.NoError(t, os.RemoveAll(dbDir)) }()
|
||||
dbDir := t.TempDir()
|
||||
|
||||
db, err := tsdb.Open(dbDir, nil, nil, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
@ -404,9 +400,7 @@ func TestHTTPMetrics(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestShutdownWithStaleConnection(t *testing.T) {
|
||||
dbDir, err := ioutil.TempDir("", "tsdb-ready")
|
||||
require.NoError(t, err)
|
||||
defer func() { require.NoError(t, os.RemoveAll(dbDir)) }()
|
||||
dbDir := t.TempDir()
|
||||
|
||||
db, err := tsdb.Open(dbDir, nil, nil, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
|
Loading…
Reference in a new issue